Most efficient way to interface seven segment

Hello people!

I need to write code that shows a counter on a single seven segment display module (0-9), and I need help figuring out what the most effective way to display numbers on a seven segment display is, without using external libraries. I would also like it to be not too complex, as I am a beginner to Arduino and C in general. So far, I'm doing it manually in a function:

    case 0:
      digitalWrite(A, HIGH);
      digitalWrite(B, HIGH);
      digitalWrite(C, HIGH);
      digitalWrite(D, HIGH);
      digitalWrite(E, HIGH);
      digitalWrite(F, HIGH);
      digitalWrite(G, LOW); 
    break;

This adds ~100 lines of extra unnecessary messy code, and I was wondering if there was a more efficient way to do this? I've attempted messing around with arrays and whatnot, but I couldn't get it to work. Help?

There must be thousands of pages on the net for "arduino 7 segment code"

If you want help with your code, post it all, well formatted and in a code block, and tell us what the code does and how that differs from what the code should do.

If there are compile errors, post the entire error message.

you can look at the multifunction board for both electrical design and software

code i wrote for it
see in particular, SEGMENT_MAP_DIGIT [] that simplifies your ~100s of lines

// drive 7-seg displays on MultiFuction boardj
#include "seg7disp.h"

// -------------------------------------
//  constants for multiplexed 7-segment display
#define Latch   4
#define Clock   7
#define Data    8
#define LED0   10
#define LED1   11

byte pins [] = { Latch, Clock, Data, LED0, LED1 };

//    a      d
//   f b    c e
//    g      g
//   e c    b f
//    d h    a
//
//   h g f e d c b a

const byte SEGMENT_MAP_DIGIT[] = {
    0xC0, 0xF9, 0xA4, 0xB0, 0x99, 0x92, 0x82, 0xF8, 0X80, 0X90
};

const byte SEGMENT_MAP_DIGIT_F [] = {
    0xC0, 0xCF, 0xA4, 0x86, 0x8B, 0x92, 0x90, 0xC7, 0x80, 0x82
};

const byte DISP_MAP [] = { 1, 2, 4, 8 };
#define N_DISP  sizeof(DISP_MAP)

byte disp [N_DISP] = {SEGMENT_OFF, SEGMENT_OFF, SEGMENT_OFF, SEGMENT_OFF};

int flag;

// -----------------------------------------------------------------------------
// shift 16-bits from data into the shift register
void output (
    uint16_t  data)
{
    digitalWrite (Latch, LOW);

    for (unsigned i = 0; i < 16; i++, data <<= 1)  {
        digitalWrite (Data, 0 != (data & 0x8000));

        digitalWrite (Clock, HIGH);
        digitalWrite (Clock, LOW);
    }

    digitalWrite (Latch, HIGH);
}

// -----------------------------------------------------------------------------
// repeatedly display one digit
//      lower 8-bits selects the digit
//      upper 8-bits species the segments
void isr (void)
{
    static byte idx = 0;

    uint16_t val = (disp [idx] << 8) + DISP_MAP [idx];
    output (val);

    if (N_DISP <= ++idx)
        idx = 0;
}

// -----------------------------------------------------------------------------
// update the value of each digit
void seg7segs (
    int  val,
    byte segs )
{
    for (int i = N_DISP-1; i >= 0; i--, val /= 2)
        disp [i] = val & 1 ? segs : SEGMENT_OFF;
}

// -----------------------------------------------------------------------------
// update the value of each digit
void seg7disp (
    int  valX10,
    int  flip )
{
    Serial.println (__func__);

    int i;
    if (flip)  {
        for (i = 0; i < (int)N_DISP; i++, valX10 /= 10)
            disp [i] = SEGMENT_MAP_DIGIT_F [valX10 % 10];

        // blank leading zeros
        i = N_DISP-1;
        while (SEGMENT_MAP_DIGIT [0] == disp [i])
            disp [i--] = SEGMENT_OFF;
    }
    else  {
        for (i = N_DISP-1; i >= 0; i--, valX10 /= 10)
            disp [i] = SEGMENT_MAP_DIGIT [valX10 % 10];
        disp [N_DISP-2] &= SEGMENT_DEC;       // decimal pt

        // blank leading zeros
        i = 0;
        while (SEGMENT_MAP_DIGIT [0] == disp [i])
            disp [i++] = SEGMENT_OFF;
    }
}

