Control de Servo Web con Arduino UNO y Shield PHPoC WiFi
Componentes y materiales
![]() |
Arduino UNO
|
× | 1 | |
![]() |
PHPoC WiFi Shield para Arduino
|
× | 1 | |
|
Servomotor Seeed
|
× | 1 | ||
|
Cables de conexión
|
× | 1 |
Acerca de este proyecto
Introducción
Si eres principiante, te recomiendo leer sobre Arduino - Servomotor y Arduino - WiFi.
Para conectar Arduino a Internet, necesitamos usar algún tipo de shield de Internet, como Ethernet shield, WiFi shield, PHPoC shield o PHPoC WiFi shield.
La característica destacada del shield PHPoC es que no solo proporciona conexión a Internet como los shields Ethernet y WiFi, sino que también proporciona un servidor web que permite controlar y monitorizar Arduino desde un navegador web. También soporta WebSocket, por lo que podemos controlar y monitorizar Arduino en tiempo real sin recargar una página web.
El shield PHPoC tiene algunas aplicaciones web integradas. Consulta este enlace para más detalles.
En este proyecto, cambié la IU (Interfaz de Usuario) de la aplicación web Control Remoto Web/Deslizador, y escribí el código de Arduino para rotar el ángulo del servomotor según el ángulo recibido desde el navegador web.
Cableado

- Monta el shield PHPoC sobre el Arduino
- Conecta el pin GND, VCC y señal del servomotor a GND, 5V y pin 9 del Arduino, respectivamente.
Flujo de datos
Navegador web → Shield PHPoC → Arduino
La aplicación web calculará el ángulo basado en eventos táctiles o de ratón, lo enviará al shield PHPoC vía WebSocket. Al recibir estos datos, el shield PHPoC los pasa a Arduino. Arduino rota el servomotor según el ángulo.
Qué necesitamos hacer
- Configurar la información WiFi para el shield PHPoC (SSID y contraseña)
- Subir la nueva IU al shield PHPoC
- Escribir el código de Arduino
Configuración de la información WiFi para el shield PHPoC
Consulta esta instrucción: https://www.phpoc.com/support/manual/p4s-347_user_manual/contents.php?id=network_first_setup
Subir nueva IU al shield PHPoC
- Descarga el código fuente PHPoC remote_rotate.php (en la sección de código)
- Súbelo al shield PHPoC usando PHPoC debugger según esta instrucción
Escribir código de Arduino
- Instala la librería para Arduino en Arduino IDE (ver la instrucción) y reinicia Arduino IDE.
- En Arduino IDE, ve a Archivo → Ejemplos → Phpoc → WebRemoteSlide y Archivo → Ejemplos → Servo → sweep.
- Combina los dos ejemplos en uno, tenemos el código para controlar el servomotor vía página web (ver el código fuente en la sección de código).
Pruebas
- Haz clic en el botón serie en Arduino IDE para ver la dirección IP
- Abre el navegador web, escribe https://reemplaza_dirección_ip/remote_rotate.php
- Haz clic en el botón conectar y pruébalo
El mejor kit de inicio de Arduino para principiantes
Si buscas un kit de Arduino, consulta El Mejor Kit de Arduino para Principiantes
Referencias de funciones
- Arduino - Librería Servo
- Servo.attach()
- Servo.write()
- Servo.writeMicroseconds()
- Servo.read()
- Servo.attached()
- Servo.detach()
- Serial.begin()
- Serial.println()
- delay()
- bucle for
- bucle while
- if else
- loop()
- setup()
- String.toInt()
Código
- remote_rotate.php
- Código de Arduino
remote_rotate.phpPHP
<!DOCTYPE html> <html> <head> <title>PHPoC Shield - Control Remoto Web para 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) == "[")) { 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_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; 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.offsetY; 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; } } } window.onload = init; </script> </head> <body> <p> <h1>Control Remoto Web / Rotación</h1> </p> <canvas id="remote" width="400" height="400"></canvas> <h2> <p> WebSocket : <span id="ws_state">null</span><br> Ángulo : <span id="debug">0</span> </p> <button id="bt_connect" type="button" onclick="connect_onclick();">Conectar</button> </h2> </body> </html>
Código de ArduinoArduino
/* arduino web server - control remoto (deslizador) */
#include "SPI.h"
#include "Phpoc.h"
#include <Servo.h>
PhpocServer server(80);
Servo myservo; // crea objeto servo para controlar un 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("Dirección del servidor WebSocket : ");
Serial.println(Phpoc.localIP());
myservo.attach(9); // conecta el servo en el pin 9 al objeto servo
myservo.write(1);
}
void loop() {
// espera un nuevo cliente:
PhpocClient client = server.available();
if (client) {
String slideStr = client.readLine();
if(slideStr) {
slideValue = slideStr.substring(1).toInt();
myservo.write(slideValue);
Serial.print("Ángulo: ");
Serial.println(slideValue);
}
}
}
Proceso de manufactura
- Sistema de Iluminación DMX Controlado por Web – Controlador Maestro Arduino
- Construye un Spybot controlado por Bluetooth con Arduino
- Alcancía Inteligente: Controla un Aceptador de Monedas con Arduino Nano
- Control de electrodomésticos inteligente vía Web y Apps móviles
- Centro de Control de Potencia Arduino: N-FET, P-FET, Relé y RTC
- Controla un LED por Bluetooth con Arduino – Guía DIY paso a paso
- Controlador de Humidificador DIY con Arduino y Relé: Configuración Segura de Alto Voltaje
- Controla Dos Motores Paso a Paso con Arduino Nano y Joystick - Tutorial Sencillo
- Arduino UNO + Shield WiFi: Visualización de Temperatura en Tiempo Real en Web vía Serial
- Protege tu Arduino con desbloqueo por patrón web: configuración fácil y control remoto
- Shield de Programación Inalámbrica para Arduino con HC-05 Bluetooth – Sin Cable USB

