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

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

Комментарии

Вячеслав_45

★★✩✩✩✩✩
10 Июл 2020
72
64
Про дату переход на вывод даты в 269 строке
EepromTick()) там условие в самом начале
С остальным согласен, в будущем поправлю, но а пока задача стояла чтоб в 168-ю влезло
 
  • Лойс +1
Реакции: bort707

Вячеслав_45

★★✩✩✩✩✩
10 Июл 2020
72
64
@bort707,
Консультацию можно.
class button сам не писал, позаимствовал, так как не совсем разобрался с классами внёс изменения в виде static byte key так как нужен был флаг в виде 0 или 1 в строку 276. if (mode < 20 && button::key)
при нажатии любой кнопки, сделал как мог. Есть ли альтернатива, более правильная.
Хочу освоить классы, и есть ли смысл перевести например DigitOut в класс.
 

bort707

★★★★★★✩
21 Сен 2020
2,901
863
class button сам не писал, позаимствовал, так как не совсем разобрался с классами внёс изменения в виде static byte key так как нужен был флаг в виде 0 или 1 в строку 276. if (mode < 20 && button::key)
не очень понял, что вы хотели сделать. Этот key у вас один общий на все кнопки. Или вы так и хотели?
 

Вячеслав_45

★★✩✩✩✩✩
10 Июл 2020
72
64
@bort707,
Да так и хотел сделать, просто реализация правильная или как-то по другому надо было сделать
 

bort707

★★★★★★✩
21 Сен 2020
2,901
863
@bort707,
Да так и хотел сделать, просто реализация правильная или как-то по другому надо было сделать
Посмотрел, в принципе вроде ОК (хотя я сам имею небольшой опыт со статическими членами класса)
Только не вполне понял, зачем эта переменная имеет тип byte, если по смыслу это boolean
 

maksland

★★★✩✩✩✩
13 Янв 2019
464
107
Omsk
А я пока закажу платы под датчик и буду рисовать новый корпус... и универсальный (надеюсь скетч Вячеслава потом плавно перекочует на esp8266 :) )

P.S. платы в железе еще не проверены
корпус в тинкеркаде рисую, потом можно будет легко сделать по два светодиода на сегмент
не очень, конечно, но как смог...
 

Вложения

Изменено:

начинающий

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

ASM

★★★★✩✩✩
26 Окт 2018
1,514
294
При нажатии кнопки установить секунды в нули, сложности нету. Указывайте не просто номер сообщения, а прикрепляйте ссылку, чтобы с мобильного проще было открыть, а не искать)
 
  • Красота! +2
Реакции: начинающий

начинающий

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

ASM

★★★★✩✩✩
26 Окт 2018
1,514
294
Если использовать удержание, то надо использовать библиотеку gyver button)
 
  • Красота! +2
Реакции: начинающий

начинающий

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

ASM

★★★★✩✩✩
26 Окт 2018
1,514
294
Тогда жди, может кто подскажет. Тут надо с ПК сидеть) Переделывать код)
Если просто обнулить при нажатии специальной для этого кнопки, то код будет простым)
 
  • Красота! +2
Реакции: начинающий

начинающий

✩✩✩✩✩✩✩
13 Дек 2020
130
9
Если просто обнулить при нажатии специальной для этого кнопки, то код будет простым)
Вот думаю, что для минимизации трудоемкости по переделке кода, лучше конечно для этого дела задействовать отдельную кнопку, обозвать ее к примеру time reset. Прошу помощи у уважаемых гуру по программированию, если кто может, подправьте скетч под кнопку "обнуление секунд", пожалуйста, уверен, что многие форумчане обрадуются новому функционалу.
 
Изменено:

ASM

★★★★✩✩✩
26 Окт 2018
1,514
294
Оформи код соответствующим тэгом
void SecondReset() {
int buttonR = digitalRead(4);
if (buttonR == LOW) {
delay(100);
tmElements_t Now;
RTC.read(Now);
int second = Now.Second;
if (buttonR == LOW) {
Now.Second = 0;
}
RTC.write(Now);
}
}
Как-то так)
 
  • Красота! +2
Реакции: начинающий

начинающий

✩✩✩✩✩✩✩
13 Дек 2020
130
9
Так правильно будет? Фрагмент кода из #482:
C++:
//======================================= Массив управляет кнопками с часами и минутами ===============================


void SecondReset() {

int buttonR = digitalRead(4);

if (buttonR == LOW) {

delay(100);

tmElements_t Now;

RTC.read(Now);

int second = Now.Second;

if (buttonR == LOW) {

Now.Second = 0;

}

RTC.write(Now);

}

}

void TimeAdjust() {

  int buttonH = digitalRead(2);

  int buttonM = digitalRead(3);

  if (buttonH == LOW || buttonM == LOW) {

    delay(100);//время реакции на нажатие

    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);

  }

}


//Меняем эффекты

void fadeall() {

  for (int i = 0; i < NUM_LEDS; i++) {

    leds[i].nscale8(250);

  }

}
 

ASM

★★★★✩✩✩
26 Окт 2018
1,514
294
Без разницы куда вставлять) можно и так) подключай на любой свободный пин и пропиши его, я написал на D4
 
  • Красота! +2
Реакции: начинающий

начинающий

✩✩✩✩✩✩✩
13 Дек 2020
130
9
ну что касается прописки номеров пинов тут проблем нет, просто макетка на работе, и о свободных пинах узнаю только завтра. Теперь пара вопросов по реализации: значит пины под кнопку задействовать только цифровые (Dn), хотя да, у кнопки ведь только два состояния единица и ноль, по любому цифра, удалять не нужно вдруг кому пригодится, второй вопрос о месте вставки блока опроса кнопки в фрагмент скетча: блок
void SecondReset() {
действительно может быть вставлен в любом месте скетча (разумеется не в разрыве отдельных программных блоков, а то каша получицца) или же есть какие то предпочтения, может вероятность правильной безотказной работы этого фрагмента кода все таки зависит от места где он расположен в теле основного скетча
 

ASM

★★★★✩✩✩
26 Окт 2018
1,514
294
Это все компилируется в машинный код, порядок функций не имеет значение)
 
  • Красота! +2
Реакции: начинающий

начинающий

✩✩✩✩✩✩✩
13 Дек 2020
130
9
Что то с обнулением секунд не получается, посмотрел loop там ведь ни одна кнопка не прописана (хотел сделать по аналогии)
 

ASM

★★★★✩✩✩
26 Окт 2018
1,514
294
@начинающий,
DSTcheck(); // Проверяем цветовые режимы
TimeAdjust(); // Проверяем время если сменилось на 1 цифру
 

начинающий

✩✩✩✩✩✩✩
13 Дек 2020
130
9
@начинающий,
DSTcheck(); // Проверяем цветовые режимы
TimeAdjust(); // Проверяем время если сменилось на 1 цифру
И как туда воткнуть обнуление секунд, что то в этом блоке ни одна кнопка не описана, минуты, часы, смена цвета не въезжаю как прописать кнопку обнуления, подскажите пожалуйста.