High side switching of 7-seg display

Hi everyone, I've got some common cathode 7-seg displays with a Vf of 7.8V at 20mA and If max of 60mA (excl. decimal point but that's irrelevant), I want to make daisy chain-able modules using a shift register. I thought I could use TPIC6C595s but realised only after buying a tube that they only sink, they don't source.

The common anode equivalent of the display I'm using costs around 50% more and I need to make three 11-digit displays which will have a massive impact on the budget, so I'd like to think of a different solution. Is the best option a BJT-based 595 with darlington driver arrays on the outputs? Bearing in mind that I don't have a great deal of time to work on this and I'm most comfortable with doing this with SIPO shift registers (though BCD to 7-seg decoder ICs are also fine by me). The MAX7219/7221 are too expensive, it'd be cheaper to change from a CC to CA display.

Thanks!

How about the MIC5891?

1 Like

You may study the thread of this link for driving large CA-type 7-segment display devices.

So will there be any multiplexing, or will all the cathodes just be tied to ground?

These are anyway ruled out because their maximum voltage is 6v.

Since we dont all know what that is

I'm sure I've seen driver IC's for this application but I'm too idle to google for them.

Maybe someone might suggest a solution using mosfets (not my area)

1 Like

I'm repeating my suggestion of the MIC5891.

https://www.mouser.com/datasheet/2/268/MIC5891_8_Bit_Serial_Input_Latched_Source_Driver_D-3442109.pdf

It appears to be a high-voltage, high-current equivalent of the 595 latched shift register, but with open-emitter darlington outputs. Digikey and Mouser carry them, but they are not cheap. Still, I don't see another practical way to do this.

they look good Sherman but I've not used them.
would the OP need to provide level shifting for the input?

No the input is all normal:

"The CMOS inputs are compatible with standard
CMOS, PMOS, and NMOS logic levels."

And there's a separate input for the Load Supply, which can be up to 50V.

In theory, you could use a normal HC595 which could drive an NPN array, which could in turn drive a PNP array. That's assuming you could find those arrays. The MIC5891 is $3 and change, but anything else you do is probably going to cost nearly that, and take up a lot more space. Of course he's also going to need a resistor in series with each segment.

Actually, when you think about it, it's hard to see how this is going to work at all. 33 digits times 7 segments per digit is 231 segments. That's 29 8-bit shift registers. So it seems he would have to multiplex in some way to keep the chip count within reason. But it's not obvious how he would do that. I guess he could drive the common cathodes using the TPIC6C595s he already has, and then several MIC5891s to drive the anodes. But it seems like that would all take too long to prevent flickering. 33 digits is just a lot to deal with.

1 Like

@ShermanP You're a legend, thank you for the suggestion, thanks also to @johnerrington for sharing the datasheet for the TPIC6C595 for me, I had ruled it out so didn't feel it was worth posting but in hindsight it was.

I'll order a few MIC5891s, they aren't cheap but are much cheaper than switching to the CA version of the display and I'm sure they'll do the job. Once I've confirmed they'll work I'll consider how best to use them - I don't have 33 digits in a single daisy chain, I've got up to 11, possibly fewer, across three identical devices but still don't want to multiplex because I'll need to be able to photograph/film the displays without issue and 11 digits is still a lot. Given the cost though I would like to be able to repurpose the digits for future projects so adding the option of multiplexing to the module design would be a good idea, thank you.

Good to know, thanks, I saw the price first and that was enough to immediately rule them out so didn't get as far as looking at the spec.

If you don't multiplex, then even if you don't use the decimal point you're still looking at 10 shift register chips per 11-digit device. For all three devices, that's about $100 just for the chips. On the other hand, if you do multiplex all 11 digits, then each digit would be lit up only 9% of the time, which could produce flicker as well as video issues.

However, I did a video illustrating multiplexing by segment, instead of the normal by digit, which cycled through the seven segments one at a time, so each segment was lit up about 14% of the time. And the video shows no flicker with a refresh period of 2ms (about 71Hz). So maybe an 11-digit multiplex would still work fine.

