Большие часы на адресных светодиодах WS2812B

Большие часы на адресных светодиодах WS2812B
Всем привет, хочу рассказать о том как я попробовал повторить проект, но столкнулся с некоторыми проблемами.

Как-то раз на просторах зарубежного интернета я нашел вот такой проект часов на базе светодиодной ленты WS2812B: Big, Auto Dim, Room Clock, и мне захотелось его повторить. Часы устроены как семи сегментный циферблат и работают на RTC модуле DS3231 . Часы умеют показывать температуру, имеют кнопки для настройки и перевода на зимнее время и обратно, позже я добавил датчик влажности DHT11. Температура уже вместе с влажностью считывалась с этого датчика и выводилась раз в минуту. Хоть и в модуле часов есть температурный датчик, но похоже он показывал температуру не корректно из-за самонагрева (ИМХО).




Untitled Sketch_МП.png
И главное нанести много горячих соплей

IMG_20180907_120755.jpg


Когда все было собрано, повозившись с библиотеками, все заработало. И тут возникло одно большое НО: положения яркости в только в двух позициях меня не устраивало. Тем более на границе значений происходило мерцание. Установка яркости на статичном значении меня тоже не очень устраивала ибо днем при установленном тусклом свете ничего не было видно, а ночью даже со значениями близким к минимуму можно было осветить всю Москву. Поинтересовавшись как в других проектах с этим справляется Alex было решено заменить такой код настройки яркости.

C:
void BrightnessCheck(){
  const byte sensorPin = BRI_PIN; // light sensor pin
  const byte brightnessLow = 1; // Low brightness value
  const byte brightnessHigh = 50; // High brightness value
  int sensorValue = analogRead(sensorPin); // Read sensor
  Serial.print("Sensor is: ");Serial.println(sensorValue);
  sensorValue = map(sensorValue, 0, 255, 1, 100);
  LEDS.setBrightness(sensorValue);
  };
вот такими строчками:
C:
void BrightnessCheck() {

  if (auto_bright) {                         // если включена адаптивная яркость
    if (millis() - bright_timer > 100) {     // каждые 100 мс
      bright_timer = millis();               // сброить таймер
      new_bright = map(analogRead(BRI_PIN), 0, bright_constant, min_bright, max_bright);   // считать показания с фоторезистора, перевести диапазон
      new_bright = constrain(new_bright, min_bright, max_bright);
      new_bright_f = new_bright_f * coef + new_bright * (1 - coef);
      LEDS.setBrightness(new_bright_f);      // установить новую яркость
    }
  }
};

Тут стоит упомянуть что программистом я не являюсь и большинство проблем я пытаюсь решить методом тыка и перебора.

И тут все заработало, моей радости не было придела, пока не наступила ночь. Появилась проблема с отключением ленты при полной темноте. Иногда это было только на минуту, а иногда на целую ночь. Еще есть проблема со слабим мерцанием светодиодов если освещения в комнате было мало (например когда работал телик), но это было редко и длилось это одну минуту.

Что касается кода вот сылка на GitHub. Кое-что я перевел для лучшего понимания.

Давно хотел поделиться готовым и работоспособным проектом в кругах аудитории Алекса, но вышло так что собственно нормальной работоспособностью тут не пахнет. Буду благодарени, если у кто сможет помочь.
 
Изменено:

Комментарии

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

★★★★★★★
14 Авг 2019
4,185
1,280
Москва
@начинающий, вот и вся раскарска:
цвет=CHSV(map(температаура,-45,45,205,0),255,255);
Пример для библиотеки FastLED. Нужно подставить переменные вместо температуры и цвета, И еще 205 , что после -45 может придется подкорректировать по своему вкусу.
Этот пример в общем виде, он растягивает палитр от фиолетового до красного без таких пожеланий -"желтый +20"

Как будут выглядеть цвета можно посмотреть тут: https://wokwi.com/playground/fastled
Вставить этот код:
C++:
#include <FastLED.h>

#define LED_PIN     5
#define NUM_LEDS    16
#define BRIGHTNESS  255
#define LED_TYPE    WS2812
#define COLOR_ORDER GRB
CRGB leds[NUM_LEDS];

void setup() {
  FastLED.addLeds<LED_TYPE, LED_PIN, COLOR_ORDER>(leds, NUM_LEDS).setCorrection( TypicalLEDStrip );
  FastLED.setBrightness(  BRIGHTNESS );
  leds[0]=CHSV(225,255,255);
  leds[1]=CHSV(205,255,255);
  leds[2]=CHSV(0,255,255);
  FastLED.show();
  Serial.begin(115200);
}


