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

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

CodeNameHawk

Moderator
Команда форума
И там датчик AHT10 опрашивается один раз на экране, и пока не уйдешь с этого экрана(пункта меню) и не вернешься обратно то данные о температуре/влажности не обновятся.
Не надо "сидеть в меню".
Алгоритм примерно такой:
Если нажали кнопку - и если надо, отрисовали новый экран - и опять в основной цикл.
Уже в основном цикле, с нужным интервалом опрашиваете датчик(рекомендуют не чаще раза в секунду).
В ардуино все должно выполнятся максимально быстро в основном цикле.
(как только заканчивается цикл, выполняются внутренние функции есп)
 

CodeNameHawk

Moderator
Команда форума
И без switch-case просто работать.
Придумайте, что и когда должно выполняться, тогда даже при помощи if напишите скетч.

if кнопка нажата - делаем тото(нарисовали нывый пункт меню, запомнили в каком месте меню находитесь или просто, что то запомнить и.т.д.);
if уже пора по новой считать датчик - считываем;
if температура поменялась отрисовываем на дисплее;
if температура вышла за предел - включаем-выключаем реле;

Если не одно if не сработало - значит цикл будет пустым.

это все в основном цикле, если что еще надо добавьте еще if.
 

Mоnk

Member
И без switch-case просто работать.
В некоторых случаях помогает...
Если экран один, а информации много.
C++:
#ifdef TM1637
void showTime()
{
  switch (flagSW)
  {
    case 0:       //--------------------------------  ----------------------------------
      countShT ++;

      if (countShT <= ShT_A * 2 + 1)
      {
        if (NTPtimeGet || DS3231present)  // Если время по NTP или от DS3231 получено
        {
          ArrayData[0] = hourDS / 10;
          if (ArrayData[0] == 0) ArrayData[0] = 17;
          ArrayData[1] = hourDS % 10;
          ArrayData[2] = minuteDS / 10;
          ArrayData[3] = minuteDS % 10;
          TM1637_colon(colonUp = !colonUp);
        }
 

enjoynering

Well-known member
Жесть однако - ставить частоту шины i2c 1МГц когда AHT10 больше 400кгц не умеет. И даже так вы выше 800кгц не получите, не хватит производительности esp8266. Для тех кто в танке, читаем про библиотеку тут - https://elchupanibrei.livejournal.com/53764.html . Всегда ваш, изобретатель библиотеки AHTxx.


Экодер надо не опрашивать в цикле, а вешать на прерывания - https://elchupanibrei.livejournal.com/29025.html
 

Mоnk

Member
Для тех кто в танке
Ура! Тяжелая артиллерия подтянулась! Сейчас всё победим.

Можете показать свои примеры логики меню?
Попробую. На примере обогрева полов на крыльце в деревне.
Разделено на день-ночь, по просьбе друга. Без изменения внедрил и у себя.
В состоянии "покоя" коробка смотрит температуру воздуха (si7021) и пола (ds18b20). В настройках можно выбрать датчик, на который ориентируется нагреватель в полу.
Дисплей tm1637 показывает поочередно время (куда же без него :) ), температуру-влажность помещения, режим нагрева (авто или постоянный).
Вращение энкодера начинает регулировать температуру в соответствии с текущим временем. Если это день, то дневную, после 23 - ночную. В этом режиме кнопкой энкодера можно выбрать, какая в данный момент регулируется температура, дневная или ночная. Если был включен постоянный нагрев, включается автоматический. Если не трогать энкодер 10 секунд, возвращаемся на "основной" экран, и сохраняем настройки.
Так же с основного экрана кнопкой энкодера можно поочередно смотреть температуру пола, и настройки день-ночь. Долгое нажатие - авто или постоянный нагрев. Тройное нажатие - время из ntp пишем в ds3231. Четверное - ребут.
 

Mоnk

Member
А код можно посмотреть?
C++:
void encoderPosition()
{
#ifdef TM1637
  ArrayData[ColonUp] = 17;
#endif
  if (set_D_or_N)
  {
    pos < newPos ? setpointDAYPlus() : setpointDAYMinus();
  }
  else
  {
    pos < newPos ? setpointNIGHTPlus() : setpointNIGHTMinus();
  }
  pos = newPos;
}

void click1()
{
  click1wait = 14;
  if (flagSW == 0)
  {
    if (hide[DS18B20] == false)
    {
      flagSW = 1;
    }
    else
    {
      flagSW = 2; set_D_or_N = true;
    }
  }
  else if (flagSW == 1)
  {
    flagSW = 2; set_D_or_N = true;
  }
  else if (flagSW == 2)
  {
    flagSW = 3; set_D_or_N = false;
  }
  else if (flagSW == 3)
  {
    flagSW = 2; set_D_or_N = true;
  }
}

void doubleclick1()
{
}

void longPressStart1()
{
  heattoggle == OFF ? heattoggle_ON() : heattoggle_OFF();
  pubStatus(sTopic[TUMBLER], stat[TUMBLER]);
  chkdRt();
}

void longPress1()
{
}

void longPressStop1()
{
}

void multiClick1()
{
  switch (button1.getNumberClicks())
  {
    case 3: tone(D0, 3000, 100); StfNTPtDS(); break;
    case 4: handle_Reboot();                  break;
  }
}
 

Mоnk

Member
Что означают инструкции в коде?
Использую в самоделках два типа индикаторов (пока), TM1637 и LCD HD44780 с PCF8574. Точне их вариации.
TM1637 с Али с двоеточием. Так же самодельные на TM1637, с двоеточием и отдельными точками.
20200522_135712.jpg
20200522_135716.jpg
IMG_1637.JPG
20200912_121510.jpg
LCD 2402 на HD44780 надергал из телефонных аппаратов Siemens, Avaya и разных приборов. Естественно кодовые таблицы разные, и подход к выводу информации разный.
IMG_20160705_203732.jpg
Соответственно применяемый дисплей дефайнится. И в зависимости от дефайна компилится кусок кода.
C++:
#if defined(LCD)
  #include "LiquidCrystal_I2C.h"  //---------- https://github.com/fdebrabander/Arduino-LiquidCrystal-I2C-library
  #define Siemens                 //---------- Siemens Optiset Avaya BG1602G
  #include "LCD_type.h"           //---------- Символы
  String outLCD, outLCD2;
  int countShT = 0;               //---------- Счетчик для индикации
#elif defined(TM1637)
  #define CLK_pin     D6          //---------- TM1637 CLK 12
  #define DIO_pin     D5          //---------- TM1637 DIO 14
  #define ColonUp_1               //---------- В каком разряде двоеточие?
    #if   defined(ColonUp_1)
      #define ColonUp   1
    #elif defined(ColonUp_5)
      #define ColonUp   5
    #endif
  #define ShT_A       2           //---------- Сколько секунд показывать время?
  #define ShT_B       5           //---------- Сколько секунд показывать температуру?
  #define ShT_C       1           //---------- Сколько секунд показывать влажность?
  #define ShT_D       1           //---------- Сколько секунд показывать TUMBLER?
  bool colonUp = false;           //---------- Двоеточие светится?
  int countShT = 0;               //---------- Счетчик для индикации
  int brightUp = 8;               //---------- Яркость
  int ArrayData[6] = {24, 0, 10, 13, 17, 17}; // LOAD
  const int txtArray[71] =
  {
    5, 10, 12, 12, 14, 5, 5,                                // 0-6    SACCES
    14, 19, 19, 25, 19,                                     // 7-11   Error
 
Сверху Снизу