phpoc_man
Published © GPL3+

Arduino - Serial High-Color Display

This video tutorial shows you how to program line by line.

BeginnerFull instructions provided1 hour6,479

Things used in this project

Story

Read more

Schematics

Stack Shield

1. Stack PHPoC WiFi Shield on Arduino
2. Stack RS-232 Board on PHPoC WiFi shield

wiring

Connect RS-232 board with Serial Display via RS-232 cable

Code

ArduinoRemoteDraw.ino

Arduino
// 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);
}

remote_draw.php

PHP
<?php
include_once "config.php";
include_once "/lib/sc_envs.php";

$envs = envs_read();

if($wrp_width = envs_find($envs, ENV_CODE_APP_ANY, WPD_WIDTH))
	$wrp_width = bin2int($wrp_width, 0, 2);
else
	$wrp_width = 400;

if($wrp_height = envs_find($envs, ENV_CODE_APP_ANY, WPD_HEIGHT))
	$wrp_height = bin2int($wrp_height, 0, 2);
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>

Credits

phpoc_man
62 projects • 409 followers
Contact

Comments

Please log in or sign up to comment.