ESP, IoT [BigClock] Большие часы на WS2812, ESP8266, Народный мониторинг

Какой вариант датчика используется у вас? Интересно, использует ли кто BME280, как у меня?)

  • BMP280

    Голосов: 23 29.1%
  • BME280

    Голосов: 56 70.9%

  • Всего проголосовало
    79
[BigClock] Большие часы на WS2812, ESP8266, Народный мониторинг
Создаю отдельную тему по разработке прошивки на базе NodeMCU.

Мой проект сделан на ДВП, на нее наклеил ленту, объем цифрам сделал из сэндвич панели, поверх белый лист бумаги.
Корпус из дерева, покрашен акриловой краской, смесь белой и коричневой.

Данная прошивка проверяет время по NTP, часы RTC теоретически не нужны.
Барометр на базе BME280.
Имеется датчик освещенности и датчик DS18B20
Clock_схема.pngсхема пайки.jpgClock_схема3.jpg
Плата: NodeMCU 1.0 (ESP 12-E Module)
Если в качестве микроконтроллера вы используете Wemos D1 - в менеджере плат для компиляции все равно выбирайте "NodeMCU v1.0 (ESP-12E)", в противном случае, если выберете плату Wemos D1 (xxxx), - будет работать нестабильно.
Выбирайте ядро ESP версии 2.7.4.

ESP8266 (SDK v2.7+)

Необходимые библиотеки находим в репозитории программы IDE.
Настраиваем прошивку под себя, если нужно, меняем пароли для точки и OTA, WiFi можно не задавать.

Если не задавали настройки WiFi, то стартует точка, адрес стандартный 192.168.4.1 пароль по умолчанию administrator, задавать не менее 8 символов, иначе название точки не отобразится, а будет ее внутреннее имя, типа ESP12345.
Адрес портала http://clock.local/ или по IP адресу, выданному роутером.
Данные для OTA: имя: admin пароль: pass

Для подключения к сервису "Народный мониторинг" MAC адрес отображается на соответствующей странице, вводите этот адрес при регистрации устройства.

Новая версия на гитхаб, последние изменения и публикация свежих версий будет там)

Версия от 16.04.2023 CLOCK_ESP_2.0:
  • оптимизация под новый портал
  • переделано давление с инт на флоат для мониторинга
  • переделан интерфейс на UI
  • добавлена ручная синхронизация времени
  • заменена библиотека rtc на microDS3231
  • багфиксы)
  • добавлена в код точка, для десятичного знака уличной температуры
  • добавлена строка с версией прошивки
  • исправление даты
  • добавление DFPlayer, спасибо: @Maxx1200 и @Romshteks
  • добавлен режим с датой (номер 5)
  • обновлена библиотека EEManager (сбросятся настройки!!!)
  • добавлен режим с показом первого нуля в часах
  • добавлена возможность устанавливать цветовое оформление в настройках прошивки, визуальные правки
  • fix GMT
  • заменены библиотеки датчиков
  • визуальные правки
  • может что-то еще))
Проект на гитхаб со всеми библиотеками и mp3
  • Дофига изменений))
  • Появилась web страничка с настройками на базе GyverPortal.
  • Изменены библиотеки.
  • Переписан код, распределил по вкладкам.
исправлено:
  • баг со сменой цвета на последней цифре
добавлен
  • символ давления, включать в настройках
исправлено:
  • переделан вывод сегментов
  • переделана функция показа точек
добавлено:
  • выбор режима мигания секунд 1 и 2 раза в сек
  • можно вручную задать порядок отображения датчиков и время показа каждого датчика
  • откл. WiFi без мониторинга
  • корректировка показания датчиков
внедрение датчика BME280, добавлен режим влажности с возможностью включить символ проценты
[*]багфиксы
багфиксы
незначительные изменения кода (настройки под себя и комментарии)
  • все настройки вынесены в Constants, вроде:)
  • добавлен web сервер, для обновления через браузер, изначально прошить через кабель, потом можете вносить изменения под себя и обновляться через бинарный файл
  • добавлены библиотеки
  • изменение в коде, из-за выноса настроек:)
  • добавлен НГ режим :)
  • возможно исправлена анимация, про которую писали, с точками и цифрами :)
  • теперь при запуске часов идет проверка с датчика времени, и если все ОК, то запускаются часы без синхронизации
  • исправлена функция освещенности заменой switch на if/else
  • подправлен код с switch в других местах
Увидел в коде небольшую ошибку с НГ режимом, не важно, включен он или нет, все равно будет) только разными методами)
leds[cursor] = (digit & mask) ? CHSV(random(0, 255), random(0, 255), random(0, 255)) : CRGB (0, 0, 0);
leds[cursor] = (digit & mask) ? ledColor : CRGB (0, 0, 0);
  • исправлен НГ режим
  • отключена точка доступа за ненадобностью
  • оптимизирован код
  • выбор в настройках кол-во разделительных точек
  • можно запускать с RTC модулем и без него
  • изменена библиотека NTP
  • поправлен код :)
