• Уважаемые посетители сайта esp8266.ru!
    Мы отказались от размещения рекламы на страницах форума для большего комфорта пользователей.
    Вы можете оказать посильную поддержку администрации форума. Данные средства пойдут на оплату услуг облачных провайдеров для сайта esp8266.ru
  • Система автоматизации с открытым исходным кодом на базе 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
 
Сверху Снизу