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

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

Комментарии

Somikv

✩✩✩✩✩✩✩
27 Фев 2019
14
7
кнопку " переход на зимнее время" посмотри.может замкнуто
Изначально кнопки вообще не устанавливал. Потом подключил, поклацал. Минуты и часы переводит, а вот летнее-зимнее никакой реакции.
 
  • Лойс +1
Реакции: aнатолий

Somikv

✩✩✩✩✩✩✩
27 Фев 2019
14
7
В программировании не то что "0" а скорее даже минус.
Может быть кто-то знающий поправит скетч на кнопки управления (убрать их вообще)


#include <DS3232RTC.h>
#include <TimeLib.h>
#include <Time.h>
#include <Wire.h>
#include <FastLED.h>


#define NUM_LEDS 114 // 4*7*4 +2 Number of LED controlled
#define COLOR_ORDER GRB // Define color order for your strip
#define LED_PIN 6 // Data pin for led comunication
#define DST_PIN 5 // Define DST adjust button pin
#define MIN_PIN 4 // Define Minutes adjust button pin
#define HUR_PIN 3 // Define Hours adjust button pin

CRGB leds[NUM_LEDS]; // Define LEDs strip
// 0,0,0,0
// 1,1,1,1
// 1 2 3 4 5 6 7 8 9 10111213141516171819202122232425262728
byte digits[12][28] = {{0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1}, // Digit 0
{0,0,0,0,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1}, // Digit 1
{1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,1,1,1,1,1,1,1,1,0,0,0,0}, // Digit 2
{1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1}, // Digit 3
{1,1,1,1,1,1,1,1,0,0,0,0,1,1,1,1,0,0,0,0,0,0,0,0,1,1,1,1}, // Digit 4
{1,1,1,1,0,0,0,0,1,1,1,1,1,1,1,1,0,0,0,0,1,1,1,1,1,1,1,1}, // Digit 5
{1,1,1,1,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1}, // Digit 6
{0,0,0,0,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1}, // Digit 7
{1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1}, // Digit 8
{1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,1,1,1,1,1,1,1,1}, // Digit 9 | 2D Array for numbers on 7 segment
{1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0}, // Digit *0
{0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0}}; // Digit C

bool Dot = true; //Dot state
bool DST = false; //DST state
bool TempShow = true;
int last_digit = 0;

// int ledColor = 0x0000FF; // Color used (in hex)
long ledColor = CRGB::DarkOrchid; // Color used (in hex)
//long ledColor = CRGB::MediumVioletRed;
//Random colors i picked up
long ColorTable[16] = {
CRGB::Amethyst,
CRGB::Aqua,
CRGB::Blue,
CRGB::Chartreuse,
CRGB::DarkGreen,
CRGB::DarkMagenta,
CRGB::DarkOrange,
CRGB::DeepPink,
CRGB::Fuchsia,
CRGB::Gold,
CRGB::GreenYellow,
CRGB::LightCoral,
CRGB::Tomato,
CRGB::Salmon,
CRGB::Red,
CRGB::Orchid
};


void setup(){
Serial.begin(9600);
Wire.begin();
FastLED.addLeds<WS2812B, LED_PIN, RGB>(leds, NUM_LEDS);
LEDS.setBrightness(75); // Set initial brightness
pinMode(DST_PIN, INPUT_PULLUP); // Define DST adjust button pin
pinMode(MIN_PIN, INPUT_PULLUP); // Define Minutes adjust button pin
pinMode(HUR_PIN, INPUT_PULLUP); // Define Hours adjust button pin

}

// Get time in a single number, if hours will be a single digit then time will be displayed 155 instead of 0155
int GetTime(){
tmElements_t Now;
RTC.read(Now);
//time_t Now = RTC.Now();// Getting the current Time and storing it into a DateTime object
int hour=Now.Hour;
int minute=Now.Minute;
int second =Now.Second;
if (second % 2==0) {Dot = false;}
else {Dot = true;};
return (hour*100+minute);
};