Внимание: у кого мигает первый светодиод, необходимо изменить ядро ESP на 2.7.4 (инструменты/Плата/Менеджер плат).
Новые версии нестабильные на октябрь 2021г.
 

Вложения

Изменено:

Комментарии

S_Sergey_G

✩✩✩✩✩✩✩
23 Фев 2021
165
3
C++:
void TempStreetToArray() {             // вывод уличной температуры на экран
  sensors.requestTemperatures();                      // опрос датчика уличной температуры
  FtempS = sensors.getTempCByIndex(0) + o.cor_tempS;  // чтение уличной температуры с датчика 0, аналогично следующий будет 1
  tempS = FtempS;
  Serial.println((String)tempS + " | " + FtempS);
  Dots(!Dot);
  Digit(digits[10], segment_4);  // символ градуса
  int digit = FtempS *100;
  Digit(digits[digit], segment_3);
  digit = abs(tempS / 10);
  if (digit == 0) Digit(digits[12], segment_2);  // если впереди ноль, то выключаем его
  else
    Digit(digits[digit], segment_2);              // иначе показываем как есть
  if (tempS <= -1) Digit(digits[13], segment_1);  // если < или = -1, то показываем -
  else
    Digit(digits[12], segment_1);  // иначе выключаем 1 сегмент
};
При таком коде показывает так:
Строку Digit(digits[10], segment_4); // символ градуса, надо тоже менять на число, но выдаёт ошибку если я делаю так :
C++:
Digit(digits[digit], segment_4);
 

Вложения

  • 53.6 KB Просмотры: 0

ASM

★★★★★✩✩
26 Окт 2018
1,602
311
@S_Sergey_G, так и будет ошибку, он не знает что такое digit, для первого случая значение не требовалось вычислять, а брался символ из кода.
Поэтому по аналогии с предыдущим, сделай вычисление int digit =
Затем этот код с segment 4, затем просто digit =, без int, т.к. он определен ранее.
 

S_Sergey_G

✩✩✩✩✩✩✩
23 Фев 2021
165
3
Спасибо получилось
прописал так: правильно?
C++:
  int digit = abs(FtempS / 100);
  Digit(digits[digit], segment_4);  // десятые градуса
  digit = abs(tempS % 10);
Но вывод на дисплей теперь так: 25.0 26.0 27.0
В сериал пишет 25.3 26.4 27.7 . Как вывести не округленные данные?
 

ASM

★★★★★✩✩
26 Окт 2018
1,602
311
@S_Sergey_G, FtempS. abs это модуль, чтобы убрать возможный минус, который портит вывод)
п.с. надо будет подумать, как реализовать это у себя, чтобы можно было включать дробный режим)
 

S_Sergey_G

✩✩✩✩✩✩✩
23 Фев 2021
165
3
Если прописываю так: int digit = FtempS / 100; десятки округляются.
Если пишу так: int digit = FtempS * 100; то десятки вижу меняются но сегменты не все загораются.
 

Вложения

  • 30.3 KB Просмотры: 1

ASM

★★★★★✩✩
26 Окт 2018
1,602
311
@S_Sergey_G, так логично если 25.45 / 100, будет ровно 25. Если умножить, то будет 2545. Теперь остаётся понять, где ошибка в коде. Если смотря на картинку, то одиночной цифры 45 не существует, невозможно записать ее в один сегмент. Нужно для третьего 45 / 10, а для четвертого от 45 взять остаток от деления на 10, т.е. %10. Как и ранее описывал математику.
 

S_Sergey_G

✩✩✩✩✩✩✩
23 Фев 2021
165
3
Поставил так: int digit = (tempS % 10); десятка появилась, но странно ведёт себя. Редко обновляется, разные показания с сериал портом.
 

ASM

★★★★★✩✩
26 Окт 2018
1,602
311
@S_Sergey_G, думаю от интервала зависит, который настроил. Попробуй выставить чаще.
 

S_Sergey_G

✩✩✩✩✩✩✩
23 Фев 2021
165
3
Интервалы менял (в настройках веб) . Не помогает. Заметил, что обновление десятки градусов происходит только при изменении целых градусов.
 

ASM

★★★★★✩✩
26 Окт 2018
1,602
311
@S_Sergey_G, у тебя для температуры планируется отрицательная температура? Без нее можно попробовать сделать, целые слева, нижняя точка, после запятой справа.
 

S_Sergey_G

✩✩✩✩✩✩✩
23 Фев 2021
165
3
Да датчик будет на улице, минус нужен. Я думал дополнительную точку поставить после 3 символа.

Обновление десятых происходит вместе с обновлением целых градусов, наверное надо как то делать обновление отдельно для десяток.
 

ASM

