Hardware components
  • Arduino UNO & Genuino UNO
  • PHPoC WiFi Shield 2 for Arduino
  • Smart RS232 Board
  • Serial High Color Display
  • RS232 cable - male to female



Demonstration





Wiring
  • Stack PHPoC WiFi Shield on Arduino
  • Stack RS-232 Board on PHPoC WiFi shield
  • Connect RS-232 board with Serial Display via RS-232 cable
Click image for larger version  Name:	20190809_114421.jpg Views:	0 Size:	83.8 KB ID:	1652Click image for larger version  Name:	20190809_114455.jpg Views:	0 Size:	92.9 KB ID:	1653





How To

1. Web User Interface

PHPoC shield has a bult-in web application, called Web Remote Pad. We will modify this Web app just by changing some line of code.
PHP Code:
<?php
include_once "config.php";
include_once 
"/lib/sc_envs.php";

$envs envs_read();

if(
$wrp_width envs_find($envsENV_CODE_APP_ANYWPD_WIDTH))
    
$wrp_width bin2int($wrp_width02);
else
    
$wrp_width 400;

if(
$wrp_height envs_find($envsENV_CODE_APP_ANYWPD_HEIGHT))
    
$wrp_height bin2int($wrp_height02);
else
    
$wrp_height 400;

