Skip to content

Switch & Relay Control - Ардуино-библиотека для создания простых модулей WiFi-выключателей и WiFi-реле на базе ESP8266 и ESP32

Notifications You must be signed in to change notification settings

VAleSh-Soft/shSRControl

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

52 Commits
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

shSRControl - (Switch & Relay Control) - библиотека для создания простых модулей WiFi-выключателей и WiFi-реле на базе ESP8266 и ESP32

Библиотека предназначена для огранизации работы и взаимодействия модулей друг с другом в локальной WiFi-сети с помощью udp-пакетов.

Основные возможности

  • Взаимодействие модулей с помощью udp-пакетов, как адресных, так и широковещательных;
  • Быстрый поиск реле в сети; модуль WiFi-выключателя может обнаруживать привязанные к нему реле сразу после подключения к сети;
  • Для обнаружения привязанных реле не используется заранее прописанный IP-адрес модулей WiFi-реле; поиск ведется с помощью широковещательных udp-пакетов и позволяет обнаруживать модули реле практически мгновенно;
  • в модуле WiFi-выключателя есть возможность подачи звукового сигнала в случае ошибки отправки команды удаленному реле;
  • Периодическая проверка доступности реле в сети; периодичность проверки настраивается;
  • Наличие Web-интерфейса для настройки модуля;
  • При использовании Web-интерфейса настройки сохраняются в файловой системе и автоматически подгружаются при старте модуля;
  • Модули реле могут использовать как высокий (HIGH), так и низкий (LOW) управляющий логический уровень; для каждого реле этот уровень настраивается индивидуально;
  • Модули WiFi-реле могут иметь локальные кнопки, для управления реле по месту;

История версий

Версия 1.3 - 23.12.2024

  • теперь вывод отладочных сообщений возможен в любой поток, наследующий класс Print, будь то Serial, File, LCD, и т.д.;
  • изменен способ инициализации списка реле - теперь не нужно создавать массив и заполнять его данными реле, достаточно указать количество реле в методе init();
  • добавлены методы addRelay(), позволяющие добавить данные локального или удаленного реле; вызывать их следует после метода init();
  • обработка событий сервера перенесена в методы tick(), теперь вызывать HTTP.handleClient(); в loop() не нужно;
  • примеры приведены в соответствие с изменениями библиотеки;
  • мелкие изменения и исправления;

Версия 1.2 - 03.09.2024

  • в библиотеку внедрен код библиотеки для работы с тактовыми кнопками; библиотека shButton.h в список зависимостей больше не входит;
  • инициализация модулей перенесена из конструктора в метод init();
  • методы begin() переименованы в startDevice(), т.к. при наличии метода init() это более логично;
  • в связи с изменениями доработаны примеры;
  • файлы исходников перемещены в папку src;
  • добавлена поддержка использования вывода отладочных сообщений через USB CDC (STM32C3, STM32S3 и т.д.);
  • исправлена ошибка, приводящая к перезапуску модуля реле, если получена команда на переключение реле по имени, которое отсутствует в списке локальных реле;
  • в структуры, описывающие локальные и удаленные реле, добавлены конструкторы; исправлены примеры в части инициализации структур, описывающих реле;
  • мелкие изменения и исправления;

Версия 1.1 - 29.09.2023

  • Для модуля выключателя добавлены метод setStateForAll(), позволяющий одновременно включить или выключить все реле, ассоциированные с этим выключателем, или на всех модулях WiFi-реле, доступных в сети;
  • доработаны примеры выключателей для демонстрации работы метода setStateForAll();
  • мелкие изменения и исправления;

Версия 1.0 - 6.09.2023

  • добавлены методы setRelayState(), позволяющие установить конкретное состояние локального или удаленного реле;
  • добавлена возможность вывода сообщений в заданный Serial, например, Serial1, если он доступен;
  • в модуль выключателя добавлена возможность выдачи звукового сигнала об ошибке отправки команды удаленному реле; в случае, если удаленное реле не ответило на предыдущий запрос, т.е. считается недоступным, выдается два коротких пика; в случае отсутствия WiFI-соединения выдается три коротких пика;
  • в модуль выключателя добавлены методы setErrorBuzzerState() и getErrorBuzzerState(), позволяющие управлять выдачей звукового сигнала об ошибке;
  • доработаны примеры;
  • мелкие изменения и исправления;

Версия 0.9 - 29.08.2023

  • передача массива данных реле и их количества перенесена в конструкторы модулей, так логичнее и исключает некоторые проблемы считывания настроек при старте модуля;
  • обновлены примеры;
  • мелкие изменения и исправления;