// Convert time to array needet for display
void TimeToArray(){
int Now = GetTime(); // Get time

int cursor = 114; // last led number

// Serial.print("Time is: ");Serial.println(Now);
if (DST){ // if DST is true then add one hour
Now+=100;
// Serial.print("DST is ON, time set to : ");Serial.println(Now);
};
if (Dot){leds[57]=ledColor;
leds[56]=ledColor;}
else {leds[57]=0x000000;
leds[56]=0x000000;
};

for(int i=1;i<=4;i++){
int digit = Now % 10; // get last digit in time
if (i==1){
// Serial.print("Digit 4 is : ");Serial.print(digit);Serial.print(" ");

cursor = 86;

for(int k=0; k<=27;k++){
// Serial.print(digits[digit][k]);
if (digits[digit][k]== 1){leds[cursor]=ledColor;}
else if (digits[digit][k]==0){leds[cursor]=0x000000;};
cursor ++;
};
// Serial.println();

if (digit != last_digit)
{
cylon();
ledColor = ColorTable[random(16)];
}
last_digit = digit;

}
else if (i==2){
// Serial.print("Digit 3 is : ");Serial.print(digit);Serial.print(" ");

cursor =58;

for(int k=0; k<=27;k++){
// Serial.print(digits[digit][k]);
if (digits[digit][k]== 1){leds[cursor]=ledColor;}
else if (digits[digit][k]==0){leds[cursor]=0x000000;};
cursor ++;
};
// Serial.println();
}
else if (i==3){
// Serial.print("Digit 2 is : ");Serial.print(digit);Serial.print(" ");
cursor =28;
for(int k=0; k<=27;k++){
// Serial.print(digits[digit][k]);
if (digits[digit][k]== 1){leds[cursor]=ledColor;}
else if (digits[digit][k]==0){leds[cursor]=0x000000;};
cursor ++;
};
// Serial.println();
}
else if (i==4){
// Serial.print("Digit 1 is : ");Serial.print(digit);Serial.print(" ");
cursor =0;
for(int k=0; k<=27;k++){
// Serial.print(digits[digit][k]);
if (digits[digit][k]== 1){leds[cursor]=ledColor;}
else if (digits[digit][k]==0){leds[cursor]=0x000000;};
cursor ++;
};
// Serial.println();
}
Now /= 10;
};
};

// Convert temp to array needet for display
void TempToArray(){
tmElements_t tm;
RTC.read(tm);

if (tm.Second != 27) {
TempShow = false;
return;
}
TempShow = true;
int t = RTC.temperature();
int celsius = (t / 4.0) * 100;

Serial.print("Temp is: ");Serial.println(celsius);

int cursor = 114; // last led number

leds[57]=0x000000;
leds[56]=0x000000;

for(int i=1;i<=4;i++){
int digit = celsius % 10; // get last digit in time
if (i==1){
Serial.print("Digit 4 is : ");Serial.print(digit);Serial.print(" ");

cursor = 86;

for(int k=0; k<=27;k++){
Serial.print(digits[11][k]);
if (digits[11][k]== 1){leds[cursor]=ledColor;}
else if (digits[11][k]==0){leds[cursor]=0x000000;};
cursor ++;
};
Serial.println();
}
else if (i==2){
Serial.print("Digit 3 is : ");Serial.print(digit);Serial.print(" ");

cursor =58;

for(int k=0; k<=27;k++){
Serial.print(digits[10][k]);
if (digits[10][k]== 1){leds[cursor]=ledColor;}
else if (digits[10][k]==0){leds[cursor]=0x000000;};
cursor ++;
};
Serial.println();
}
else if (i==3){
Serial.print("Digit 2 is : ");Serial.print(digit);Serial.print(" ");
cursor =28;
for(int k=0; k<=27;k++){
Serial.print(digits[digit][k]);
if (digits[digit][k]== 1){leds[cursor]=ledColor;}
else if (digits[digit][k]==0){leds[cursor]=0x000000;};
cursor ++;
};
Serial.println();
}
else if (i==4){
Serial.print("Digit 1 is : ");Serial.print(digit);Serial.print(" ");
cursor =0;
for(int k=0; k<=27;k++){
Serial.print(digits[digit][k]);
if (digits[digit][k]== 1){leds[cursor]=ledColor;}
else if (digits[digit][k]==0){leds[cursor]=0x000000;};
cursor ++;
};
Serial.println();
}
celsius /= 10;
};
};


void DSTcheck(){
int buttonDST = digitalRead(2);
// Serial.print("DST is: ");Serial.println(DST);
if (buttonDST == LOW){
if (DST){
DST=false;
// Serial.print("Switching DST to: ");Serial.println(DST);
}
else if (!DST){
DST=true;
// Serial.print("Switching DST to: ");Serial.println(DST);
};
delay(500);
};
}

