[Solved] Ghost digits' on 4 digit miltiplexed display

Hi,

I was playing around with multiplexing and shift registers today and noticed something weird, every digit has a ghost on the digit on the left… Is this coding related or due to a bad display (it was included in a kit) or shift register?
Can’t seem to figure it out.
Thanks!

EDIT:
shift registry: sn74hc595n
display: 3491AS
resistors on display 220 ohm

forgot the code

int const numOfDigits = 4;
int d1 = 7;
int d2 = 5;
int d3 = 13;
int d4 = 11;
int DS_pin = 8;
int STCP_pin = 9;
int SHCP_pin = 10;
int count = 0;
int const numOfOutputs = 7;
int outputPins[numOfOutputs] = {d1, d2, d3, d4, DS_pin, STCP_pin, SHCP_pin};
int digitPins[numOfDigits] = {d1, d2, d3, d4};
int const numOfInputs = 2;
int inputPins[numOfInputs] = {2, 3};
int reading = LOW;
int debounceDelay = 30;
int inputState[numOfInputs] = {HIGH, HIGH};
int lastInputState[numOfInputs] = {HIGH, HIGH};
int inputFlag[numOfInputs] = {LOW, LOW};
int lastInputFlag[numOfInputs] = {LOW, LOW};
unsigned long lastDebounceTime[numOfInputs] = {0, 0};
int digits[numOfDigits] = {0, 0, 0, 0};


//      BBBBB
//     A     C
//     A     C
//      DDDDD
//     E     G
//     E     G
//      FFFFF   H

//{A, B, C, D, E, F, G, H} for every number
boolean registers[10][8] = {{1, 1, 1, 0, 1, 1, 1, 0}, {0, 0, 1, 0, 0, 0, 1, 0}, {0, 1, 1, 1, 1, 1, 0, 0}, {0, 1, 1, 1, 0, 1, 1, 0}, {1, 0, 1, 1, 0, 0, 1, 0}, {1, 1, 0, 1, 0, 1, 1, 0}, {1, 1, 0, 1, 1, 1, 1, 0}, {0, 1, 1, 0, 0, 0, 1, 0}, {1, 1, 1, 1, 1, 1, 1, 0}, {1, 1, 1, 1, 0, 1, 1, 0}};


void setup() {
  for (int i = 0; i < numOfInputs; i++) {
    pinMode(inputPins[i], INPUT);
    digitalWrite(inputPins[i], HIGH); //20k ohm pullup resistor
  }
  for (int i = 0; i < numOfOutputs; i++) {
    pinMode(outputPins[i], OUTPUT);
  }
  pinMode(DS_pin, OUTPUT);
  pinMode(STCP_pin, OUTPUT);
  pinMode(SHCP_pin, OUTPUT);
  Serial.begin(9600);
}

void setDigits() {
  digits[0] = count / 1000;
  digits[1] = (count % 1000) / 100;
  digits[2] = (count % 100) / 10;
  digits[3] = (count % 10);
}

void writeDisplay() {
  for (int j = 0; j < numOfDigits; j++) {
    digitalWrite(digitPins[j], LOW); //select digit
    digitalWrite(STCP_pin, LOW);
    for (int i = 7; i >= 0; i--) {
      digitalWrite(SHCP_pin, LOW);
      digitalWrite(DS_pin, registers[digits[j]][i]); //outputs segments to light up
      digitalWrite(SHCP_pin, HIGH);
    }
    digitalWrite(STCP_pin, HIGH);
    digitalWrite(digitPins[j], HIGH);
  }
}