Версия 0.8 - 21.08.2023

  • добавлен Web-интерфейс для управления модулем реле; страница отображает состояние каждого реле и позволяет переключать состояние реле кликом мыши; так же со страницы есть доступ как к настройкам модуля, так и к настройкам WiFi (при условии использования библиотеки shWiFiConfig);
  • добавлен Web-интерфейс для управления модулем выключателя; страница отображает кнопки, зарегистрированные в прошивке модуля; кнопки позволяют переключать привязанные к ним удаленные реле, но их состояние не отображают; ссылки на настройки идентичны таковым на странице модуля реле;

Версия 0.7 - 18.08.2023

  • добавлен Web-интерфейс для настройки модуля;
  • добавлены методы для работы с Web-интерфейсом;
  • доработаны примеры для использования Web-интерфейса;
  • добавлена документация методов библиотеки;

Версия 0.6 - 09.08.2023

  • первая публикация библиотеки;

Состав библиотеки

Библиотека содержит два класса;

  • shRelayControl - для создания модулей WiFi-реле ("умные" розетки, "умные" люстры и т.д.);
  • shSwitchControl - для создания модулей WiFi-выключателей;

А также две структуры, описывающие свойства реле и кнопок;

// описание свойств реле
struct shRelayData
{
  String relayName; 
  uint8_t relayPin;
  uint8_t shRelayControlLevel;
  shButton *relayButton; 
  String relayDescription;
};

Здесь:

  • relayName - имя реле (идентификатор), по которому к нему будет обращаться выключатель; имена реле не должны повторяться в пределах одного модуля; в случае одинаковых имен срабатывать всегда будет то, индекс которого в массиве меньше;
  • relayPin - пин, к которому подключено реле;
  • shRelayControlLevel - управляющий уровень реле (LOW или HIGH)
  • relayButton - локальная кнопка, управляющая реле (располагается на самом модуле и предназначена для ручного управления реле); если локальная кнопка не нужна, свойству relayButton присваивается значение NULL;
  • relayDescription - описание реле, которое будет видно в Web-интерфейсе;
// описание свойств выключателя
struct shSwitchData
{
  String relayName;
  bool relayFound;
  IPAddress relayAddress;
  shButton *relayButton; 
  String relayDescription;
};

Здесь:

  • relayName - имя ассоциированного с кнопкой удаленного реле; имена реле не должны повторяться в пределах одного модуля; в случае одинаковых имен команда на переключение всегда будет подаваться по адресу реле, индекс которого в массиве меньше;
  • relayFound - найдено или нет ассоциированное удаленное реле в сети; свойству присваивается false после отправки запроса на переключение реле (или его поиска в сети) и присваивается true после получения отклика от него;
  • relayAddress - сохраненный последний IP-адрес модуля реле; по этому адресу выключатель отправляет запрос на переключение реле;
  • relayButton - кнопка, управляющая удаленным реле с именем relayName;
  • relayDescription - описание ассоциированного удаленного реле;

Работа с библиотекой

Каждый модуль может иметь несколько реле или кнопок, к каждой кнопке модуля WiFi-выключателя должно быть привязано реле на модуле WiFi-реле. Привязка осуществляется путем задания имени реле. Количество реле/кнопок для одного модуля ограничено лишь числом доступных пинов и доступной памятью модуля ESP и теоретически может достигать 128, однако, при использовании Web-интерфейса сохранение данных гарантировано не более, чем для 8 реле.

Экземпляр модуля объявляется с помощью конструктора

shSwitchControl switch_control;

или

shRelayControl relay_control;

Экземпляры модуля требуют инициализации с указанием количества локальных/удаленных реле:

void shSwitchControl::init(uint8_t _switch_count);

Здесь:

  • _switch_count - количество удаленных реле в модуле;
void shRelayControl::init(uint8_t _relay_count);

Здесь:

  • _relay_count - количество локальных реле в модуле;

После инициализации модуля необходимо добавить данные реле:

bool shSwitchControl::addRelay(String relay_name,
                               srButton *relay_button = nullptr);

Здесь:

  • relay_name - имя удаленного реле;
  • relay_button - ссылка на кнопку, управляющую удаленным реле;

Примечание: не каждое удаленное реле, привязанное к модулю, должно иметь собственную кнопку на модуле. В этом случае такое реле может управляться с помощью Web-интерфейса, а в методе addRelay() достаточно указать только имя удаленного реле.

