• Система автоматизации с открытым исходным кодом на базе esp8266/esp32 микроконтроллеров и приложения IoT Manager. Наша группа в Telegram

Esp8266 + дисплей +энкодер + датчики

Мы вас не тролим, просто вы очень чувствительный к конструктивной критике.
Ну точно не люблю оффтоп, и сам же волей-неволей участвую в нем.
Да была бы критика и подсказки, код выше выложил уже третью версию, но кроме как о философии сайта и не слышу в ответ :ROFLMAO:
Где вкрадывается ошибка, что с "делеями" все гуд, а с миллис полная неразбериха и неадекватное выполнение кода.
Сам понимаю, что дело во множественных "входах" в функцию
Но иначе никак, у меня устройство с дисплеем и энкодером, в добавок управляющие воздействия приходят от mqtt сервера, и при всем этом нужно сохранить автономность работы без интернета, в моменты подключения к вайфаю, при отвале датчиков.
Также это все, не без труда, было собрано на esp12f, что наложило ограничения на использование serial порта для дебага, потому что все ноги МК ушли куда надо, даже PCF8575 использовал для дисплея и периферии.
И при всем этом код умудряется работать, учитывая мои "навыки" и "умения".
 

enjoynering

Well-known member
У меня есть похожий проект - tthRelay. Там я делал так. Раз в минуту я запускаю функцию опроса сенсора, проверяю что температура/влажность не выше/ниже установленной+гистерезис и вкл/выкл реле. Чаще не вижу смысла - температура в помещениях изменяется медленно и за минуту сильно не измениться.
 

enjoynering

Well-known member
Библиотекy ESPAsyncWebServer не использовал. Всё на стандартной ESP8266WebServer.

В место millis(), я использовал стандартную для arduino esp8266 - Ticker.h
Пример её использования можно посмотреть в моей библиотеке для энкодера, там вместо прерываний, я через тикер опрашиваю энкодер раз 10 миллисекунд. Этого достаточно чтоб не пропускать клики.
 

pvvx

Активный участник сообщества
Раз в минуту я запускаю функцию опроса сенсора, проверяю что температура/влажность не выше/ниже установленной+гистерезис и вкл/выкл реле. Чаще не вижу смысла - температура в помещениях изменяется медленно и за минуту сильно не измениться.
Зависит от типа (инерции) нагревателя. В холе температура меняется на десятки градусов в минуту при открытии двери на улицу. И включение "теплого барьера" должно отрабатывать за доли секунд.
Даже для управления обычным масляным нагревателем требуется период опроса в десятку секунд, и то будут колебания:
1670959510222.png
 

enjoynering

Well-known member
У вас дом неправильно построен - хол должен быть отделен от жилых помещений, чтоб открытая входная дверь не изменяла температуру в доме на десятки градусов в минуту.
 

pvvx

Активный участник сообщества
В начале графика - это подобие ESP с невозможностью точно и быстро определять температуру - гистерезис более 0.1 С :p
У вас дом неправильно построен - хол должен быть отделен от жилых помещений, чтоб открытая входная дверь не изменяла температуру в доме на десятки градусов в минуту.
А в холле?
И там уже всё хорошо с "тепловым барьером" и он аналоговый, а не цифровой (On/Off)...
 
Этого достаточно чтоб не пропускать клики.
Да я уперся только с попеременную работу реле, хотел сделать, чтобы реле насоса циркуляционного отключалось через 2 минуты после отключения реле ТЭНов, и включалось с задержкой условной, например 4-10 секунд.
В итоге пока сделал одновременно все, может перепишу позже весь код, уйду от библиотек к нативному коду.
 

enjoynering

Well-known member
Узнаю перфекциониста pvvx. Если удерживать температуру то только с точностью 0.000000001С.

Вы в холле живёте? Разделся и прошёл дальше где тепло. Или вы до трусов? Тогда надо ставить PID и тёплый барьер на 3КВт..4КВт. Открывать в -20с входную дверь на полчаса, а потом постить сюда графики как у вас все ровно.
 

pvvx

Активный участник сообщества
Это к тому, что скорость опроса автор темы должен сам подбирать под свои инерции нагревателей и требуемый диапазон отклонений с гистерезисом, как и тип управления – тупой On/Off или ШИМ c ПИД регулировкой.
Но в проект заложено что-то хилое, что не даст разгуляться и сделать качественно. Тут уж ничем не помочь.
 

enjoynering