void TimeAdjust(){
int buttonH = digitalRead(HUR_PIN);
int buttonM = digitalRead(MIN_PIN);
if (buttonH == LOW || buttonM == LOW){
delay(500);
tmElements_t Now;
RTC.read(Now);
int hour=Now.Hour;
int minutes=Now.Minute;
int second =Now.Second;
if (buttonH == LOW){
if (Now.Hour== 23){Now.Hour=0;}
else {Now.Hour += 1;};
}else {
if (Now.Minute== 59){Now.Minute=0;}
else {Now.Minute += 1;};
};
RTC.write(Now);
}
}

/* coool effect function*/
void fadeall() { for(int i = 0; i < NUM_LEDS; i++) { leds.nscale8(250); } }


void cylon () {
static uint8_t hue = 0;
Serial.print("x");
// First slide the led in one direction
for(int i = 0; i < NUM_LEDS; i++) {
// Set the i'th led to red
leds = CHSV(hue++, 255, 255);
// Show the leds
FastLED.show();
// now that we've shown the leds, reset the i'th led to black
// leds = CRGB::Black;
fadeall();
// Wait a little bit before we loop around and do it again
delay(10);
}
Serial.print("x");

// Now go in the other direction.
for(int i = (NUM_LEDS)-1; i >= 0; i--) {
// Set the i'th led to red
leds = CHSV(hue++, 255, 255);
// Show the leds
FastLED.show();
// now that we've shown the leds, reset the i'th led to black
// leds = CRGB::Black;
fadeall();
// Wait a little bit before we loop around and do it again
delay(10);
}
}

void loop() // Main loop
{
DSTcheck(); // Check DST
TimeAdjust(); // Check to se if time is geting modified
TimeToArray(); // Get leds array with required configuration
TempToArray();
FastLED.show(); // Display leds array
if (TempShow == true) delay (8000);
}
 

Kort

★✩✩✩✩✩✩
31 Янв 2019
23
10
Ну судя по названию ролика намекают на подключение. Поэтому наверное нужно их просто отключить тут
#define DST_PIN 5 // Define DST adjust button pin
#define MIN_PIN 4 // Define Minutes adjust button pin
#define HUR_PIN 3 // Define Hours adjust button pin

На самом деле не пойму зачем что-то делать с кнопками если их физически нету? Проблем с работоспособностью не должно быть, ничего не меняя в программе.
 
  • Лойс +1
Реакции: superflint

Wan-Derer

★★★★★✩✩
Команда форума
31 Июл 2018
2,002
406
Москва
wan-derer.ru
@Somikv, Здесь так. Либо ты тратишь своё время и изучаешь тему, либо идёшь в раздел "Ищу разработчика" и кто-то тратит своё время ради тебя.
 
  • Лойс +1
Реакции: Юрий Саныч

Kort

★✩✩✩✩✩✩
31 Янв 2019
23
10
Да ладно что уж так жестоко то. В какую тему не зайду везде на...уй шлют :) Нельзя же так. Если никто не отвечает то и понятно что не хотят ломать голову.

З.Ы. По по воду вопрос, я лично не совсем понимаю что нужно. Есть какая то проблема, что то надо искать в коде....сам понимаешь разбирать чей то код никто не хочет. Задай направляющие вопросы что бы тебе смогли помочь не делая всю работу за тебя и не тратя свое время более 5 минут скажем так.
 

Duzer

✩✩✩✩✩✩✩
27 Фев 2019
4
1
Уважаемый автор, слёзно умоляю - выложите пожалуйста библиотеки , которые использовались в этом проекте. Перебрал их уже огромное количество, но постоянные ошибки, даже если не изменяю ваш код под себя. Буду вам очень признателен.
 

Somikv

✩✩✩✩✩✩✩
27 Фев 2019
14
7
Проблема мигания была решена удаление DST. Кнопки настройки времени и переход летнее - зимнее время были удалены со схемы. Время выставляется отдельным скетчем. Библиотеки, скетч настройки времени, скетч основной программы часов прикрепляю. Вдруг кому пригодиться.
 

Вложения

  • Лойс +1
Реакции: KOS77

Duzer

✩✩✩✩✩✩✩
27 Фев 2019
4
1
Оу, спасибо огромное! Буду пробовать переделать под свои часы. У меня по 6 диодов в сегменте.
 

Duzer

