Hi everyone,
I'm working on a project that involves six 4-digit 7-segment displays, each controlled by CD4094B shift registers in a daisy chain configuration. All the displays share the same data, clock, and latch pins (connected to an Arduino). The displays are showing numbers correctly, but I'm facing a flickering issue whenever the numbers are updated. I've made some changes to the code, which have significantly reduced the flicker, but it’s still noticeable and I would like to eliminate it completely.
Here are the details of my setup:
- The displays are updated via the
shiftOut()
function. - I'm using a single set of clock, data, and latch pins for all displays.
- I buffer the data and update all displays in one go, latching the data afterward.
- Despite these optimizations, there’s still some flickering during updates.
I would like to avoid using separate clock or latch pins for each display, as I want to conserve I/O pins.
Has anyone experienced similar issues or have any suggestions on how to achieve a flicker-free display update?
#include <Arduino.h>
// Define shared pins for all shift registers
const int latchPin = 10;
const int clockPin = 13;
const int dataPin = 2;
// Segment patterns for digits 0-9
const byte segmentData[] = {
0b00111111, // 0
0b00000110, // 1
0b01011011, // 2
0b01001111, // 3
0b01100110, // 4
0b01101101, // 5
0b01111101, // 6
0b00000111, // 7
0b01111111, // 8
0b01101111 // 9
};
// Number of digits per display
const int numDigits = 4;
// Number of displays
const int numDisplays = 6;
// Array to hold the data to be displayed
byte displayBuffer[numDigits * numDisplays] = {0};
void setup() {
// Set shared pins as output
pinMode(latchPin, OUTPUT);
pinMode(clockPin, OUTPUT);
pinMode(dataPin, OUTPUT);
}
void loop() {
// Update the buffer with the numbers to be displayed
updateDisplayBuffer(3030, 6); // Update sixth display
updateDisplayBuffer(2021, 5); // Update fifth display
updateDisplayBuffer(1015, 4); // Update fourth display
updateDisplayBuffer(7893, 3); // Update third display
updateDisplayBuffer(4564, 2); // Update second display
updateDisplayBuffer(1238, 1); // Update first display
// Send the buffered data to the displays
updateDisplays();
delay(1000); // Wait 1 second before updating again
}
// Function to update the buffer for a specific display
void updateDisplayBuffer(int number, int display) {
// Calculate the starting position in the buffer for the specific display
int startShiftRegister = (display - 1) * numDigits;
// Flag to indicate if a non-zero digit has been encountered
bool hasNonZeroDigit = false;
// Store the digits in the buffer from most significant to least significant
for (int i = numDigits - 1; i >= 0; i--) {
int digit = number / pow(10, i);
digit %= 10;
// Suppress leading zeros
if (digit != 0 || hasNonZeroDigit || i == 0) {
hasNonZeroDigit = true;
displayBuffer[startShiftRegister + (numDigits - 1 - i)] = segmentData[digit];
} else {
// If it's a leading zero and hasn't encountered a non-zero digit, turn off the segments
displayBuffer[startShiftRegister + (numDigits - 1 - i)] = 0b00000000; // Turn off all segments
}
}
}
// Function to update all displays at once
void updateDisplays() {
// Prepare to send data to all shift registers
digitalWrite(latchPin, LOW);
// Shift out all data from the buffer in reverse order
for (int i = (numDigits * numDisplays) - 1; i >= 0; i--) {
shiftOut(dataPin, clockPin, MSBFIRST, displayBuffer[i]);
}
// Latch the data to display the updated numbers
digitalWrite(latchPin, HIGH);
}
Any help would be greatly appreciated!
This is the video of the display flickering
This is the display I am using