I'm thinking you could use just one MIC5891 to drive the 7 segment anodes of all 11 digits in common, and then use two of the TPIC6C595 you already have to cycle through the common cathodes one at a time. You would just shift an "On" bit through the TPIC6C595's one clock at a time.

Will each 11-digit device have it's own MCU?

Edit: I should have said - my video was at 30fps. There might have been flicker at 60fps.

Thinking further about this, it seems to me that multiplexing is the way to go. Multiplexing by digit. Looking back at my work on the video, I ended up using a 3ms refresh interval without any flicker. But that's human eye flicker, and it might be different for still pictures or video. But you could easily reduce the interval to 2ms or 1ms without much more load on the processor than the millis() interrupt.

You would shift out the seven-anode pattern for the next digit by sending out one byte to the MIC5891 using SPI. That shifting would take place in the background during the refresh interval, so it wouldn't slow down the processor, or even other interrupts. Then when your 2ms timer interrupt triggers, you would disable /OE, latch the new value into the output register, and then re-enable /OE.

Then on the low side, while the high-side /OE is disabled, you would just do one clock cycle to the two cascaded TPIC6C595s to shift an "Off" bit into registers, and move the single "On" bit along to the next digit. But if you are at digit zero you would instead send an On bit to start the sequence again. The latch ("Strobe") input would be tied high so the input bits flow immediately to the outputs. And /OE would be tied low so it's always on.

So in the aggregate, you would need three chips plus seven resistors for each 11-digit device. And it would require four pins for the high side register - clock, data, latch and output enable - but just two pins for the low side - clock and data. So really, the load on the system, even at a fast refresh rate, would be very small, mainly because all the high-side shifting takes place automatically in the MCU's SPI peripheral.

So then the question is how fast you need to refresh to get good stills and video. I'm betting that won't be a problem. It would be for 33 digits, but not for 11.

I revised my code to use 11 segments and a refresh period of 0.5ms. Video at 60fps looks completely solid. But still pictures only work at shutter speeds of 1/160 sec or slower. At higher speeds, some of the segments show as dark in the picture but are actually lit up. This stands to reason because a shutter speed of, say, 1/200 sec would have the shutter open for 5ms, but 11 digits at 0.5ms each takes 5.5ms to go through them all. And that's not even counting the effects of the rolling shutter of a CMOS sensor.

So if you're taking pictures in bright light, you'd have to do something to get the shutter speed down - use the lowest possible ISO, and the smallest aperture. You could use an even faster refresh, but at some point you're doing nothing but servicing interrupts. Of course we don't know what processor you're using. Maybe something really fast would work well enough.

It just seems to be a daunting and expensive task to make it all continuous just so you can take still pictures.

Apart from the cost (which is within budget, as wasteful as it is), what else would you be concerned about if you executed it the way I was going to? I must admit I'm a little concerned about the power draw (not in a practical sense, rather because I've estimated a max possible draw of 5A and average of 3.5A which means 42-60W which feels like a lot) but I don't even know if multiplexing would help reduce that since I assume at like-for-like levels of perceived brightness you'd need to run the segments a bit hotter if you're multiplexing since they aren't in a steady state?

Speaking of which, I was planning on using an Arduino, probably an Uno but that's just because I have a drawer full of them. Yes, each counter will have its own MCU, each unit will be completely independent and identical (well, possibly except for the number of digits). The counters will have an RTC module each and they'll do a simple calculation on the date and time to derive the value to display, so they're basically doing nothing else.

You've given me a lot to think about and I massively appreciate you taking the time to write such detailed responses, thank you!

I don't think there would be much of a power difference to get the same average brightness. There would be more chips running in your original plan, but I doubt the total difference in idle current would be very significant. In either case, the choice of segment resistors would determine how bright it would be. While the multiplexed On current would be much higher, when it's on, I think you're right that average current would be about the same either way to get the same brightness. I don't know of any free lunches in that regard, particularly if we're talking about photographs. As for total power, 11 x 7 x 20mA is 1.54A, but that's assuming your LED segments don't need more than 20mA. Of course you can test that.