bool shRelayControl::addRelay(String relay_name,
                              uint8_t relay_pin,
                              uint8_t control_level,
                              srButton *relay_button = nullptr,
                              String relay_description = "");

Здесь:

  • relay_name - имя локального реле;
  • relay_pin - пин, к которому подключено реле;
  • control_level - логический уровень, которым управляется реле (HIGH или LOW);
  • relay_button - ссылка на кнопку для локального управления реле ;
  • relay_description - описание реле;

Примечание: имя реле должно быть задано обязательно, иначе оно не будет добавлено (метод вернет false).

Если вы планируете использовать Web-интерфейс, то нужно вызвать метод

void attachWebInterface(ESP8266WebServer *_server, FS *_file_system, String _config_page = "/relay_config");

Здесь:

  • _server - ссылка на экземпляр Web-сервера (ESP8266WebServer для esp8266 или WebServer для esp32), с которым будет работать модуль;
  • _file_system - ссылка на экземпляр файловой системы модуля для сохранения файла с настройками;
  • _config_page - необязательный параметр, адрес, по которому будет вызываться Web-страница конфигурации; по умолчанию используется адрес /relay_config;

В обоих классах методы attachWebInterface() идентичны

relay_control.attachWebInterface(&HTTP, &FILESYSTEM);
switch_control.attachWebInterface(&HTTP, &FILESYSTEM);

При вызове метода выполняется загрузка сохраненных параметров, поэтому файловая система к моменту вызова метода уже должна быть инициирована. Для модуля реле выполняется восстановление последнего состояния всех подключенных к нему реле, если это задано в настройках.

Перед началом работы необходимо вызвать метод startDevice():

void shRelayControl::startDevice(WiFiUDP *_udp, 
                           uint16_t _local_port)

Здесь:

  • _udp - ссылка на экземпляр WiFiUDP, который будет использоваться для работы модуля;
  • _local_port - порт для отправки/приема udp-пакетов; должен быть одинаковым для всех связанных модулей;

В обоих классах методы startDevice() идентичны.

relay_control.startDevice(&udp, localPort);
switch_control.startDevice(&udp, localPort);

Для работы используется метод tick(), который должен вызываться как можно чаще, поэтому просто помещается в loop().

void loop()
{
  switch_control.tick();// или relay_control.tick();
}

События HTTP-сервера так же обрабатываются в методе tick().

Остальные методы классов

shSwitchControl

  • void setLogOnState(bool _on, Print *_serial = &Serial) - включение и отключение вывода информации о работе модуля; второй параметр - Serial для вывода сообщений, позволяет задать, например, Serial1, если тот доступен;
  • bool getLogOnState() - включен или отключен вывод информации о работе модуля через Serial;
  • void setErrorBuzzerState(bool _state, int8_t _pin = -1) - включить/выключить подачу звукового сигнала об ошибке отправки команды удаленному реле; _state - новое состояние опции; _pin - пин, к которому подключен буззер; если не указать номер пина, то он будет установлен в значение -1 (не задан), а опция будет в любом случае отключена;
  • bool getErrorBuzzerState() - получить состояние опции подачи звукового сигнала об ошибке отправки команды удаленному реле;
  • void setCheckTimer(uint32_t _timer) - установка интервала проверки доступности связанных реле в сети в милисекундах; по умолчанию установлен интервал в 30 секунд;
  • uint32_t getCheckTimer() - получение размера интервала проверки доступности связанных реле в сети в милисекундах;
  • void switchRelay(int8_t index) - переключение удаленного реле; index - индекс реле в массиве данных;
  • void switchRelay(String _name) - переключение удаленного реле; _name - имя удаленного реле;
  • void setRelayState(int8_t index, bool state) - установить состояние удаленного реле; index - индекс реле в массиве данных, state - новое состояние удаленного реле;
  • void setRelayState(String _name, bool state) - установить состояние удаленного реле; _name - имя удаленного реле, state - новое состояние удаленного реле;
  • void setStateForAll(bool state, bool _self = true) - установить состояние всех удаленных реле; state новое состояние реле; true - включено, иначе выключено; _self если true - команда на изменения состояния посылается только для реле, ассоциированных с выключателем; иначе команда посылается для всех реле, доступных в сети
  • void findRelays() - поиск связанных реле в сети;
  • void setModuleDescription(String _descr) - установка описания модуля; _descr - описание;
  • String getModuleDescription() - получение текущего описания модуля;
  • void setRelayName(int8_t index, String _name) - установка имени удаленного реле, которым будет управлять кнопка; index - индекс реле в массиве данных, _name - новое имя реле;
  • String getRelayName(int8_t index) - получение имени реле; index - индекс реле в массиве данных;
  • void setFileName(String _name) - установка имени файла для сохранения параметров модуля; _name - имя файла;
  • String getFileName() - получение текущего именя файла;
  • bool saveConfige() - сохранение настроек в файл;
  • bool loadConfig() - считывание настроек из файла; при старте модуля загрузка сохраненных параметров выполняется автоматически в методе attachWebInterface().

