Большие часы на адресных светодиодах 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. Кое-что я перевел для лучшего понимания.

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

Комментарии

bort707

★★★★★★✩
21 Сен 2020
3,046
909
В программировании не силен, но попробую рискнуть "посоветовать" нельзя ли попытаться сплагиатить фрагмент скетча из той версии где ноль отключается?
зачем что-то копипастить, логика отключения нуля элементарна... Если в первой позиции ноль - гасим все сегменты. Что тут непонятного?
...ноль отключается так, если ноль, то отобразить пустой символ, который указан в массиве)..)) в массиве стоит ноль но после полуночи он не отключается. Вот скетч:
нет у вас в массиве пустого символа, потому и не отключается
Замените вот этот кусок в TimeToArray()
C++:
/*// добавил но не работает 
if ( (i != 4) || (digit != "")) BrightDigit(digits[digit], cursor); // 24:00 показывает 0:00
    else BrightDigit("", cursor);                                    // был "0" перед запятой                                 
    //BrightDigit(digits[digit], cursor);                           //  24:00 показывает 00:00
*/
    BrightDigit(digits[digit], cursor);
на вот это
C++:
if ( (i == 4) || (digit == 0)) BrightDigit(0, cursor);
else  BrightDigit(digits[digit], cursor);
 
  • Лойс +1
Реакции: kym13

kym13

★★✩✩✩✩✩
14 Ноя 2020
472
70
зачем что-то копипастить, логика отключения нуля элементарна... Если в первой позиции ноль - гасим все сегменты. Что тут непонятного?

нет у вас в массиве пустого символа, потому и не отключается
Замените вот этот кусок в TimeToArray()
C++:
/*// добавил но не работает
if ( (i != 4) || (digit != "")) BrightDigit(digits[digit], cursor); // 24:00 показывает 0:00
    else BrightDigit("", cursor);                                    // был "0" перед запятой                                
    //BrightDigit(digits[digit], cursor);                           //  24:00 показывает 00:00
*/
    BrightDigit(digits[digit], cursor);
на вот это
C++:
if ( (i == 4) || (digit == 0)) BrightDigit(0, cursor);
else  BrightDigit(digits[digit], cursor);
Уважаемый bort707
Я в программировании как "Медведь на ухо наступил" вообщем минус ноль, всё делаю и проверяю методом научного тыка. Простите меня за наглость, хочу попросить Вас если возможно вставить в код который я выложил ещё и датчик DS18b20, чтобы измерять температуру на улице.
 

kym13

★★✩✩✩✩✩
14 Ноя 2020
472
70
Толку-то. Его ж ещё отображать нужно. Причём как-то отлично от внутренней температуры.
Вот и я про это, добавить не проблема, вывести проблема. Лет 40 назад был отличником по физике, а потом армия, афган контузия и теперь не держится ничего в голове.
 

начинающий

✩✩✩✩✩✩✩
13 Дек 2020
130
9
Вот и я про это, добавить не проблема, вывести проблема. Лет 40 назад был отличником по физике, а потом армия, афган контузия и теперь не держится ничего в голове.
С ардуино только знакомлюсь, но все же предложу как вариант или вопрос: что если сделать идентификацию внутреннего и внешнего датчиков температуры сделать в виде бегущей строки с текстом: " на улице столько то градусов, такая то влажность", " В помещении (или внутри) такая то температура". К вышесказанному вопрос: можно ли "эксплуатировать" / разместить датчик BME280 на улице (за периметром помещения) во влагозащитном "кожухе" типа такого только к верху ногами чтобы влага "стекала".
 

kym13

★★✩✩✩✩✩
14 Ноя 2020
472
70
Скорее всего мозгов в ардуине не хватит на всё вами перечисленное. У меня где-то был скетч для матрицы на ws2812(можно готовую матрицу, можно из ленты сделать) с бегущей строкой, там всё бегущей строкой идет(часы, температура и т.д.). Поищу

Есть просто часы-бегущая строка без BMP/BME на ардуине, а чтобы всё вместе то это сделано на ESP8266
 

poty

