Веб-управление лампой на Arduino: пошаговое руководство
Компоненты и материалы
| Компонент | Количество |
|---|---|
| Arduino UNO | 1 |
| PHPoC Shield 2 для Arduino | 1 |
| Релейный модуль PHPoC (4 канала) | 1 |
| Лампа накаливания / LED-лампа | 1 |
О проекте
Управление устройствами через веб-интерфейс стало стандартом. В этом проекте показано, как за пару шагов создать приложение для управления лампой через браузер.
Веб-управление не нова, но с PHPoC Shield оно реализуется максимально просто. Любой, кто знаком с основами веб-программирования, может создать интерфейс для контроля/мониторинга устройств.
Аппаратная часть
Используются: Arduino Uno, PHPoC WiFi Shield, PHPoC Arduino Relay Board.
Принцип работы
PHPoC Shield превращает Arduino в веб-сервер / WebSocket-сервер. Нужны две части:
Клиентская часть (веб-интерфейс): обеспечивает UI для управления лампой. Пользователь отправляет команды на веб-сервер (Arduino), а интерфейс отображает статус лампы, полученный от сервера. Исходный код веб-страницы загружается на Shield. При HTTP-запросе от браузера Shield отдаёт интерпретированные файлы.
Серверная часть (Arduino-скетч): управляет лампой на основе данных от браузера. Код крутится в цикле: проверяет наличие запросов от веб-клиента, включает/выключает реле, отправляет статус лампы обратно в браузер.
В проекте используется SVG-элемент для отображения лампы и кнопка для отправки команд. Обмен данными идёт через WebSocket — идеально для реального времени.
Чем больше усилий вложено в UI, тем лучше результат. Но можно использовать готовые бесплатные решения из интернета вместо написания всего с нуля.
Код
remote_led.php (клиентская часть, загружается на PHPoC Shield)
<html> <head> <title> <? echo system("uname -i") ?> </title>
<meta content="initial-scale=0.7, maximum-scale=1.0, minimum-scale=0.5, width=device-width, user-scalable=yes" name="viewport">
<style>
body { text-align: center; font-family: verdana, Helvetica, Arial, sans-serif, gulim; background: #C2CCD0; }
h2 { font-size: 16px; line-height: 25px; }
body.active { background: #E2ECF1; }
#on { opacity: 0; }
.active #on { opacity: 1; }
.light-bulb { width: 250px; height: 400px; margin-top: 100px }
.container { margin: auto; width: 250px; }
.switches { width: 150px; height: 65px; background-color: #38434A; font-size: 24px; margin: auto; border-radius: 10px; color: white; cursor: pointer; letter-spacing: 0.2px; line-height: 65px; text-align: center; user-select: none; transition: none; }
</style> </head> <body>
<div class="container">
<div class="light-bulb">
<svg version="1.1" xmlns="https://www.w3.org/2000/svg" xmlns:xlink="https://www.w3.org/1999/xlink" x="0px" y="0px" viewBox="0 0 275.3 413.3" enable-background="new 0 0 275.3 413.3" xml:space="preserve">
<g>
<path fill="#E2ECF1" d="M137.7,13.7C67.2,13.7,10,70.9,10,141.4c0,58.3,72.8,118.2,79.9,162.3h47.8h47.8 c7.1-44,79.9-103.9,79.9-162.3C265.3,70.9,208.2,13.7,137.7,13.7z" />
</g>
<g id="on">
<path fill="#FFDB55" d="M137.7,13.7C67.2,13.7,10,70.9,10,141.4c0,58.3,72.8,118.2,79.9,162.3h47.8h47.8 c7.1-44,79.9-103.9,79.9-162.3C265.3,70.9,208.2,13.7,137.7,13.7z" />
</g>
<g>
<path fill="#F1F2F2" stroke="#38434A" stroke-width="19.1022" stroke-miterlimit="10" d="M168.5,375.5h-61.7c-8.9,0-16-7.2-16-16 v-55.8h93.8v55.8C184.6,368.3,177.4,375.5,168.5,375.5z" />
<path fill="#F1F2F2" stroke="#38434A" stroke-width="19.1022" stroke-miterlimit="10" d="M151.2,401.5h-27.1c-3.9,0-7-3.2-7-7v-19 h41.1v19C158.2,398.4,155.1,401.5,151.2,401.5z" />
<line fill="none" stroke="#38434A" stroke-width="19.1022" stroke-miterlimit="10" x1="184.6" y1="339.6" x2="90.8" y2="339.6" />
<path fill="none" stroke="#38434A" stroke-width="19.1022" stroke-miterlimit="10" d="M137.7,13.7C67.2,13.7,10,70.9,10,141.4 c0,58.3,72.8,118.2,79.9,162.3h47.8h47.8c7.1-44,79.9-103.9,79.9-162.3C265.3,70.9,208.2,13.7,137.7,13.7z" />
</g>
<g>
<path fill="#FFDB55" stroke="#FFFFFF" stroke-width="21.0124" stroke-linecap="round" stroke-miterlimit="10" d="M207.1,89.5 c-12.3-16.1-28.4-29.1-46.9-37.8" />
<path fill="#FFDB55" stroke="#FFFFFF" stroke-width="21.0124" stroke-linecap="round" stroke-miterlimit="10" d="M225,121.4 c-0.8-2.2-1.8-4.4-2.7-6.5" />
</g>
</svg>
</div>
<div class="switches"> Switch </div>
</div>
<br> <h2 id="ws_state"></h2> </body>
<script>
var is_on; var ws; var button = document.querySelector('.switches'); var ws_state = document.getElementById("ws_state");
function init() { button.addEventListener("click", toogleLed); connect(); is_on = 0; }
function connect() { if (ws == null) { var ws_host_addr = " echo _SERVER("HTTP_HOST") ?>"; 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_led", "text.phpoc"); ws_state.innerHTML = "Connecting. Please wait!"; ws.onopen = ws_onopen; ws.onclose = ws_onclose; ws.onmessage = ws_onmessage; } else ws.close(); }
function ws_onopen() { ws_state.style.display = "none"; display_lightbulb(); }
function ws_onclose() { button.style.backgroundColor = "#C2C2C2"; ws_state.style.display = ""; ws_state.innerHTML = "<span style='color: gray'>Can not connect to Arduino Board. <br> Please check again and reload this page!</span>"; ws.onopen = null; ws.onclose = null; ws.onmessage = null; ws = null; is_on = 0; display_lightbulb(); }
function ws_onmessage(e_msg) { e_msg = e_msg || window.event; is_on = parseInt(e_msg.data); display_lightbulb(); }
function toogleLed() { if (is_on) ws.send("0"); else ws.send("1"); }
function display_lightbulb() { document.body.className = (is_on) ? "active" : ""; }
window.onload = init;
</script> </html>
remoteLed.ino (серверная часть на Arduino)
#include <Phpoc.h>
#include <PhpocExpansion.h>
#define ON '1'
#define OFF '0'
byte expansionId = 1;
ExpansionRelayOutput relay(expansionId, 0);
PhpocServer server(80);
void setup() {
Serial.begin(9600);
while(!Serial) ;
Phpoc.begin(PF_LOG_SPI | PF_LOG_NET);
server.beginWebSocket("remote_led");
Serial.print("WebSocket server address : ");
Serial.println(Phpoc.localIP());
Expansion.begin();
Serial.println(relay.getName());
}
void loop() {
PhpocClient client = server.available();
if (client) {
if (client.available() > 0) {
char thisChar = client.read();
switch(thisChar) {
case OFF:
Serial.println("Turn LED OFF");
relay.off();
server.write(OFF);
break;
case ON:
Serial.println("Turn LED ON");
relay.on();
server.write(ON);
break;
}
}
}
}
Производственный процесс
- От огня к нити накаливания: эволюция и производство современной лампы накаливания
- Веб-управляемая DMX-система освещения: Arduino Mega как мастер-контроллер
- Настольная RGB-лампа с управлением жестами – Интерактивное беспроводное освещение
- Умная копилка: управление монетоприёмником на Arduino Nano
- Arduino Power Control Center: N-FET, P-FET, реле и RTC
- Управление светодиодом по Bluetooth с Arduino: простой DIY-гид
- DIY-контроллер увлажнителя на Arduino с реле: безопасная работа с высоким напряжением
- Умный беспроводной выключатель света: Arduino-контроллер для удаленного управления
- Arduino UNO + WiFi Shield: реальный график температуры в вебе через Serial
- Защитите свой Arduino с помощью веб-разблокировки по шаблону — простое управление и удалённый контроль