Show 11 digit number on 7-segment displays

Hello,

i have build a big 7 segment Display made of 11 "SparkFun 7-Segment Display 6.5"" they are all equiped with the " SparkFun Large Digit Driver" with the TPIC6C596 IC.

It is running fine untill I increment the number of digits over the 8th digit. As soon as I try to show 9 or more digits, the digits start to behave strange. No more counting. Some sporadic numbers.

What am I doing wrong?

Thanks for any help!

This is my code so far:

//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
byte segmentClock = 6;
byte segmentLatch = 5;
byte segmentData = 7;

//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=

char snumber[10];

void setup()
{
  Serial.begin(9600);
  Serial.println("Large Digit Driver Example");

  pinMode(segmentClock, OUTPUT);
  pinMode(segmentData, OUTPUT);
  pinMode(segmentLatch, OUTPUT);

  digitalWrite(segmentClock, LOW);
  digitalWrite(segmentData, LOW);
  digitalWrite(segmentLatch, LOW);
}

unsigned long long number = 12345678901;

void loop()
{
  showNumber(number); //Test pattern
  number = number + 16;
  number %= 100000000000; //Reset x after 99999999999
  
  sprintf(snumber, "%llu", number);
  Serial.println(snumber); //For debugging
  
  delay(100);
}

//Takes a number and displays 11 numbers. Displays absolute value (no negatives)
void showNumber(float value)
{
  unsigned long long number = abs(value); //Remove negative signs and any decimals

  for (byte x = 0 ; x < 11 ; x++)
  {
    unsigned long long remainder = number % 10;

    postNumber(remainder, false);

    number /= 10;
  }

  //Latch the current segment data
  digitalWrite(segmentLatch, LOW);
  digitalWrite(segmentLatch, HIGH); //Register moves storage register on the rising edge of RCK
}

//Given a number, or '-', shifts it out to the display
void postNumber(byte number, boolean decimal)
{
  //    -  A
  //   / / F/B
  //    -  G
  //   / / E/C
  //    -. D/DP

#define a  1<<0
#define b  1<<6
#define c  1<<5
#define d  1<<4
#define e  1<<3
#define f  1<<1
#define g  1<<2
#define dp 1<<7

  byte segments;

  switch (number)
  {
    case 1: segments = b | c; break;
    case 2: segments = a | b | d | e | g; break;
    case 3: segments = a | b | c | d | g; break;
    case 4: segments = f | g | b | c; break;
    case 5: segments = a | f | g | c | d; break;
    case 6: segments = a | f | g | e | c | d; break;
    case 7: segments = a | b | c; break;
    case 8: segments = a | b | c | d | e | f | g; break;
    case 9: segments = a | b | c | d | f | g; break;
    case 0: segments = a | b | c | d | e | f; break;
    case ' ': segments = 0; break;
    case 'c': segments = g | e | d; break;
    case '-': segments = g; break;
  }

  if (decimal) segments |= dp;

  //Clock these bits out to the drivers
  for (byte x = 0 ; x < 8 ; x++)
  {
    digitalWrite(segmentClock, LOW);
    digitalWrite(segmentData, segments & 1 << (7 - x));
    digitalWrite(segmentClock, HIGH); //Data transfers to the register on the rising edge of SRCK
  }
}

This array should have a size of at least 12 if you use sprintf to print an 11-digit number

why this parameter is float?
Float number has limited accuracy. Use long long number instead

On AVR-based Arduinos, float values are limited to at most 7 decimal digits of accuracy and type double is not supported (treated as four byte float).

Thank you all.

This solved my problem:

As long long everything works perfectly.

One more thing. I changed the array size to 12.
But my serialmonitor output is empty.

Where is the truth - have you solved everything

or nothing works?

Sorry for that misunderstanding! :crazy_face:

The output on the 7-segment displays works perfectly as mentioned.
The output on my serialmonitor is not working as it should.
On the serialmonitor I get the Setup-message: Serial.println("Large Digit Driver Example");

But no number is showing up. I see the empty lines scrolling.

Thanks

Post the revised code, using code tags.

Here it is:

//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
byte segmentClock = 6;
byte segmentLatch = 5;
byte segmentData = 7;

//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=

char snumber[12];

void setup()
{
  Serial.begin(9600);
  Serial.println("Large Digit Driver Example");

  pinMode(segmentClock, OUTPUT);
  pinMode(segmentData, OUTPUT);
  pinMode(segmentLatch, OUTPUT);

  digitalWrite(segmentClock, LOW);
  digitalWrite(segmentData, LOW);
  digitalWrite(segmentLatch, LOW);
}

unsigned long long number = 74152676000 ;

void loop()
{
  showNumber(number); //Test pattern
  number = number + 16;
  number %= 100000000000; //Reset x after 99999999999
  
  sprintf(snumber, "%llu", number);
  Serial.println(snumber); //For debugging
  
  delay(100);
}

//Takes a number and displays 11 numbers. Displays absolute value (no negatives)
void showNumber(long long value)
{
  unsigned long long number = abs(value); //Remove negative signs and any decimals

  for (byte x = 0 ; x < 11 ; x++)
  {
    unsigned long long remainder = number % 10;

    postNumber(remainder, false);

    number /= 10;
  }

  //Latch the current segment data
  digitalWrite(segmentLatch, LOW);
  digitalWrite(segmentLatch, HIGH); //Register moves storage register on the rising edge of RCK
}

//Given a number, or '-', shifts it out to the display
void postNumber(byte number, boolean decimal)
{
  //    -  A
  //   / / F/B
  //    -  G
  //   / / E/C
  //    -. D/DP

#define a  1<<0
#define b  1<<6
#define c  1<<5
#define d  1<<4
#define e  1<<3
#define f  1<<1
#define g  1<<2
#define dp 1<<7

  byte segments;

  switch (number)
  {
    case 1: segments = b | c; break;
    case 2: segments = a | b | d | e | g; break;
    case 3: segments = a | b | c | d | g; break;
    case 4: segments = f | g | b | c; break;
    case 5: segments = a | f | g | c | d; break;
    case 6: segments = a | f | g | e | c | d; break;
    case 7: segments = a | b | c; break;
    case 8: segments = a | b | c | d | e | f | g; break;
    case 9: segments = a | b | c | d | f | g; break;
    case 0: segments = a | b | c | d | e | f; break;
    case ' ': segments = 0; break;
    case 'c': segments = g | e | d; break;
    case '-': segments = g; break;
  }

  if (decimal) segments |= dp;

  //Clock these bits out to the drivers
  for (byte x = 0 ; x < 8 ; x++)
  {
    digitalWrite(segmentClock, LOW);
    digitalWrite(segmentData, segments & 1 << (7 - x));
    digitalWrite(segmentClock, HIGH); //Data transfers to the register on the rising edge of SRCK
  }
}

Check whether the Arduino version of sprintf supports long longs. It does not support floats, for example.

Seems a bit silly to declare "remainder" as long long, since it can never be greater than 9.

    unsigned long long remainder = number % 10;

I suspect that this type is not supported in the sprintf version of avr-libc.

You can check this here.

[edit]

Here is a print function that might be useful.

Indeed it is not. You could use this ulltoa() function:

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