Multiplexing vs separate shift registers

good day guys.

i'm working on a bubble hockey game project that has a total of 14 7 segment displays on the scoreboard.

i've already designed my circuit using 74HC595 shift registers in conjunction with CD4511 bcd decoders to operate the segment displays but now im reading about multiplexing, and curious as to which i should use for the final project.

multiplexing looks like more code with for loops etc, but less chips overall, the way i've done it, its not alot of code with no loops, but obviously chip heavy with one shift register and 2 decoders for each pair of segment displays.

i need to be able to update the displays as fast as possible and return to the main loop to continue game play.

if im understanding multiplexing correctly, it looks like i have to continuously refresh the display to be able to show the numbers where they need to be? which seems like alot of time over all where either a shot on goal might be missed, or the display might "glitch" as the shot/goal/etc sensors are being activated and their associated functions are called.

i guess i'm just looking for guidance as to which method would be better suited for the project.

I'd use I2C controlled 7segment displays.

alesam: I'd use I2C controlled 7segment displays.

firstly i havent dabbled into the iic world yet, though im going to have to at some point if i plan on doing some of the things i want to do with it....

secondly, a quick search i can only find 4 digit iic displays. are they available as 2 digit or single digit?

my scoreboard has mostly 2 digit displays on in.

additionally, it looks like the iic displays are ultimately multiplexed, which still brings me to the question, is multiplexing right for this project.

leonbourassa: I'm working on a bubble hockey game project that has a total of 14 7 segment displays on the scoreboard.

Right. Now before I make any further comments, I need to know how large you want the displays.

If you want large displays, then I bow out except to point out you should be using TPIC6B595s or similar (for common anode) rather than antique CD4511 chips (which are for common cathode displays).

If just small displays, you should be using these types: |500x500 You can drive quite a number (at least 8) of these 8-digit displays from just three pins (as you can from the TPIC6B595 or your 74HC595s) but the multiplexing is all performed for you.

Back to you! :grinning:

Paul__B: Right. Now before I make any further comments, I need to know how large you want the displays.

...

Back to you! :grinning:

They are small, 14ish mm common cathode displays, but they are separated into different areas of the scoreboard.

2 digits each for home and away score, home and away shots on goal, period, and then 4 for the time clock.

so 4 digit displays wont work except for the clock.

right now, the way i have it all set up with my simulator, i only use 3 pins, in addition to 5v and gnd, and update all the displays with a few lines of code that only get called once per second (to update the time) or additionally if a goal or shot on goal occurs.

Not sure what you are doing with a "simulator". If you have the displays, then you can wire them to a couple of MAX219 PCBs which are dirt cheap. Each one drives 8 digits. Use these kits: |500x500 Ignore the matrix LED; you have the MAX7219 wired to a nice little durable PCB, you just wire your displays to it.

You can also get two digit displays or - even easier actually - you can just use the four digit ones from the socketed version of the module I cited earlier by pulling them off and wiring them back to the PCB - three of those boards (six displays of four or two digits) would do it all for you - just ignore the extra digits on each side! |500x500

It's an interesting question. If I understand correctly, you are using 14 individual digits driven by 21 chips. I would hate to have to breadboard that. But yes, with any form of multiplexing, the flicker problem arises. We watch TV at 30 fps, and most movies are still 24 fps, but for reasons I don't really understand the common target refresh rate for digitial displays is 60 Hz to guarantee there will be no flicker or even shimmer. That means if you are turning on one digit at a time, that digit is on only 1/14 of the time, so the overall refresh rate will have to be 840 times per second, or essentially once per milli, to give an individual digit a 60 Hz refresh rate. There is a chance that will conflict with other functions, but on the other hand the actual time to do a refresh is usually very short - on the order of tens of microseconds.

A microprocessor can usually handle multiplexing a couple of digits, or even four, with no problem, but at some point on the way to 14 digits it starts to make more sense to transfer the display operation to another chip(s) which devotes its full time to the displays, and actually you have done that in a way with your 21 chips. The MAX7219 that Paul__B referred to is another solution, and I believe it handles 8 digits, so you would need two of them, which is a lot better than 21. And as he says, they would do the multiplexing for you.

But on the chance that there might be an intermediate solution, could you tell me how many pins you could reasonably devote to the display function, how much current one of your displays draws when displaying "8" brightly enough to suit you, and whether you need to use any of the decimal points? Also, have you already bought all this stuff?

ShermanP:
It’s an interesting question. If I understand correctly, you are using 14 individual digits driven by 21 chips. I would hate to have to breadboard that. But yes, with any form of multiplexing, the flicker problem arises. We watch TV at 30 fps, and most movies are still 24 fps, but for reasons I don’t really understand the common target refresh rate for digitial displays is 60 Hz to guarantee there will be no flicker or even shimmer. That means if you are turning on one digit at a time, that digit is on only 1/14 of the time, so the overall refresh rate will have to be 840 times per second, or essentially once per milli, to give an individual digit a 60 Hz refresh rate. There is a chance that will conflict with other functions, but on the other hand the actual time to do a refresh is usually very short - on the order of tens of microseconds.

