Demonstration of how to use an ATMega328 or Arduino Uno/Nano/Pro Micro etc to drive a 4 digit, 7 segment led display with colon etc.
Achieved with simply 5 ordinary npn transistors, 8 series resistors and 13 Arduino outputs.
This circuit uses most of the outputs of an ATmega328/Nano/Pro Micro Arduino, but if the chip is doing little or nothing else, why not use it to drive a display directly rather than use shift registers (e.g. 75hc595, not a great choice because of limited current, or tip6c595, a better option) or an led driver chip such as max7219 (best option if you need to use the Arduino outputs for other functions).
This particular display is common anode, but common-cathode is also achievable with some minor changes to the circuit & sketch.
If no colon or other segments are present/needed on the display, transistor T5 can be omitted. Alternatively, 6 more separate leds could be added as shown in the schematic.
Schematic shows 150R resistors, calculated to allow maximum current/brightness without overloading the Arduino's outputs, but I used 330R and brightness was still excellent (although maybe not great in bright sunlight).
Video: Arduino Nano 4 digit 7 segment - YouTube
Sketch:
const byte segmentPin[8] = {2, 3, 4, 5, 8, 9, 10, 11};
const byte digitPin[5] = {6, 7, 14, 13, 12};
const byte digitPattern[10] = {
B10000100,
B11110110,
B10010001,
B11010000,
B11100010,
B11001000,
B10001000,
B11110100,
B10000000,
B11000000 };
unsigned long updateDisplay;
byte currAnode;
byte digit[5];
void setup() {
for (byte i=0; i<8; i++) {
pinMode(segmentPin[i], OUTPUT);
}
for (byte i=0; i<5; i++) {
pinMode(digitPin[i], OUTPUT);
}
}
void loop() {
unsigned long now = millis();
int n = now / 100;
digit[0] = digitPattern[n % 10];
digit[1] = digitPattern[(n / 10) % 10];
digit[2] = digitPattern[(n / 100) % 10];
digit[3] = digitPattern[(n / 1000) % 10];
digit[4] = B11111110 | ((n / 5) & 1);
if (now - updateDisplay >= 3) {
updateDisplay = now;
digitalWrite(digitPin[currAnode], LOW);
if (currAnode++ >= 4) currAnode = 0;
for (byte i=0; i<8; i++) {
digitalWrite(segmentPin[i], bitRead(digit[currAnode], i));
}
digitalWrite(digitPin[currAnode], HIGH);
}
}
Apologies if this is all a bit brief, if you ask I will be happy to explain any particular points further.
Paul