?>
<!DOCTYPE html>
<html>
<head>
<title>PHPoC Shield - Web Remote Pad</title>
<meta name="viewport" content="width=device-width, initial-scale=0.7, maximum-scale=0.7">
<style>
body {text-align: center; font-family: verdana, Helvetica, Arial, sans-serif, gulim; height: 750px; }
h1 {font-weight: bold; font-size: 20pt; padding-bottom: 5px; color: navy; }
h2 {font-weight: bold; font-size: 15pt; padding-bottom: 5px; }
button {font-weight: bold; font-size: 15pt; } 
canvas {background: #000000; }
.sub-footer {margin: 0 auto; position: relative; width:<?echo ($wrp_width>400$wrp_width:400)?>px; }
.sub-footer a {position: absolute; font-size: 10pt; top: 3px; }
</style>
<script>
var PAD_WIDTH = <?echo(int)$wrp_width?>;
var PAD_HEIGHT = <?echo(int)$wrp_height?>;
var STATE_UNTOUCH    = 'U';
var STATE_START        = 'S';
var STATE_MOVE        = 'M';
var touch_x = 0, touch_y = 0;
var touch_state = STATE_UNTOUCH;
var pre_x = -1, pre_y = -1;
var ws;

function init()
{
    var remote = document.getElementById("remote");

    remote.width = PAD_WIDTH;
    remote.height = PAD_HEIGHT;
    remote.style = "border:1px solid black";

    remote.addEventListener("touchstart", mouse_down);
    remote.addEventListener("touchmove", mouse_move);
    remote.addEventListener("touchend", mouse_up);
    remote.addEventListener("touchcancel", mouse_up);

    remote.addEventListener("mousedown", mouse_down);
    remote.addEventListener("mousemove", mouse_move);
    remote.addEventListener("mouseup", mouse_up);
    //remote.addEventListener("mouseout", mouse_up);
    //remote.addEventListener("mouseleave", mouse_up);
    document.body.addEventListener("mouseup", mouse_up);

    update_pad(touch_x, touch_y);
}
function connect_onclick()
{
    if(ws == null)
    {
        var ws_host_addr = "<?echo _SERVER("HTTP_HOST")?>";
        var debug = document.getElementById("debug");

        if((navigator.platform.indexOf("Win") != -1) && (ws_host_addr.charAt(0) == "["))
        {
            // network resource identifier to UNC path name conversion
            ws_host_addr = ws_host_addr.replace(/[\[\]]/g, '');
            ws_host_addr = ws_host_addr.replace(/:/g, "-");
            ws_host_addr += ".ipv6-literal.net";
        }

        ws = new WebSocket("ws://" + ws_host_addr + "/remote_pad", "text.phpoc");

        document.getElementById("ws_state").innerHTML = "CONNECTING";

        ws.onopen = ws_onopen;
        ws.onclose = ws_onclose;
        ws.onmessage = ws_onmessage;
    }
    else
        ws.close();
}
function ws_onopen()
{
    document.getElementById("ws_state").innerHTML = "<span style='color: blue'>CONNECTED</span>";
    document.getElementById("bt_connect").innerHTML = "Disconnect";
    document.getElementById("debug").style.color = "blue";
    update_pad(touch_x, touch_y);
}
function ws_onclose()
{
    document.getElementById("ws_state").innerHTML = "<span style='color: gray'>CLOSED</span>";
    document.getElementById("bt_connect").innerHTML = "Connect";
    document.getElementById("debug").style.color = "gray";
    update_pad(touch_x, touch_y);

    ws.onopen = null;
    ws.onclose = null;
    ws.onmessage = null;
    ws = null;
}
function ws_onmessage(e_msg)
{
    e_msg = e_msg || window.event; // MessageEvent

    alert("msg : " + e_msg.data);
}
function update_pad(x, y)
{
    var remote = document.getElementById("remote");
    var ctx = remote.getContext("2d");
    ctx.lineWidth = 6;

    /* plus 0.5 for thin line */
    x =  x + PAD_WIDTH / 2 + 0.5;
    y = -y + PAD_HEIGHT / 2 + 0.5;

    if(ws && (ws.readyState == 1))
        ctx.strokeStyle = "Magenta";
    else
        ctx.strokeStyle = "gray";

    if(touch_state == STATE_START)
        ctx.beginPath();

    ctx.lineTo(x, y);
    ctx.stroke();
}
function touch_process(event)
{
    if(touch_state != STATE_UNTOUCH)
    {
        var x, y;
        if(event.changedTouches)
        {
            if( event.changedTouches.length > 1)
                return;

            var touch = event.changedTouches[0];

            x = Math.round(touch.pageX - touch.target.offsetLeft);
            y = Math.round(touch.pageY - touch.target.offsetTop);
        }
        else
        {
            x = Math.round(event.offsetX);
            y = Math.round(event.offsetY);
        }

        if(x < 0 || x > PAD_WIDTH || y < 0 || y > PAD_HEIGHT)
            return;

        if(pre_x == x && pre_y == y)
            return;

        pre_x = x;
        pre_y = y;

        touch_x = Math.round( x - PAD_WIDTH / 2);
        touch_y = Math.round(-y + PAD_HEIGHT / 2);
    }
    else
    {
        if(document.getElementById("bt_center").checked == true)
        {
            touch_x = 0;
            touch_y = 0;
        }
    }

    if(ws && (ws.readyState == 1))
        ws.send(touch_x + "," + touch_y + "," + touch_state + "\r\n");

    update_pad(touch_x, touch_y);
    document.getElementById("debug").innerHTML = "(" + touch_x + ", " + touch_y + ")";
}
function mouse_down(event)
{
    pre_x = -1;
    pre_y = -1;

    touch_state = STATE_START;
    touch_process(event);

    event.preventDefault();
}
function mouse_up(event)
{
    if(touch_state != STATE_UNTOUCH)
    {
        touch_state = STATE_UNTOUCH;
        touch_process(event);
    }

    event.preventDefault();
}
function mouse_move(event)
{
    if(touch_state != STATE_UNTOUCH)
    {
        touch_state = STATE_MOVE;
        touch_process(event);
    }

    event.preventDefault();
}
function bt_center_change()
{
    if(document.getElementById("bt_center").checked == true)
    {
        touch_x = 0;
        touch_y = 0;
        update_pad(touch_x, touch_y);
    }
}

function clear_onclick()
{
    var remote = document.getElementById("remote");
    var ctx = remote.getContext("2d");

    ctx.clearRect(0, 0, PAD_WIDTH, PAD_HEIGHT);
    if(ws && (ws.readyState == 1))
        ws.send(touch_x + "," + touch_y + "," + "C" + "\r\n"); // C: clear;
}
window.onload = init;
</script>
</head>
<body>
    <h1>Web Remote Pad</h1>
    <canvas id="remote"></canvas>
    <div class="sub-footer">
        <a href="index.php" style="left:0">HOME</a>
        <h2>WebSocket <span id="ws_state"><span style="color: gray">CLOSED</span></span></h2>
        <a href="setup_app.php#wpd" style="right:0">SETUP</a>
    </div>

    <button id="bt_connect" type="button" onclick="connect_onclick();">Connect</button>
    <button id="bt_clear" type="button" onclick="clear_onclick();">Clear</button>

</body>
</html>




2. Arduino Code

We will combine two example: WebRemotePad.ino and ExpansionSerialRS232.ino.
Code:
// Arduino Web Server - Remote Control (Touch Pad)
//
// PHPoC Shield and PHPoC WiFi Shield are Internet Shields for Arduino Uno and
// Mega.
// These Shields have the buit-in web server and WebSocket server. These Shields
// contain some buit-in embedded web apps. One of the buit-in embedded web apps
// is "Web Remote Pad". When an user clicks or touches on touchable area of this
// web app, the web app sends x, y coordinates and touch's state to Arduino via
// WebSocket.
//
// This example code shows how Arduino communicate with "Web Remote Pad".
//
// Arduino communicates with PHPoC [WiFi] Shield via pins 10, 11, 12 and 13 on
// the Uno, and pins 10, 50, 51 and 52 on the Mega. Therefore, these pins CANNOT
// be used for general I/O.
//
// This example code was written by Sollae Systems. It is released into the
// public domain.
//
// Tutorial for the example is available here:
// https://forum.phpoc.com/articles/tutorials/1247-arduino-web-server-remote-pad

#include <Phpoc.h>
#include <PhpocExpansion.h>

PhpocServer server(80);
ExpansionSerial rs232(1);

char touch_state;
int touch_x;
int touch_y;

void setup() {
  Serial.begin(115200);
    while(!Serial)
        ;

    // initialize PHPoC [WiFi] Shield:
    Phpoc.begin(PF_LOG_SPI | PF_LOG_NET);
    //Phpoc.begin();

    // start WebSocket server
    server.beginWebSocket("remote_pad");

    // print IP address of PHPoC [WiFi] Shield to serial monitor:
    Serial.print("WebSocket server address : ");
    Serial.println(Phpoc.localIP());

    // initialize expansion board
    Expansion.begin(460800);
    rs232.begin(F("115200N81N"));

    sendCmd("ClearPath");
    sendCmd("Clear");
    sendCmd("Color FF1493");
    sendCmd("LineWidth 6");
}

void loop() {
    // wait for a new client:
    PhpocClient client = server.available();

    if (client) {
        // read a string that is terminated by a carriage return and a newline
        // characters:
        String touchStr = client.readLine();

        if(touchStr) {
            // when an user clicks or touches on touchable area of web app, web app
            // sends a string to Arduino. The string includes x, y coordinates and
            // touch's state in order (separated by comma). The string is terminated
            // by a carriage return and a newline characters.
            int commaPos1 = touchStr.indexOf(',');
            int commaPos2 = touchStr.lastIndexOf(',');

            touch_y = touchStr.substring(0, commaPos1).toInt();
            touch_x = touchStr.substring(commaPos1 + 1, commaPos2).toInt();
            touch_x = 800/2 - touch_x;
            touch_y = 480/2 - touch_y;
            touch_state = touchStr.charAt(commaPos2 + 1);

            // touch's state is a character. The possible values of touch's state are
            // 'S', 'M' and 'U', standing for "touch start", "touch move" and "touch
            // end", respectively.
            if(touch_state == 'S')
                sendCmd(String("MoveTo ") + touch_x + " "  + touch_y);
            else
            if(touch_state == 'M' || touch_state == 'U')
                sendCmd(String("LineTo ") + touch_x + " "  + touch_y);
            if(touch_state == 'C') {
                sendCmd("ClearPath");
                sendCmd("Clear");
            }

            sendCmd("DrawPath");

            Serial.print(touch_x);
            Serial.print(", ");
            Serial.println(touch_y);

        }
    }
}

void sendCmd(String cmd)
{
    String frame = "\n" + cmd + "\r";
    rs232.print(frame);
}





Video Tutorial