shRelayControl

  • void setLogOnState(bool _on, Print *_serial = &Serial) - включение и отключение вывода информации о работе модуля; второй параметр - Serial для вывода сообщений, позволяет задать, например, Serial1, если тот доступен;
  • bool getLogOnState() - включен или отключен вывод информации о работе модуля через Serial;
  • void switchRelay(int8_t index) - переключение реле; index - индекс реле в массиве данных;
  • void switchRelay(String _name) - переключение реле; _name - имя реле;
  • void setRelayState(int8_t index, bool state) - установить состояние реле; index - индекс реле в массиве данных, state - новое состояние реле; true - включено, иначе выключено;
  • void setRelayState(String _name, bool state) - установить состояние реле; _name - имя реле, state - новое состояние реле; true - включено, иначе выключено;
  • String getRelayState(int8_t index) - получение информации о текущем состоянии реле (включено/отключено); index - индекс реле в массиве данных;
  • String getRelayState(String _name) - получение информации о текущем состоянии реле (включено/отключено); _name - имя реле;
  • void setModuleDescription(String _descr) - установка описания модуля; _descr - описание;
  • String getModuleDescription() - получение текущего описания модуля;
  • void setSaveStateOfRelay(bool _state) - включение/выключение сохранения последнего состояния реле для последующего восстановления при перезапуске модуля; _state - значение для установки;
  • bool getSaveStateOfRelay() - получение текущего состояния опции;
  • void setRelayName(int8_t index, String _name) - установка имени реле; index - индекс реле в массиве данных, _name - новое имя реле;
  • String getRelayName(int8_t index) - получение имени реле; index - индекс реле в массиве данных;
  • void setRelayDescription(int8_t index, String _descr) - установка описания реле; index - индекс реле в массиве данных, _descr_ - описание;
  • String getRelayDescription(int8_t index) - получение текущего описания реле; index - индекс реле в массиве данных;
  • void setFileName(String _name) - установка имени файла для сохранения параметров модуля; _name - имя файла;
  • String getFileName() - получение текущего именя файла;
  • bool saveConfige() - сохранение настроек в файл;
  • bool loadConfig() - считывание настроек из файла; при старте модуля загрузка сохраненных параметров выполняется автоматически в методе attachWebInterface().

Web-интерфейс

Главная страница модуля

Доступ к Web-интерфейсу модуля осуществляется по адресу /. На этой странице отображаются:

  • описание модуля;
  • для модуля реле - переключатели и описание для каждого реле. Переключатели отображают текущее состояние реле и позволяют менять его кликом мыши.
  • для модуля выключателя - кнопки и описания удаленных реле, привязанных к кнопкам; кнопки позволяют отправлять команду на переключение состояния удаленных реле кликом мыши;

Так же с этой страницы есть доступ как к настройкам модуля, так и к настройкам WiFi (ссылка на настройки wiFi будет работать только при условии использования библиотеки shWiFiConfig).

Страница настройки

Доступ к Web-интерфейсу настройки модуля осуществляется по адресу /relay_config как для модуля реле, так и для модуля выключателя. Здесь можно настраивать следующие параметры:

Общие параметры модуля:

  • Описание модуля - общее описание, например "Выключатель возле рабочего стола"; отображается только на главной странице модуля;
  • Сохранять состояние реле при перезагрузке - опция доступна только для модуля реле, позволяет восстанавливать последнее состояние каждого реле модуля после включения в сеть, например, после отключения электроэнергии в доме;

Параметры для каждого реле/выключателя модуля:

  • Имя реле - сетевой идентификатор, по которому к реле будет обращаться выключатель;
  • Описание реле - текстовое описание, которое видно только в Web-интерфейсе, для удобства настройки; для модуля выключателей это поле только для чтения;

Количество пар Имя+Описание на странице зависит от количества реле/выключателей, подключенных к модулю и заданного в прошивке.

Настройки сохраняются в файловой системе модуля в файлах relay.json и switch.json соответственно.

