7-сегментный дисплей с WS2312B и FastLED
Мне пришла в голову идея использовать светодиодную ленту WS2312B для управления индивидуальным 7-сегментным дисплеем. Проект потребует большого количества этих дисплеев и управления ими с помощью одного Arduino (я думаю об Arduino MEGA). Для управления светодиодами я использую библиотеку FastLED.
Я написал код, управляющий одним дисплеем. Он работает, но я думаю, что его можно упростить. Код, который я написал, хранит цифры в массивах и использует эти массивы в функциях, настроенных для каждой цифры. вот пример:
//Цифровые массивы:
byte digit0[] = {0,1,2,3,4,5};
byte digit1[] = {1,2};
byte digit2[] = {0,1,3,4,6};
byte digit3[] = {0,1,2,3,6};
byte digit4[] = {1,2,5,6};
byte digit5[] = {0,2,3,5,6};
byte digit6[] = {0,2,3,4,5,6};
byte digit7[] = {0,1,2};
byte digit8[] = {0,1,2,3,4,5,6};
byte digit9[] = {0,1,2,3,5,6};
Функции примерно такие:
void AllOff(){
//Выключить все светодиоды в сегменте. Должен быть выключен на 1 секунду
for(int i=0; i<7; i++){
leds[i] = CRGB::Black;
FastLED.show();
}
// задержка (1000);
}
void AllOn(CRGB myColor){
// Включаем все светодиоды в сегменте (должно отображаться 8)
//Выбранный цвет #1E78A0
for(int i=0; i<7; i++){
leds[i] = CRGB (30,120,160);
FastLED.show();
}
delay(1000);
}
void Print0(CRGB myColor){
// Печатает цифру 0:
AllOff();
ArraySize = sizeof(digit0); //получаем размер массива
for(int i=0; i<ArraySize; i++){
LED_Number = digit0[i]; //получаем номер светодиода из массива
leds[LED_Number] = CRGB (myColor); // Включаем светодиод
FastLED.show();
}
}
Когда я вызываю его в коде, я просто делаю что-то вроде этого:
Print0(CRGB::Purple);
delay(500);
Большую часть последних двух дней я пытался найти лучший способ сделать это, но не смог. Я думаю, возможно, создать функцию, которая будет хранить все цифры вместо того, чтобы хранить каждую в виде массива, а затем вызывать ее, возможно, в цикле for? что-то вроде
for(int i=0; i<10; i++){
displaydigit[i];
FastLED.show();
}
Знаете ли вы какую-либо библиотеку, в которой есть что-то подобное, или, возможно, какие-либо идеи о том, как этого добиться?
Как всегда, мы очень ценим вашу помощь.
Спасибо.
@MDChaara, 👍1
2 ответа
Лучший ответ:
Во-первых, для всех цифр я бы использовал массив из 7 значений, указывающий для каждого сегмента, включен он или выключен. Таким образом, для 0
вы получите byte digit0[] = {1,1,1,1,1,1,0}
, где 1
указывает сегмент включен, а 0
указывает, что он выключен. Затем ваш код становится:
void Print0(CRGB myColor){
// Печатает цифру 0:
for(int i=0; i<7; i++){
if( digit0[i] )
leds[i] = CRGB (myColor); // Включаем светодиод
else
leds[i] = CRGB::Black; // Выключаем светодиод
}
FastLED.show();
}
Следующим шагом будет создание двумерного массива, содержащего, какие сегменты включены для каких цифр.
byte digits[10][7] = {
{1,1,1,1,1,1,0} //0
,{0,1,1,0,0,0,0} //1
,{1,1,0,1,1,0,1} //2
,{1,1,1,1,0,0,1} //3
,{0,1,1,0,0,1,1} //4
,{1,0,1,1,0,1,1} //5
,{1,0,1,1,1,1,1} //6
,{1,1,1,0,0,0,0} //7
,{1,1,1,1,1,1,1} //8
,{1,1,1,1,0,1,1} //9
}
Теперь вы можете обобщить функцию Print0, чтобы она принимала любое число:
void PrintNumber(byte number, CRGB myColor){
if( number>9 )
return;
for(int i=0; i<7; i++){
if( digit[number][i] )
leds[i] = CRGB (myColor); // Включаем светодиод
else
leds[i] = CRGB::Black; // Выключаем светодиод
}
FastLED.show();
}
Вызвать новую функцию в вашем цикле
; например, PrintNumber(3, CRGB:White);
Если вы хотите последовательно разместить несколько 7-сегментных дисплеев, вы можете добавить аргумент offset
в функцию PrintNumber и вместо этого использовать светодиоды[i+offset]
. . Затем вызовите PrintNumber со смещением 0 для первой цифры/дисплея, 7 для второй, 14 для третьей и так далее.
Вообще, во многих инженерных работах необходимо учитывать определение функций и ограничений. Функция, которую вы создаете, представляет собой большой 7-сегментный дисплей. Теперь решите, с какими ограничениями вы работаете. Обычно в программировании встраиваемых систем это означает ограниченную память, ограниченную мощность и взаимодействие с людьми.
Из-за ограниченного объема памяти рассмотрите возможность хранения шаблонов из 7 сегментов в сжатой форме. Также рассмотрите возможность создания максимально простого кода. Обычно чем больше данных сжато, тем сложнее должен быть код. Если имеется большой объем данных (например, звуковая дорожка, сжатая в формате mp3), стоимость сильного сжатия и сложного кода можно оправдать. Но хранить 7-сегментные шаблоны сравнительно просто. Итак, рассмотрите возможность расширения массива, чтобы включить все 7 сегментов для каждой из 10 цифр. Сохранить, если каждый сегмент включен или выключен. Затем удалите из кода циклы "все включено" и "все выключено", оставив только один цикл для чтения массива и выключения или включения каждого сегмента.
Адаптация проекта для облегчения взаимодействия с людьми может быть сложной и запутанной. Возможно, наиболее распространенной проблемой дисплеев являются задержки и мерцание. Для этого проекта выбор линейки светодиодов WS* должен смягчить проблемы с мерцанием (по крайней мере, это уберет его из ваших рук), как PWM является обязанностью каждого чипа WS*. Люди мирятся (ожидают) с небольшими задержками при просмотре больших дисплеев. Ожидается, что этот подход позволит обновить примерно 10 цифр менее чем за сотни миллисекунд.
Вы абсолютно правы. Память — это одно, а простота чтения и отладки кода — другое. SE — замечательная платформа, потому что люди могут делиться мыслями и вместе решать проблемы. Хорошо структурированные проблемы, то есть :), @MDChaara
Спасибо @MDChaara., @st2000
- Улучшенное циклическое переключение цветов RGB.
- FastLED fill_rainbow - Неожиданный красный пиксель
- Управление светодиодной лентой с помощью ИК-контроллера с помощью Arduino
- Странный артефакт при записи в последовательный порт во время выполнения цикла
- Библиотека FastLED: Как настроить яркость одного пикселя в абсолютном масштабе?
- Управление цифровой адресной светодиодной лентой RGB 12 В с помощью Arduino
- Код Arduino для управления 4 светодиодами с 4 кнопок
- Как управлять встроенными светодиодами Arduino Nano 33 BLE Sense?
вы можете добавить еще две строки в массив
digits
длявсе выключено
ивсе включено
, @jsotola@Гербен Спасибо! Сейчас тестирую код. Я думаю, что я буду делать дисплеи последовательно для некоторых сегментов и используя разные пины для других. Светодиоды[i+offset] — это то, что я искал, так что вы фактически ответили на два вопроса одним сообщением., @MDChaara
@Гербен Спасибо! работает как шарм, и это намного красивее, чем код, который я написал. Я приму ваш ответ!, @MDChaara
@jsotola На самом деле это хорошая идея. Реализовано, @MDChaara
@jsotola в чем разница между «все включено» и цифрой 8? д-;, @Gerben