Industrial manufacturing
Industrial Internet of Things | Industrial materials | Equipment Maintenance and Repair | Industrial programming |
home  MfgRobots >> Industrial manufacturing >  >> Manufacturing Technology >> Manufacturing process

Arduino UNO Web-Enabled Servo Control with PHPoC WiFi Shield

Components and supplies

Arduino UNO Web-Enabled Servo Control with PHPoC WiFi Shield
Arduino UNO
×1
Arduino UNO Web-Enabled Servo Control with PHPoC WiFi Shield
PHPoC WiFi Shield for Arduino
×1
Seeed Servo motor
×1
Jumper wires
×1

About this project

Introduction

If you are beginner, I recommend reading about Arduino - Servo Motor and Arduino - Wifi.

To connect Arduino to internet, we need to use some kind of internet shield such as Ethernet shield, Wifi shield, PHPoC shield, or PHPoC Wifi shield.

The outstanding feature of PHPoC shield is that it not only provides Internet connection like Ethernet and Wifi shield, but also provides a web server which allows to control and monitor Arduino from a web browser. It also supports WebSocket, therefore we can control and monitor Arduino in real-time without reloading a webpage.

PHPoC Shield has some built-in web applications. Refer to this link for more detail.

In this project, I changed UI (User Interface) of Web Remote Control/Slide web application, and wrote Arduino code to rotate servo motor angle according to angle received from web browser.

Wiring

Arduino UNO Web-Enabled Servo Control with PHPoC WiFi Shield
  • Stack PHPoC shield on Arduino
  • Connect pin GND, VCC and signal of servo motor to GND, 5V and pin 9 of Arduino, respectively.

Data Flow

Web browser ---> PHPoC Shield ---> Arduino

Web app will calculate the angle based on touch or mouse event, send it to PHPoC shield via websocket. When receiving this data, PHPoC shield passes it to Arduino. Arduino rotates servo motor according to the angle.

What We Need to Do

  • Set Wifi information for PHPoC shield (SSID and password)
  • Upload new UI to PHPoC shield
  • Write Arduino code

Setting Wifi Information for PHPoC Shield

See this instruction: http://www.phpoc.com/support/manual/p4s-347_user_manual/contents.php?id=network_first_setup

Upload new UI to PHPoC Shield

  • Download PHPoC source code remote_rotate.php (on code section)
  • Upload it to PHPoC shield using PHPoC debugger according to this instruction

Write Arduino Code

  • Install library for Arduino on Arduino IDE (see the instruction ) and restart Arduino IDE.
  • On Arduino IDE, go to File -> Examples -> Phpoc -> WebRemoteSlide and File -> Examples ->Servo->sweep.
  • Combine two examples into one, we have the code to control servo motor via webpage (see the source code in code section).

Testing

  • Click serial button on Arduino IDE to see the IP address
  • Open web browser, type http://replace_ip_address/remote_rotate.php
  • Click connect button and test it

The Best Arduino Starter Kit for Beginner

If you are looking for an Arduino kit, see The Best Arduino Kit for Beginners

Function References

  • Arduino - Servo Library
  • Servo.attach()
  • Servo.write()
  • Servo.writeMicroseconds()
  • Servo.read()
  • Servo.attached()
  • Servo.detach()
  • Serial.begin()
  • Serial.println()
  • delay()
  • for loop
  • while loop
  • if else
  • loop()
  • setup()
  • String.toInt()

Code

  • remote_rotate.php
  • Arduino code
remote_rotate.phpPHP
<!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; font-size: 15pt; }
h1 { font-weight: bold; font-size: 25pt; }
h2 { font-weight: bold; font-size: 15pt; }
button { font-weight: bold; font-size: 15pt; }
</style>
<script>
var canvas_width = 400, canvas_height = 400;
var plate_radius = 160;
var click_state = 0;
var last_plate_angle = 0
var plate_angle = 0, last_angle = 0;
var ws;
function init()
{
	var canvas = document.getElementById("remote");
 
	canvas.addEventListener("touchstart", mouse_down);
	canvas.addEventListener("touchend", mouse_up);
	canvas.addEventListener("touchmove", mouse_move);
	canvas.addEventListener("mousedown", mouse_down);
	canvas.addEventListener("mouseup", mouse_up);
	canvas.addEventListener("mousemove", mouse_move);
 
	var ctx = canvas.getContext("2d");
 
	ctx.translate(canvas_width / 2, canvas_height / 2);
 
	rotate_plate(0);
}
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";
		}
		//debug.innerHTML = "<br>" + navigator.platform + " " + ws_host_addr;
		ws = new WebSocket("ws://" + ws_host_addr + "/remote_slide", "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";
}
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;
}
function ws_onmessage(e_msg)
{
	e_msg = e_msg || window.event; // MessageEvent
	alert("msg : " + e_msg.data);
}