✩✩✩✩✩✩✩
27 Фев 2019
4
1
Приветствую всех. Ну и конечно же прошу помощи :sneaky:. Решил собрать ещё одни часики, но маленькие, первые с вашей помощью уже висят на работе в цехе. И столкнулся с такой проблемой. Датчик освещения работает наоборот, когда светло - убавляет яркость, когда темно - прибавляет. Хотя в первых часах всё работало правильно, с таким же датчиком. Скетчи проверял, всё идентичны, только количество диодов изменено. Скетч использовал тот, что выкладывал автор темы для одного диода на сегмент. Может быть датчик бракованный, но думаю, что можно исправить это програмно. Ткните носом, пожалуйста. Вот такой датчик. 1554403079399420078556.jpg
 
  • Лойс +1
Реакции: oleg-krgorb

oleg-krgorb

✩✩✩✩✩✩✩
24 Янв 2019
1
0
Добрый день!
У кого есть скетч на 3 светодиода 2812 в сегменте.
 

Somikv

✩✩✩✩✩✩✩
27 Фев 2019
14
7
Может и на 2 у кого то есть, буду благодарен.
Днями на просторах был найден универсальный. Вписываете количество диодов в сегменте и все. Регулируется смена цвета. Очень удобно.
https://www.drive2.com/b/462707479390715926?page=0 источник
код полностью переписан и доведен до ума, еще осталось несколько хотелок (которые еще буду реализовывать), но и в таком виде уже на много лучше чем было. Скетч адаптирован под все ленты как 2811 так и 2812, теперь в скетче можно выбрать количество светодиодов в одном сегметнте, так и количество разделительных точек (для 2811). Датчик освещения теперь работает более плавно и не моргает в сумерках как ненормальный. Есть выбор режима автоматической яркости по датчику (авто яркость имеет настройки), либо ручная яркость. Бесполезная раньше кнопка DTS (летнее/зимнее время) теперь меняет цвет часов на один из 16 записанных, плюс есть возможность включить смену цвета: никогда, раз в минуту, каждые десять минут, каждый час, каждые десять часов. Время отображения температуры можно задать в самом низу скетча. Скетч для простоты и понятия, подробно закоментирован забираем тут yadi.sk/d/AavBf_sUUBOVDQтут обсуждаем ok.ru/profile/61355019403/statuses/66016109251467
https://i-a.d-cd.net/zUAAAgF4quA-1920.jpg
 

Вложения

Dimakazhan

✩✩✩✩✩✩✩
18 Янв 2019
3
0
Днями на просторах был найден универсальный. Вписываете количество диодов в сегменте и все. Регулируется смена цвета. Очень удобно.
https://www.drive2.com/b/462707479390715926?page=0 источник
код полностью переписан и доведен до ума, еще осталось несколько хотелок (которые еще буду реализовывать), но и в таком виде уже на много лучше чем было. Скетч адаптирован под все ленты как 2811 так и 2812, теперь в скетче можно выбрать количество светодиодов в одном сегметнте, так и количество разделительных точек (для 2811). Датчик освещения теперь работает более плавно и не моргает в сумерках как ненормальный. Есть выбор режима автоматической яркости по датчику (авто яркость имеет настройки), либо ручная яркость. Бесполезная раньше кнопка DTS (летнее/зимнее время) теперь меняет цвет часов на один из 16 записанных, плюс есть возможность включить смену цвета: никогда, раз в минуту, каждые десять минут, каждый час, каждые десять часов. Время отображения температуры можно задать в самом низу скетча. Скетч для простоты и понятия, подробно закоментирован забираем тут yadi.sk/d/AavBf_sUUBOVDQтут обсуждаем ok.ru/profile/61355019403/statuses/66016109251467
Спасибо, у меня этот и стоит, просто в этот что в этой теме мне нравится радуга при переключении
 

liharly

✩✩✩✩✩✩✩
21 Май 2019
4
0
Добрый день.
А у меня вот вопрос почему бы функционал данных часов не расширить до даты, давления, температуры и т.д. Вплоть до полноцееной бегущей строки.
 

valek

✩✩✩✩✩✩✩
28 Июн 2019
17
1
Москва
друзья что означают цифры этом участке кода? часы на 30 диодов
}
if (temp10 < -500) { // если датчик отключен, то выводим "---с"
digitout (0, 13 ); // отрисовываем "-" (выставляем черные точки)
digitout (7, 13 ); // отрисовываем "-" (выставляем черные точки)
digitout (16, 13 ); // отрисовываем "-" (выставляем черные точки)