Well-known member
чтобы реле насоса циркуляционного отключалось через 2 минуты после отключения реле ТЭНов
Я бы делал так. Запоминал время отключения реле ТЭНов - millis() = timeOFF. А потом в главном цикле проверя три условия реле ТЭНов отключено, реле насоса включенно и millis() >= timeOFF + 120000 (где 120000 это 2 минуты в миллисекундах) и если все три true, то выключаем реле насоса.
 
Но в проект заложено что-то хилое, что не даст разгуляться и сделать качественно.
Изначально выбрал ESP12f, если бы взял AVR428P например или nano, то было бы больше возможностей.
А здесь сложно с периферией, не говоря уже о быстродействии и поточном выполнении операций.
 

enjoynering

Well-known member
Если сильно извратится, с некоторыми ограничениями можно высвободить как минимум ещё 2 пина у ESP8266, а с паяльником плюс ещё один. Ну и если надо больше, то тогда без раширителя портов никак. Но зато у вас wifi, а AVR428P кукиш с маслом.
 

CodeNameHawk

Moderator
Команда форума
что наложило ограничения на использование serial порта для дебага,
Так не надо делать дебаг на этой плате, возьмите другую плату и отладьте на ней часть кода с реле.
Реле к ней можете не подключать, достаточно в том месте писать реле сработало или отключилась.
И плата для отладки может любая из ардуинок, где есть сериал.
 
возьмите другую плату и отладьте на ней часть кода с реле.
В том и соль, что делаю так - отладка на "голой" wemos d1 mini.
Выполняю debug через serial, даже unit-test написал под одну функцию, не связанную с реле.
Сдается мне количество millis() для esp12 - конечно.
Все работает, как переношу на основное железо, с огромным кодом - сразу вылазят проблемы.
 
Открою вам великую тайну, millis() вообще то только один.
Это просто функция и пользовать ее можно без ограничений.
Ну тут секретов нет, я понимаю, что таймер на борту ESPшки - один.
Просто количество вызовов функции millis() видимо имеет пределы.
Сам код бывает тормозит выполнение, и начинаются лаги, сбои в циклах.
 

CodeNameHawk

Moderator
Команда форума
Ну тут секретов нет, я понимаю, что таймер на борту ESPшки - один.
Просто количество вызовов функции millis() видимо имеет пределы.
Сам код бывает тормозит выполнение, и начинаются лаги, сбои в циклах.
Вы похоже думаете, что когда вы вызываете millis(), то дополнительно нагружаете таймер(как это делают в модуле timer), это не так.
millis() читает значение счетчика и выдает вам, операция довольно быстрая. Хотя когда можно ее выкинуть, то так стоит и сделать.
видимо имеет пределы
Нет не имеет. Ограничение только в размере доступной памяти.
 
Последнее редактирование:

CodeNameHawk

Moderator
Команда форума
Ваш код:
Код:
if (temp < (temp_set - gisterezis))
    {
      relay1 = true;
      if (millis() - tmr >= 8000) {
        tmr = millis();
        relay1 = true;
      }
      updateStatePins();
    }
Я бы делал отладку примерно так:
Код:
#define DEBUG
{
#ifdef DEBUG
Serial.print("Znaczenieje temp ="); Serial.println(temp);
Serial.print("Znaczenieje temp_set ="); Serial.println(temp_set);
Serial.print("Znaczenieje gisterezis ="); Serial.println(gisterezis);
#endif//DEBUG

if (temp < (temp_set - gisterezis))
{
      relay1 = true;
//тут вывод значения в serial relay1
    uint32t vremia = millis();
//тут вывод значения в serial vremia
//тут вывод значения в serial tmr
      if ( vremia - tmr >= 8000)
      {
        tmr = vremia; //Вот вам пример, как выбросит лишний millis
//тут вывод значения в serial tmr
        relay1 = true;
//тут вывод значения в serial relay1 и почему тут опять relay1 (хз)
      }
      updateStatePins();
  }
}
И в самом начале надо вывести значения в serial relay1, откуда знать что в ней находится true или false.
 
Последнее редактирование:
Кто то может помочь с кодом?
Код:
  String temp_preset;
  for (int i = 0; i < length; i++) {
    temp_preset += String((char)payload[i]);
  }

  if ( String(topic) == temper_set ) {
    AirTarget = temp_preset.toInt();//конвертация строки в переменную
  }
Задаю temp_preset например 1.6
Но на выходе получаю AirTarget равную 1(округляет в меньшую сторону
У меня температура AirTarget имеет тип int, а temp_preset ввиду его пересылки через брокера mqtt допускается только типом char.
В итоге код
AirTarget = temp_preset.toInt();
"съедает" число с одним знаком после запятой и выдает целое число.
Как это победить?
 
Сверху Снизу