Suitable segement driver IC for multiplexed displays

Hi there!

I have the circuit depicted in the diagram below previously discussed here that is driving 6 seven segment displays, everything works fine although I do not like to multiplex via software as it is very prone to interference from other parts of the code which could introduce flickering therefore I would like to drive this circuit or create a new one using a dedicate IC such as MAX7219/7221, TM1637 etc.

Unfortuantely I do not have the datasheet for the displays the only things I know is that they are 3" common cathode and that by testing they seem to have a Vf of 12V.

Basically the circuit works that the digit and segment that need to be turned on need to be both high while there rest needs to stay low therefore I am not sure if a dedicated IC will work for this purpose.

I am open to suggestions, I am also wodering should I keep the current circuit and integrate shit registers or shoud I go with a different approach?

EDIT 1:

I am using is a custom 4809 board with a CS5530 ADC connected to SPI and 14 pins to drive the segments, not delays are used in the code and all the timers are handled by millis.

EDIT 2:

Code I have tried to avoid blocking code, the 4809 has different timers than 328 therefore I have used megaAVR_TimerInterrupt library but without great results.

#define USE_TIMER_0 true
#define TIMER0_INTERVAL_MS 2
#define TIMER0_FREQUENCY (float)(5.0f)
#define TIMER0_DURATION_MS 0 //(10 * TIMER1_INTERVAL_MS)
#define ADJUST_FACTOR ((float)0.99850)

#include "megaAVR_TimerInterrupt.h"
#include <SevSeg.h>

SevSeg display;

byte numDigits = 6;
byte digitPins[] = { 5, 6, 7, 8, 9, 10 };
byte segmentPins[] = { 11, 12, 13, 14, 15, 16, 37, 36 };  //  8, 9, 10, 15, 14, 13, 12, 11
byte hardwareConfig = N_TRANSISTORS;
bool resistorsOnSegments = true; 
bool updateWithDelays = false;
bool leadingZeros = false;
bool disableDecPoint = false;

