// IV-12 VFD Signle Digit Clock Project - 2024.03 - tomcii // Changelog: // 2024.03.08 - Program init structure // 2024.03.11 - Test pin define, void(setup) mod according to TEST mode // 2024.10.30 - printTime time values decreased // 2024.10.30 - TEST Mode under construction #include #include #define DS3231 B1101000 // I2C address RTClib myRTC; const int pinTest = 10; // Test button // IV-12 VFD Pinout and Pin assignments to ATMEGA328P // segmA -> PD2 // segmB -> PD3 // segmC -> PD4 // segmD -> PD5 // segmE -> PD6 // segmF -> PD7 // segmG -> PB0 // // a // _ // f / _ / b // e / _ / c // d // // Middle is G (there is no decimal point on IV-12 VFD) byte segment[] = { 2, // segmA = PD2 3, // segmB = PD3 4, // segmC = PD4 5, // segmD = PD5 6, // segmE = PD6 7, // segmF = PD7 8, // segmG = PB0 11 }; byte leds[] = { A0, // Hours 1st place = PC0 A1, // Hours 2nd place = PC1 A2, // Minutes 3rd place = PC2 A3}; // Minutes 4th place = PC3 byte second = 0, minute = 0, hour = 0; int test_delay = 200; void updateTime(); void printTime(); void print7Digit(byte number); byte DECTOBCD(byte val); byte BCDTODEC(byte val); /* // Test the segments during TEST mode void test7Digit_Test(byte test_number) { // Bitfield for digits 0-9 const byte test_numtable[] = { B00111111, // 0 B00000110, // 1 B01011011, // 2 B01001111, // 3 B01100110, // 4 B01101101, // 5 B01111101, // 6 B00000111, // 7 B01111111, // 8 B01101111 }; // 9 byte testpins = test_numtable[test_number]; byte test_nums; for (test_nums = 0; test_nums < 8; test_nums++) { digitalWrite(segment[test_nums], (testpins >> test_nums) & 1); delay(test_delay); } } void test4Leds (byte test_leds) { const byte test_led_numtable[] = { B00000001, // 1st LED (Hour 1) B00000010, // 2nd LED (Hour 2) B00000011, // 3rd LED (Minutes 1) B00001000 // 4th LED (Minutes 2) }; byte testleds = test_led_numtable[test_leds]; byte test_hhmm; for (test_hhmm = 0; test_hhmm < 3; test_hhmm++) { digitalWrite(leds[test_hhmm], (testleds >> test_hhmm) ); delay(test_delay); } } //// */ void setup() { byte init_segm; byte init_leds; pinMode(A0, OUTPUT); pinMode(A1, OUTPUT); pinMode(A2, OUTPUT); pinMode(A3, OUTPUT); pinMode(pinTest, INPUT); // Serial.begin(9600); // Begin Serial Port Wire.begin(); // Begin I2C communication // Initialize segments and pull them down for (init_segm = 0; init_segm < 8; init_segm++) { pinMode(segment[init_segm], OUTPUT); digitalWrite(segment[init_segm], LOW); } // Initialize leds and pull them down for (init_leds = 0; init_leds < 4; init_leds++) { pinMode(leds[init_leds], OUTPUT); digitalWrite(leds[init_leds], LOW); } // Test all the segments and leds when holding the "TEST" button during powering up (Reset will allow to change back clock mode) if (digitalRead(pinTest) == HIGH) { int led = 0; int segm = 0; for (segm = 0; segm < 8; segm++) { digitalWrite(segment[segm], LOW); delay(test_delay); } for (led = 0; led < 4; led++) { digitalWrite(leds[led], HIGH); delay(test_delay); } } } void loop() { updateTime(); // Call updateTime subroutine printTime(); // Call printTime subroutine } // Pull current time off the DS3231 void updateTime() { Wire.beginTransmission(DS3231); Wire.write(0x00); Wire.endTransmission(); Wire.requestFrom(DS3231, 3); // Don't actually use seconds value. Feel free to. second = BCDTODEC(Wire.read()); minute = BCDTODEC(Wire.read()); hour = BCDTODEC(Wire.read()); } // Flash each digit of the time in turn on the 7 segment void printTime() { byte printTimeVar; // Convert from 24 hour to 12 hour mode byte temphour = hour; if (temphour == 0) { // Not zero based, not one based, but 24 based. temphour = 24; } // Hours 1 if (temphour > 0) { print7Digit(temphour / 10); digitalWrite(A0, HIGH); // Hours 1 digitalWrite(A1, LOW); // Hours 2 digitalWrite(A2, LOW); // Minutes 1 digitalWrite(A3, LOW); // Minutes 2 delay(500); for (printTimeVar = 0; printTimeVar < 8; printTimeVar++) { digitalWrite(segment[printTimeVar], HIGH); } delay(100); } // Hours 2 print7Digit(temphour % 10); digitalWrite(A0, LOW); // Hours 1 digitalWrite(A1, HIGH); // Hours 2 digitalWrite(A2, LOW); // Minutes 1 digitalWrite(A3, LOW); // Minutes 2 delay(500); for (printTimeVar = 0; printTimeVar < 8; printTimeVar++) { digitalWrite(segment[printTimeVar], HIGH); } delay(100); // Minutes 1 print7Digit(minute / 10); digitalWrite(A0, LOW); // Hours 1 digitalWrite(A1, LOW); // Hours 2 digitalWrite(A2, HIGH); // Minutes 1 digitalWrite(A3, LOW); // Minutes 2 delay(500); for (printTimeVar = 0; printTimeVar < 8; printTimeVar++) { digitalWrite(segment[printTimeVar], HIGH); } delay(100); // Minutes 2 print7Digit(minute % 10); digitalWrite(A0, LOW); // Hours 1 digitalWrite(A1, LOW); // Hours 2 digitalWrite(A2, LOW); // Minutes 1 digitalWrite(A3, HIGH); // Minutes 2 delay(500); for (printTimeVar = 0; printTimeVar < 8; printTimeVar++) { digitalWrite(segment[printTimeVar], HIGH); } digitalWrite(A0, LOW); // Hours 1 digitalWrite(A1, LOW); // Hours 2 digitalWrite(A2, LOW); // Minutes 1 digitalWrite(A3, LOW); // Minutes 2 delay(1000); } // Display a single digit on the 7 segment void print7Digit(byte number) { // Bitfield for digits 0-9 const byte numtable[] = { B11000000, // 0 B11111001, // 1 B00100100, // 2 B00110000, // 3 B10011001, // 4 B00010010, // 5 B10000010, // 6 B11111000, // 7 B10000000, // 8 B10010000 }; // 9 byte litpins = numtable[number]; byte nums; for (nums = 0; nums < 8; nums++) { digitalWrite(segment[nums], (litpins >> nums) & 1); } } byte DECTOBCD(byte val) { return ((val / 10) << 4) + (val % 10); } byte BCDTODEC(byte val) { return (val >> 4) * 10 + (val & 0xf); }