void loop()
{
 for (int i=-45; i<46;i++)
 {
   Serial.println(i);
   CRGB col=CHSV(map(i,-45,45,205,0),255,255);
   FastLED.showColor(col);

   delay(1000);
 }
}
 
  • Лойс +1
Реакции: ASM

начинающий

✩✩✩✩✩✩✩
13 Дек 2020
132
9
как бы это дело прикрутить к #482, кто возьмется подкорректировать скетч #482? Или подскажите фрагмент кода меняющий цвет температуры в зависимости от ее величины и знака, и подскажите между каких строк вставить этот фрагмент. Спасибо.
 
Изменено:

bort707

★★★★★★✩
21 Сен 2020
2,894
860
@начинающий, ведь дали уже готовую строчку - что опять непонятно-то? Это же ваше хобби - сделайте хоть что-то сами...
 

maksland

★★★✩✩✩✩
13 Янв 2019
462
105
Omsk
Еще есть предложения кроме красного и синего цветов применить градиентные оттенки для промежуточных значений температур, например: для диапазона от -45 до +45 градусов распределить шкалу цветов от фиолетового до темно красного
У меня даже такая таблица была распределения цветов и -45 это сильно :), мне +23 само то !
нашёл свои наброски 2019
 

Вложения

Изменено:
  • Лойс +1
Реакции: начинающий

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

★★★★★★★
14 Авг 2019
4,185
1,280
Москва
@maksland, Я вот разницы в цветах 6-12 и 8-12 не вижу, как и 0-6 и -12-0. Но это лично мои глаза так себя ведут.
И даже такой вариант можно сделать с плавным переходом. Для этого надо предусмотреть не просто цвет, а два его крайних оттенка , причем стыковочные цвета могут быть как и близки по оттенку, так и нет. В последнем случае будет "зебра" и при пороговом значении температуры, когда она может прыгать (по показаниям датчика) туда сюда будет сами понимаете что)
Фрагмент кода для функции которая будет вычислять цвет в формате HSV в зависимости от температуры, в функцию так же передаются яркость и насыщенность. Если с насыщенностью можно не заморачиваться, то вот яркость вроде меняется от показаний фоторезистора, если не путаю.
Сам фрагмент:
C++:
CHSV tempetaColor(float t,uint8_t S,uint8_t V)
{
  if (t>35) return CHSV(map(t,35,45,20,0),S,V);
  else if (t>30) return CHSV(map(t,30,35,40,20),S,V);
  else if (t>25) return CHSV(map(t,25,30,80,40),S,V);
 // продолжить для других значений! последнее значение должно быть без if, только else!
}
 

maksland

★★★✩✩✩✩
13 Янв 2019
462
105
Omsk

Александр Злюс

✩✩✩✩✩✩✩
10 Фев 2020
19
1
привет друзья , подскажите пожалуйста как настроить, неполное свечение ленты , в режиме авто подстройка с датчиком фоторезистора по умолчанию это 255 а сделать 200 -220 максимально . и еще как в прошивке подправить температуру а то отличается у меня от провереного в один градус и еще как уменьшить скорость анимации каждой минут пробовал delay менять как мне советовали что то особых изменений не наблюдал подскажите пожалуйста
 

ASM

★★★★✩✩✩
26 Окт 2018
1,514
294
@Александр Злюс, так поставь яркость сколько нужно) можно свой диапазон указать)
Так где считываются показания датчика добавь корректировку, + или - 1, или как нужно. На счёт задержки не помогло?) Ну, тут надо код смотреть, чей используется?) Уже путаница у кого чей используется)
 

maksland

★★★✩✩✩✩
13 Янв 2019
462
105
Omsk
Две последние платы в железе не проверял, вторая плата (2 ds18b20) уже приехала но еще не собирал. В третьей версии платы BME280 поставил вертикально.
 

Вложения

Изменено:

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