void setup() {
  ITimer0.init();
  ITimer0.attachInterruptInterval(TIMER0_INTERVAL_MS * ADJUST_FACTOR, TimerHandler1,   TIMER0_DURATION_MS);

  display.begin(hardwareConfig, numDigits, digitPins, segmentPins, resistorsOnSegments, updateWithDelays, leadingZeros, disableDecPoint);
  display.setBrightness(10);

void loop() {
  display.setNumber(value);
}

void TimerHandler1() {
  display.refreshDisplay();
}

This should not be a problem if your code is written correctly. If you share your code, the forum may be able to assist with changes that would minimise flickering.

If there are some aspects of your code which for some reason cannot be easily changed to reduce the flickering, it may be appropriate to use the internal hardware timer of the Arduino to achieve precise timing and minimise flickering. The hardware timer interrupts the sketch at a precise interval and the interrupt routine can then multiplex the display.

It will be important to know the maximum segment current, so that you can maximise the brightness of the displays without risk of damaging them. Is there any way to know that? If not, I recommend you assume max of 20mA for safety.

I definitely do not recommend those!

You can look at TPIC6B595 for switching the cathodes and TBD62783A for switching the anodes.

1 Like

That is a very unconventional circuit for driving common anode displays. Anyway, the TPIC6B595 suggestion for the cathodes would also be my choice but I'd then use a MIC5891 shift register for the anodes. Both shift registers would be wired in the same chain. Drive the multiplexing by a hardware timer, not in the loop() to avoid flicker.
If you don't want any software multiplexing, then use six TPIC6B595 chips and drop the MIC5891.
15 volts rules out the MAX7219/7221option.

1 Like

Not necessarily. There is an application note for MAX7219 that demonstrates how to use external transistors/transistor arrays with the MAX7219 to allow this chip to multiplex higher voltage displays.

1 Like

I don't think it is unconventional. A bit old-fashioned, though. There are more modern components that could achieve the same thing with fewer components and with lower voltage drops, such as the ones you and I have already mentioned.

OK. I've just found it: https://pdfserv.maximintegrated.com/en/an/AN1196.pdf
But with higher voltages you end up adding so many external components that it loses its main advantage.

I have difficulty with that circuit as a solution for common anode displays. It is drawn upside down but F and G which are conventionally notations for segments and appear to be powered by PNP transistors from the high side (15 volts) implying that the common is the cathode.

EDIT

OH! I see. I followed the link where he started talking about common anode displays. In this post he is talking about common cathode.

1 Like

Unfortunately I was unable to find a datasheet for the displays, I had one spare and I did a test applying 0 to 12V without resistors and it had good brightness around 12, I will try the same resistor values with the new circuit at different voltage steps to try to find the sweet spot, I know this is a terrible practice but without datasheet will be impossible to know the specs for the diodes.

Thanks for the input but using a transistor array is a solution similar to the original circuit which takes too many pins off the MCU, therefore while I redesign the circuit I believe it would be good to use only 3/4 pins to drive the segments, perhaps I could use two daisy chained TPIC6B595, use one to drive the cathodes and the other to drive the TBD62783A connected to the anodes?

Yes the circuit is ancient it uses an AT89 and some Phillips BD138.

Yes I know it is terrible but with the transistor the right way the schematic was a mess.

Yes, I had initially mistaken the displays for CA but in fact are CC as the transistors are PNP.

I have drawn a new circuit with your suggestions combined which I like as this configuration only requires four pins from the MCU to drive the circuit.

I believe that the connections I have made are correct, the OE pins could be connected to ground as well if I wanted to save an extra pin but that is not a big deal, four pins is more acceptable than 14, which is what I have at the moment.

Please point out any mistakes I have made and if you have any further suggestions about the circuit! Thank you for the time you guys have taken so far!

Since the cathode selected is always going to be the next one, I wonder if if would be possible to replace the B595 with a counter of some kind that would handle the high current, and that would be clocked by the Latch signal. That way you would only have to shift out one byte instead of two on each refresh.

Logically it would be a counter that behaves like a CD4017 that activates the outputs one at a time, and can be set to reset at six, except it would have low outputs instead of high. It wouldn't need to be high voltage because of the Vf of the segments, but would need to be high current. Actually, you could use a CD4017 that would drive a ULN2003. But maybe there's a single chip that would work.

The CD4017 powers up in a random state, but you can clock it until it's at Q0 without having to dedicate a pin to reset it.

Yes, although I think you would need to attach pull-up resistors (to 5V) on the inputs of the TBD62783A. You could use a 74HC595 instead of the second TPIC6B595, then no pull-up resistors needed. Or MIC5891 as suggested above to replace TPIC6B595/74HC595 and TBD62783A, but watch out for the higher voltage drop (2~2.5V) you might encounter.

Thanks again for your input! Well if you reckon the voltage drop is too large, I prefer your 74HC595 option to drive the array without any additional components.

I have updated the schematic, please let me know what do you think if you would modify anything or if I have made any mistakes!

vs

I wonder what kind of improvement you want to achieve if you use any kind of shift registers and blocking code with a multiplexed display.

Imho a dedicated LED driver chip (Max7219, TM1637, HT16K33...) AND additional components to meet the Vf are the only way you will get around your blocking code.

@floxia
You may consider using the following design (Fig-1) approach (shown for one sement of a large CC-type 7-segment display device) using TPIC6C596 power buffer IC.


Figure-1:

I didn't say that. But it could be. It depends on your segments and supply voltage.

Let's say your segments have 7.5V forward voltage and your power supply is 12V. You need to drop the other 4.5V. If your driver chips have a very low voltage drop, then almost all of the 4.5V must be dropped by the segment series resistors. But if your driver chips drop 2.5V, you still have 2V for your series resistors to drop, which should be ok I think.

But if your segments have 9V forward voltage, you only have 3V to drop. If your driver chips drop 2.5V, you have only 0.5V for your series resistors to drop, which is not enough for safety.

I don't think you've said which Arduino you're using. Anyway, if you aren't using its SPI for anything else, then you can use it to shift out data to the shift registers in the background. You set up a timer to interrupt at the refresh rate, and all your ISR has to do is start the transfer, then exit. The actual transfer will take place between refresh interrupts in the background. It won't be blocking, and there should never be any flickering.

If you have two bytes to shift out, the first ISR can enable an interrupt on completion of the transfer of the first byte, and the ISR for that interrupt would start transmision of the second byte, then disable further SPI interrupts. So it's still all in the background, and not blocking.

What I usually do is include a new millis() update in the refresh ISR, so both functions happen on the same interrupt. The 1ms interrupt rate is usually fast enough for four digits. I don't know about six.

Good point, my intention was to avoid software multiplexing but for what I am seeing does not seem an easy solution with high voltage displays therefore I am taking the chance to at least improve the circuit to use fewer pins instead of the 14 that I am currently using.

Thanks for your input but this solution seems to be using a high number of pins and components therefore I do not think it is a great improvement over the circuit I am already using.

Yes makes sense, thanks for explaining in details!

Sorry I will edit the post to make it clearer, I am using a 4809 custom board I have made, I am using the SPI bus at the moment, the board has 3 SPI buses but I have not tried the pins swap and I am not sure whether I'll be able to to swap the pins in the loop.

I have also updated the post to show my workaround I had previously tried to use a timer interrupt to avoid disturbing the multiplexing, but by something like SoftwareSerial notorious for being blocking as a test still disrupted the multiplexing so I had abandoned that idea as I though it did not workout as expected, perhaps I used it the wrong way?

It appears the 4809 only has one SPI peripheral and one USART, so if you're using both already, plus software serial, then I suspect SPI won't be a good option for handling the refresh. But my understanding is that software serial disables interrupts for extended periods, and if that's true, you may have difficulty doing any kind of refresh without some flickering.

You'd just use shiftOut() to send the 2 bytes to the shift registers which control the display.
ShifOut() is not particularly fast because it uses digitalWrite() in the background but 2 bytes should pass quickly enough to have no noticeable visible effect.

Anyway, correct use of the latch/strobe should minimise any visual disturbance during the refresh of the display.

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