TPIC6C596D 6 digit 7 segment display

Hi there,

i am working on a 6 digit 7 segment display.

Everything works fine. There´s only one thing i don´t like.
If i show a number that does not uses all digits the unused digits show "0" (a zero) i would like them to stay off. How can i do this?

This is my code so far:

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

void setup()
{
  pinMode(segmentClock, OUTPUT);
  pinMode(segmentData, OUTPUT);
  pinMode(segmentLatch, OUTPUT);

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

}

void loop()
{
  showNumber(222222); //Test pattern
}

//Takes a number and displays 6 numbers. Displays absolute value
void showNumber(long number)
{
  //Chop the value into the array
  byte values[6];
  for (byte x = 0 ; x < 6 ; x++)
  {
    values[6 - x] = number % 10;
    number /= 10;
  }

  //Push the values out to the display
  for (byte x = 6 ; x > 0 ; x--)
  {
    
      postNumber(values[x], false); //Don't write a decimal
   
  }

  //Latch the current segment data - this causes display to show what's been clocked in
  digitalWrite(segmentLatch, LOW);
  digitalWrite(segmentLatch, HIGH); //Register moves storage register on the rising edge of RCK
}


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

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

  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
  }
}

Thanks for any help!

Hello

You are writing outside of the array, the array size is 6 so the index range is 0 to 5, not 6.


I suggest using something like this : ScEwnK - Online C++ Compiler & Debugging Tool - Ideone.com
Or without using an array to store digits : I0UuQ6 - Online C++ Compiler & Debugging Tool - Ideone.com

Thank you for the correction of the array range.
Your suggestions does not change anything.
I am feeding the shift-registers from the first to the last your code inverses the direction.

My code is doing the same thing as your code, but replaces the leading zeros with spaces (or underscores, for demonstration). Isn't it what you wanted to do ? su0cL7 - Online C++ Compiler & Debugging Tool - Ideone.com

yes, that´s exactly what i want to do.

Maybe i did not implemented it right.

I removed the "%huu" and the underscore loops. Could you please show me how to implement it.
Thank you very much!

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

void setup()
{
  pinMode(segmentClock, OUTPUT);
  pinMode(segmentData, OUTPUT);
  pinMode(segmentLatch, OUTPUT);

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

}

void loop()
{
  showNumber(474747); //Test pattern
}

//Takes a number and displays 6 numbers. Displays absolute value
void showNumber(long number)
{
  int digits[6];
  int digitsCounter = 0;
 
  while ( number > 0 && digitsCounter < 6 )
  {
    digits[digitsCounter++] = number % 10;
    number /= 10;
  }
 


    //Push the digits out to the display
  for (byte x = 0 ; x < 6 ; x++)
  {
    
      postNumber(digits[x], false); //Don't write a decimal
   
  }

  //Latch the current segment data - this causes display to show what's been clocked in
  digitalWrite(segmentLatch, LOW);
  digitalWrite(segmentLatch, HIGH); //Register moves storage register on the rising edge of RCK
}


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

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

  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
  }
}

Try

  //Push the digits out to the display
  for (byte x = 0; x < digitsCounter; x++)
  {
      postNumber(digits[x], false); //Don't write a decimal
  }

  // Leading spaces
  for (byte x = digitsCounter; x < 6 ; x++)
  {
      postNumber( ' ', false);
  }

That worked perfect.

But i don´t understand what and why it happens.
Could you please ad 1 or 2 comments or notes.

Thank you so much!

Not sure what to explain..? Maybe this is easier for you to understand

for (byte x = 0; x < 6; x++)
{
  if ( x < digitsCounter )
  {
    postNumber(digits[x], false); //Don't write a decimal
  }
  else
  {
    postNumber( ' ', false);
  }
}