What Am I Doing Wrong? 74HC595 + 7 Segment LED Displays

Hi! I'm new to Arduino and trying to build my first project but having some difficulties and I think it might be a code issue, unless I've missed something silly with the wiring.

The project is a simple button pressing game that can add up and display scores on 3x LED seven-segment displays - for showing scores of 0 to 999. You can view the code and simulation here: Button Banger - Wokwi ESP32, STM32, Arduino Simulator

I don't know what I'm doing wrong, I think it should work. Any help would be greatly appreciated.

  • Pin 13 is the low true OE’ (output enable) pin, you have it floating.
  • In real life LEDs require current limiting resistors !
1 Like
  • Looks like your segments are inverted.

  • A zero has the perimeter LEDs OFF when they should be ON.

  • Invert the 7 segments when updating the display.

Hmm, that isn't working.

Can you elaborate on the "rules" of how to play?

And also what the display should show and what it is showing.

  • What did you do with OE’ ?

Did you change something?

Sorry yes, you can run the simulation and press any of the buttons for yourself. You can only press 3 buttons and then the game ends showing the total score. It waits for 3 seconds before allowing you to press any buttons again (starting a new game).

You have not connected the 3 shift registers in a chain. They are all connected in parallel, so the 3 displays will always show the same digit, which is the last digit shifted out.

2 Likes
  • Your switch code should be looking at when a switch changes state not the switch level.

Aha! Yes the shift registers were connect in parallel, not daisy changed. I've updated the wiring now to what I think is correct but the displays are still garbled. At least they all show something different now however:

  • Do you understand what this means ?
    Your switch code should be looking at when a switch changes state not the switch level.

  • Pin 13 needs to be enabled/disabled accordingly.

  • Do you understand what this means ?
    Looks like your segments are inverted.
    A zero has the perimeter LEDs OFF when they should be ON.
    Invert the 7 segments when updating the display.

Your table " byte segments[] = {" is inverted.
Where there is 0, put 1 and where there is 1, put 0.

1 Like

Because you did not do anything about the points made by @LarryD in post #3. Now he has needed to repeat that advice.

Sometimes, less experienced and knowledgeable forum members will give incorrect or useless advice on the forum. But when that happens, more experienced forum members will usually step in. That hasn't happened in this topic...

Or use the ~ operator to invert all bits before shifting them out.

Your simulate using this "table";

byte digitToSegments(int digit) {
  // Lookup table for segment values for each digit
  byte segments[] = {
    B11000000, // 0
    B11111001, // 1
    B10100100, // 2
    B10110000, // 3
    B10011001, // 4
    B10010010, // 5
    B10000010, // 6
    B11111000, // 7
    B10000000, // 8
    B10010000  // 9
  };
  return segments[digit];
}

1 Like

Also you are sending the digits in the wrong order for your daisy-chain wiring. You need the units to appear on the right-hand display, so you need to send that first.

Alternatively, rather than change the code, change the wiring so the so that the right-hand digit's shift register is connected directly to the Arduino and the middle and left-hand digit's registers are chained to the right-hand one.

You'll want to figure out what @LarryD means by

Your switch code should be looking at when a switch changes state not the switch level.

but for now, the delay(200) should allow the sketch to function.

The delay just means you have to get off the switch within 200 milliseconds, and can not possibly press switches faster than 5 times a second.

With the addition of '~' in line 137, the displays are fine. Same as @PaulRB's idea but applied at another place, which makes the function return the proper byte:

  return ~segments[digit];  // ~ flip all bits... easier then editing the table!

The pin 13 (/OE) on the shift registers may function correctly in the simulator, but not IRL, same as the LED needing a series current limiting resistor.

Output enable

Connect to GND if not used.

From the wokwi page for the part.

a7

1 Like

I didn't actually say where to use the ~. Only that it should be before shifting the data out.

But I was also thinking that the digitToSegments() function is unnecessary. The array could be a global constant and the displayScore() function could access it directly.

Haha, yes I see. I musta thought "right before" and TBH the last place I saw was when I finiched reading the sketch.

a7