★★★★★★✩
19 Фев 2020
3,220
938
@начинающий, такой проект имеется на данном форуме, но он немного для другого сделан. 7-сегментные индикаторы мало приспособлены для вывода букв.
 

kym13

★★✩✩✩✩✩
14 Ноя 2020
472
70
С ардуино только знакомлюсь, но все же предложу как вариант или вопрос: что если сделать идентификацию внутреннего и внешнего датчиков температуры сделать в виде бегущей строки с текстом: " на улице столько то градусов, такая то влажность", " В помещении (или внутри) такая то температура". К вышесказанному вопрос: можно ли "эксплуатировать" / разместить датчик BME280 на улице (за периметром помещения) во влагозащитном "кожухе" типа такого только к верху ногами чтобы влага "стекала".
Что касается размещения датчика, можно и на улице разместить. Единственное условие обеспечить не попадание осадков и прямых солнечных лучей на датчик. В таком корпусе его и рекомендуют размещать.
 

начинающий

✩✩✩✩✩✩✩
13 Дек 2020
130
9
Что касается размещения датчика, можно и на улице разместить. Единственное условие обеспечить не попадание осадков и прямых солнечных лучей на датчик. В таком корпусе его и рекомендуют размещать.
так называемый "влагозащитный кожух" монтируется нижней стороной вверх с "верхнего по ссылке рисунка", т.е. рисунок на который дана ссылка выше изображен почему то вверх ногами, соответственно кронштейн и разъем для кабеля остаются внизу, обеспечивая таким образом стекание капель от верхней тарели до нижней, защищая от попадания влаги на датчик, даже при "косом дожде". НО главным остается вопрос о диапазоне температур, при котором можно использовать датчик BME280 по прямому назначению.
 

Вложения

Изменено:

kym13

★★✩✩✩✩✩
14 Ноя 2020
472
70
так называемый "влагозащитный кожух" монтируется нижней стороной вверх с "верхнего по ссылке рисунка", т.е. рисунок на который дана ссылка выше изображен почему то вверх ногами, соответственно кронштейн и разъем для кабеля остаются внизу, обеспечивая таким образом стекание капель от верхней тарели до нижней, защищая от попадания влаги на датчик, даже при "косом дожде". НО главным остается вопрос о диапазоне температур, при котором можно использовать датчик BME280 по прямому назначению.
В даташите написано от - 40 до +85 и влажность от 0 до 100%

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

начинающий

✩✩✩✩✩✩✩
13 Дек 2020
130
9
В даташите написано от - 40 до +85 и влажность от 0 до 100%

Спасибо за поддержку, т.е. в "средней полосе" где диапазон годовой температуры находится в пределах "-33......+33" датчик BME280 запросто может быть размещен "на улице" при условии его размещения во влаго-брызгозащищающем кожухе"... Таким образом он может быть задействован для измерения температуры, влажности и давления снаружи и более достоверных измерений влажности воздуха (с наружи достовернее чем в помещении).
 
Изменено:

maksland

