Інтерактивне керування вбудованим світлодіодом та реле через WEB інтерфейс на телефоні чи компютері, за допоиогою плати розробки Arduino UNO WiFi R3.
Arduino UNO WiFi R3 платка на якій інтегровано класичний контролер Arduino UNO з вбудованим Wi-Fi модулем ESP8266. Обидві частини можуть працювати як спільно так незалежно.
На платі розміщений 8-и позиційний перемикач, яким задається функціонал для режиму роботи.
Режим робрти | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 |
---|---|---|---|---|---|---|---|---|
ESP8266 + ATMega328 працюють разом | ON | ON | OFF | OFF | OFF | OFF | OFF | NC |
ESP8266 + ATMega328 працюють незалежно | OFF | OFF | OFF | OFF | OFF | OFF | OFF | NC |
ATMega328 завантаження скетчу | OFF | OFF | ON | ON | OFF | OFF | OFF | NC |
ESP8266 завантаження скетчу | OFF | OFF | OFF | OFF | ON | ON | ON | NC |
ESP8266 звичайна робота | OFF | OFF | OFF | OFF | ON | ON | OFF | NC |
Програмування ATMega328
У PlatformIO створюєм новий проект, обираєм мікроконтролер Arduino Uno, та копіюєм наступний код у файл main.cpp в папці src.
#include <Arduino.h>
#define RELAY_PIN 13 // Пін для реле.
bool flag_relay_status = false; // Статус реле.
void setup()
{
pinMode(RELAY_PIN, OUTPUT); // Встановлюєм пін як вихід.
Serial.begin(9600); // Вмикаєм серійний порт.
}
void relay_action(bool action)
{
if (action == flag_relay_status) // Якщо команда співпадає з станом реле нічого не робимо.
{
return;
}
if (action == true) // Якщо отримали true (увімкнути).
{
digitalWrite(RELAY_PIN, HIGH); // Вмикаєм реле.
}
else if (action == false) // Якщо отримали false (вимкнути).
{
digitalWrite(RELAY_PIN, LOW); // Вимикаєм реле.
}
flag_relay_status = action; // Зберігаєм стан.
}
void loop() {
if (Serial.available()) // Очікуєм дані від ESP.
{
String incoming = Serial.readStringUntil('\n'); // Читаємо вхідні дані до закінчення рядка '\n'.
if (incoming == "on") // Якщо вхідна команда 'on'.
{
relay_action(true); // Вмикаєм реле.
}
else if (incoming == "off") // Якщо вхідна команда 'off'.
{
relay_action(false); // Вимикаємо реле.
}
else if (incoming == "get")
{
if (flag_relay_status == true)
{
Serial.write("on\n");
}
else
{
Serial.write("off\n");
}
}
}
}
ATMega буде прослуховувати команди від ESP, по серійному порту та вмикати чи вимикати світлодіод та реле, залежно від вхідних команд. GPIO 13 підєднаний до вбудованого світлодіода L, тому світлодіод буде служити індикатором роботи реле.
Виставляєм перемикачі згідно таблиці для програмування ATMega328.
OFF | OFF | ON | ON | OFF | OFF | OFF | NC |
Підключаємо USB кабель, компілюємо та завантажуєм у мікроконтролер.
Програмування ESP8266
У PlatformIO створюєм ще один проект, обираєм мікроконтролер Espressif ESP8266 ESP-12E, копіюєм в main.cpp наступний код.
Назву точки доступу та пароль поля *ssid, *password по бажанню змініть своїми значеннями.
#include <Arduino.h>
#include <ESP8266WiFi.h>
#include <ESPAsyncTCP.h>
#include <ESPAsyncWebServer.h>
bool flag_relay_status = false; // Статус реле.
const char *ssid = "ESP-AP"; // Назва точки доступу
const char *password = "12345678"; // Пароль точки доступу ('NULL' щоб залишити точку доступу без пароля).
// HTML сторінка
const char index_html[] PROGMEM = R"rawliteral(
<!DOCTYPE HTML><html><head><meta name="viewport" content="width=device-width, initial-scale=1">
<style>html{font-family: Helvetica;display: inline-block;margin: 0px auto;text-align: center;}
body{margin-top: 50px;}
.button{display: block;width: 80px;background-color: #f48100;border: none;
color: white;padding: 13px 30px;text-decoration: none;font-size: 25px;
margin: 0px auto 35px;cursor: pointer;border-radius: 4px;}
.button-on{background-color: #f48100;}
.button-on:active {background-color: #463c32;}
.button-off{background-color: #26282d;}
.button-off:active{background-color: #b86404;}</style>
</head><body><table align="center"><td>
<div id="btn-on" class="button button-off" onclick="btn_on()">ON</div></td>
<td><div id="btn-off" class="button button-off" onclick="btn_off()">OFF</div></td>
</table><script>status();function btn_on() {var xhr = new XMLHttpRequest();
xhr.open('GET', '/action_on');xhr.onload = function () {if (xhr.status === 200) {btn("on");}};xhr.send();}function btn_off(action) {
var xhr = new XMLHttpRequest();xhr.open('GET', '/action_off');xhr.onload = function () {if (xhr.status === 200) {btn("off");}};
xhr.send();}function btn(action) {if (action === "on")
{document.getElementById("btn-on").className = "button button-on";document.getElementById("btn-off").className = "button button-off";} else if (action === "off")
{document.getElementById("btn-on").className = "button button-off";document.getElementById("btn-off").className = "button button-on";}}
function status(){var xhr = new XMLHttpRequest();xhr.open('GET', '/status');xhr.onload = function () {
if (xhr.status === 200) {btn("on");} else if (xhr.status === 201){btn("off");}};xhr.send();}
</script></body></html>)rawliteral";
AsyncWebServer server(80);
bool status() {
Serial.write("get\n");
delay(50);
if (Serial.available()) {
String incoming = Serial.readStringUntil('\n');
if (incoming == "on") { flag_relay_status = true; }
else if (incoming == "off") { flag_relay_status = false; }
}
return flag_relay_status;
}
bool relay_on() {
if (flag_relay_status) return true;
bool _status = false;
Serial.write("on\n");
unsigned int time = millis();
while ((millis() - time) < 200) {
_status = status();
if (_status) break;
}
return _status;
}
bool relay_off() {
if (!flag_relay_status) return true;
bool _status = true;
Serial.write("off\n");
unsigned int time = millis();
while ((millis() - time) < 200) {
_status = status();
if (!_status) break;
}
return !_status;
}
void setup() {
Serial.begin(9600);
WiFi.softAP(ssid, password);
server.on("/", HTTP_GET, [](AsyncWebServerRequest *request)
{ request->send_P(200, "text/html", index_html); });
server.on("/action_on", HTTP_GET, [](AsyncWebServerRequest *request)
{ if (relay_on()) { request->send(200);}
else { request->send(201);} });
server.on("/action_off", HTTP_GET, [](AsyncWebServerRequest *request)
{ if (relay_off()) { request->send(200);}
else { request->send(201);} });
server.on("/status", HTTP_GET, [](AsyncWebServerRequest *request)
{ if (status()) { request->send(200);}
else if (!status()) { request->send(201);} });
server.begin();
}
void loop() {
}
Для додавання бібліотеки вебсервера ESP Async WebServer, додайте наступний рядок у файл platformio.ini.
lib_deps = me-no-dev/ESP Async WebServer@^1.2.3
Для завантаження виставляєм перемикачі згідно таблиці для програмування ESP8266.
OFF | OFF | OFF | OFF | ON | ON | ON | NC |
Підключаємо USB кабель, компілюємо та завантажуєм у мікроконтролер.
Перевірка роботи
Для роботи в режимі ESP8266 + ATMega328 працюють разом, виставляєм перемикачі згідно таблиці.
ON | ON | OFF | OFF | OFF | OFF | OFF | NC |
Після подачі живлення з телефона чи компютера підключіться до Wi-Fi “ESP-AP”, та введіть пароль “12345678”. Після підключення відкрийте браузер та в рядку адреси введіть “192.168.4.1”.
Тепер спробуйте увімкнути та вимкнути реле.
Тепер можна перейти до наступного проекту Автоматичне керування двома реле на ESP32, з віддаленими датчиками освітлення та температури.