7-сегментный дисплей с WS2312B и FastLED

Мне пришла в голову идея использовать светодиодную ленту WS2312B для управления индивидуальным 7-сегментным дисплеем. Проект потребует большого количества этих дисплеев и управления ими с помощью одного Arduino (я думаю об Arduino MEGA). Для управления светодиодами я использую библиотеку FastLED.

(2 разных 7-сегментных дисплея; это буква E)

Я написал код, управляющий одним дисплеем. Он работает, но я думаю, что его можно упростить. Код, который я написал, хранит цифры в массивах и использует эти массивы в функциях, настроенных для каждой цифры. вот пример:

//Цифровые массивы:
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();
  }

Знаете ли вы какую-либо библиотеку, в которой есть что-то подобное, или, возможно, какие-либо идеи о том, как этого добиться?

Как всегда, мы очень ценим вашу помощь.

Спасибо.

, 👍1


2 ответа


Лучший ответ:

1

Во-первых, для всех цифр я бы использовал массив из 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 для третьей и так далее.

,

вы можете добавить еще две строки в массив digits для все выключено и все включено, @jsotola

@Гербен Спасибо! Сейчас тестирую код. Я думаю, что я буду делать дисплеи последовательно для некоторых сегментов и используя разные пины для других. Светодиоды[i+offset] — это то, что я искал, так что вы фактически ответили на два вопроса одним сообщением., @MDChaara

@Гербен Спасибо! работает как шарм, и это намного красивее, чем код, который я написал. Я приму ваш ответ!, @MDChaara

@jsotola На самом деле это хорошая идея. Реализовано, @MDChaara

@jsotola в чем разница между «все включено» и цифрой 8? д-;, @Gerben


0

Вообще, во многих инженерных работах необходимо учитывать определение функций и ограничений. Функция, которую вы создаете, представляет собой большой 7-сегментный дисплей. Теперь решите, с какими ограничениями вы работаете. Обычно в программировании встраиваемых систем это означает ограниченную память, ограниченную мощность и взаимодействие с людьми.

Из-за ограниченного объема памяти рассмотрите возможность хранения шаблонов из 7 сегментов в сжатой форме. Также рассмотрите возможность создания максимально простого кода. Обычно чем больше данных сжато, тем сложнее должен быть код. Если имеется большой объем данных (например, звуковая дорожка, сжатая в формате mp3), стоимость сильного сжатия и сложного кода можно оправдать. Но хранить 7-сегментные шаблоны сравнительно просто. Итак, рассмотрите возможность расширения массива, чтобы включить все 7 сегментов для каждой из 10 цифр. Сохранить, если каждый сегмент включен или выключен. Затем удалите из кода циклы "все включено" и "все выключено", оставив только один цикл для чтения массива и выключения или включения каждого сегмента.

Адаптация проекта для облегчения взаимодействия с людьми может быть сложной и запутанной. Возможно, наиболее распространенной проблемой дисплеев являются задержки и мерцание. Для этого проекта выбор линейки светодиодов WS* должен смягчить проблемы с мерцанием (по крайней мере, это уберет его из ваших рук), как PWM является обязанностью каждого чипа WS*. Люди мирятся (ожидают) с небольшими задержками при просмотре больших дисплеев. Ожидается, что этот подход позволит обновить примерно 10 цифр менее чем за сотни миллисекунд.

,

Вы абсолютно правы. Память — это одно, а простота чтения и отладки кода — другое. SE — замечательная платформа, потому что люди могут делиться мыслями и вместе решать проблемы. Хорошо структурированные проблемы, то есть :), @MDChaara

Спасибо @MDChaara., @st2000