Things used in this project

Schematics

wiring_SLhmifR38E.png
Wiring slhmifr38e

Code

Arduino CodeArduino
#include "SPI.h"
#include "Phpoc.h"
#include <Wire.h>
#include <Adafruit_GFX.h>
#include "Adafruit_LEDBackpack.h"

PhpocServer server(80);
Adafruit_BicolorMatrix matrix = Adafruit_BicolorMatrix();

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

	Phpoc.begin(PF_LOG_SPI | PF_LOG_NET);
	//Phpoc.begin();

	server.beginWebSocket("remote_keypad");

	Serial.print("WebSocket server address : ");
	Serial.println(Phpoc.localIP());
	
	matrix.begin(0x70);	// pass in the address
	matrix.setRotation(3);
	matrix.setTextColor(LED_RED);
 
}

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

	if (client) {
		if (client.available() > 0) {
			// read the bytes incoming from the client:
			char thisChar = client.read();
			
			matrix.clear();
			matrix.setCursor(1,0);
			matrix.print(thisChar);
			matrix.writeDisplay();
		}
	}
}
User Interface (remote_keypad.php)PHP
<!DOCTYPE html>
<html>
<head>
<title>PHPoC Shield - Web Remote Control for Arduino</title>
<meta name="viewport" content="width=device-width, initial-scale=0.7, maximum-scale=0.7">
<style>
body { text-align: center; }
h1 { font-weight: bold; font-size: 25pt; }
h2 { font-weight: bold; font-size: 15pt; }
button { font-weight: bold; font-size: 15pt; }
</style>
<script>
var BOX_WIDTH = 120;
var BOX_HEIGHT = 120;
var KEY_WIDTH = 85;
var KEY_HEIGHT = 85;
var OFFSET_X = 65;
var OFFSET_Y = 40;
var canvas_width, canvas_height;
var push_info = [];
var push_text = [ "1", "2", "3", "4", "5", "6", "7", "8", "9", "*", "0", "#" ];
var push_font = "bold 50px Arial";
var ws;

function init()
{
	var remote = document.getElementById("remote");
	
	remote.width = canvas_width = BOX_WIDTH * 3 + OFFSET_X * 2;
	remote.height = canvas_height = BOX_HEIGHT * 4 + OFFSET_Y * 2;
	
	var ctx = remote.getContext("2d");
	ctx.strokeStyle = "white";
	ctx.lineJoin = "round";

	for(var push_id = 0; push_id < 12; push_id++)
	{
		if(push_id == 9 || push_id == 11)
			push_info[push_id] = {state:false, identifier:null, font:push_font, text:push_text[push_id], color_1:"Crimson", color_2:"Red"};
		else
			push_info[push_id] = {state:false, identifier:null, font:push_font, text:push_text[push_id], color_1:"#1E90FF", color_2:"Aqua"};
	}
	
	update_view();
	
	remote.addEventListener("touchstart", mouse_down);
	remote.addEventListener("touchend", mouse_up);
	remote.addEventListener("touchmove", mouse_move);

	remote.addEventListener("mousedown", mouse_down);
	remote.addEventListener("mouseup", mouse_up);
	remote.addEventListener("mousemove", mouse_move);
	remote.addEventListener("mouseout", mouse_up);
}
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_keypad", "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 = "<font color='blue'>CONNECTED</font>";
	document.getElementById("bt_connect").innerHTML = "Disconnect";

	for(var push_id = 0; push_id < 12; push_id++)
		push_info[push_id].state = false;
		
	update_view();
}
function ws_onclose()
{
	document.getElementById("ws_state").innerHTML = "<font color='gray'>CLOSED</font>";
	document.getElementById("bt_connect").innerHTML = "Connect";

	ws.onopen = null;
	ws.onclose = null;
	ws.onmessage = null;
	ws = null;

	for(var push_id = 0; push_id < 12; push_id++)
		push_info[push_id].state = false;
		
	update_view();
}
function ws_onmessage(e_msg)
{
	e_msg = e_msg || window.event; // MessageEvent

	alert("msg : " + e_msg.data);
}
function update_view()
{
	var remote = document.getElementById("remote");
	var ctx = remote.getContext("2d");
	var cx, cy, x, y;
	
	ctx.clearRect(0, 0, canvas_width, canvas_height);
	ctx.lineWidth = 4;
	ctx.fillStyle = "black";
	ctx.shadowBlur = 0;
	
	var margin, radius;
	for(var i = 0; i < 3; i++)
	{
		if(i == 0)
			margin = 0;
		else if(i == 1)
			margin = 20;
		else
			margin = 28;
		
		radius = 45 - margin;
		
		ctx.beginPath(); 
		ctx.arc(margin + radius, margin + radius, radius, Math.PI, 1.5*Math.PI);
		ctx.lineTo(margin + radius, margin);
		ctx.lineTo(canvas_width - margin - radius, margin);
		ctx.arc(canvas_width - margin - radius, margin + radius, radius, 1.5*Math.PI, 0);
		ctx.lineTo(canvas_width - margin, canvas_height - margin - radius);
		ctx.arc(canvas_width - margin - radius, canvas_height - margin - radius, radius, 0, 0.5*Math.PI);
		ctx.lineTo(margin + radius, canvas_height - margin);
		ctx.arc(margin + radius, canvas_height - margin - radius, radius, 0.5*Math.PI, Math.PI);
		ctx.closePath();
		
		if(i == 0)
			ctx.fill();
		else
			ctx.stroke();
	}
	
	ctx.translate(OFFSET_X, OFFSET_Y);
	
	for(var push_id = 0; push_id < 12; push_id++)
	{
		var push = push_info[push_id];
		var state = push.state;
		
		if(state)
		{
			ctx.fillStyle = push.color_2;
			ctx.shadowBlur = 80;
			ctx.shadowColor = push.color_2;
		}
		else
		{
			ctx.shadowBlur = 0;
			ctx.fillStyle = push.color_1;
		}
		
		cx = BOX_WIDTH * (push_id % 3) + BOX_WIDTH / 2;
		cy = BOX_HEIGHT * parseInt(push_id / 3) + BOX_HEIGHT / 2;
		x = cx - KEY_WIDTH / 2;
		y = cy - KEY_HEIGHT / 2;
		
		ctx.beginPath();
		ctx.lineWidth = 7;
		ctx.rect(x, y, KEY_WIDTH, KEY_HEIGHT);
		ctx.fill();
		ctx.stroke();

		ctx.font = push.font;
		ctx.textAlign = "center";
		ctx.textBaseline = "middle";
		ctx.fillStyle = "white";
		ctx.fillText(push.text, cx, cy);

		if(!state)
			push.identifier = null;
	}
	
	ctx.translate(-OFFSET_X, -OFFSET_Y);
}