But I would worry about getting the cascade to work through 11 595 equivalents. I've never done more than two chips in sequence, and don't know how the 328P does with that. The Data line should work ok since it is effectively refreshed at each chip. But that's not the case for the Clock, Latch, and /OE lines, with your Uno switching 11 devices at the same time. You might need drivers for them, or maybe dedicate multiple GPIOs to them.

But at the cathode end it's very simple since you just tie them all to ground.

I guess the other thing is having to shift out 11 bytes of data anytime any digit changes.

I've done my multiplex tests on a Nano, which is the same processor as your Unos. But if you want really fast refresh times that would show up reliably in photos, you might have to switch to a much higher speed processor. Maybe the ESP32 would work, which I believe is 160 MHz, or 10 times the Uno. Then you could make the refresh period about as short as you need to. That's assuming the 595s will go really fast, which I think is the case - megahertz.

The ESP32 also has multiple SPI peripherals, so it might be possible to divide up the 11 digits into two groups of 6, at the expense of using an extra MIC per device. So you could effectively refresh the digits twice as often. I just don't have any experience with driving a 595 chip with SPI on the ESP32.

I modified my test sketch to to refresh the 11 segments, one every 100us. I also included the millis() ISR in mine, so millis() now bumps every 10th interrupt, which is confirmed in the blink loop(). And I have D10 going high at the beginning of the ISR, then back low at the end. This lets me use my scope to see how much time the ISR servicing takes up. This is on a Nano which of course is running at 16MHz.

ISR servicing takes up about 32% of the time, with the remaining 68% being available for loop() stuff. This assumes there's nothing else that uses interrupts. I don't think I2C for your RTC uses interrupts.

Using my DSLR, I get good stills at 1/1000 sec, but not at 1/1250. But if this is going to be indoors, 1/1000 sec should be plenty fast enough. Here's a picture taken at 1/1000.

What I don't have any experience dealing with is the long distances I assume are involved with your display. In your continuous setup I assume each chip would be close to its digit, so only the clock and latch lines (not /OE as I said before in error) would need to work over a distance, particularly the clock line which is the highest frequency.

But in my multiplex version, the lines carrying the segment current would be long, and if you used 100us refresh, if my math is right they would be switching relatively high currents at 10KHz. That may or may not be a problem. I just don't know. Maybe some of the EEs here can comment. You would put the Nano and the MIC chip in the middle of course, but even so there's a distance involved, and I don't know if you'd get ringing or whatever.

I guess the other concern about multiplexing all 11 digits is whether they would be bright enough, even with very low, or no, resistors. Do you have a feel for what the continuous current would be needed to make them bright enough?

So are you going to design the board? And could you post a link to your digits?

I don't know if @neema_t is still around, but for some reason this project continues to be interesting to me. I guess continuous DC drive is the safest solution, particularly for outdoors use, but I still wonder if multiplexing might work ok. Anyway, below is a sketch that tests a single digit for brightness and picture taking as if it were part of a display refreshing at 100us. It uses one MIC5891 on the anodes, one TPIC6C595 on the cathode, seven resistors, and an Uno. So it could be breadboarded just to see if it would be bright enough within the current limits of the chips and the display. It also combines the millis() generation routine that works better than the IDE version does.

/*
This code is intended to test the brightness and video/picture suitability of
an 11-digit common-cathode multiplexed 7-segment display.  The test uses only one
display digit, which is turned on 1/11th of the time.  It is assumed the segment
anodes are driven from a MIC5891, and the common cathodes by a TIPC6C595.
Segment resistors must also be used so current does not exceed permitted
maximums for the chips or the displays.

The refresh interrupt occurs every 100us, and new high-side data is shifted out
automatically by the SPI peripheral during the period between interrupts.

This should work for any microcontroller using the Atmega328P, including the Uno,
the Nano and the Pro Mini 5V 16MHz.

This code does not test the overall power dissipation of the two chips since it
only subjects them to 1/11th of the average current that would be seen in a full
11-digit display. However, the single test display digit behaves as it would in
a full setup.

Note that the TPIC6C595's maximum pulse current is 250mA, about 36mA per segment.
Resistors should be chosen accordingly.  To measure segment current accurately,
measure the voltage across the resistor with your scope, then calculate current.
*/

