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