★★★★★★★
14 Авг 2019
4,185
1,280
Москва
@Александр Злюс, вы реально не можете в этом тексте найти для яркости вот эти 2 строки?
C++:
#define LIGHT_MIN 4 // Минимальный уровень яркости (0...255) должно быть меньше максимального
#define LIGHT_MAX 250 // Максимальный уровень яркости (0...255) должно быть больше минимального
А по температуре внутри есть вот такой раздел
C++:
case 20: { // Режим вывода температуры внутри
if(temp_flag == false){
temp = 10 * sensor1.getTemp();
 
  • Лойс +1
Реакции: ASM

ASM

★★★★✩✩✩
26 Окт 2018
1,514
294
Анимация тоже видна
C++:
void Fadefonction() { // Фунция анимации при смене минуты
Увеличить delay, и анимация будет медленнее
 

kym13

★★✩✩✩✩✩
14 Ноя 2020
444
67
Александр Злюс
А у Вас скетч который вы выложили компилируется? У меня при компиляции выдаёт ошибку в строке 167
<incompatible types in assignment of 'CHSV' to 'CRGB [86]'>
 

Александр Злюс

✩✩✩✩✩✩✩
10 Фев 2020
19
1
@Александр Злюс, вы реально не можете в этом тексте найти для яркости вот эти 2 строки?
C++:
#define LIGHT_MIN 4 // Минимальный уровень яркости (0...255) должно быть меньше максимального
#define LIGHT_MAX 250 // Максимальный уровень яркости (0...255) должно быть больше минимального
А по температуре внутри есть вот такой раздел
C++:
case 20: { // Режим вывода температуры внутри
if(temp_flag == false){
temp = 10 * sensor1.getTemp();
Анимация тоже видна
C++:
void Fadefonction() { // Фунция анимации при смене минуты
Увеличить delay, и анимация будет медленнее
менял . и как уменьшал так и как увеличивал значения и key менял ))) и delay и большие значения ставил и маленькие как было так и есть .
// Режим установки отображения анимации при смене минут
if (key == 1) { //увеличиваем
delay(200);
if (set_shows == 1) set_shows = 0; else set_shows += 1;}
if (key == 3) { //уменьшаем
delay(200);
 

Александр Злюс

✩✩✩✩✩✩✩
10 Фев 2020
19
1
Александр Злюс
А у Вас скетч который вы выложили компилируется? У меня при компиляции выдаёт ошибку в строке 167
<incompatible types in assignment of 'CHSV' to 'CRGB [86]'>
да работает . может с библиотеками не совпадение поэтому я не меняю ничего в прошивке самостоятельно ))) запарился уже перебирать эти библиотеки
 

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

★★★★★★★
14 Авг 2019
4,185
1,280
Москва
@Александр Злюс,
Почти. Я так понял там температура с десятыми долями градуса ?
Тогда если надо увеличить на 1 градус после чтения сенсора надо написать temp += 10 ; или сразу temp = 10 * sensor1.getTemp()+10;
 

Александр Злюс

✩✩✩✩✩✩✩
10 Фев 2020
19
1
@Александр Злюс,
Почти. Я так понял там температура с десятыми долями градуса ?
Тогда если надо увеличить на 1 градус после чтения сенсора надо написать temp += 10 ; или сразу temp = 10 * sensor1.getTemp()+10;
да с десятыми долями , я правильно написал фрагмент ? а что такое десять или тупо вписать это и все))))
case 20: { // Режим вывода температуры внутри
if(temp_flag == false){
temp = 10 * sensor1.getTemp()+10;
 

Александр Злюс

✩✩✩✩✩✩✩
10 Фев 2020
19
1
ясненько спасибо большое попробовал скомпилировать - пока без о шибок . попробую вечерком прошить .. и пока еще горячий вопрос . а если на оборот снизить градус то вписать нужно со знаком минус temp = 10 * sensor1.getTemp() -10 ?
 
Изменено:

Вячеслав_45

★★✩✩✩✩✩
10 Июл 2020
72
64
Избыточное цитирование
Здравствуйте . Обращаюсь к Вячеслав_45 , будет ли дальнейшее развитие вашей прошивки из поста #202 ? (разные цвета температуры , может отдельная настройка цвета отображения часов , добавление датчика давления ...). Просто, как то всё с этой прошивкой заглохло , а очень жаль , в ней есть много полезного (сохранение настроек в памяти , а самое главное для меня "установка количества отображения температуры и даты в минуту" ) .
В планах есть развитие прошивки, пока нет времени.
 
  • Лойс +1
Реакции: maksland

maksland

★★★✩✩✩✩
13 Янв 2019
462
105
Omsk
Вячеслав_45, ждём ! мне уже платы на 2 DS18b20 пришли и нарисовал плату с датчиком давления.
может добавить пару светиков для информативности температуры ?
 

Вложения

Изменено: