Arduino with 7-segment display and potentiometer and display is flickering

so i have the following Arduino code that takes the input of 2 buttons A and B and uses a shift register to make shift the data into its output LEDs binary number but I made it in such a way that the output is divided into 2 4-bits to count both A and B which is working very fine on its own and then the count is also displayed on a 7 segment display in hexadecimal which is also working very fine but i wanted to add a method to multiplex through the 7 segments and also added a potentiometer to change the delay of the multiplexing and display how it works but when i added the potentiometer into this, the LEDs start flickering sometimes and also when i use button B, the count keeps switching between displaying count A or B each click instead of just staying at B... also this switching happens regardless if there's a potentiometer or not... so here's the code:

int dataPin = 6;
int latchPin = 7;
int clockPin = 8;
int resetButtonPin = 11;
int clearPin = 2;
int extraButton = 12;

int buttonPinA = 9; 
int buttonPinB = 10; 

byte LEDsAllOff = 0x00;
byte LEDsAllOn = 0xFF;
byte LEDs2 = 0b10101010;
byte LEDs3 = 0b01010101;
byte LEDs4 = 0b11101111;

int buttonAState = LOW;
int lastButtonAState = LOW;

int buttonBState = LOW;
int lastButtonBState = LOW;

int resetButtonState = 0;
int lastResetButtonState = 0;

int countA = 0;
int countB = 0;
int maxCount = 15;
bool displayCountA = true; // Flag to alternate between countA and countB
int delayTime = 1000;

// 7-segment display pins
int segmentPins[] = {5, A1, A2, A3, A4, A5, 3}; // A1 to A5 for a to g, 3 for f, 5 for a
int decimalPointPin = 4; // Pin for the decimal point
int poten = A0;
int interval = 1;

// Segment patterns for digits 0-F
byte digitPatterns[] = {
  0b00000000, // 0
  0b00000110, // 1
  0b0111011, // 2
  0b00101111, // 3
  0b01100110, // 4
  0b01101101, // 5
  0b01111101, // 6
  0b00000111, // 7
  0b01111111, // 8
  0b01101111,  // 9
  0b01110111, // A
  0b01111100, // b
  0b01011001, // C
  0b00111110, // d
  0b01111001, // E
  0b01110001  // F
};

void setup() {
  Serial.begin(9600);
  pinMode(dataPin, OUTPUT);
  pinMode(latchPin, OUTPUT);
  pinMode(clockPin, OUTPUT);
  pinMode(resetButtonPin, INPUT_PULLUP);

  pinMode(buttonPinA, INPUT_PULLUP);
  pinMode(buttonPinB, INPUT_PULLUP);

  pinMode(clearPin, OUTPUT);
  digitalWrite(clearPin, HIGH); // Ensure SRCLR is high to enable shift register
  pinMode(decimalPointPin, OUTPUT); // Initialize pin for decimal point


  // Initialize 7-segment display pins
  for (int i = 0; i < 7; i++) {
    pinMode(segmentPins[i], OUTPUT);
  }
}

void updateShiftRegister(int valueA, int valueB) {
  byte combinedValue = (valueA << 4) | (valueB & 0x0F);
  digitalWrite(latchPin, LOW);
  shiftOut(dataPin, clockPin, LSBFIRST, combinedValue);
  digitalWrite(latchPin, HIGH);
}

void clearShiftRegister() {
  digitalWrite(clearPin, LOW);  
  delay(1);                     
  digitalWrite(clearPin, HIGH); 
  updateShiftRegister(0, 0);  
}


void displayDigit(int digit, bool decimalPoint) {
  byte pattern = digitPatterns[digit];
  for (int i = 0; i < 7; i++) {
    digitalWrite(segmentPins[i], (pattern >> i) & 0x01); // Turn on the current segment
    delay(interval); // Small delay to allow the segment to be visible
    digitalWrite(segmentPins[i], LOW); // Turn off all segments 
  }
}


void loop() {
  // int potValue = analogRead(poten);
  // // Map the potentiometer value to a suitable delay range (e.g., 1 to 100 milliseconds)
  // interval = map(potValue, 0, 1023, 1, 100);

    if (displayCountA) {
      displayDigit(countA, false);
    } else {
      displayDigit(countB, true);
    }

  buttonAState = digitalRead(buttonPinA);
  buttonBState = digitalRead(buttonPinB);
  resetButtonState = digitalRead(resetButtonPin);

  // Check if button A is pressed
  if (buttonAState == HIGH && lastButtonAState == LOW && countA + countB < maxCount) {

    displayCountA = displayCountA;
    countA++;
    updateShiftRegister(countA, countB);
    delay(200); // Debounce delay
  
  }
  lastButtonAState = buttonAState;

  //check if button B is pressed
  if (buttonBState == HIGH && lastButtonBState == LOW && countA + countB < maxCount) {

    displayCountA = !displayCountA;
    countB++;
    updateShiftRegister(countA, countB);
    delay(200);
    }
  lastButtonBState = buttonBState;

  // Check if the reset button is pressed
  if (resetButtonState == HIGH && lastResetButtonState == LOW) {
    countA = 0;
    countB = 0;
    clearShiftRegister();
    displayDigit(0 ,false); // Display 0 on reset
    delay(delayTime);
  }
}

what's this for ??

should you use

    displayCountA = true;

and

    displayCountA = false;

Using a potentiometer with 7-segment display causes flickering - Using Arduino / LEDs and Multiplexing - Arduino Forum

@runaway_pancake flag one of the topics as cross-posting.

Thanks.
They are too busy trolling.

so i have the following Arduino code that takes the input of 2 buttons A and B and uses a shift register to make shift the data into its output LEDs binary number but I made it in such a way that the output is divided into 2 4-bits to count both A and B which is working very fine on its own and then the count is also displayed on a 7 segment display in hexadecimal which is also working very fine but i wanted to add a method to multiplex through the 7 segments and also added a potentiometer to change the delay of the multiplexing and display how it works but when i added the potentiometer into this, the LEDs start flickering sometimes and also when i use button B, the count keeps switching between displaying count A or B each click instead of just staying at B... also this switching happens regardless if there's a potentiometer or not... so here's the code:

int dataPin = 6;
int latchPin = 7;
int clockPin = 8;
int resetButtonPin = 11;
int clearPin = 2;
int extraButton = 12;

int buttonPinA = 9; 
int buttonPinB = 10; 

byte LEDsAllOff = 0x00;
byte LEDsAllOn = 0xFF;
byte LEDs2 = 0b10101010;
byte LEDs3 = 0b01010101;
byte LEDs4 = 0b11101111;

int buttonAState = LOW;
int lastButtonAState = LOW;

int buttonBState = LOW;
int lastButtonBState = LOW;

int resetButtonState = 0;
int lastResetButtonState = 0;

int countA = 0;
int countB = 0;
int maxCount = 15;
bool displayCountA = true; // Flag to alternate between countA and countB
int delayTime = 1000;

// 7-segment display pins
int segmentPins[] = {5, A1, A2, A3, A4, A5, 3}; // A1 to A5 for a to g, 3 for f, 5 for a
int decimalPointPin = 4; // Pin for the decimal point
int poten = A0;
int interval = 1;

// Segment patterns for digits 0-F
byte digitPatterns[] = {
  0b00000000, // 0
  0b00000110, // 1
  0b0111011, // 2
  0b00101111, // 3
  0b01100110, // 4
  0b01101101, // 5
  0b01111101, // 6
  0b00000111, // 7
  0b01111111, // 8
  0b01101111,  // 9
  0b01110111, // A
  0b01111100, // b
  0b01011001, // C
  0b00111110, // d
  0b01111001, // E
  0b01110001  // F
};

void setup() {
  Serial.begin(9600);
  pinMode(dataPin, OUTPUT);
  pinMode(latchPin, OUTPUT);
  pinMode(clockPin, OUTPUT);
  pinMode(resetButtonPin, INPUT_PULLUP);

  pinMode(buttonPinA, INPUT_PULLUP);
  pinMode(buttonPinB, INPUT_PULLUP);

  pinMode(clearPin, OUTPUT);
  digitalWrite(clearPin, HIGH); // Ensure SRCLR is high to enable shift register
  pinMode(decimalPointPin, OUTPUT); // Initialize pin for decimal point


  // Initialize 7-segment display pins
  for (int i = 0; i < 7; i++) {
    pinMode(segmentPins[i], OUTPUT);
  }
}

void updateShiftRegister(int valueA, int valueB) {
  byte combinedValue = (valueA << 4) | (valueB & 0x0F);
  digitalWrite(latchPin, LOW);
  shiftOut(dataPin, clockPin, LSBFIRST, combinedValue);
  digitalWrite(latchPin, HIGH);
}

