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

Вячеслав_45

★★✩✩✩✩✩
10 Июл 2020
72
64
Устранил замечания. Добавил второй датчик температуры, некоторые настройки часов (все внутри в описании). Как сделать настройка цвета температуры чтоб настраивалась из прошивки или часов.
 

Вложения

bort707

★★★★★★✩
21 Сен 2020
3,295
958
@bort707, на заметку строка
led_color = color_table[set_color - 1];
при set_color = 0 ошибку не вызывает, просто led_color = последнему элементу массива color_table [ ]
Вячеслав это Вы сами придумали или как?
Вот, запустите тест и убедитесь, что это чушь:
C++:
byte a[] = {11,21,31,41,51,55};
void setup() {
  // put your setup code here, to run once:
Serial.begin(9600);
byte element =0;
Serial.print("Element #-1 =");
Serial.println(a[element-1]);
}

void loop() {}
Результат работы программы
C++:
Element #-1 =184
Результат чтения -1(минус первого) значения массива - вовсе не последний элемент (в данном случае 55), а ячейка памяти, расположенная на одно смещение ДО начала массива. Что у вас там будет - неизвестно, у меня вот - 184.
Если вы будете читать color_table[set_color - 1] - будет выдаваться ерунда, а не цвет. А если вы попытаетесь писать по этому адресу - вы с вероятностью 99.99% нарушите структуру данных и завесите программу.

Так что не надо спорить, это именно ошибка. Называется "выход за границу массива" - и это одна из самых грубых ошибок.
 
Изменено:

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

★★★★★★★
14 Авг 2019
4,320
1,319
Москва
Ну в некоторых случаях такое может быть, но скорее эти случаи исключения и хаки. например если в массиве 256 элементов, а указатель имеет тип uint8_t. Но такое чревато...
 

bort707

★★★★★★✩
21 Сен 2020
3,295
958
Ну в некоторых случаях такое может быть, но скорее эти случаи исключения и хаки. например если в массиве 256 элементов, а указатель имеет тип uint8_t. Но такое чревато...
Ну такое использование указателей скорей можно отнести к "грязным хакам", поскольку очень легко можно запутаться самому и получить распашку памяти :)

И да, твое замечание никак не относится к Вячеславу - у него в массиве 20 элементов, так что тут явная ошибка.
 

Вячеслав_45

★★✩✩✩✩✩
10 Июл 2020
72
64
Спорить не буду. Может Ардуино IDEпри компиляции что-то подправляет. Но при такой строке с минусом всё работало и при включении часов первый цвет был последний из массива.
 

bort707

★★★★★★✩
21 Сен 2020
3,295
958
Спорить не буду. Может Ардуино IDEпри компиляции что-то подправляет.
Простите, но Вы сейчас именно спорите. Вы пример-то запускали? Можете попробовать запустить его не в Ардуино, а например в любом компиляторе С на винде или в линуксе.
Ардуино ничего не поправляет, то что я вам пишу - это правила языка С/С++. Никакой "последний элемент" в такой записи не выдается.
 

Вячеслав_45

★★✩✩✩✩✩
10 Июл 2020
72
64
@bort707, я не спорю что это ошибка. Просто написал по факту как было и как работало. Запустить не могу, сижу с телефона.
 

bort707

★★★★★★✩
21 Сен 2020
3,295
958
Просто написал по факту как было и как работало.
эта ошибка вылезет не при любом запуске, а только после полного сброса, когда вы в ЕЕПРОМ пишете нули.
При обычном старте цвет берется из ЕЕПРОМ и все работает.

Кстати, советую так же отрабатывать не только вариант "цвет меньше нуля", а так же "цвет больше числа элементов таблице цветов". В принципе, всяких раз когда вычитаете конфиг откуда-то, в вашем случае из ЕЕПРОМ - необходимо ВСЕ НАСТРОЙКИ проверять на правильность значений.
 

Вячеслав_45

★★✩✩✩✩✩
10 Июл 2020
72
64
Из ЕЕПРОМ цвет берется при каждом старте, и в моих часах там всегда был 0. Работают с февраля этого года вроде, не одного сбоя или зависания, много раз отключались и включались. У меня нет таких познаний объяснить не могу но факт есть факт до версии 1.7 была эта ошибка и всё работало.

Може просто светодиоды отображали такой цвет на выданную им обра-кадабру в 16 битном цвете я незнаю. Надо пробовать на 1.6 вывести в монитор.
 

suhorukov-p

✩✩✩✩✩✩✩
16 Фев 2019
39
6
Всем привет!!! Может для кого-то покажется глупым мой вопрос, уточню, я в программирование не чего не понимаю.
Возможно ли осуществить память настроек?
а то при моей первой сборки часов, я не ставил фоторезистор, и когда произошёл сбой по питанию (отключили свет), то я аж испугался когда часы потухли, думал всё кабздец пришёл, а оказалось, что по умолчании в настройках стоит яркость на 0, и её нужно было добавить, еще цвет стал меняться каждую минуту, и отображении даты и температуры раз в минуту
 

