/*
Project: ShiftRegister_7Seg_Demo
Description: In a real circuit add transistors on each digit!
The gray wires are digits, colored are the segments.
Written for common cathode displays.
TO DO:
Add digit shift register
Support negative numbers
Creation date: 11/10/24
Author: AnonEngineering
License: https://en.wikipedia.org/wiki/Beerware
*/
const uint8_t MAX_DIGITS = 4;///////////////////////////////////////////
// pin definitions
const uint8_t CLOCK_PIN = 8;
const uint8_t LATCH_PIN = 7;
const uint8_t DATA_PIN = 6;
const uint8_t POT_PIN = A0;
const uint8_t DIGIT_PINS[MAX_DIGITS] = {2, 3, 4, 5}; //, A1, A2, A3, A4};
// lookup table, which segments are on for each value
const uint8_t SEG_BYTES[] = {
0xFC, /* 0 */
0x60, /* 1 */
0xDA, /* 2 */
0xF2, /* 3 */
0x66, /* 4 */
0xB6, /* 5 */
0xBE, /* 6 */
0xE0, /* 7 */
0xFE, /* 8 */
0xF6, /* 9 */
0x00 /* blank */
};
uint8_t DP_POSITION = 0; // for test
// for hardware test only
void testDisplay() {
writeShiftDigit(0, 1, false);
writeShiftDigit(1, 2, false);
writeShiftDigit(2, 3, false);
writeShiftDigit(3, 4, false);
writeShiftDigit(4, 5, false);
writeShiftDigit(5, 6, true);
writeShiftDigit(6, 7, false);
writeShiftDigit(7, 8, false);
}
void updateDisplay(uint32_t value, uint8_t dpPos) {
uint8_t digitVal;
uint8_t powOfTen = MAX_DIGITS - 1;
uint32_t op1 = 1, op2 = 1;
for (uint8_t digit = 0; digit < powOfTen; digit++) {
for (uint8_t p = powOfTen - digit; p >= 1; p--) {
op1 = op1 * 10;
}
op2 = op1 * 10;
// with leading zero blanking (10 is a blank char)
digitVal = value < op1 ? 10 : (value % op2) / op1;
writeShiftDigit(digit, digitVal, ((dpPos - 1) == digit) ? true : false);
op1 = 1; op2 = 1;
}
// last digit is never blanked
writeShiftDigit(powOfTen, value % 10, ((dpPos - 1) == powOfTen) ? true : false);
}
void writeShiftDigit(uint8_t digit, uint8_t number, bool dp) {
uint8_t value = SEG_BYTES[number];
digitalWrite(LATCH_PIN, LOW);
shiftOut(DATA_PIN, CLOCK_PIN, LSBFIRST, dp ? (value | 0x01) : value);
digitalWrite(LATCH_PIN, HIGH);
digitalWrite(DIGIT_PINS[digit], LOW);
digitalWrite(DIGIT_PINS[digit], HIGH);
}
void setup() {
Serial.begin(115200);
pinMode(DATA_PIN, OUTPUT);
pinMode(CLOCK_PIN, OUTPUT);
pinMode(LATCH_PIN, OUTPUT);
for (uint8_t i = 0; i < MAX_DIGITS; i++) {
pinMode(DIGIT_PINS[i], OUTPUT);
}
}
void loop() {
// multiply pot value by 1000 for 8 digits
uint32_t potVal = analogRead(POT_PIN); // * 1000ul;
// update display often
updateDisplay(potVal, DP_POSITION);
//testDisplay();
}