void clearShiftRegister() {
  digitalWrite(clearPin, LOW);  
  delay(1);                     
  digitalWrite(clearPin, HIGH); 
  updateShiftRegister(0, 0);  
}


void displayDigit(int digit, bool decimalPoint) {
  byte pattern = digitPatterns[digit];
  for (int i = 0; i < 7; i++) {
    digitalWrite(segmentPins[i], (pattern >> i) & 0x01); // Turn on the current segment
    delay(interval); // Small delay to allow the segment to be visible
    digitalWrite(segmentPins[i], LOW); // Turn off all segments 
  }
}


void loop() {
  // int potValue = analogRead(poten);
  // // Map the potentiometer value to a suitable delay range (e.g., 1 to 100 milliseconds)
  // interval = map(potValue, 0, 1023, 1, 100);

    if (displayCountA) {
      displayDigit(countA, false);
    } else {
      displayDigit(countB, true);
    }

  buttonAState = digitalRead(buttonPinA);
  buttonBState = digitalRead(buttonPinB);
  resetButtonState = digitalRead(resetButtonPin);

  // Check if button A is pressed
  if (buttonAState == HIGH && lastButtonAState == LOW && countA + countB < maxCount) {

    displayCountA = displayCountA;
    countA++;
    updateShiftRegister(countA, countB);
    delay(200); // Debounce delay
  
  }
  lastButtonAState = buttonAState;

  //check if button B is pressed
  if (buttonBState == HIGH && lastButtonBState == LOW && countA + countB < maxCount) {

    displayCountA = !displayCountA;
    countB++;
    updateShiftRegister(countA, countB);
    delay(200);
    }
  lastButtonBState = buttonBState;

  // Check if the reset button is pressed
  if (resetButtonState == HIGH && lastResetButtonState == LOW) {
    countA = 0;
    countB = 0;
    clearShiftRegister();
    displayDigit(0 ,false); // Display 0 on reset
    delay(delayTime);
  }
}
  • Always show us a good schematic of your proposed circuit.
    Show us good images of your ‘actual’ wiring.
    Give links to components.

Arduino with 7-segment display and potentiometer and display is flickering - Using Arduino / LEDs and Multiplexing - Arduino Forum

I merged both threads


@abdelrahman666 Your two topics on the same or similar subject have been merged.

Cross-posting is against the Arduino forum rules. The reason is that duplicate posts can waste the time of the people trying to help. Someone might spend a lot of time investigating and writing a detailed answer on one topic, without knowing that someone else already did the same in the other topic.

Please create one topic only for your question and choose the forum category carefully. If you have multiple questions about the same project then please ask your questions in the one topic as the answers to one question provide useful context for the others, and also you won’t have to keep explaining your project repeatedly.

Repeated duplicate posting could result in a temporary or permanent ban from the forum.

Could you take a few moments to Learn How To Use The Forum. It will help you get the best out of the forum in the future.

Thank you.

apologies for not following the rules, i will make sure to not do this next time... should i delete the two posts and post a new one with everything correct and schematics + components used? or edit one of them? or delete one and edit other?

it wasn't there in the beginning i only added this thinking it might solve the switching problem

No, the topics are merged now, post your schematics etc here.

I don't think this function is necessary. You clear all the outputs with with a pulse to the clear pin, but then you immediately shift out 8 bits which are all zero, which has the same effect. Suggest deleting this function, connecting the clear pin of the shift register to 5V and freeing up that Arduino pin.

I guess this is the cause of the flickering.

You are only lighting one segment at a time, then switching the segments off again. Why not switch
on all that you need, and leave them until you need to change them?

the purpose of this is to implement multiplexing to display the number on the led... before that yes it directly switched on all the led's at once but i made it this way to multiplex but for some reason the multiplexing causes the problems in the post to happen

The purpose of multiplexing is to reduce the number of pins/wires required to illuminate all your display segments. You have 7 segments and 7 pins. No multiplexing is necessary and would give no advantage.

I know in this case multiplexing is practically useless, and that multiplexing is usually done in 7 segment displays by having multiples segments wired to the same data lines and only one is allowed to work at a time, but in this project I wanted to showcase how multiplexing works by tricking the eye in lighting one segment at a time on one display. but if this is hard or troublesome to implement I won't pursue this further. thank you...

Where is lastResetButtonState updated?

Did you miss a ! here?