A microprocessor can usually handle multiplexing a couple of digits, or even four, with no problem, but at some point on the way to 14 digits it starts to make more sense to transfer the display operation to another chip(s) which devotes its full time to the displays, and actually you have done that in a way with your 21 chips. The MAX7219 that Paul__B referred to is another solution, and I believe it handles 8 digits, so you would need two of them, which is a lot better than 21. And as he says, they would do the multiplexing for you.

But on the chance that there might be an intermediate solution, could you tell me how many pins you could reasonably devote to the display function, how much current one of your displays draws when displaying “8” brightly enough to suit you, and whether you need to use any of the decimal points? Also, have you already bought all this stuff?

Some of the stuff i have already bought, some I have on its way along with my arduinos.

This project started as a repair job on an old bubble hockey game, where i was working on replacing all of the ICS (at some point i decided that chasing the problems in the original board would be far more time consuming than just replacing everything since it had been repaired at least a half dozen times since the 80s.

once i did that, and found that the original ROM was damaged, and unable to be fully read, with no hope of finding the original to rewrite it, i decided to start from scratch with arduino.

I started by duplicating the original scoreboard in tinkercad to be able to test my code with it, with the intent on reusing it. which then as things do, turned into a case of “If im rewriteing the whole thing, why not make it do MORE than the original?”

and so as it were, the scoreboard grew from 6 individual digits (scores and period), to the current 14. (double sided, so in actuality, 28 total)

i plan to reuse the existing harness that runs from the control board to the top of the scoreboard, it carries 12v for the lights, 5v for the scoreboard, both from the main power supply, a ground, and 4 pins for communication with the scoreboard.

I have started looking at the MAX ICs the last day or two when i discovered that newer versions of the game actually use the MAX chips on their scoreboards. Im still not too far in to change things, and im sure the MAX code would likely be similar to what i have with minimal changes.

im not a total stranger to electronics, and coding, was a software developer in another life, and been repairing my own circuitry since i was a teen. just never really stopped to fully understand what the ICs did until the last year or so, so its been a fun learning experience.

thanks for your comment which actually helped to answer my original question without proposing 4 digit displays that arent suited for this particular project. the refresh is what i was concerned most about, as there are points where triggers are activated which interrupt the code, and wait for a second trigger to be active before resuming, in such a case where for example, maybe to goal sensor was activated, but the puck jammed and didn’t make it to the center ice sensor allowing the resume, the scoreboard refresh would be interrupted.

So based on your answer, my best option would appear to be using the MAX chip, and saving that, stay with my existing setup.

One factor you didn’t mention is power requirements. Decoded, direct-drive displays require current for all segments/LEDs for all the time the time they are illuminated. Multiplexing reduces the continuous power requirement to just those on at any given moment.*

Consider wiring requirements as well, There is a sweet spot between interface, # conductors and power requirements. If you intend to photograph or film the displays, you also need to work out the best refresh rate to avoid flicker/ blinking.

  • the layout, and bussing of the individual LEDs will affect the lowest current achievable.... but worth exploring. Along with (100% duty cycle multiplexing), there may be more flexibility for TDM/PWM dimming of individual display elements.

lastchancename: One factor you didn’t mention is power requirements. Decoded, direct-drive displays require current for all segments/LEDs for all the time the time they are illuminated. Multiplexing reduces the continuous power requirement to just those on at any given moment.*

Consider wiring requirements as well, There is a sweet spot between interface, # conductors and power requirements. If you intend to photograph or film the displays, you also need to work out the best refresh rate to avoid flicker/ blinking.

  • the layout, and bussing of the individual LEDs will affect the lowest current achievable.... but worth exploring. Along with (100% duty cycle multiplexing), there may be more flexibility for TDM/PWM dimming of individual display elements.

the 5v for the scoreboard is powered by the original 300watt power supply, not the arduino itself, so theres lots of power available to drive everything.

You’re probably ok, but if there are a LOT of lit elements, keep an eye on voltage drop over your display interconnect wiring.

Here is a partial view of my scoreboard layout, i haven't added my shots on goal displays yet.

as you can see, on a breadboard, it would be a nightmare, which is where a simulator comes in handy. the other nice thing is being able to export to eagle to layout my actual PCB

Yeah... Looking at that, Assuming all the displays are close to each other, I’d definitely use multiplexing. 90% of the wiring will be on custom display PCBs.

If there is a need to ‘remote’ the displays - e.g. a gantry over the playing field, use a second processor (Arduino?) as a display controller, and send the display data from the game controller to that over a local 3-wire serial link.

Even using MAX 7219s for each block of digits, you can buss the SPI and really simplify the wiring and component count on the display subsystem.

P.S. add a buzzer for quarter/ half time etc!

leonbourassa: thanks for your comment which actually helped to answer my original question without proposing 4 digit displays that aren't suited for this particular project.

I am not sure what you mean by this. For a two digit display, you simply use a four digit module with the unwanted digits masked behind your scoreboard cutout. It is actually cheaper that way, as well as making the wiring much simpler.

leonbourassa: the refresh is what i was concerned most about, as there are points where triggers are activated which interrupt the code, and wait for a second trigger to be active before resuming, in such a case where for example, maybe to goal sensor was activated, but the puck jammed and didn't make it to the center ice sensor allowing the resume, the scoreboard refresh would be interrupted.

With MAX7219s, the refresh is not your concern. The whole display is refreshed 80 times per second, there are very few situations where you would notice that as the assembly is not moving.

In any case, you do not use microprocessor interrupts for this sort of project. The loop() code runs continuously, cycling many thousand of times per second. Decisions are made according to the various inputs and branches taken according to various "switches" or "states". This is called "state machine" coding; there are no busy waits and no "while"s. No use of the "delay()" primitive either.

leonbourassa: I have started looking at the MAX ICs the last day or two when i discovered that newer versions of the game actually use the MAX chips on their scoreboards.

Of course they do! :grinning:

Paul__B: use a four digit module with the unwanted digits masked behind your scoreboard cutout. It is actually cheaper that way,

doing that takes unnecessary space on the PCB.

With MAX7219s, the refresh is not your concern. The whole display is refreshed 80 times per second, there are very few situations where you would notice that as the assembly is not moving.

this is what im likely going to rework to use, the modern version of this game uses the same chip

In any case, you do not use microprocessor interrupts for this sort of project. The loop() code runs continuously, cycling many thousand of times per second. Decisions are made according to the various inputs and branches taken according to various "switches" or "states". This is called "state machine" coding; there are no busy waits and no "while"s. No use of the "delay()" primitive either.

actually, interrupts are exactly what you would use in this type of project. the whole point is to be able to capture a trigger exactly when it happens, not hope that it gets caught by the loop function which is busy handling other things. If you've ever played bubble hockey, triggers an be tripped and released almost within a microsecond of each other as a puck is shot across the playing surface by aggressive players. the act of scoring a goal involves the shot sensor, goal sensor, and puck ready sensor all being activated in less than a half second (exact time im sure i could time out programatically if i wanted to) but it happens faster than you would think. with the process of monitoring the sensors, the coin slots, the music, the time, etc, theres alot going on where a shot or goal could be missed. if it will work without interrupts i wont use them, but depending on how fast everything actually works once i get the hardware, it may become necessary.

doing that takes unnecessary space on the PCB.

You don’t have to use a 4-digit displaymodule, just the chip, and nail on as many (1-4) displays as you need. Or one chip, across two 2-digit displays that are relatively close to each other.

lastchancename: P.S. add a buzzer for quarter/ half time etc!

An asynchronous sound module will be part of the project playing music and sounds throughout the game and in response to the triggers. if everything works as expected, its going to be a hell of an upgrade to the original.

im ordering the 7219s as we speak.

so how would i update my setsegment function to work with the 7219?

right now this is how i update my displays.

//takes a segment ID, value to set the segments to, 
//and a boolean whether to remove the leading zero from the value
void setSegment(int segmentID, int nValue, bool trimZero){

  //converts the digits (nValue) to an 8bit binary code representing the first and second digits
  byte digits = dec_to_bcd(nValue,trimZero); 
  
  // figure out which segment is changing
  switch (segmentID){
  case SEG_HOME_SCORE:
    bHomeScore=digits;
   break;
  case SEG_AWAY_SCORE:
    bAwayScore=digits;
    break;
  case SEG_PERIOD:
    if(nValue==4 || nValue==5){
      bPeriod=B11100000; // Set the display to show Ot (requires 74LS47 segment decoder)
    }
    else{
      bPeriod=digits;
    }
    break;
   case SEG_MINUTES:
    bMinutes=digits;
    break;
   case SEG_SECONDS:
    bSeconds=digits;
    break;
    
  }
   digitalWrite(latchPin, LOW); // Get the shift registers ready to take input
  
  // send the values into the shift registers
   shiftOut(dataPin, clockPin, MSBFIRST, bSeconds);
   shiftOut(dataPin, clockPin, MSBFIRST, bMinutes);
   shiftOut(dataPin, clockPin, MSBFIRST, bPeriod);
//shiftout(dataPin, clockpin, MSBFIRST, bAwayShots);
//shiftout(dataPin, clockpin, MSBFIRST, bHomeShots);
   shiftOut(dataPin, clockPin, MSBFIRST, bAwayScore);
   shiftOut(dataPin, clockPin, MSBFIRST, bHomeScore);
   
  // lock the values in and output to the segments
   digitalWrite(latchPin, HIGH);
  
}

Assuming you're going to use MAX7219's - the easy way is to use an off-the-shelf library Same idea as shift registers - daisy chain the number of chips you want to use - and shift 'em out.

They're pretty easy to drive manually, but if someone else has done good work - you may as well see if i solves your need.

The actual code would be very similar if they're daisy chained in the same way, or if you have to split the shift lines - you have to choose which clock pin you're going to shake.