void loop() {
  for (int i = 0; i < numOfInputs; i++) {
    reading = digitalRead(inputPins[i]);
    if (reading != lastInputState[i]) {
      lastDebounceTime[i] = millis();
    }
    if ((millis() - lastDebounceTime[i]) > debounceDelay) {
      if (reading != inputState[i]) {
        inputState[i] = reading;
        if (inputState[i] == LOW) {
          inputFlag[i] = HIGH;
        } else if (inputState[i] == HIGH) {
          inputFlag[i] = LOW;
        }
      }
    }
    lastInputState[i] = reading;  //enables rising edge/falling edge detection
  }

  if (inputFlag[0] == HIGH && inputFlag[1] == LOW) {
    if (inputFlag[0] != lastInputFlag[0]) {
      count++;
    }
  }

  if (inputFlag[1] == HIGH && inputFlag[0] == LOW) {
    if (inputFlag[1] != lastInputFlag[1]) {
      count--;
    }
  }
  lastInputFlag[0] = inputFlag[0];
  lastInputFlag[1] = inputFlag[1];

  if (count == 10000) {
    count = 0;
  }
  if (count == -1) {
    count = 9999;
  }
  setDigits();
  writeDisplay();
}

SOLVED

void writeDisplay() {
  for (int j = 0; j < numOfDigits; j++) {
    digitalWrite(STCP_pin, LOW);
    digitalWrite(digitPins[j], LOW);
    for (int i = 7; i >= 0; i--) {
      digitalWrite(SHCP_pin, LOW);
      digitalWrite(DS_pin, registers[digits[j]][i]); //outputs segments to light up
      digitalWrite(SHCP_pin, HIGH);
    }
    digitalWrite(digitPins[j], HIGH);
    digitalWrite(STCP_pin, HIGH);
  }
}

in stead of:

void writeDisplay() {
  for (int j = 0; j < numOfDigits; j++) {
    digitalWrite(digitPins[j], LOW); //select digit
    digitalWrite(STCP_pin, LOW);
    for (int i = 7; i >= 0; i--) {
      digitalWrite(SHCP_pin, LOW);
      digitalWrite(DS_pin, registers[digits[j]][i]); //outputs segments to light up
      digitalWrite(SHCP_pin, HIGH);
    }
    digitalWrite(STCP_pin, HIGH);
    digitalWrite(digitPins[j], HIGH);
  }
}

the problem was the order of sending and selecting digits. The digit was selected, with the old byte still active and this caused a faint shadow.

For people saying this is bad code: I coded my first ‘hello world’ less than a week ago!

Use CTRL T to format your code.
Attach your ‘complete’ sketch between code tags, use the </> icon in the posting menu.
[code]Paste your sketch here[/code]

larryd:

Use CTRL T to format your code.
Attach your ‘complete’ sketch between code tags, use the </> icon in the posting menu.
[code]Paste your sketch here[/code]

updated the post, sorry

Bad circuit + bad code.

PaulRB:
Bad circuit + bad code.

That helps.....

Probably bad code. Between selecting a digit and latching the shift register there should be no time but your code runs a loop to shift out the data.

Try the following:

  • Shift out the data
  • De-select all digits
  • Latch the shit register
  • Select one digit

Moshtaraq:
That helps.....

You asked if the display or shift register was the problem. They aren't.

PaulRB:
At least you are now informed. Do some research, see if you can figure out why.

Informed that it doesn't work? I concluded that myself lol. Saying that something doesn't work cause it doesn't work is not helpfull

Can't make my way through that murky code I am afraid!

"Ghost" digits simply cannot be due to any aspect of the LED display. It is always due to a foul-up in the code.

OK, you have the segments defined by a shift register and four pins for the digits. To display a digit, you need to:

  • Switch off the drive to the previous digit.
  • shift in the segment data for the new digit
  • latch the segment data for the new digit
  • switch on the drive to the new digit
  • Wait the multiplex time before the successive digit.

Note that it may be slightly more efficient to perform step 1 after step 2, but that requires "remembering" which is which, probably not worth it.

Note also that using current limit resistors per digit will mean the segment brightness varies with the number of segments lit. You should instead have current limit resistors per segment of eight times the value - i.e, 1k5.

And your notation of the segments is wrong. It should be:

//      AAAAA
//     F     B
//     F     B
//      GGGGG
//     E     C
//     E     C
//      DDDDD   H

See the datasheet:

Rintin:
shit register

I don't think there's anything wrong with the shift register.