★★★✩✩✩✩
13 Янв 2019
512
116
Omsk
так называемый "влагозащитный кожух"
экран Стивенсона ... у вас я так понимаю заводская модель ? нам придется печатать :(

дома делал из PETG белого и обработал дихлорметаном - года 2 уже на улице висит
 
Изменено:

kym13

★★✩✩✩✩✩
14 Ноя 2020
472
70
С ардуино только знакомлюсь, но все же предложу как вариант или вопрос: что если сделать идентификацию внутреннего и внешнего датчиков температуры сделать в виде бегущей строки с текстом: " на улице столько то градусов, такая то влажность", " В помещении (или внутри) такая то температура". К вышесказанному вопрос: можно ли "эксплуатировать" / разместить датчик BME280 на улице (за периметром помещения) во влагозащитном "кожухе" типа такого только к верху ногами чтобы влага "стекала".
У китайцев на али цена на такой кожух от 10 $ начинается
 

начинающий

✩✩✩✩✩✩✩
13 Дек 2020
130
9
Загрузил последний скетч, чаы "тикают", незначащий ноль не сетится, а вот информация с BME280 отсутствует, т.е. температура равна нулю, влажность тоже нуль, давление тоже нуль. Не подскажете, в чем может быть проблема, да кстати хоть я и полный ноль в программировании, но ранее встречал информацию о том, что в скетче датчике BME280 присваивается адрес, что то вроде (0Х76) или (0Х77) в зависимости от положения перемычки на датчике, но читая выше выложенный скетч ничего похожего на (0Х77), что бы попробовать заменить хлтябы на (0Х77) не обнаружил, в связи с чем вопрос куда и в каком виде вписать этот адрес, чтобы появились показания температуры, влажности и давления вместо нулей?
 

kym13

★★✩✩✩✩✩
14 Ноя 2020
472
70
Загрузил последний скетч, чаы "тикают", незначащий ноль не сетится, а вот информация с BME280 отсутствует, т.е. температура равна нулю, влажность тоже нуль, давление тоже нуль. Не подскажете, в чем может быть проблема, да кстати хоть я и полный ноль в программировании, но ранее встречал информацию о том, что в скетче датчике BME280 присваивается адрес, что то вроде (0Х76) или (0Х77) в зависимости от положения перемычки на датчике, но читая выше выложенный скетч ничего похожего на (0Х77), что бы попробовать заменить хлтябы на (0Х77) не обнаружил, в связи с чем вопрос куда и в каком виде вписать этот адрес, чтобы появились показания температуры, влажности и давления вместо нулей?
Да я менял адрес в файле Adafruit_BME280.h строка 37 библиотеки. Вот мои библиотеки, пробуйте.
 

Вложения

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

poty

★★★★★★✩
19 Фев 2020
3,220
938
@начинающий, это делается внутри библиотеки. Чтобы автоматически искался нужный адрес найдите строку:

C++:
bme.begin(); //bmp.begin(); //датчик температуры, влажности для BMP280 и давления для BME280
и замените её на
C++:
  boolean isBMEhere = bme.begin();
  if( !isBMEhere) {
    isBMEhere = bme.begin(BME280_ADDRESS_ALTERNATE);
  }
 
  • Лойс +1
Реакции: начинающий

начинающий

✩✩✩✩✩✩✩
13 Дек 2020
130
9
Заработало, появились метеоданные. Огромное спасибо!!!! Если не сложно, можно добавить отключаемый (закомментируемый) блок в программу с обработкой сигнала о температуре с датчика ds18b20? о вариантах идентификации где то были предложения ранее в районе стр №8 п. №199
 

kym13

★★✩✩✩✩✩
14 Ноя 2020
472
70
@начинающий, это делается внутри библиотеки. Чтобы автоматически искался нужный адрес найдите строку:

C++:
bme.begin(); //bmp.begin(); //датчик температуры, влажности для BMP280 и давления для BME280
и замените её на
C++:
  boolean isBMEhere = bme.begin();
  if( !isBMEhere) {
    isBMEhere = bme.begin(BME280_ADDRESS_ALTERNATE);
  }
Poty. Чет я не нашел в файле библиотеки такого параметра: bme.begin();
 

poty

★★★★★★✩
19 Фев 2020
3,220
938
@kym13, трудно сказать, я - нашёл! ;)
можно добавить отключаемый (закомментируемый) блок в программу с обработкой сигнала о температуре с датчика ds18b20? о вариантах идентификации где то были предложения ранее в районе стр №8 п. №199
я этим заниматься точно не буду.
 

начинающий

✩✩✩✩✩✩✩
13 Дек 2020
130
9
Ну может я не точно сформулировал мысль, имеется ввиду снабдить часы двумя термометрами уличным и комнатным, ну и все, дальше хотелки типа возможности отличать уличную температуру от комнатной, ну и совсем малозначимая функция кода так это возможность отключения "части кода" при отсутствии необходимости измерять "две" температуры, вот как то так.
 

kym13

★★✩✩✩✩✩
14 Ноя 2020
472
70
@kym13, трудно сказать, я - нашёл! ;)
я этим заниматься точно не буду.
Вот в этой библиотеке оба адреса прописаны. В трёх библиотеках просмотрел на пять раз не нашёл bme.begin(); такую строку:rolleyes:
 

Вложения