Ones Digit flickers on SevSeg Display

Hello,

My program “drops” one LED from the top of an hourglass into the bottom each minute. After 60 minutes my Seven Segment display will advance its display by one.

All seems to be working well (I have it sped up for testing), but the problem is when the number on the SevSeg changes from 9 to 10, 10 to 11, and 11 to 12. After the change, the ones digit flickers terribly for about 10 seconds. The frequency of the flicker then begins to slow down until the number becomes solid after a total of about 20 seconds.

I have a 220 ohm resistor on pins 1,3,4,6,7,8, and 9 (not using decimal point pin 2). Do I need one on 5 and 10 (Common Cathode) as well?

Any suggestions will be appreciated.

My code is below.

Thank you,

Michael

// FastLED - Version: Latest
/*
     Shift register SN74hc595 pin 1 to digital display 9
                               2                    8
                               3                    6
                               4                    7
                               5                    4
                               6                    1
                               7                    not used
                               8                    grnd
                               9                    not used
                               10 to +5V
                               11 to arduino 4
                               12 to arduino 7
                               13 to grnd
                               14                   not used
                               15 to digital display 3
                               16 to +5V
*/

#include <FastLED.h>
#define LED_Pin 2
#define NUM_LEDS 120
CRGB leds[NUM_LEDS];
#define color1  CRGB::Red;
#define color2  CRGB{230, 126, 34};
#define color3  CRGB::Yellow;
#define color4  CRGB::Green;
#define color5  CRGB::Blue;
#define color6 CRGB::Indigo;
#define color7 CRGB::Black;

int HourTen = 0; // ten digit for hours
int HourOne = 1; // one digit for hours
unsigned long prevTime  = 0;
unsigned long currentTime = millis();
unsigned int HrInterval = 6000;
unsigned int MinInterval = 1000;
unsigned MinCount = -1;
int y = 0;
int ResetHourglass = 0;

int DATA = 3; // Data Pin (pin 14 on the 74HC595)
int LATCH = 7; // Latch Pin (pin 12 on the 74HC595)
int CLOCK = 4; // Clock Pin (pin 11 on the 74HC595)

int TensDigit = 5; // tens digit for hours (HourTen)
int OnesDigit = 6; // one digit for hours (HourOne)

int Digit[10] = {64, 121, 36, 48, 25, 18, 2, 120, 0, 24};

void setup() {
  int DATA = 3;
  int LATCH = 7;
  int CLOCK = 4;

  int HourTen = 0; // ten digit for hours
  int HourOne = 1; // one digit for hours


  pinMode(LATCH, OUTPUT);
  pinMode(DATA, OUTPUT);
  pinMode(CLOCK, OUTPUT);
  pinMode(TensDigit, OUTPUT);
  pinMode(OnesDigit, OUTPUT);

  FastLED.addLeds<WS2812, LED_Pin, GRB>(leds, NUM_LEDS);
  FastLED.setBrightness(10);
  FastLED.clear();
  FastLED.show();

  //  Initialize all LEDs
  for (int x = 0; x < 10; x++) {
    leds[x] = CRGB::Red;
    leds[x + 10] = CRGB{230, 126, 34};
    leds[x + 20] = CRGB::Yellow;
    leds[x + 30] = CRGB::Green;
    leds[x + 40] = CRGB::Blue;
    leds[x + 50] = CRGB::Indigo;
    FastLED.show();
  }

  pinMode(LATCH, OUTPUT);
  pinMode(DATA, OUTPUT);
  pinMode(CLOCK, OUTPUT);
  pinMode(TensDigit, OUTPUT);
  pinMode(OnesDigit, OUTPUT);

  //Initializing the Hourglass
  for (int x = 0; x < 10; x++) {
    leds[x] = CRGB::Red;
    leds[x + 10] = CRGB{230, 126, 34};
    leds[x + 20] = CRGB::Yellow;
    leds[x + 30] = CRGB::Green;
    leds[x + 40] = CRGB::Blue;
    leds[x + 50] = CRGB::Indigo;
  }
  for (int x = 60; x < 120; x++) {
    leds [x] = CRGB::Black;
  }
  FastLED.show();
  Serial.begin(9600);
}

