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

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

CodeNameHawk

Moderator
Команда форума
Если датчик оборвался не надо читать с него значения.
Есть функции обнаружения датчиков getdevicecont.
Там куча примеров.
ps. Вернее, получив ошибку считывания температуры, полезней по новой запустить опрос присутствия датчиков.
 
Последнее редактирование:

enjoynering

Well-known member
Там не все так просто - GPIO9 использовать без паяльника не получится. Почему, читаем тут.
 

Mоnk

Member
Кто что думает по поводу модулей PCF8574
В Гугле много примеров попадается. В основном INTERRUPTED_PIN используют. Нас же интересует минимум пинов. Вот например https://github.com/RobTillaart/rotaryDecoder без "третьей ноги", сразу на 4 энкодера, но скудненько по функционалу. Слегка допилил направление ротации и деление количества щелчков. На 3.0.2 работает.
А вообще возьмите 8285-ю. Вам же FS не нужно для хранения логов.
 

Вложения

Друзья, спасибо за ссылки из гугла, но без обид - пользоваться сам умею поисковиками, но к сожалению, и вы со мной согласитесь, примеры на сайтах и реально работающие устройства - это разные вещи!
В надежде на форум, что здесь все таки люди в большинстве реально практикующие, а не "кто-то" и "где-то" написал, сам не повторял, но вот на.
Устройство, на которое ищу кое-какие решения по коду, я создаю самостоятельно и оно будет в железе и будет информация по нему.
Реально в рунете никого не видел, кто подключал пины для флешки под вход/выход.
Решений по энкодеру масса, в авиа сфере, где собственно и работаю, для приборов используется код Грея, для увеличения четкости срабатывания кремальер.
Вот например https://github.com/RobTillaart/rotaryDecoder без "третьей ноги"
Этот пример энкодера по I2C?
Да, там функционала маловало...
 

Mоnk

Member
Да, там функционала маловало...
На самом деле это всего лишь инструмент. А заставить его выполнять поставленные задачи - наш вопрос.
Лично я испльзую
для кнопки #include "OneButton.h" //---------- https://github.com/mathertel/OneButton
для энкодера #include <Encoder.h> //---------- Rotary Encoder https://github.com/PaulStoffregen/Encoder
C++:
void loop()
{
  newPos = myEnc.read()/12;
  if (pos != newPos) encoderPosition();

  button1.tick();
...............

void encoderPosition()
{
  pos < newPos ? setpointPlus() : setpointMinus();
  pos = newPos;
.............

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

    case 4:
      handle_Reboot();
    break;

    case 5:
      fanToggle();
    break;
как раз на Вемос
#define D3 0 // SCL_pin ---------- I2C SCL
#define TX 1 // DS18B20_pin ---------- Dallas Temperature
#define D4 2 // SDA_pin ---------- I2C SDA
#define RX 3 // AM2302_pin ---------- AM2302 резерв
#define D2 4 // REdt_pin ---------- Rotary Encoder DT
#define D1 5 // REclk_pin ---------- Rotary Encoder CLK
#define D6 12 // light_pin ---------- Свет
#define D7 13 // REsw_pin ---------- Rotary Encoder button SW
#define D5 14 // fan_pin ---------- Вентилятор
#define D8 15 // heat_pin ---------- Нагреватель
#define D0 16 // tone_pin ---------- Пищалка

C++:
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 encoderPosition()
{
#ifdef TM1637
  ArrayData[4] = 17;
#endif
  if (set_D_or_N)
  {
    pos < newPos ? setpointDAYPlus() : setpointDAYMinus();
  }
  else
  {
    pos < newPos ? setpointNIGHTPlus() : setpointNIGHTMinus();
  }
  pos = newPos;
}
.................

  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);
 

Mоnk

Member
здесь все таки люди в большинстве реально практикующие
По поводу подключения 5110 к мультиплексору автору отписал о проблеме в 3.0.2. Обещал решить, но сроки не указывает.
Я в своё всремя отказался от этой схемы, ибо имеется много 2402, но без подсветки.
IMG_20220530_145020.jpg
Screenshot_20191122-064542.png
 

enjoynering

Well-known member
ну у вас же 5110 spi. зачем вы все усложняете подключая spi через i2c? вам же дали ссылку там все есть

Код:
SPI.pins(6, 7, 8, 0);
SPI.begin();
 
Продолжаю разработку контроллера электрокотла(картинки кликабельны).
Некоторое время не доходили руки разобраться с проблемой "подтормАживания" меню и всего кода.
photo1657294966.jpeg
Были вначале подозрения на задержки в коде(delay's), но от них избавился путем millis() и даже пробовал диспетчер задач gyverOS - получал небольшой прирост скорости отклика от меню, но не более того.
photo1657699291.jpeg
Проблемы начинались, когда я начинал опрос датчика температуры, AHT10, который подключается по I2C(SDA, SCL).
photo1665416334.jpeg
Вначале обновил библиотеку, вместо AHT10.h использую теперь "AHTxx.h"
Код:
#include "AHTxx.h"
По рекомендации авторов библиотеки инициализирую библиотеку.
В "мурзилке" написано, что надо в блоке SETUP добавить строку
Код:
AHT10.begin();
А затем в цикле LOOP добавить код
Код:
float temp = AHT10.readTemperature();
Тем самым запросить у датчика по двум проводам I2C температуру(ну или влажность) и записать ее в переменную temp
И тут начинается самое интересное.
Пока я не добавляю в setup
Код:
AHT10.begin();
Мой код "цветет и пахнет" и задержек в работе меню и всей программе нет.
Как только добавляю - все виснет и меню становится "вязким".
Ну хватит эпитетов.
В общем стал разбираться с кодом библиотек.
Ах....забыл сказать, что я еще попробовал подключить дисплей нокия 5110, тот что по SPI обычно работает, подключить через интерфейс PCF8574, используя библиотеку.
Итого - получается у меня на шине i2C два устройства - AHT10 и расширитель портов PCF8574.
В общем дисплей подключился на "ура", и на моей esp12f освободилось порядком ног.
Но как писал выше, при инициализации строки
Код:
AHT10.begin();
Код виснет и меню тормозит.
Стал экспериментировать с библиотеками.
Нашел в коде AHTxx.h дефайн
Код:
#define AHTXX_I2C_SPEED_100KHZ   100000  //sensor I2C speed 100KHz..400KHz, in Hz
Изменил 100000 на 1000000 и О ЧУДО, задержки пропали.
Стал искать значения скорости шины I2C в коде библиотеки для PCF8574, нашел такие строки.
Код:
#ifdef ESP8266
  _i2c_sda=SDA;
  _i2c_scl=SCL;
  _i2c_speed=1000000L;
Также нашел, что скорость шины I2C для работы датчика AHT10 можно задавать с помощью строки
Код:
Wire.setClock(400000L);
В общем это 400000kHz - не нашел зачем пишут литеру L в конце, может кто подскажет?
Если убираю инициализацию датчика строкой
Код:
AHT10.begin();
То температура с датчика все равно читается, получается библиотека, которая работает с расширителем портов PCF8574 для подключения дисплея нокия 5110 по шине I2C включает шину в работу и задает скорость, и если я повторно инициализирую работу шины I2C и задаю ей скорость меньше 400кГц то разумеется все начинает тормозить.
Не понятно еще, почему температура с датчика AHT10 читается, если нет дескриптора функции, он закомментирован.
Код:
void setup() {
  // начинаем работу с датчиком AHT10
  //AHT10.begin();
}
void loop() {
float temp = AHT10.readTemperature();//несмотря на закоментированный AHT10
//данные в переменную temp попадают
}
Также ради интереса решил побаловаться анализатором сигналов(клон Saleae на 25 мГц/8 каналов) и поиграться разной частотой шины.
Код:
Wire.setClock(400000L);
Скриншот 10-10-2022 17.20.24.png
По таймингам видно, что частоты импульсов доходят до 135 кГц, если же уменьшаю частоту до 50 кГц например, то код заметно тормозит, меню "вялое" и тайминги импульсов максимальные 35 кГц.
Скрин для частоты шины 400000L - правильно же понимаю, это 400000 кГц?
И зачем добавляют L в конце?
P.S. Тема смежная с этой
 

Mоnk

Member
Мой код "цветет и пахнет" ...
Ах....забыл сказать, что я еще попробовал подключить дисплей нокия 5110, тот что по SPI обычно работает, подключить через интерфейс PCF8574, используя библиотеку.
Прошу прощения, у Вас какая версия ядра используется? У меня на 3.0.2 эта битлотека компилится, но не работает...
 

Mоnk

Member
ну а чем не датчик)))?
Ну я думал, может какие религиозные причины...
Я в его, AHT10, сторону посматривал. Как вариант дешевой замены si7021, а особенно BME280. Но не решился.
Соответствено библиотеку на запчасти не разбирал.
Попутный вопрос, у Вас датчик сколько раз допустим в 10 минут опрашивается?