function find_push_id(x, y)
{
	var cx, cy, push_id;
	
	x -= OFFSET_X;
	y -= OFFSET_Y;
	
	if((x < 0) || (x >= BOX_WIDTH * 3))
		return 12;

	if((y < 0) || (y >= BOX_HEIGHT * 4))
		return 12;

	push_id = parseInt(x / BOX_WIDTH);
	push_id += 3 * parseInt(y / BOX_WIDTH);

	cx = BOX_WIDTH * (push_id % 3) + BOX_WIDTH / 2;
	cy = BOX_HEIGHT * parseInt(push_id / 3) + BOX_HEIGHT / 2;

	if( Math.abs(x - cx) < KEY_WIDTH && Math.abs(y - cy) < KEY_HEIGHT)
		return push_id;
	else
		return 12;
}
function mouse_down(event)
{
	var debug = document.getElementById("debug");
	var x, y, push_id;

	if(event.changedTouches)
	{
		for(var touch_id = 0; touch_id < event.changedTouches.length; touch_id++)
		{
			var touch = event.changedTouches[touch_id];

			x = touch.pageX - touch.target.offsetLeft;
			y = touch.pageY - touch.target.offsetTop;

			push_id = find_push_id(x, y);

			if(push_id < 12)
			{
				var push = push_info[push_id];

				if(push.state == false)
				{
					var key = push_info[push_id].text;
					send_key(key);
					push_info[push_id].state = true;
					update_view();
					push.identifier = touch.identifier;
				}
			}
		}
	}
	else
	{
		x = event.offsetX;
		y = event.offsetY;

		push_id = find_push_id(x, y);

		if(push_id < 12)
		{
			var key = push_info[push_id].text;
			send_key(key);
			push_info[push_id].state = true;
			update_view();
		}
	}

	event.preventDefault();
}
function mouse_up(event)
{
	var debug = document.getElementById("debug");
	var push_id;

	if(event.changedTouches)
	{
		for(var touch_id = 0; touch_id < event.changedTouches.length; touch_id++)
		{
			var touch = event.changedTouches[touch_id];

			for(var push_id = 0; push_id < 12; push_id++)
			{
				if(touch.identifier == push_info[push_id].identifier)
					break;
			}

			if(push_id < 12)
			{
				push_info[push_id].state = false;
				update_view();
			}
		}
	}
	else
	{
		for(var push_id = 0; push_id < 12; push_id++)
		{
			if(push_info[push_id].state)
			{
				push_info[push_id].state = false;
				update_view();
				break;
			}
		}
	}

	event.preventDefault();
}
function mouse_move(event)
{
	event.preventDefault();
}
function send_key(key)
{
	if(ws && (ws.readyState == 1))
		ws.send(key);
}
window.onload = init;
</script>
</head>

<body>

<p>
<h1>Web-based Remote Keypad</h1>
</p>

<canvas id="remote"></canvas><br>

<h2>WebSocket <font id="ws_state" color="gray">CLOSED</font></h2>
<button id="bt_connect" type="button" onclick="connect_onclick();">Connect</button>
<span id="debug"></span>

</body>
</html>

Credits

Replications

Did you replicate this project? Share it!

I made one

Love this project? Think it could be improved? Tell us what you think!

Give feedback

Comments

Similar projects you might like

Using CA and CC RGB LED by Current Sourcing and Sinking!
Easy
  • 444
  • 48

Protip

RGB LEDs are of two types, common cathode and common anode which behave differently with same Arduino code; how to resolve this.

Quadrature Encoder Demo
Easy
  • 64
  • 3

Full instructions

Use a 3D printed encoder wheel, LED, and 2 photocells to demonstrate how a quadrature encoder works.

Simple Dark Sensor
Easy
  • 69
  • 2

A simple dark sensor with or without Arduino.

Arduino Amiga Floppy Disk Reader
Easy
  • 3,239
  • 5

Work in progress

An Arduino powered floppy disk controller and reader for making disk images from old AmigaDOS floppy disks.

Simple RGB LED Light with Fade
Easy
  • 17
  • 1

A Simple RGB LED light on Arduino UNO with Fade.

Door Lock System with Arduino
Easy
  • 32
  • 1

This is a door lock security system made with Arduino.

ProjectsCommunitiesTopicsContestsLiveAppsBetaFree StoreBlogAdd projectSign up / Login