suhorukov-p

✩✩✩✩✩✩✩
16 Фев 2019
39
6
Устранил замечания. Добавил второй датчик температуры, некоторые настройки часов (все внутри в описании). Как сделать настройка цвета температуры чтоб настраивалась из прошивки или часов.
Извините пожалуйста, а эта прошивка на 2 датчика рабочая или бета версия???И там отображение "ДОМ (С)", а "УЛИЦА (0)", как выше на картинках которые , я рисовал??? А то уже ручки чешутся вкрутить второй датчик :)
 

maksland

★★★✩✩✩✩
13 Янв 2019
615
144
Omsk
давайте с одним датчиком допилим прошивку а потом и со вторым
 

suhorukov-p

✩✩✩✩✩✩✩
16 Фев 2019
39
6
давайте с одним датчиком допилим прошивку а потом и со вторым
Так второй датчик не мешает же, в настройках можно выбрать варианты
9. (t) включение датчиков температуры (0 - комнатный, 1 - уличный, 2 - оба)
 

Вячеслав_45

★★✩✩✩✩✩
10 Июл 2020
72
64
В настройках можно выбрать какой символ на какую температуру хоть одинаковые хоть разные. Работать прошивка должна, пока не было возможности проверить. У меня она стоит в часах с одним датчиком. На выходных постараюсь проверить. С одним датчиком если включить на отображение оба то второй показывает 0. Подключение сделал на разные пины, т.к. для меня на данном этапе это было проще и адреса DS18B20 не надо вытягивать.
 
  • Лойс +1
Реакции: andrey170587

Вячеслав_45

★★✩✩✩✩✩
10 Июл 2020
72
64
Всем привет!!! Может для кого-то покажется глупым мой вопрос, уточню, я в программирование не чего не понимаю.
Возможно ли осуществить память настроек?
а то при моей первой сборки часов, я не ставил фоторезистор, и когда произошёл сбой по питанию (отключили свет), то я аж испугался когда часы потухли, думал всё кабздец пришёл, а оказалось, что по умолчании в настройках стоит яркость на 0, и её нужно было добавить, еще цвет стал меняться каждую минуту, и отображении даты и температуры раз в минуту
Можно замкнуть вывод А0 на +5в и будет максимальная яркость
 

ASM

★★★★★✩✩
26 Окт 2018
1,918
422
Конструкторов часов маловато, присоединяюсь к вам.
Мой проект сделан на двп, на нее наклеил ленту, объем цифрам сделал из сэндвич панели, поверх белый лист бумаги.
Корпус из дерева, покрашен акрилом, смесь белой и коричневой.
Основан на коде, который был в интернете, переработан, чтобы работал и добавлены датчики)
Сейчас буду изучать ваш) Позвал @bort707.
часы выглядят так, провода торчат, т.к. занимаюсь ими сейчас.
Тема, в которой я работал
 
Изменено:
  • Лойс +1
Реакции: Старик Похабыч

ASM

★★★★★✩✩
26 Окт 2018
1,918
422
@Вячеслав_45, или у кого его скетч, переделал на 114 диодов, рабочий код у меня такой, проверьте, будет ли работать в ваших вариантах)
C++:
void DigitOut(int cursors, int digit){  // Функция вывода на диоды
  int cursor = cursors;
  for(int k = 0; k <= 6; k++){
    if (digits[digit][k] == 1){
      for(int i = 1; i <= num_point; i++){leds[cursor] = led_color; cursor++;}}
    else if (digits[digit][k] == 0){
      for(int i = 1; i <= num_point; i++){leds[cursor] = 0x000000; cursor++;}
      }}}
 
Изменено:

bort707

★★★★★★✩
21 Сен 2020
3,295
958
@ASM,
посмотрите код из сообщения #104 - это код похожий на ваш, но кардинально переписанный, оптимизированный и с исправленными косяками. Например цифры там заданы всего десятком байт, а не как в вашем коде - огромными массивами.
C++:
uint8_t  digits[] = {
  0b00111111,     // Digit 0
  0b00100001,     // Digit 1
  0b01110110,     // Digit 2
  0b01110011,     // Digit 3
  0b01101001,     // Digit 4
  0b01011011,     // Digit 5
  0b01011111,     // Digit 6
  0b00110001,     // Digit 7
  0b01111111,     // Digit 8
  0b01111011,     // Digit 9
  0b01111000,     // Digit * градус  10
  0b00011110,     // Digit C         11
  0b01111100,     // Digit P         12
  0b01111000,     // Digit % знак % из двух частей 13
  0b01000111,     // Digit % знак % из двух частей 14
  0b00000000      // Blank
};
соответнно и выод цифр на ленту тоже короче и проще:
C++:
void BrightDigit (uint8_t digit, uint8_t cursor)
{
  for (uint8_t mask = 0b01000000; mask > 0; mask = mask >> 1)
  {
    for (uint8_t i = 0; i < LEDS_IN_SEGMENT; i++)
    {
      leds[cursor] = (digit & mask) ? ledColor : 0;
      cursor ++;
    }
  }
}
Код настраивается на любое число диодов в сегменте
 
  • Лойс +1
