16 segment 8digit multiplexing using 3 shift register [GHOSTING]

Am using 3x 74HC595 (2 drive NPN darlinkton transistors[BD679] connected to the display segments and 1 drive PNP darlinkton transistors[BDX34C] which connect digits to the ground).

Am driving display in this order:

  • Send 0x00 to 3. SR [turn off all digits
  • Send eq. 0xF3 to daisy chained SR
  • Send 0x01 to 3. SR [turn on 1. digit
  • delay(1) which will be replaced with millis() in future

Everything is in for loop which refresh entire display

I tried to PULLUP base of the PNP but it doesn't work (just dimm segments)

Any ideas what should i do to prevent ghosting?

Schematic_16-8SEG.pdf (160 KB)

That's a fascinating circuit design. I think it's the most complex circuit for driving led segment displays that I have seen. All those Darlingtons and opto-isolators. Can you please explain how you arrived that this design? Why are the pnp Darlingtons connecting the digits to ground instead of Vcc? Did you consider using an ht16k33 chip?

Ghosting can often be caused by the software, so please post that also. The forum guide in the sticky post will show you how to post code correctly on the forum.

I was wondering how to drive NPN and somehow separate 12v and 5v soo i decided to try optocoupler and it work.

//SEGMENT SR
int latchPin = 2; 
int dataPin = 3;
int clockPin = 4;

//DIGIT SR
int latchPin2 = 5;
int dataPin2 = 6;
int clockPin2 = 7;

//          0         1     2       3       4       5       6       7     8       9       A       B       C     D       E       F       G       H       I     J      K      L     M       N       O     P       Q       R         S      T      U      V       W      X       Y        Z
int anh[] = {0x44FF, 0x0C, 0x8877, 0x883F, 0x888C, 0x90B3, 0x88FB, 0xF, 0x88FF, 0x88BF, 0x88CF, 0x2A3F, 0xF3, 0x223F, 0x80F3, 0x80C3, 0x8FB, 0x88CC, 0x2233, 0x7C, 0x94C0, 0xF0, 0x5CC, 0x11CC, 0xFF, 0x88C7, 0x10FF, 0x98C7, 0x88BB, 0x2203, 0xFC, 0x4480, 0x50CC, 0x5500, 0x88BC, 0x4433};
int digitpick[] = {0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80}; //turn ON each digit
void setup() 
{
  pinMode(latchPin, OUTPUT);
  pinMode(clockPin, OUTPUT);
  pinMode(dataPin, OUTPUT);
  
  pinMode(latchPin2, OUTPUT);
  pinMode(clockPin2, OUTPUT);
  pinMode(dataPin2, OUTPUT);
}
    
   
void loop()
{
  //output 12345678 on display
  out(1,2,3,4,5,6,7,8);
}
 
void out(int n1,int n2,int n3,int n4,int n5,int n6,int n7, int n8)
{
   int xx[] = {n1,n2,n3,n4,n5,n6,n7,n8};
    for(int i = 1; i < 9; i++)
    {
        DIGIT(digitpick[0]); 
        NUM(anh[xx[i-1]]);
        DIGIT(digitpick[i]);
        delay(1);
    }
}

void NUM(int num)
{
    digitalWrite(latchPin, LOW);
    shiftOut( dataPin, clockPin, MSBFIRST, (num >> 8) );
    shiftOut( dataPin, clockPin, MSBFIRST, num );
    digitalWrite(latchPin, HIGH);
}

void DIGIT(int num)
{
    digitalWrite(latchPin2, LOW);
    shiftOut( dataPin2, clockPin2, MSBFIRST, num );
    digitalWrite(latchPin2, HIGH);
}

Maybe something with timing/delay ?

Make it a little simpler. The following circuit will work just fine. Take a look at the Rhom chips BD18337EFV-M BD18347EFV-M, they will do a nice job. This response is to help you get started in solving your problem, not solve it for you.
Good Luck & Have Fun!
Gil

12v and 5v? Your schematic did not indicate two different supply voltages.

Can you tell us more about the display? What forward voltage and current do the segments need?

Perhaps tpic6b595 would be a good chip to consider. Two chips per digit, 8 in total, may be able to drive your display with no need for multiplexing.

I forget to mention that im usig LED strips.

1 digit require ~ 1.5A.

And yes, my transistors are overkill but i used what i had on hand

Look like this

This is how you should post a picture on the forum:


I built a clock similar to your project. The segments were 12V strips with 6 leds per strip. The digits were only 7 segment. I used a tpic6b595 per digit and did not multiplex.

I took another look at your driver circuits.

High side:

NPN darlinkton transistors[BD679]

To switch the anodes, you need PNP, not NPN. I can't figure out, reading the data sheet, if BD679 is PNP or NPN. To switch on a PNP, you need current to flow out of its base. How can that happen here?

Low side:

PNP darlinkton transistors[BDX34C] which connect digits to the ground

BDX34C are NPN, not PNP. NPN is what you need for driving the segment cathodes.


To switch on an NPN darlington, you need current to flow into it's base. How can that happen here?

Konisz:
Any ideas what should I do to prevent ghosting?

Are you saying you are actually getting ghosting?

Ghosting is caused by using bipolar transistors which you saturate - as you need to in order to minimise switching losses. Even worse is that you are using Darlingtons which have intrinsic switching losses.

Sorry, but your whole design is hopeless! :astonished: You mention 1.5 A per digit and 16 segments. I take that to indicate each segment requires about 100 mA. A TPIC6B595 will comfortably handle 8 segments; two per digit, all chained to be controlled by three Arduino pins. No multiplexing so a bright, flicker and ghosting-free display.

Konisz:
And yes, my transistors are overkill but I used what I had on hand

Quaint as that is, I am sorry, but this is just a total design disaster. :roll_eyes:

Please, just go and get the TPIC6B595s and "cut your losses". It will be worth it in the long run. :grinning:

Thank you very much everyone, I will try to use TPIC6B595. One question, do I think right when it comes to sending data to 16 SR?

int TT[] = {...} //Truth table [0..9, A..Z]

void loop() {

OUTPUT(TT[1],TT[23]....);


}

void OUTPUT(int n1,int n2,int n3,int n4,int n5,int n6, int n7,int n8)
{
    digitalWrite(latchPin, LOW);
[...]
    shiftOut( dataPin, clockPin, MSBFIRST, (n5 >> 56) ); //DIGIT 5
    shiftOut( dataPin, clockPin, MSBFIRST, (n5 >> 48) ); 

    shiftOut( dataPin, clockPin, MSBFIRST, (n4 >> 40) ); //DIGIT 4
    shiftOut( dataPin, clockPin, MSBFIRST, (n4 >> 32) ); 

    shiftOut( dataPin, clockPin, MSBFIRST, (n3 >> 24) ); //DIGIT 3
    shiftOut( dataPin, clockPin, MSBFIRST, (n3 >> 16) ); 

    shiftOut( dataPin, clockPin, MSBFIRST, (n2 >> 24) ); //DIGIT 2
    shiftOut( dataPin, clockPin, MSBFIRST, (n2 >> 16) ); 

    shiftOut( dataPin, clockPin, MSBFIRST, (n1 >> 8) ); //DIGIT1
    shiftOut( dataPin, clockPin, MSBFIRST, n1 );

    digitalWrite(latchPin, HIGH);
}

Or again my imagination went too far?

Or maybe connect everything i want to output into 1 chain and then send it ?

shiftOut( dataPin, clockPin, MSBFIRST, (n5 >> 56) ); //DIGIT 5

n5 is an int, so only 16 bits in size. Shifting it by 56 in either direction will give zero! Try using the highByte() and lowByte() arduino functions.

For example

Int value = 0xEF5F;

Int H=HighByte(value);
Int L=LowByte(value);

ShiftOut( [...], H); //shift 0x5F
ShiftOut( [...], L); //shift 0xEF

That is how it should looks?

Yes, or just:

Int value = 0xEF5F;

ShiftOut( [...], HighByte(value)); //shift 0x5F
ShiftOut( [...], LowByte(value)); //shift 0xEF

For some reason I am unable to quote on an iPad?

Anyway, to expand upon Paul's response, the easy way to remember how to switch transistors is in the designation... In order to switch on, an NPN requires a positive signal on its base with respect to the emitter. A PNP requires a negative signal on its base with respect to its emitter. You see the relationship?