4 x 7 segment display "ghosting"

Hi experts,

I controlled a 4 x 7 segment display with a 74HC595. This works fine, just the LED's from the previous number is still switched on at the next numer. They have less brigthness.
e.g. at position 1 number 1 is displayed and at position 2 number 2 is displayed.
Number obe is displayed perfect and at number two, the led "c" is still switched on.
Attached you find a picture to illustrate. Because of the multiplexing effect it is not very clear at the picture.

I would be really happy if someone could help me, I lost hours for trouble shooting :confused:

int taktPin = 8;      // SH_CP
int speicherPin = 9;  // ST_CP
int datenPin = 10;    // DS
byte einerStelle = 7, zehnerStelle = 6, hunderterStelle = 4, tausenderStelle = 5;

int zeit = 5;

byte wert0 = B11111101;   // 0
byte wert1 = B01100001;   // 1
byte wert2 = B11011011;   // 2
byte wert3 = B11110011;   // 3
byte wert4 = B01100111;   // 4
byte wert5 = B10110111;   // 5
byte wert6 = B10111111;   // 6
byte wert7 = B11100001;   // 7
byte wert8 = B11111111;   // 8
byte wert9 = B11110111;   // 9
byte wertF = B11100011;   // 

int PotWert,Punkt;

void setup() {
 pinMode(taktPin,OUTPUT);
 pinMode(speicherPin,OUTPUT);
 pinMode(datenPin, OUTPUT);
 pinMode(einerStelle, OUTPUT);
 pinMode(zehnerStelle, OUTPUT);
 pinMode(hunderterStelle, OUTPUT);
 pinMode(tausenderStelle, OUTPUT);
}

void loop() {
//PotWert = analogRead(3);
PotWert = 1121;
anzeige(PotWert);


}

void anzeige(int AnalogWert){

 byte einer, zehner, hunderter, tausender;
 tausender = int (AnalogWert/1000 % 10);
 hunderter = int (AnalogWert - tausender*1000)/100;
 zehner = int (AnalogWert - tausender * 1000 - hunderter *100)/10;
 einer = AnalogWert - tausender * 1000 - hunderter *100 - zehner *10;


//einer Stelle aktiv schalten

digitalWrite(einerStelle, HIGH);
digitalWrite(zehnerStelle, LOW);
digitalWrite(hunderterStelle, LOW);
digitalWrite(tausenderStelle, LOW);
//digitalWrite(9,HIGH);

schreibezahl(einer);                   //Anforderung der Anzeige der Zehnerstelle


//zehner Stelle aktiv schalten
if ((zehner == 0)&&(hunderter == 0)&&(tausender ==0))
 digitalWrite(zehner, LOW);
 else {
digitalWrite(einerStelle, LOW);
digitalWrite(zehnerStelle, HIGH);
digitalWrite(hunderterStelle, LOW);
digitalWrite(tausenderStelle, LOW);
//digitalWrite(9,LOW);

schreibezahl(zehner);                  // Anforderung der Anzeige Zehnerstelle
}
 
 //hunderter Stelle aktiv schalten
if ((hunderter == 0) && (tausender == 0))
 digitalWrite(hunderter, LOW);
 else {
digitalWrite(einerStelle, LOW);
digitalWrite(zehnerStelle, LOW);
digitalWrite(hunderterStelle, HIGH);
digitalWrite(tausenderStelle, LOW);
//digitalWrite(9,LOW);

schreibezahl(hunderter);                  // Anforderung der Anzeige Zehnerstelle
}

 
//tausender Stelle aktiv schalten
if (tausender > 0){
 digitalWrite(einerStelle, LOW);
 digitalWrite(zehnerStelle, LOW);
 digitalWrite(hunderterStelle, LOW);
 digitalWrite(tausenderStelle, HIGH);
// digitalWrite(9,HIGH);
schreibezahl(tausender);                  // Anforderung der Anzeige Zehnerstelle
}
else
 digitalWrite(tausenderStelle, LOW);
 
}

void schreibezahl(byte a) {
Serial.begin(9600);
Serial.print(a);

digitalWrite(speicherPin, LOW); // ST_CP
switch(a){
case 0:
 shiftOut(datenPin, taktPin, LSBFIRST, wert0);
 break;
case 1:
 shiftOut(datenPin, taktPin, LSBFIRST, wert1);
 break;
case 2:
 shiftOut(datenPin, taktPin, LSBFIRST, wert2);
 break;
case 3:
 shiftOut(datenPin, taktPin, LSBFIRST, wert3);
 break;
case 4:
 shiftOut(datenPin, taktPin, LSBFIRST, wert4);
 break;
case 5:
 shiftOut(datenPin, taktPin, LSBFIRST, wert5);
 break;
case 6:
 shiftOut(datenPin, taktPin, LSBFIRST, wert6);
 break;
case 7:
 shiftOut(datenPin, taktPin, LSBFIRST, wert7);
 break;
case 8:
 shiftOut(datenPin, taktPin, LSBFIRST, wert8);
 break;
case 9:
 shiftOut(datenPin, taktPin, LSBFIRST, wert9);
 break;
default:
 shiftOut(datenPin, taktPin, LSBFIRST, wertF);
break;
}
 digitalWrite(speicherPin, HIGH);
 delay(zeit);
}

number.jpg

This is a common mistake and easy to fix. It is sometimes called "ghosting".

But first, please read the forum rules and then edit your post above to correct the rules you broke.

Sorry Paul, I corrected mistakes which I recognize.

This is how you post a picture. It is not well explained in the rules, but you must first attach the picture to your post as you did earlier, post, copy the address of the picture, edit the post and use the picture icon to insert the picture into your post.

037d0b23123e3f4b88db85ba6c7d1d1ed812d8be.jpg

OK. The secret to avoid ghosting. You must turn off all digits, then shift out the segment pattern, then switch on the digit. If you do not switch off all the digits before shifting, you get the ghost digit appearing.

Let me know of you need more help.

Also, of you like, I can show you tricks to reduce your sketch down to around 25% of it's current length.

Thank you, I could improve it.

I really would like to get information how to reduce the code.

First, fix the ghosting! Is it gone?

One point worth considering. I see what appear to be display driver transistors on the breadboard. I am supposing that these are used to switch the common pin of each seven-segment display in turn. I once had a design using common-anode displays where the positive supply was switched, rather than switching zero volts (ie high-side rather than low-side switching). This required PNP transistors, driven by pulling down each transistor's base through a resistor. And it suffered ghosting despite ensuring the LED 'column' drive signals did not overlap.

It turned out the problem was the inherent capacitance of the base-emitter junction. For PNP transistors this is much higher than NPN, meaning the capacitance was preventing fast switching by effectively delaying transistor turn off. My solution in this case was simply to use FETs instead. I could also have tried staying with the PNP transistors and strapping a resistor across the base-emitter junction for faster capacitance discharge. Could this be the problem you are having?

Jim.

1 Like

Hello Paul,

yes the ghosting is gone. I changed the paramters in the code as you suggested. Thank you!

@Jim, thank you too.

Well done. Post the updated code. It might help others. And we can discuss those improvements I mentioned to make it shorter