// -----------------------------------------------------------------------------
// update the value of each digit
void seg7off (void)
{
    Serial.println (__func__);
    for (int i = N_DISP-1; i >= 0; i--)
        disp [i] = SEGMENT_OFF;
}

void seg7on (void)
{
    Serial.println (__func__);
    for (int i = N_DISP-1; i >= 0; i--)
        disp [i] = 0;
}

// -----------------------------------------------------------------------------
void seg7init (void)
{
    Serial.println (__func__);
    for (unsigned i = 0; i < sizeof(pins); i++)  {
        digitalWrite (pins [i], HIGH);
        pinMode      (pins [i], OUTPUT);
    }

    Timer1.initialize(5000);
    Timer1.attachInterrupt (isr); // blinkLED to run every 0.15 seconds
}

Hi ChatGPT!
how are you today?

2 Likes

I don't remember what they decided about chatGPT - should we notify the moderator?

allow me a sec.

EDIT:
from english to french to english : to be flagged for future reference

It's been flagged as spam due to the embedded advertisement.

Edit - that they cleverly deleted. Maybe a mod convinced them to remove it...

AFAIK the forum managers haven't weighed in about chatGPT or don't have a policy yet.

This will never happen. The most efficient way will never be the simplest way. Tell us what you are really trying to do. Is it an assignment? It has the "air" of one.

I've attempted messing around with arrays and whatnot, but I couldn't get it to work. Help?

We can't help with code we can't see.

Another presentation:
1. Wiring Diagram (Fig-1) //Edit following post #12.


Figure-1:

2. Codes to show 2 on the display unit
(1) Set directions of the IO lines as outputs using pinMode() function.

for(int i = 6; i < 15; i++)
{
     pinMode(i, OUTPUT);
}

(2) Turn ON segment-a, b, d, e, g using digitalWrite() function.

digitalWrite(8, HIGH);
digitalWrite(9, HIGH);
digitalWrite(11, HIGH);
digitalWrite(12, HIGH);
digitalWrite(6, HIGH);

(3) Turn OFF segment-c, f, p using digitalWrite() function.

digitalWrite(10, LOW);
digitalWrite(13, LOW);
digitalWrite(7, LOW);

(4) Assert LOW on DPin-14 as the display device is of type common cathode.

digitalWrite(14, LOW);

3. Assemble all the above discrete codes into a sketch and upload into Arduino UNO.
4. Check that 2 has appeared on the display unit.

This will exceed the maximum output current specification.

You are right!

In the worst case (all segments are ON), the total sink current comes to 35 mA (limit is 20 mA) for DPin-14.

The solution is to increase the current limiting resistors from 560R to 1.5k.

Hello again!

I apologize for forgetting about this for a while, but I've followed groundFungus' reply and searched online for a while to find a solution, and I found one that works well enough (after a few adjustments) for my needs.

Simply put, you make an array of the segment pins, and another (2d) array of possible positions (0-9), and then you simply make a function that loops through both of them.

Here's the code
Do note however, if you're going to use this, that it only works with one display, you will need to modify it a little if you plan on using this for multiple displays.

// Define seven segment LED ports
char Segments[7] = { 2, 3, 4, 5, 6, 7, 8 };

// Define seven segment positions
char SegmentPositions[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, 0, 0, 1, 1 }   // 9
};

// Define "SegmentDisplay" function. This function takes seven segment ports and a number
// and displays the number on the seven segment display
void SegmentDisplay(char ArrayOfSegments[], char ArrayOfPositions[10][7], short Number) {
  if (Number > 9 || Number < 0) {
      return;
    }
  } else {
    for (char i = 0; i <= 7; i++) {
      digitalWrite(ArrayOfSegments[i], ArrayOfPositions[Number][i]);
    }
  }
}

void setup() {
  for (char i = 0; i <= 7; i++) {
    pinMode(Segments[i], OUTPUT);
  }
}

void loop() {
  SegmentDisplay(Segments, SegmentPositions, 5);
}

Have a wonderful day!

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