Всех приветствую.
Сейчас пытаюсь сделать часы, управляемую с ИК-пульта (либа NecDecoder), используя светодиодную ленту ws2812b длиной 1 м, на 144 светодиода (у меня используются 142). Программировать пробовал на библиотеке microLED, но ни скетч с радугой из гайда по светодиодкам, ни мой скетч не заставили ленту светиться: она не реагировала вообще.
Перешёл на FastLED, скопировал скетч из гайда, выводящий радугу: он заработал правильно, и лента выводила радугу корректно. Но когда я написал и загрузил свой скетч, возникла проблема. При выполнении функции setup() всё нормально (там я поочерёдно заполняю ленту красным, зелёным и синим цветом). Далее выполняется функция loop(), и тут чуть более половины ленты (где-то 80-90 светодиодов) работает нормально, а остальная часть мерцает в разных местах, но не случайными цветами, а такими же, как у остальных светодиодов.
Так как с другими скетчами всё работает правильно, с питанием всё в порядке, а сигнальный кабель короткий (10 см) и вряд ли ему мешают помехи, то могу предположить, что дело именно в программе. Подключал по схеме, тоже взятой из гайда.
Сам скетч:
Занимаюсь программированием не так долго, поэтому код может быть корявым
Сейчас пытаюсь сделать часы, управляемую с ИК-пульта (либа NecDecoder), используя светодиодную ленту ws2812b длиной 1 м, на 144 светодиода (у меня используются 142). Программировать пробовал на библиотеке microLED, но ни скетч с радугой из гайда по светодиодкам, ни мой скетч не заставили ленту светиться: она не реагировала вообще.
Перешёл на FastLED, скопировал скетч из гайда, выводящий радугу: он заработал правильно, и лента выводила радугу корректно. Но когда я написал и загрузил свой скетч, возникла проблема. При выполнении функции setup() всё нормально (там я поочерёдно заполняю ленту красным, зелёным и синим цветом). Далее выполняется функция loop(), и тут чуть более половины ленты (где-то 80-90 светодиодов) работает нормально, а остальная часть мерцает в разных местах, но не случайными цветами, а такими же, как у остальных светодиодов.
Так как с другими скетчами всё работает правильно, с питанием всё в порядке, а сигнальный кабель короткий (10 см) и вряд ли ему мешают помехи, то могу предположить, что дело именно в программе. Подключал по схеме, тоже взятой из гайда.
Сам скетч:
C++:
#define LED_PIN 6 // пин ленты
#define LED_NUM 142 // кол-во светодидов
#define SEGMENT_LENGTH 5 // количество светодиодов на один сегмент часов
#define DOT_LENGTH 1 // количество светодиодов на одну точку - разделитель
// коды всех нужных кнопок пульта:
#define BTN_1 0xa2
#define BTN_2 0x62
#define BTN_3 0xe2
#define BTN_4 0x22
#define BTN_5 0x2
#define BTN_6 0xc2
#define BTN_7 0xe0
#define BTN_8 0xa8
#define BTN_9 0x90
#define BTN_0 0x98
#define BTN_UP 0x18
#define BTN_DOWN 0x4a
#define BTN_LEFT 0x10
#define BTN_RIGHT 0x5a
#define BTN_OK 0x38
#include <Arduino.h> // стандартная библиотека Arduino
#include <NecDecoder.h> // библиотека для использования ИК-пульта
#include <FastLED.h> // библиотека для управления светодиодной лентой
#include <limits.h> // определитель лимитов значений типов переменных
CRGB leds[LED_NUM]; // массив светодиодов
NecDecoder ir; // инициализация приёмника ИК-пульта
static uint8_t minute = 0; // текущая минута
static uint8_t hour = 0; // текущий час
void irIsr() {
ir.tick();
}
void set_time(uint8_t number); // режим установки времени
void time_add(uint8_t number, uint8_t digit); // прибавление переменных времени
void display(uint8_t number, uint8_t digit, CRGB disp_color); // вывод значений на часы в заданном цвете
void fill_leds(uint8_t from_led, uint8_t to_led, CRGB fill_color); // заполнение участка ленты заданным цветом
void setup(){
pinMode(6, OUTPUT);
FastLED.addLeds<WS2812, LED_PIN, GRB>(leds, LED_NUM).setCorrection(TypicalLEDStrip); // инициализация ленты
attachInterrupt(0, irIsr, FALLING);
FastLED.setBrightness(40); // яркость = 40
FastLED.clear();
fill_leds(0, LED_NUM, CRGB::Red);
FastLED.show();
delay(800);
FastLED.clear();
fill_leds(0, LED_NUM, CRGB::Green);
FastLED.show();
delay(800);
FastLED.clear();
fill_leds(0, LED_NUM, CRGB::Blue);
FastLED.show();
delay(800);
}
void loop() {
static uint8_t brightness = 255; // текущая яркость
static uint8_t color = 0; // текущий цвет
static uint8_t color_mode = 0; // режим цвета (0 - плавное изменение цвета, 1 - установленный пользователем цвет)
static unsigned long last_minute_millis = millis(); // последнее прибавление минуты [в миллисекундах с начала работы часов]
if(millis() - 60000 >= last_minute_millis || (last_minute_millis > millis() && ULONG_MAX - last_minute_millis + millis() >= 60000)){ // счётчик минут
if(minute == 59){
if(hour == 23){
hour = 0;
}
else{
++hour;
}
minute = 0;
}
else{
++minute;
}
last_minute_millis = millis();
}
FastLED.clear();
// чтение команд с ИК-пульта:
if(ir.available()){
switch(ir.readCommand()){
case BTN_0:
minute = 0;
hour = 0;
FastLED.clear();
fill_leds(SEGMENT_LENGTH * 14, SEGMENT_LENGTH * 14 + DOT_LENGTH * 2, CRGB::Green);
display(0, 0, CRGB::Green);
set_time(1);
last_minute_millis = millis();
FastLED.show();
break;
case BTN_1:
minute = 0;
hour = 10;
FastLED.clear();
fill_leds(SEGMENT_LENGTH * 14, SEGMENT_LENGTH * 14 + DOT_LENGTH * 2, CRGB::Green);
display(0, 1, CRGB::Green);
set_time(1);
last_minute_millis = millis();
FastLED.show();
break;
case BTN_2:
minute = 0;
hour = 20;
FastLED.clear();
fill_leds(SEGMENT_LENGTH * 14, SEGMENT_LENGTH * 14 + DOT_LENGTH * 2, CRGB::Green);
display(0, 2, CRGB::Green);
set_time(1);
last_minute_millis = millis();
FastLED.show();
break;
case BTN_UP: brightness++; break;
case BTN_DOWN: brightness--; break;
case BTN_OK: color_mode = 0; break;
case BTN_RIGHT:
color_mode = 1;
color += 10;
break;
case BTN_LEFT:
color_mode = 1;
color -= 10;
break;
}
}
if(color_mode == 0){ // плавное изменение цвета при режиме цвета == 0
color++;
}
fill_leds(SEGMENT_LENGTH * 14, SEGMENT_LENGTH * 14 + DOT_LENGTH * 2, CHSV(color, 255, brightness)); // вывод точек
// поочерёдный вывод всех цифр:
display(0, hour / 10, CHSV(color, 255, brightness));
display(1, hour % 10, CHSV(color, 255, brightness));
display(2, minute / 10, CHSV(color, 255, brightness));
display(3, minute % 10, CHSV(color, 255, brightness));
FastLED.show();
FastLED.delay(200);
}
void set_time(uint8_t number){ // функция cчитывания нажатий для установки времени
if(ir.available()){
switch(ir.readCommand()){
case BTN_0: time_add(number, 0); break;
case BTN_1: time_add(number, 1); break;
case BTN_2: time_add(number, 2); break;
case BTN_3: time_add(number, 3); break;
case BTN_4: time_add(number, 4); break;
case BTN_5: time_add(number, 5); break;
case BTN_6: time_add(number, 6); break;
case BTN_7: time_add(number, 7); break;
case BTN_8: time_add(number, 8); break;
case BTN_9: time_add(number, 9); break;
}
}
if(number < 3){
set_time(number + 1);
}
}
void time_add(uint8_t number, uint8_t digit){ // функция установки времени
if(number == 1){
hour += digit;
}
else if(number == 2){
minute += (digit * 10);
}
else{
minute += digit;
}
display(number, digit, CRGB::Green);
}
void display(uint8_t number, uint8_t digit, CRGB disp_color) { // функция вывода цифр на часы, где number - место выведения цифры, digit - выводимая цифра
int offset = number * SEGMENT_LENGTH * 7; // смещение в зависимости от места выведения цифры
if(digit > 1){
offset += DOT_LENGTH * 2;
}
switch(digit){
case 0:
fill_leds(0 + offset, SEGMENT_LENGTH * 6 + offset, disp_color);
break;
case 1:
fill_leds(SEGMENT_LENGTH * 2 + offset, SEGMENT_LENGTH * 4 + offset, disp_color);
break;
case 2:
fill_leds(SEGMENT_LENGTH + offset, SEGMENT_LENGTH * 3 + offset, disp_color);
fill_leds(SEGMENT_LENGTH * 4 + offset, SEGMENT_LENGTH * 7 + offset, disp_color);
break;
case 3:
fill_leds(SEGMENT_LENGTH + offset, SEGMENT_LENGTH * 5 + offset, disp_color);
fill_leds(SEGMENT_LENGTH * 6 + offset, SEGMENT_LENGTH * 7 + offset, disp_color);
break;
case 4:
fill_leds(0 + offset, SEGMENT_LENGTH + offset, disp_color);
fill_leds(SEGMENT_LENGTH * 2 + offset, SEGMENT_LENGTH * 4 + offset, disp_color);
break;
case 5:
fill_leds(0 + offset, SEGMENT_LENGTH * 2 + offset, disp_color);
fill_leds(SEGMENT_LENGTH * 3 + offset, SEGMENT_LENGTH * 5 + offset, disp_color);
fill_leds(SEGMENT_LENGTH * 6 + offset, SEGMENT_LENGTH * 7 + offset, disp_color);
break;
case 6:
fill_leds(0 + offset, SEGMENT_LENGTH * 2 + offset, disp_color);
fill_leds(SEGMENT_LENGTH * 3 + offset, SEGMENT_LENGTH * 7 + offset, disp_color);
break;
case 7:
fill_leds(SEGMENT_LENGTH + offset, SEGMENT_LENGTH * 4 + offset, disp_color);
break;
case 8:
fill_leds(0 + offset, SEGMENT_LENGTH * 7 + offset, disp_color);
break;
case 9:
fill_leds(0 + offset, SEGMENT_LENGTH * 5 + offset, disp_color);
fill_leds(SEGMENT_LENGTH * 6 + offset, SEGMENT_LENGTH * 7 + offset, disp_color);
break;
}
}
void fill_leds(uint8_t from_led, uint8_t to_led, CRGB fill_color){ // функция заполнения участка ленты определённым цветом
for(uint8_t i = from_led; i < to_led; i++){
leds[i] = fill_color;
}
}
Изменено: