4-Digit Seven-Segment Displays

I know this topic is really common on the forum, but I optimized my code quite a lot and made it differently than most people that ask for help about this. I already made my own functions to print numbers on digits but, like most people, im stuck at the actual "displaying phase", as I like to call it.
I know it's not technically possible to display different numbers at the same time, and i'm also aware that you have to "flash" the display for the trick to work. I just don't know how to do it. If possible, I'd like to learn it instead of having to rely on libraries.

Thanks in advance!

Since im a "new user", i can't send the file for my code so i'll link it to a Docs: [code]

deactivate all segments
activate digit 1,
activate the segments to show the number for digit 1
let some time pass
deactivate all segments
activate digit 2,
activate the segments to show the number for digit 2
let some time pass
...

it's a simple multiplexing, like done in dozens of seven segment libraries.

p.s.: read again the forum how to.
You can post code in code tags,
you can upload pictures to forum.

Actually, no!

More appropriate:
deactivate digit 1; // if not already done
activate the segments to show the number for digit 1;
activate digit 1;
let some time pass;
deactivate digit 1;
activate the segments to show the number for digit 2;
activate digit 2;
let some time pass;
deactivate digit 2;
...

Depending on how it is coded, switching a digit on or off is simpler and more concise than setting up the segment pattern.

"Bit-banging" a 7-segment LED display is generally nothing more than a coding exercise, and not really appropriate for practical use of a display.

1 Like

What does that mean -- please explain with reference to the following 4-digit 7-seg display unit.
7seg4xy

Codes to show 1234 on the display unit.
1. Declare a lookup table that contains cc-code vs digits:

byte ccTable[] = 
{
      0x3F, 0x06, 0x5B, 0x4F, 0x66, 0x6D, 0x7D, 0x07, 
      //0	   1      2	      3	 4	     5	       6	7	
      0x7F, 0x6F, 0x77, 0x7C, 0x39, 0x5E, 0x79, 0x71
};    //8	  9	    A        B        C        D        E         F	

2. Set directions of IO lines as outputs:

for(int i = 2; i<14; i++)
{
    pinMode(i, OUTPUT);
}

23 Extract 01 from 1234

int y = 0x1234;
byte digit0 = (byte) y>>12;

4. Collect cc-code from LUT.

byte ccD0 = ccTable[digit0];    //ccD0 = 0x064

5. Show 1 at DP0 position of the display unit

PORTB = ccD0;
digitalWrite(6, bitRead(ccD0, 6));
digitalWrite(7, bitRead(ccD0, 7));
//--------------------------------------------
digitalWrite(2, LOW);
digitalWrite(3, HIGH);
digitalWrite(4, HIGH);
digitalWrite(5, HIGH);

6. Do similar to above to show 2 at DP1, 3 at DP2, and 4 at DP3 positions.
7. Then use for() loop to reduce the number of lines.
8. You can avoid using so many lines of codes by using SevSeg.h Library.

Here are the basic guts of a 4-digit 7-segment matrix display.

int NumberToDisplay = 8901;

// List of digit select lines, least significant digit first
// Digit Common Anodes (HIGH for on, LOW for off)
const byte DigitCount = 4;
const byte DigitPins[DigitCount] = {A0, 2, 3, 4};

// Segment Cathodes (LOW for on, HIGH for off)
const byte SegmentCount = 7;
const unsigned char SegmentPins[SegmentCount] = {5, 6, 7, 8, 9, 10, 11};

// Segment Cathodes (0/LOW for on, 1/HIGH for off)
const byte Segments[] =
{
  0b11000000, // 0
  0b11001111, // 1
  0b10100100, // 2
  0b10000110, // 3
  0b10001011, // 4
  0b10010010, // 5
  0b10010000, // 6
  0b11000111, // 7
  0b10000000, // 8
  0b10000011, // 9
};


void setup()
{
  for (int i = 0; i < DigitCount; i++)
  {
    pinMode(DigitPins[i], OUTPUT);
    digitalWrite(DigitPins[i], LOW);
  }

  for (int i = 0; i < SegmentCount; i++)
  {
    pinMode(SegmentPins[i], OUTPUT);
    digitalWrite(SegmentPins[i], HIGH);
  }
}

void loop()
{
  int number = NumberToDisplay;

  // Display each digit, right to left
  for (int i = 0; i < DigitCount; i++)
  {
    // Peel a digit off the low end of the number
    int digit = number % 10;
    number /= 10;

    // Display the digit on the seven segments
    unsigned char segments = Segments[digit];
    for (int s = 0; s < SegmentCount; s++)
    {
      digitalWrite(SegmentPins[s], segments & 1);
      segments >>= 1;
    }

    // Turn on the digit briefly
    digitalWrite(DigitPins[i], HIGH);  // Select one digit
    delayMicroseconds(3000UL);  // Higher numbers give higher brightness but more flicker
    digitalWrite(DigitPins[i], LOW);
  }  // End of for(i
}

Read the forum guidelines to see how to properly post code inline and some good information on making a good post.
Use the IDE autoformat tool (ctrl-t or Tools, Auto format) before posting code in code tags.

Getting to trust level 1 is hardly difficult. Get there by

  • Entering at least 5 topics

  • Reading at least 30 posts

  • Spend a total of 10 minutes reading posts

Users at trust level 1 can…

  • Use all core Discourse functions; all new user restrictions are removed

  • Send PMs

  • Upload images and attachments

  • etc

I did as you said, and now it works just fine! Thanks for everyone's help!

OK, now post your current code here in the thread. :grin:

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.