Промышленное производство
Промышленный Интернет вещей | Промышленные материалы | Техническое обслуживание и ремонт оборудования | Промышленное программирование |
home  MfgRobots >> Промышленное производство >  >> Manufacturing Technology >> Производственный процесс

Управление сервоприводом через веб-интерфейс на Arduino UNO с PHPoC WiFi Shield

Компоненты и материалы

Arduino UNO 1
PHPoC WiFi Shield для Arduino 1
Сервопривод Seeed 1
Перемычки 1

О проекте

Введение

Если вы новичок, рекомендую прочитать про Arduino — Сервопривод и Arduino — WiFi.

Для подключения Arduino к интернету нужен сетевой щит: Ethernet, WiFi, PHPoC или PHPoC WiFi.

Особенность PHPoC Shield — он не только даёт интернет как Ethernet/WiFi щиты, но и имеет встроенный веб-сервер для управления и мониторинга Arduino из браузера. Также поддерживает WebSocket — управление в реальном времени без перезагрузки страницы.

У PHPoC Shield есть встроенные веб-приложения. Подробнее: ссылка.

В этом проекте я изменил UI (интерфейс) веб-приложения Web Remote Control/Slide и написал код Arduino для поворота сервопривода согласно углу, полученному из браузера.

Подключение

Управление сервоприводом через веб-интерфейс на Arduino UNO с PHPoC WiFi Shield

Поток данных

Веб-браузер → PHPoC Shield → Arduino

Веб-приложение вычисляет угол на основе касания/движения мыши, отправляет его на PHPoC Shield через WebSocket. Получив данные, Shield передаёт их Arduino. Arduino поворачивает сервопривод на заданный угол.

Что нужно сделать

Настройка WiFi для PHPoC Shield

Инструкция: https://www.phpoc.com/support/manual/p4s-347_user_manual/contents.php?id=network_first_setup

Загрузка нового UI на PHPoC Shield

Написание кода Arduino

Тестирование

Лучший стартовый набор Arduino для новичка

Если ищете набор Arduino, см. The Best Arduino Kit for Beginners

Справочник функций

Код

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) == "[")) { 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.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; } } } 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>
Код ArduinoArduino
/* arduino web server - remote control (slide switch) */
#include "SPI.h"
#include "Phpoc.h"
#include <Servo.h>
PhpocServer server(80);
Servo myservo;
char slideName;
int slideValue;

void setup() {
  Serial.begin(9600);
  while(!Serial) ;
  Phpoc.begin(PF_LOG_SPI | PF_LOG_NET);
  server.beginWebSocket("remote_slide");
  Serial.print("WebSocket server address : ");
  Serial.println(Phpoc.localIP());
  myservo.attach(9);
  myservo.write(1);
}

void loop() {
  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);
    }
  }
}

Производственный процесс

  1. Веб-управляемая DMX-система освещения: Arduino Mega как мастер-контроллер
  2. Сборка Bluetooth-робота-шпиона на Arduino с управлением с телефона
  3. Умная копилка: управление монетоприёмником на Arduino Nano
  4. Умный дом: управление приборами через веб и мобильные приложения
  5. Arduino Power Control Center: N-FET, P-FET, реле и RTC
  6. Управление светодиодом по Bluetooth с Arduino: простой DIY-гид
  7. DIY-контроллер увлажнителя на Arduino с реле: безопасная работа с высоким напряжением
  8. Управление двумя шаговыми двигателями через джойстик на Arduino Nano — простой урок (Visuino)
  9. Arduino UNO + WiFi Shield: реальный график температуры в вебе через Serial
  10. Защитите свой Arduino с помощью веб-разблокировки по шаблону — простое управление и удалённый контроль