#include <SPI.h>

const byte DIGITS = 11;             //Number of digits used

const byte MILLIS_INCB = 10;        // interrupt every 100us at 16MHz
volatile byte milCount = 10;        // millis change every 10th interrupt

extern volatile unsigned long timer0_millis; //this defined in wiring.c

const int blink13Time = 500;        // flash D7 every second
unsigned long oldMillis = millis();
unsigned long newMillis = 0;

volatile byte nextDigit = DIGITS-1;
byte outByte;

const byte Latches = 5;             // latch pins of both chips connected to D5
const byte cathData = 8;
const byte cathClock = 9;
// anode data is SPI MOSI = 11
// anode clock is SPI SCK = 13
// /OE pins of both chips tied low

void setup() {

// Set up alternate interrupt for millis() and refresh

  pinMode(Latches,OUTPUT);
  pinMode(cathData,OUTPUT);
  pinMode(cathClock,OUTPUT);
  pinMode(7,OUTPUT);                         // Blink on D7
  digitalWrite(7,HIGH);

  cli();                            // disable interrupts while doing this

  TCCR0A = 0;                       // set entire TCCR0A register to 0
  TCCR0B = 0;                       // same for TCCR0B
  TCNT0  = 0;                       // initialize timer0 count to 0

  OCR0A   = (250/MILLIS_INCB) - 1;  // set top of counter for 100us interrupts
  TIMSK0 &= ~bit(TOIE0);            // disable overflow interrupt
  TCCR0A |= bit(WGM01);             // turn on CTC mode
  TCCR0B |= (bit(CS01)+bit(CS00));  // Set CS00&CS01 bits for prescaler = 64
  TIMSK0 |= bit(OCIE0A);            // enable timer compare interrupt

  sei();                            // enable interrupts

  pinMode(10,OUTPUT);               // Master Mode for SPI
  SPI.begin();                      // turn on SPI
  SPCR = 0x52;                      // set speed to fSYS/64 (full transfer = ~40us)
//  SPSR = 1;                         // inc speed to fSYS/32 if sending two bytes
}


void loop() {                       // flashes D7 for 1/2 second every second

  newMillis = millis();
  if ((newMillis - oldMillis) >= blink13Time) {
    oldMillis = newMillis;
    digitalWrite(7,!digitalRead(7)); // invert pin D7 state
  }
}

ISR(TIMER0_COMPA_vect) {            // this is the new ISR
                                    // it combines millis() and display refresh
  digitalWrite(Latches,HIGH);       // latch data already x-ferred - both chips
  digitalWrite(Latches,LOW);

  digitalWrite(cathData,LOW);       // prepare for next digit
  nextDigit++;
  if (nextDigit == DIGITS) {
    nextDigit = 0;
    digitalWrite(cathData,HIGH);    //  cathode off except for digit zero
  }

// This just outputs the character "8".
// Normally the segment pattern for the next digit would be sent
// such as "outByte = digitArray[nextDigit];"

  outByte = 0xFF;                   // testing full current ("8")
  SPDR = outByte;                   // shift-out to anode by SPI after ISR

  digitalWrite(cathClock,HIGH);     // clock the next digit cathode
  digitalWrite(cathClock,LOW);

  milCount--;                       // now do millis()
  if(milCount == 0) {
    timer0_millis++;
    milCount = MILLIS_INCB;
  }
}

The TPIC6C595 isn't actually rated to handle the 60mA x 7 of the display, So it might be necessary in the full circuit to add a third one, and use two inputs per digit CC.

Another possibility is to divide digits into groups of 6 and 5, and multiplex those simultaneously. You would need to add a second MIC5891, but no additional TPICs. And the Uno would just shift out two bytes instead of one. So that option would use 5 chips and 14 resistors, which is still better than 11 chips and 77 resistors. And it would provide double the brightness of the standard multiplex.

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