void loop() {
  currentTime = millis();
  if (currentTime - prevTime >= MinInterval == true) {
    if (MinCount < 59) {
      MinCount++;
    }
    else {
      MinCount = 0;
      ResetHourglass = 1;
    }
    prevTime = currentTime;
  }

  if (ResetHourglass > 0) {
    //Initializing the Hourglass
    for (int x = 0; x < 10; x++) {
      leds[x] = CRGB::Red;
      leds[x + 10] = CRGB{230, 126, 34};
      leds[x + 20] = CRGB::Yellow;
      leds[x + 30] = CRGB::Green;
      leds[x + 40] = CRGB::Blue;
      leds[x + 50] = CRGB::Indigo;
    }
    for (int x = 60; x < 120; x++) {
      leds [x] = CRGB::Black;
    }
    FastLED.show();
    ResetHourglass = 0;
    HourOne++;
  }
  MinDisp();
  HrDisp();

}
void MinDisp() {

  leds[60 - MinCount] = CRGB::Black;
  y = 9 - MinCount;
  if (y >= 0) {
    leds[y] = color2;
    leds[119 - MinCount] = color1;
    FastLED.show();
  }
  y = 19 - MinCount;
  if (y >= 0) {
    leds[y] = color3;
    if (MinCount > 9 && MinCount < 20) {
      leds[119 - MinCount] = color2;
    }
    FastLED.show();
  }
  y = 29 - MinCount;
  if (y >= 0) {
    leds[y] = color4;
    if (MinCount > 19 && MinCount < 30) {
      leds[119 - MinCount] = color3;
    }
    FastLED.show();
  }
  y = 39 - MinCount;
  if (y >= 0) {
    leds[y] = color5;
    if (MinCount > 29 && MinCount < 40) {
      leds[119 - MinCount] = color4;
    }
    FastLED.show();
  }
  y = 49 - MinCount;
  if (y >= 0) {
    leds[y] = color6;
    if (MinCount > 39 && MinCount < 50) {
      leds[119 - MinCount] = color5;
    }
    FastLED.show();
  }
  if (MinCount > 49) {
    leds[119 - MinCount] = color6;
    FastLED.show();
  }
}

void HrDisp() { //Displays the hour
  if (HourOne == 10) { // Reset to 0 after counting for 9 hours.
    HourOne = 0;
    HourTen = 1;
  }
  if (HourTen == 1 and HourOne == 3) { //13:00 becomes 1:00
    HourTen = 0; // Resets hours ten digit to 0
    HourOne = 1;
  }

  digitalWrite(LATCH, LOW);
  shiftOut(DATA, CLOCK, MSBFIRST, Digit[HourOne]);
  digitalWrite(LATCH, HIGH);
  display1();
  delay(5);

  if (HourTen != 0) {
    digitalWrite(LATCH, LOW);
    shiftOut(DATA, CLOCK, MSBFIRST, Digit[HourTen]);
    digitalWrite(LATCH, HIGH);
    display2();
    delay(5);
  }
}
//End of Void HrDisp()

void display1()
{
  digitalWrite(TensDigit, 1);
  digitalWrite(OnesDigit, 0);
}
void display2()
{
  digitalWrite(TensDigit, 0);
  digitalWrite(OnesDigit, 1);
}

Wouldn't you need to only show the hour when you change the value of it ?

    FastLED.show();
    ResetHourglass = 0;
    HourOne++;
  }
  MinDisp();
  HrDisp();

}

You are just updating the LED's so fast that the letters start flashing

I have a 220 ohm resistor on pins 1,3,4,6,7,8, and 9 (not using decimal point pin 2). Do I need one on 5 and 10 (Common Cathode) as well?

Hmm no i don't think so, if you leave the resistor out you burn the LED's, (so if it were not enough you would have done so already) but if all the LED's have one on the anode that's fine. I personally have a transistor on the Common cathode that i use to set the brightness.

Thank you, Deva_Rishi,

Deva_Rishi:
Wouldn't you need to only show the hour when you change the value of it ?

    FastLED.show();

ResetHourglass = 0;
   HourOne++;
 }
 MinDisp();
 HrDisp();

}



You are just updating the LED's so fast that the letters start flashingHmm no i don't think so, if you leave the resistor out you burn the LED's, (so if it were not enough you would have done so already) but if all the LED's have one on the anode that's fine. I personally have a transistor on the Common cathode that i use to set the brightness.

You are correct, I would only need to change the SevSeg as the hours change. Are you suggesting I call the HrDisp() function only when the hour changes?
Which LED's am I updating too fast, the LED's in the SevSeg or the LED's that make up the hourglass? Assuming you mean the SevSeg, would my idea to call up the HrDisp() function only as the hours change take care of that?
I very much appreciate your help.
Michael

Which LED's am I updating too fast, the LED's in the SevSeg or the LED's that make up the hourglass? Assuming you mean the SevSeg,

The leds in the SevSeg. The bitshifter has only just received the data, and then gets reset again.

would my idea to call up the HrDisp() function only as the hours change take care of that?

whose idea ? yes of course. I would only update anything that has new data, so only call HrDisp() when the hours have changed, only call MinDisp() when the minutes have changed.

Thank you again, Deva_Rishi.

I apologize for my wrong choice of words. I should have said "my understanding” rather than "my idea".

You have been most helpful and I am truly grateful for the time you've taken to help me learn.

Michael

One problem is that you are leaving the One's cathode turned on while you set the segments for the Ten's digit. That means the new Ten's value will show up briefly on the One's digit before you turn off the One's cathode and turn on the Ten's cathode. TURN BOTH CATHODES OFF AFTER THE "delay(5)" LINES.

  digitalWrite(LATCH, LOW);
  shiftOut(DATA, CLOCK, MSBFIRST, Digit[HourOne]);
  digitalWrite(LATCH, HIGH);
  display1();  // Turn on the Ones cathode
  delay(5);
  //////////////////. Add a line here to turn off both cathodes!

  if (HourTen != 0) {
    digitalWrite(LATCH, LOW);
    shiftOut(DATA, CLOCK, MSBFIRST, Digit[HourTen]);
    digitalWrite(LATCH, HIGH);  // Update the segment data
    display2(); // Turn on the Tens cathode
    delay(5);
    //////////////////. Add a line here to turn off both cathodes!