Arduino UNO WiFi R3 керування світлодіодом та реле через Wi-Fi

Інтерактивне керування вбудованим світлодіодом та реле через WEB інтерфейс на телефоні чи компютері, за допоиогою плати розробки Arduino UNO WiFi R3.

Arduino UNO WiFi R3 платка на якій інтегровано класичний контролер Arduino UNO з вбудованим Wi-Fi модулем ESP8266. Обидві частини можуть працювати як спільно так незалежно.

На платі розміщений 8-и позиційний перемикач, яким задається функціонал для режиму роботи.

Режим робрти12345678
ESP8266 + ATMega328 працюють разом ON ON OFF OFF OFF OFF OFF NC
ESP8266 + ATMega328 працюють незалежноOFFOFFOFFOFFOFFOFFOFFNC
ATMega328 завантаження скетчуOFFOFFONONOFFOFFOFFNC
ESP8266 завантаження скетчуOFFOFFOFFOFFONONONNC
ESP8266 звичайна роботаOFFOFFOFFOFFONONOFFNC

Програмування 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.

OFFOFFONONOFFOFFOFFNC

Підключаємо 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.

OFFOFFOFFOFFONONONNC

Підключаємо USB кабель, компілюємо та завантажуєм у мікроконтролер.

Перевірка роботи

Для роботи в режимі ESP8266 + ATMega328 працюють разом, виставляєм перемикачі згідно таблиці.

ONONOFFOFFOFFOFFOFFNC

Після подачі живлення з телефона чи компютера підключіться до Wi-Fi “ESP-AP”, та введіть пароль “12345678”. Після підключення відкрийте браузер та в рядку адреси введіть “192.168.4.1”.

ESP web control
ESP web

Тепер спробуйте увімкнути та вимкнути реле.

Тепер можна перейти до наступного проекту Автоматичне керування двома реле на ESP32, з віддаленими датчиками освітлення та температури.

Залишити відповідь

Ваша e-mail адреса не оприлюднюватиметься. Обов’язкові поля позначені *