C++:
if (timer10s ++ == 10)                                //---------- 10 секунд
  {
    timer10s = 0;
    getWeather();
    heat_ON_OFF();
  }
 
Не надо его, в каждом проходе, теребить.
Да это понятно, но сейчас пишу другой код с "принципиально" другим меню.
И там датчик AHT10 опрашивается один раз на экране, и пока не уйдешь с этого экрана(пункта меню) и не вернешься обратно то данные о температуре/влажности не обновятся.
Вначале датчик трогаешь и температура его должна расти, но на дисплее не обновляется.
photo1665423445.jpeg
Перехожу в другое подменю(смена экрана).
photo1665423445 (1).jpeg
Возвращаюсь на начальный экран и данные обновляются.
photo1665423445 (2).jpeg
Редкое обновление тоже не хорошо - но тут скорее всего я пока не могу в коде додумать как обновлять с заданным интервалом.
У меня структура меню на SWITCH-CASE.
 
Попутный вопрос, у Вас датчик сколько раз допустим в 10 минут опрашивается?
Я параметры свои не задавал.
В библиотеке эти значения
Код:
/* sensor delays */
#define AHTXX_CMD_DELAY          10      //delay between commands, in milliseconds
#define AHTXX_MEASUREMENT_DELAY  80      //wait for measurement to complete, in milliseconds
#define AHT1X_POWER_ON_DELAY     40      //wait for AHT1x to initialize after power-on, in milliseconds
#define AHT2X_POWER_ON_DELAY     100     //wait for AHT2x to initialize after power-on, in milliseconds
#define AHTXX_SOFT_RESET_DELAY   20      //less than 20 milliseconds

/* misc */
#define AHTXX_I2C_SPEED_100KHZ   100000  //sensor I2C speed 100KHz..400KHz, in Hz
#define AHTXX_I2C_STRETCH_USEC   1000    //I2C stretch time, in usec
#define AHTXX_FORCE_READ_DATA    true    //force to read data via I2C
#define AHTXX_USE_READ_DATA      false   //force to use data from previous read
Что из них время опроса?
10 миллисекунд или 1000?
 
Сверху Снизу