function rotate_plate(angle)
{
	var canvas = document.getElementById("remote");
	var ctx = canvas.getContext("2d");
 
	ctx.clearRect(-canvas_width / 2, -canvas_height / 2, canvas_width, canvas_height);
	ctx.rotate(angle / 180 * Math.PI);
 
	ctx.strokeStyle="red";
	ctx.fillStyle="red";
	ctx.beginPath();
	ctx.arc(0, 0, plate_radius, Math.PI, Math.PI * 1.5);
	ctx.lineTo(0, 0);
	ctx.lineTo(-plate_radius, 0);
	ctx.fill();
	ctx.stroke();
 
	ctx.strokeStyle="blue";
	ctx.fillStyle="blue";
	ctx.beginPath();
	ctx.arc(0, 0, plate_radius, 0, Math.PI / 2);
	ctx.lineTo(0, 0);
	ctx.lineTo(plate_radius, 0);
	ctx.fill();
	ctx.stroke();
 
	ctx.strokeStyle="black";
	ctx.arc(0, 0, plate_radius, 0, Math.PI * 2);
	ctx.stroke();
 
	ctx.rotate(-angle / 180 * Math.PI);
}
function mouse_down()
{
	if(ws == null)
		return;
	
	var dist_min, dist_max, dist;
 
	event.preventDefault();
 
	if(event.offsetX)
	{
		x = event.offsetX - canvas_width / 2;
		y = canvas_height / 2 - event.offsetY;
		dist_min = 40;
		dist_max = plate_radius;
	}
	else if(event.layerX)
	{
		x = event.layerX - canvas_width / 2;
		y = canvas_height / 2 - event.layerY;
		dist_min = 40;
		dist_max = canvas_width / 2;
	}
	else
	{
		x = (Math.round(event.touches[0].pageX - event.touches[0].target.offsetLeft)) - canvas_width / 2;
		y = canvas_height / 2 - (Math.round(event.touches[0].pageY - event.touches[0].target.offsetTop));		 
		dist_min = 40;
		dist_max = canvas_width / 2;
	}
 
	var dist = Math.round(Math.sqrt(x * x + y * y));
	if((dist > dist_min) && (dist < dist_max))
	{
		click_state = 1;
		last_angle = Math.round(Math.atan2(y, x) / Math.PI * 180);
	}
}
function mouse_up()
{
	if(ws == null)
		return;
	
	event.preventDefault();
 
	click_state = 0;
}
function mouse_move()
{
	if(ws == null)
		return;
	
	var dist_min, dist_max, angle, dist;
 
	event.preventDefault();
 
	if(!click_state)
		return;
 
	if(event.offsetX)
	{
		x = event.offsetX - canvas_width / 2;
		y = canvas_height / 2 - event.offsetY;
		dist_min = 40;
		dist_max = plate_radius;
	}
	else if(event.layerX)
	{
		x = event.layerX - canvas_width / 2;
		y = canvas_height / 2 - event.layerY;
		dist_min = 40;
		dist_max = canvas_width / 2;
	}
	else
	{
		x = (Math.round(event.touches[0].pageX - event.touches[0].target.offsetLeft)) - canvas_width / 2;
		y = canvas_height / 2 - (Math.round(event.touches[0].pageY - event.touches[0].target.offsetTop));		 
		dist_min = 40;
		dist_max = canvas_width / 2;
	}
 
	angle = Math.round(Math.atan2(y, x) / Math.PI * 180);
	dist = Math.round(Math.sqrt(x * x + y * y));
 
	if((dist < dist_min) || (dist > dist_max))
	{
		click_state = 0;
		return;
	}
 
	if((Math.abs(angle) > 90) && (angle * last_angle < 0))
	{
		if(last_angle > 0)
			last_angle = -180;
		else
			last_angle = 180;
	}
 
	plate_angle += (angle - last_angle);
	last_angle = angle;
 
	if(plate_angle > 180)
		plate_angle = 180;
 
	if(plate_angle < 0)
		plate_angle = 0;
 
	rotate_plate(-plate_angle);
	
	if(plate_angle != last_plate_angle)
	{
		if(ws && ws.readyState)
		{
			ws.send("C" + plate_angle.toString() + "\r\n");
			last_plate_angle = plate_angle;
			debug = document.getElementById("debug");
			debug.innerHTML = plate_angle;
			//console.log(plate_angle);
		}
	}
}
window.onload = init;
</script>
</head>

<body>

<p>
<h1>Web Remote Control / Rotate</h1>
</p>

<canvas id="remote" width="400" height="400"></canvas>

<h2>
<p>
WebSocket : <span id="ws_state">null</span><br>
Angle : <span id="debug">0</span>
</p>
<button id="bt_connect" type="button" onclick="connect_onclick();">Connect</button>
</h2>

</body>
</html>
Arduino codeArduino
/* arduino web server - remote control (slide switch) */

#include "SPI.h"
#include "Phpoc.h"
#include <Servo.h>

PhpocServer server(80);
Servo myservo;  // create servo object to control a servo

char slideName;
int slideValue;

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

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

  server.beginWebSocket("remote_slide");

  Serial.print("WebSocket server address : ");
  Serial.println(Phpoc.localIP());  

  myservo.attach(9);  // attaches the servo on pin 9 to the servo object
   myservo.write(1);     
}

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

  if (client) {
    String slideStr = client.readLine();

    if(slideStr)
    {
      slideValue = slideStr.substring(1).toInt();
      myservo.write(slideValue);     
      Serial.print("Angle: ");
      Serial.println(slideValue);
    }
  }
}

Manufacturing process

  1. Web‑Controlled DMX Lighting System – Arduino Master Controller
  2. Build a Bluetooth‑controlled Arduino Spybot
  3. Build a Smart Piggy Bank: Control a Coin Acceptor with Arduino Nano
  4. Arduino Power Control Center: N-FET, P-FET, Relay & RTC Kit
  5. DIY Arduino Humidifier Controller with Relay – Safe High‑Voltage Setup
  6. Arduino-Driven GrowBox Controller – Open-Source Firmware & Hardware Guide
  7. Smart Domotic Greenhouse: Automated Climate Control with Arduino
  8. ED BMSdiag – Arduino CAN‑BUS & OBD‑II Diagnostic Kit
  9. Arduino Web-Controlled Light Bulb: Step-by-Step Guide
  10. Remote Control of a 6‑DOF Arduino Robot Arm via Web Interface