★★★★★✩✩
26 Окт 2018
1,602
311
Хотел реализовать отдельным режимом, но что-то не работает)
Примерно так должно быть, что писал вчера)
Только надо подумать, как лучше выводить, если число целых с одним знаком)
C++:
void TempStreetToArray() {                       // вывод уличной температуры на экран Float
  sensors.requestTemperatures();                      // опрос датчика уличной температуры
  FtempS = sensors.getTempCByIndex(0) + o.cor_tempS;  // чтение уличной температуры с датчика 0, аналогично следующий будет 1
  tempS = FtempS;
  Serial.println((String)tempS + " | " + FtempS);
  Dots(!Dot);
  int a = FtempS * 10;   //25.43 -> 254
  Serial.println(a);
  int digit = abs(a % 10) ; //254 -> 4
  Serial.println(digit);
  Digit(digits[digit], segment_4);  // символ градуса
  digit = abs((a % 100)/10);   // 254 -> 54 -> 5
  Serial.println(digit);
  Digit(digits[digit], segment_3);
  digit = abs(a / 100); // 254 -> 2
  Serial.println(digit);
  if (digit == 0) Digit(digits[12], segment_2);  // если впереди ноль, то выключаем его
  else
    Digit(digits[digit], segment_2);              // иначе показываем как есть
  if (tempS <= -1) Digit(digits[13], segment_1);  // если < или = -1, то показываем -
  else
    Digit(digits[12], segment_1);  // иначе выключаем 1 сегмент
};
 

S_Sergey_G

✩✩✩✩✩✩✩
23 Фев 2021
165
3
При таком коде почему то выдаёт ошибку совсем в другом месте (
'wifi_connected' was not declared in this scope)
Моя ошибка.

Так работает. Десятки меняются в пределах градуса. Отлично!
 
Изменено:

ASM

★★★★★✩✩
26 Окт 2018
1,602
311
Выпущу для теста бета версию)
Библиотеки внутри)
Исправил запуск с ТД.
Кол-во режимов при тестировании менял, работают, только заметил, что последний режим работает дольше, возможно это связано из-за кода от DAK, т.к. размер строки передается всегда один и тот же...


  • оптимизация под новый портал
  • переделано давление с инт на флоат для мониторинга
  • переделан интерфейс на UI
  • добавлена ручная синхронизация времени
  • заменена библиотека rtc на microDS3231
  • багфиксы)
 

Старик Похабыч

★★★★★★★
14 Авг 2019
4,253
1,297
Москва
Попробуй при назначении следующего режи ма проверять не последний ли этот? и если последний сразу назначать первый. Но проверять не длинной данных!
 

S_Sergey_G

✩✩✩✩✩✩✩
23 Фев 2021
165
3
Разделительную точку между десятой градуса каким образом можно организовать? Можно допаять в конце ленты один светодиод и объявить его как сегмент и дорисовать символ?
 

ASM

★★★★★✩✩
26 Окт 2018
1,602
311
@S_Sergey_G, да в принципе без разницы, можно последовательно, можно в конце. Немного код только поправить, аналогично точкам часов будет. Зажигать в нужное время.
leds[114]=ledColor; //так можно включить последний диод
leds[114]=0; //так выключить
отсчет с нуля, 4 диода в сегменте, на 114 можно повесить точку.
 
Изменено:

S_Sergey_G

✩✩✩✩✩✩✩
23 Фев 2021
165
3
#define NUM_LEDS (LEDS_IN_SEGMENT * 28 + DOTS_NUM) здесь мы меняем, что ни будь?
leds[114]=ledColor; это в закладке "Dots"
 

ASM

★★★★★✩✩
26 Окт 2018
1,602
311
@S_Sergey_G, я думаю так сделать, если будет ещё точка
C++:
#define NUM_LEDS (LEDS_IN_SEGMENT * 28 + DOTS_NUM +1)
C++:
leds[NUM_LEDS]=ledColor;
leds[114]=ledColor; это в закладке "Dots"
Нет, это в нужном месте, там где ранее описывали температуру, там есть принудительное отключение точек от часов Dots(!Dot);
 
Изменено:

ASM

★★★★★✩✩
26 Окт 2018
1,602
311
@Старик Похабыч,
C++:
mode++;
    if (mode > 4) mode = 0;
    if (sizeof(c.orderDisplay) == mode) mode = 0;
В коде есть проверка, заменил 4 на 5, прописал в коде 5 режим, продублировал аналогичным режимом функции...
залил на гитхаб, для удобства)

А это где должно прописано?
в sensorsToArray, можно рядом с Dots(!Dot);
 
Изменено:

S_Sergey_G

✩✩✩✩✩✩✩
23 Фев 2021
165
3
C++:
  sensors.requestTemperatures();                      // опрос датчика уличной температуры
  FtempS = sensors.getTempCByIndex(0) + o.cor_tempS;  // чтение уличной температуры с датчика 0, аналогично следующий будет 1
  tempS = FtempS;
  Serial.println((String)FtempS + " | " + FtempS);
  Dots(!Dot);
  leds[114]=ledColor;
  leds[NUM_LEDS]=ledColor;
  int a = FtempS * 10;
Так должно работать? Ошибок нет. Просто проверить сейчас не могу, часы дома лента на работе осталась, завтра подпаяю.
 

ASM

★★★★★✩✩
26 Окт 2018
1,602
311
@S_Sergey_G, поэтому и сделано расчетное, 1*7*4 +2 +1, итого 31 диод. От 0 до 30.