Go Down

Topic: [Solved] Ghost digits' on 4 digit miltiplexed display (Read 431 times) previous topic - next topic

Moshtaraq

Jun 11, 2019, 09:53 pm Last Edit: Jun 12, 2019, 10:45 am by Moshtaraq
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
Code: [Select]

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

Code: [Select]

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:
Code: [Select]

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!

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]




No technical PMs.
If you are asked a question, please respond with an answer.
If you are asked for more information, please supply it.
If you need clarification, ask for help.

Moshtaraq




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

PaulRB



Rintin

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

PaulRB

#6
Jun 12, 2019, 12:08 am Last Edit: Jun 12, 2019, 12:10 am by PaulRB
That helps.....
You asked if the display or shift register was the problem. They aren't.

Moshtaraq

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

Paul__B

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:
Code: [Select]
//      AAAAA
//     F     B
//     F     B
//      GGGGG
//     E     C
//     E     C
//      DDDDD   H

See the datasheet:

PaulRB

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

Go Up