1

I thought of the idea of using the WS2312B LED strip to drive a custom 7-Segment display. The project will require a large number of these displays, and driving them with a single Arduino (I'm thinking of an Arduino MEGA). For driving the LEDs I am using the FastLED library.

(2 different 7-Segment displays; and that is the letter E)

I wrote some code that drives a single display, It works, but I think It's possible to make it simpler, the code I wrote stores the digits in arrays, and uses these arrays in functions customized to each digit. here is an example:

//Digit Arrays:
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};

The functions are something like this:

void AllOff(){
//Switch off All the LEDs in the segment. Should be off for 1 second
  for(int i=0; i<7; i++){
    leds[i] = CRGB::Black;
    FastLED.show();
  }
  //delay(1000);
}
void AllOn(CRGB myColor){
  //Switch on All the LEDs in the segment (should display 8)
  //The color of choice is #1E78A0
  for(int i=0; i<7; i++){
    leds[i] = CRGB (30,120,160);
    FastLED.show();
  }
  delay(1000);
}
void Print0(CRGB myColor){
  //Prints the digit 0:
  AllOff();
  ArraySize = sizeof(digit0);     //get the size of the array
  for(int i=0; i<ArraySize; i++){
    LED_Number  = digit0[i];      //get the LED number from the array
    leds[LED_Number]    = CRGB (myColor);  //Switch the LED on
    FastLED.show();
  }
}

When I call it in the code, I simply do something like this:

Print0(CRGB::Purple);
delay(500);

I have tried for the best part of the past two days to find a better way to go about this, but I couldn't. What I'm thinking is perhaps to create a function that would store all the digits instead of storing every one as an array, and then call it maybe within a for loop? something like

for(int i=0; i<10; i++){
    displaydigit[i];
    FastLED.show();
  }

Do you know of any library that has something similar, or perhaps any idea on how to achieve this?

Your assistance, as always, is greatly appreciated.

Thank You.

2 Answers 2

1

First, for all the digits I'd use an 7 value array, indicating for every segment if it's ON or OFF. So for 0 your get byte digit0[] = {1,1,1,1,1,1,0}, where 1 indicates the segment is ON, and 0 indicates it's OFF. Your code then becomes:

void Print0(CRGB myColor){
  //Prints the digit 0:
  for(int i=0; i<7; i++){
    if( digit0[i] )
      leds[i] = CRGB (myColor);  //Switch the LED on
    else
      leds[i] = CRGB::Black; // Switch the LED off
  }
  FastLED.show();
}

The next step would be to create a two dimensional array containing which segments are on for which digits.

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
   }

Now you can generalize you Print0 function to accept any number:

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);  //Switch the LED on
    else
      leds[i] = CRGB::Black; // Switch the LED off
  }
  FastLED.show();
}

Call the new function in your loop; for example PrintNumber(3, CRGB:White);

If you want to put multiple 7-segment displays in series, you could add and offset argument to the PrintNumber function, and use leds[i+offset] instead. Then call the PrintNumber with offset 0 for the first digit/display, 7 for the second, 14 for the third, and so on.

5
  • 2
    you could add two more rows to the digits array for all off and all on
    – jsotola
    Feb 15, 2020 at 17:22
  • @Gerben Thank You! I'm testing the code now. I'm thinking that I will do the displays in series for some segments and using different pins for other ones. The leds[i+offset] is something that I was looking for, so you have actually answered two questions with one post.
    – MDChaara
    Feb 15, 2020 at 17:39
  • @Gerben Thank you! works like a charm, and it's a lot prettier than the code I wrote. I will accept your answer!
    – MDChaara
    Feb 15, 2020 at 19:04
  • @jsotola That's actually a good idea. Implemented
    – MDChaara
    Feb 15, 2020 at 20:35
  • @jsotola what's the difference between all on and the number 8 ? q-;
    – Gerben
    Feb 16, 2020 at 18:50
0

In general, in many engineering efforts, a definition of the feature(s) and constraints need to be considered. The feature you are creating is a large-7-segment-display. Now decide what constraints you are working under. Normally, in embedded programming, this means limited memory, limited power and interacting with people.

Because of limited memory, consider storing 7-segment patterns in a condensed form. Also consider creating the simplest code possible. Usually the more data is compressed, the more complex the code needs to be. If there is a large amount of data (for example, an mp3 compressed sound track) the cost of high compression and complex code can be justified. But storing 7-segment patters is comparatively simple. So, consider expanding the array to include all 7 segments for each of the 10 digits. Store if each segment is on or off. Then, remove the "all on" and "all off" loops in your code leaving only one loop to read the array and turn off or on each segment.

Adapting the project to facilitate interacting with people can be confusing and difficult. Possibly the most common problem with displays are delays and flicker. For this project choosing the WS* line of LEDs should mitigate flicker problems (at the very least it takes it out of your hands) as the PWM feature is the responsibility of each WS* chip. People have been putting up with (expect) small delays when viewing large displays. And it is expected this approach could update perhaps 10 digits in less than hundreds of milliseconds.

2
  • You are absolutely right. Memory is one thing, and the ease of reading and debugging the code is another. SE is a wonderful platform because people get to share thoughts and solve problems together. Well structured problems, that is :)
    – MDChaara
    Feb 15, 2020 at 19:08
  • Thanks @MDChaara.
    – st2000
    Feb 15, 2020 at 21:48

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.