Реакции: ASM

ASM

★★★★★✩✩
26 Окт 2018
1,918
422
@bort707, я уже смотрел этот скетч, остановлюсь на варианте с Вячеславом, т.к. понимаю что основа сейчас на нём. Буду тогда переводить часы на его. Отображение удалось запустить, уличный датчик прикрутил. Осталось bmp280, в моём варианте на нём куча библиотек, памяти много занимает, надо бы попроще найти. Есть microBME280, но она не считывает данные, хотя адрес тот же. И в коде loop не понятны некоторые действия, на примере датчиков, за что отвечают некоторые строки.

Ребят, в моем скетче часов bmp280 работает исправно, но стоит запустить в новом скетче, где только библиотеки этого датчика, то уже не работает. Пробовал различные примеры из интернета, ни в какую) Может ли быть причиной, что на портах А4 и А5 висят два датчика, bmp280 и ds3231?
Ну и в скетче Вячеслава, заместо домашнего датчика вписал bmp280, он тоже не считывается)
C++:
#include <iarduino_Pressure_BMP.h>
iarduino_Pressure_BMP sensorTempHome(0x76);
---------------------------
        case 20: {            // Режим вывода температуры внутри
      if(temp_flag == false){
              sensorTempHome.begin();
              Serial.println (sensorTempHome.temperature);
----------------------------
-135.36
-135.36
-135.36
 
Изменено:

ASM

★★★★★✩✩
26 Окт 2018
1,918
422
После смены макс и мин работает при свете ярко, без света тускло.
Возможно ли установить плавное изменение света, аналогично моему коду текущей функцией?)
C++:
#define max_bright 100       // максимальная яркость (0 - 255)
#define min_bright 10        // минимальная яркость (0 - 255)
#define bright_constant 1000  // константа усиления от внешнего света (0 - 1023), чем МЕНЬШЕ константа, тем "резче" будет прибавляться яркость
#define coef 0.1             // коэффициент фильтра (0.0 - 1.0), чем больше - тем медленнее меняется яркость
void BrightnessCheck() {
  if (auto_bright) {                         
    if (millis() - bright_timer > 100) {     
      bright_timer = millis();               
      new_bright = map(analogRead(BRI_PIN), 0, bright_constant, min_bright, max_bright);   
      new_bright = constrain(new_bright, max_bright, min_bright);    //поменял местами max и min                     
      new_bright_f = new_bright_f * coef + new_bright * (1 - coef);
      LEDS.setBrightness(new_bright_f);}}};
C++:
void BrightnessCheck(){
  const byte sensorPin = A0; 
  const byte brightnessLow = 5;   // низкая яркость
  const byte brightnessMid = 10;  // низкая яркость
  const byte brightnessHigh = 40; // высокая яркость
  const byte brightnessDay = 60;  // высокая яркость
 int sensorValue = analogRead(sensorPin);
  sensorValue = map(sensorValue, 0, 1023, 0, 255);
  LEDS.setBrightness(sensorValue);
//если в комнате светло, то светит ярче, если мало света, то тусклее, в ночном режиме светит тускло
    if(sensorValue>=221 && sensorValue <=240){LEDS.setBrightness(brightnessHigh);delay(1000);}
        else
    if(sensorValue>=241 && sensorValue <=252){LEDS.setBrightness(brightnessMid);delay(1000);}
        else
    if(sensorValue>=253){LEDS.setBrightness(brightnessLow);delay(1000);}
        else
    if(sensorValue<=220){LEDS.setBrightness(brightnessDay);delay(1000);}};
 

Вячеслав_45

★★✩✩✩✩✩
10 Июл 2020
72
64
@ASM, встав свой код и будет плавно. Тут всего 4 уровня яркости

C++:
if(sensorValue>=101 && sensorValue <=200){LEDS.setBrightness(brightnessHigh);delay(1000);}
        else
    if(sensorValue>=201 && sensorValue <=252){LEDS.setBrightness(brightnessMid);delay(1000);}
        else
    if(sensorValue>=253){LEDS.setBrightness(brightnessLow);delay(1000);}
        else
    if(sensorValue<=100){LEDS.setBrightness(brightnessDay);delay(1000);}};
Ну или хотя бы так