Large Digit Display (Arduino Nano Every) 4, 5, 6, 8, 9 not displaying correctly.

Hey internet people!

I’ve got a few of these large-digit displays and drivers and I seem to be having a weird issue. I’m using a Arduino Nano Every and I verbatim copied the example code from the guide to start playing around with them. Unfortunately, the numbers are not displaying correctly. As mentioned in the title, specifically its numbers 4, 5, 6, 8, and 9 that are not displaying properly in that segment F is not lighting on these numbers. However, the number 0, segment F lights correctly so I don’t believe this is a hardware issue. I’ve got 4 of these displays and drivers and they all behave the same.

I suspect this has something to do with the bitwise operations as I believe I remembered reading that these can be AVR-specific?

I’ve tried “manual” displaying each segment and everything works, but when combining segments f and g, f just won’t turn on.

From the example code,

#define f 1<<1

#define g 1<<2

And from my understanding, f would be 00000010 in binary and g would be 00000100?

So for example, 4, which is segments f, b, g, and c would be 01100110?

Here is the example code:

    /*
 Controlling large 7-segment displays
 By: Nathan Seidle
 SparkFun Electronics
 Date: February 25th, 2015
 License: This code is public domain but you buy me a beer if you use this and we meet someday (Beerware license).

 The large 7 segment displays can be controlled easily with a TPIC6C594 IC. This code demonstrates how to control
 one display.

 Here's how to hook up the Arduino pins to the Large Digit Driver

 Arduino pin 6 -> CLK (Green on the 6-pin cable)
 5 -> LAT (Blue)
 7 -> SER on the IN side (Yellow)
 5V -> 5V (Orange)
 Power Arduino with 12V and connect to Vin -> 12V (Red)
 GND -> GND (Black)

 There are two connectors on the Large Digit Driver. 'IN' is the input side that should be connected to
 your microcontroller (the Arduino). 'OUT' is the output side that should be connected to the 'IN' of addtional
 digits.

 Each display will use about 150mA with all segments and decimal point on.
*/

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

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

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);

  int x = 0;
  while(1)
  {
    if(x == 9)
      postNumber(x, true); //Show decimal
    else
      postNumber(x, false);

    digitalWrite(segmentLatch, LOW);
    digitalWrite(segmentLatch, HIGH); //Register moves storage register on the rising edge of RCK
    delay(500);

    x++;
    x %= 10; //Reset x after 9

    Serial.println(x); //For debugging
  }
}

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

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

  //Serial.print("number: ");
  //Serial.println(number);

  for (byte x = 0 ; x < 2 ; x++)
  {
    int 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
  }
}

I’m a little out of my depths here and would appreciate some guidance or input on what I might be able to do to make these displays work. I don’t know if the problem is in the bitwise operations or in the writing of the data to the shift register.

Thanks!

Be VERY careful with operator precedence in C/C++. See https://en.cppreference.com/w/c/languag … precedence

I don’t know what you intended with the following line, but it is probably not doing what you expect, because “&” has higher precedence than “<<”

digitalWrite(segmentData, segments & 1 << (7 - x));

What that operation does it to move bit zero of “segments” to a different bit position, throwing the rest away.

Use parentheses to make the meaning absolutely clear. This line selects a particular bit from the variable “segments” and sets the rest to zero. Is that what you wanted?

digitalWrite(segmentData, segments & (1 << (7 - x)));

Suggestion: Use parentheses in #define statements, to avoid such problems.

Replace constructs like this

#define g 1<<2 

with

#define g (1<<2) 

My mistake, “<<” has higher precedence than bitwise AND “&”, so the line in question is probably correct.