Какой протокол использовать?
- Войдите на сайт для отправки комментариев
Втр, 28/06/2022 - 22:58
Делаю выключатели света дома, планировал использовать ModBus по RS485. Сделал мастер и слейв тестовые, и ужаснулся скоростью работы. После нажатия кнопки на слейве, мастер одупляет спустя 1 секунду. До этого пользовался кастомным протоколом на базе RS485 тоже мастер-слейв, и там всё летало моментально. Тут конечно печаль. Возможно, библиотеки кривые, но те что самые популярные для arduino/esp8266.
Отсюда вопрос: посоветуйте, на что можно заменить это безобразие? Либо, может можно улучшить работу ModBus? Или у всех такая беда?
Только у плохих инженеров
. Сделал мастер и слейв тестовые, и ужаснулся скоростью работы. После нажатия кнопки на слейве, мастер одупляет спустя 1 секунду
Или у всех такая беда?
Вы бы показали свои "тестовые мастер и слейв", думаю причина тормозов в коде
Слейв, на atmega328p 8MHz. Скорость modbus на тормоза не влияет. И 4800 и 115200 - одинаково.
#include <Arduino.h> #include <ModbusRTU.h> // Library: mathertel/OneButton #include "OneButton.h" #define SLAVE_ID 2 #define MODBUS_ENABLED 3 #define MODBUS_SPEED 115200 #define NONE 0 #define CLICK 1 #define DOUBLE_CLICK 2 #define LONG_CLICK 3 #define STOP_LONG_CLICK 4 #define REGN 0 #define BTN 5 ModbusRTU mb; OneButton button(BTN, true); void setup() { button.attachClick([]() { mb.Hreg(REGN, CLICK); }); button.attachDoubleClick([]() { mb.Hreg(REGN, DOUBLE_CLICK); }); button.attachLongPressStart([]() { mb.Hreg(REGN, LONG_CLICK); }); button.attachLongPressStop([]() { mb.Hreg(REGN, STOP_LONG_CLICK); }); Serial.begin(MODBUS_SPEED, SERIAL_8N1); mb.begin(&Serial, MODBUS_ENABLED); mb.setBaudrate(MODBUS_SPEED); mb.slave(SLAVE_ID); mb.addHreg(REGN); mb.Hreg(REGN, NONE); } void loop() { button.tick(); mb.task(); yield(); }И мастер, esp8266:
#include <Arduino.h> // Library: emelianov/modbus-esp8266 #include <ModbusRTU.h> #define MODBUS_ENABLED 4 #define MODBUS_SPEED 115200 #define SLAVE_ID 2 #define FIRST_REG 0 #define REG_COUNT 1 ModbusRTU mb; bool cbStatus(Modbus::ResultCode event, uint16_t transactionId, void* data) { // Callback to monitor errors if (event != Modbus::EX_SUCCESS) { Serial.printf_P("Send result: 0x%02X, Mem: %d\n", event, ESP.getFreeHeap()); } return true; } void setup() { pinMode(LED_BUILTIN, OUTPUT); Serial.begin(MODBUS_SPEED, SERIAL_8N1); mb.begin(&Serial, MODBUS_ENABLED); mb.setBaudrate(MODBUS_SPEED); mb.master(); } void loop() { uint16_t res[REG_COUNT] = {0}; if (!mb.slave()) { // Check if no transaction in progress mb.readHreg(SLAVE_ID, FIRST_REG, res, REG_COUNT, cbStatus); // Send Read Hreg from Modbus Server if (res[0] == 1) { digitalWrite(LED_BUILTIN, LOW); mb.writeHreg(SLAVE_ID, FIRST_REG, 0x0, cbStatus); } else { digitalWrite(LED_BUILTIN, HIGH); } while(mb.slave()) { // Check if transaction is active mb.task(); delay(10); } } yield(); }В общем в библиотеке OneButton есть waitTime для определения кол-ва нажатий на кнопку. Вот оно и дает этот лаг.
Попробуй эту (я доволен её работой): https://github.com/kakmyc-github/kakmyc_btn
Попробуй эту (я доволен её работой): https://github.com/kakmyc-github/kakmyc_btn
Там тоже есть тайм-аут для определения количества нажатий.
По умолчанию 300мс.
Но никто не запрещает его уменьшить.
Попробуй эту - https://github.com/VAleSh-Soft/shButton
Там нет таймаутов ))
Там нет таймаутов ))
Ну это если мультиклики не нужны.
Да. Но тут уж никуда и уменьшение задержки не поможет. А если используется только одиночный клик, то и задержки не будет
Так в OneButton этот период до определения клика настраивается вроде. Уменьшить его...
Так если мультиклик не используется, то смысла в ней вообще нет. У меня в этом случае используется событие BTN_DOWN - без задержки за вычетом антидребезга
очевидно, что дело не в библиотеке. Ошибка в концепции. Если нужна быстрая реакция на кнопки - никаких дабл-кликов и лонг-прессов там быть не должно
С выключателями освещения, комнатного, мультиклик как-то неудобно, ИМХО.
Или нужно придумывать алгоритм, чтобы включение/выключение работало без задержек, ибо любая задержка, для непосвященных, будет восприниматься как лаги.
Я в свое время проходил все это. Были покупные выключатели, исполнительные на 433МГц, выключатели батарейные . Порой нужно было нажать их несколько раз для включения/выключения света, помехи, просаженные батареи... Отказался в пользу своих модулей на ESP8266 и обычных выключателей. И меньше по габаритам (для двух каналов) и удобнее получилось. Только освещение 9 помещений, плюс еще розетки.
Уже много лет работают, непосвященный не поймет, что это НЕ обычный выключатель и люстра. Когда все уходят, пропадают IP телефонов после закрытия входной двери из домашней LAN, весь свет и часть эл. приборов отключатся.
С учетом того, что ванная и туалет - галогенки (5 лампочек по 50Вт - это ванная, 4*35Вт - это туалет. Светодиоды пробовал, не понравились по освещению. Это единственные лампы накаливания в квартире наверное :-) ), не помню когда их менял. Если дверь закрыли и не было движения внутри - через две минуты свет отключается. Не закрыли дверь, и не было движения 10 минут - тоже выключается. Включение/выключение - плавное ( свой диммер на Тини25 подключенный к ESP8266 по I2C).
ванная и туалет - Если дверь закрыли и не было движения внутри - через две минуты свет отключается.
уже и на унитазе спокойно не посидишь, надо постоянно руками махать, чтобы свет не гас :)
уже и на унитазе спокойно не посидишь, надо постоянно руками махать, чтобы свет не гас :)
Никто не жаловался.
Мы же заходим, закрываем дверь. Если после этого датчик движения сработал - отключаем все таймауты - внутри кто-то есть.
А вот если закрыли дверь, и не было движения внутри - никого внутри нет :-)
Для меня главный признак успешности решения, отсутствие замечаний (в смысле заметили) от домашних.
Если на вопрос поменял алгоритм - что заметили - ответ: "Все нормально, нет неудобств, А что что-то поменялось?? - это хорошо. :-)
Не написал в предыдущем посте, у меня все работает локально, вне зависимости от наличия связи по Wi-Fi.
Есть связь, нет связи - решение принимается локально, а по mqtt сбрасывается только состояние, и принимаются команды.
Это только домашняя LAN:
очевидно, что дело не в библиотеке. Ошибка в концепции. Если нужна быстрая реакция на кнопки - никаких дабл-кликов и лонг-прессов там быть не должно
Согласен. Но это как раз выясняется эмпирическим путем. В итоге я просто отключил мультиклики:
И оставил даблклик только на одном выключателе, но уменьшив лаг в два раза - теперь это сравнимо с включением светодиодного освещения с хороших драйвером, общая задержка в 0.2 секунды.
У меня стоят выключатели и реле sonoff, задержка плавает, но вообще не напрягает. Особенно когда голосом включаешь/выключаешь
С голосом понятно, пока туда .. пока сюда.
А обычный выключатель, с задержкой, хочется еще раз переключить, если не включилось сразу.
Так там подсветка включается и щелчок реле слышно.
Т.е. условно я включаю диод на выключателе.
Включил диод==включил свет, и пофигу, что это произойдет через 1-2 секунды.
А я сделал так :-)