Работа с кнопками, библиотека srButton

Для работы с тактовыми кнопками модулей используется внутренний модуль srButton.h, который является адаптированной для использования здесь копией библиотеки shButton. Все методы и возвращаемые значения аналогичны таковым библиотеки shButton.

Опрос кнопок ведется самим модулем в методе tick(), отлавливаются события BTN_DOWN, но ничто не мешает использовать это и другие события кнопок модуля в своих целях. Однако, здесь есть один нюанс - для корректной и надежной работы с кнопками нельзя допускать множественные опросы кнопки в пределах одного прохода loop(). А т.к. метод getButtonState() для каждой кнопки вызывается в методе tick() модуля, то для работы следует использовать метод getLastState() кнопок, возвращающий результат последнего опроса. Например:

void loop()
{
  switch_control.tick(); // кнопки опрашиваются здесь

  // =================================================

  // поэтому остается только получить результат опроса и использовать его
  switch (btn1.getLastState()) 
  {
  case BTN_LONGCLICK:
    Serial.println("btn1 hold");
    break;
  case BTN_DOWN:
    Serial.println("btn1 down");
    break;
  case BTN_DBLCLICK:
    Serial.println("btn1 dblclick");
    break;
  }

  switch (btn2.getLastState())
  {
  case BTN_LONGCLICK:
    Serial.println("btn2 hold");
    break;
  case BTN_DOWN:
    Serial.println("btn2 down");
    break;
  case BTN_DBLCLICK:
    Serial.println("btn2 dblclick");
    break;
  }  
}

Для подробного описания методов работы с библиотекой shButton смотрите ее файл readme.md.

Возможные проблемы и борьба с ними

Если у вас что-то идет не так - модуль не хочет запускаться, идет циклическая перезагрузка, не отображаются страницы Web-интерфейса, не сохраняются настройки и т.д. проверьте следующее:

  • правильно ли вы выбрали плату; если выбранная плата не соответствует реальному чипу, то прошивка вообще не будет заливаться с соответствующим сообщением;
  • соответствует ли выбранный размер flash-памяти тому, который имеется на плате;
  • соответствует ли выбранная таблица разделов размеру flash-памяти и выбранному типу файловой системы;
  • корректно ли указаны номера пинов кнопок и реле; если, например, для esp32c3 указать для кнопки пин GPIO17, то плата вообще не сможет стартовать;
  • для ESP32 нужно помнить, что здесь файловая система перед использованием должна быть отформатирована с последующей перезагрузкой платы; для ESP8266 это необязательно;

Если вы в затруднении, какую плату вообще выбирать, то можете выбрать следующее:

  • для ESP8266 - NodeMCU 1.0 (ESP-12E Module);
  • для ESP-01 с ее куцей памятью можно выбрать Generic ESP8266 Module и выбрать Flash Size: 1MB (FS:64kB OTA:~470kB) и надеяться, что 470КБ хватит для вашей прошивки :) ;
  • для ESP32 - выбрать ESP32 Dev Module или, если ваша ESP32 имеет дополнительный буквенный индекс, то соответственно ESP32C3 Dev Module, ESP32S2 Dev Module и т.д.;

Зависимости

Для работы модулей требуется одна сторонняя библиотека:

  • ArduinoJson.h - работа с данными в формате JSON (код писался с использованием версии 6.21.3, ниже версии 6.0 библиотека не будет работать, с версиями 7.0 и выше работа не тестировалась);

Аддоны для ESP8266 и ESP32

Инструкцию по установке аддонов смотри в документации к Arduino IDE.

ESP8266

Для работы с ESP8266 используется аддон esp8266 by ESP8266 Community, ссылка для установки:

Если не знаете, какую плату выбрать, выбирайте NodeMCU 1.0 (ESP-12E Module).

ESP32

Для работы с ESP32 используется аддон esp32 by Espressif Systems, ссылка для установки:

Если не знаете, какую плату выбрать, выбирайте ESP32 Dev Module (или ESP32C3 Dev Module, ESP32S3 Dev Module, ESP32S2 Dev Module и т.д. - в зависимости от того, какой процессор используется на вашей плате).

Для работы с МК ESP32C2, ESP32C6, ESP32H2 требуется версия аддона не ниже 3.0.


Если возникнут вопросы, пишите на [email protected]

About

Switch & Relay Control - Ардуино-библиотека для создания простых модулей WiFi-выключателей и WiFi-реле на базе ESP8266 и ESP32

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published