Vacuum Fluorescent Display Clock | |
March 2019
The Arduino SketchDS1307/DS3231 RTC Library
/* Vacuum Fluorescent Display (VFD) Real Time Clock - vwlowen.co.uk * */ #include <Wire.h> #include "RTClib.h" // https://github.com/adafruit/RTClib //RTC_DS1307 rtc; // Choose the RTC clock module here. RTC_DS3231 rtc; const int filament_pin1 = 2; const int filament_pin2 = 4; const int dp_pin = 3; const int setHours_pin = A2; const int setMins_pin = A3; // Define Arduino pins used for the grids. const int grid_pins[5] {8, 7, 6, 5}; // Hours x 10, Hours, Mins x 10, Mins // Define Arduino pins used for the segments (anodes). const int segment_pins[8] {A1, A0, 13, 12, 11, 10, 9}; // Segments (Anodes) a b c d e f int theTime[4] {0, 0, 0, 0}; // Each read of the RTC is stored here. // gfedcba const int numbers[10] = { // Define which segments are lit for each number. B0111111, // 0 B0000110, // 1 B1011011, // 2 B1001111, // 3 B1100110, // 4 B1101101, // 5 B1111101, // 6 B0000111, // 7 B1111111, // 8 B1101111 // 9 }; byte hours, mins, secs; unsigned long settingHours = 0; // Timer for incrementing hours when the button is pressed. unsigned long settingMinutes = 0; // Timer for incrementing minutes when its button is pressed. bool filament_flag = false; // Display filament is powered from two IO pins which alternate. int grid = 0; // Define first grid to be activated/updated (grid 0 is Hours x 10). void setup() { Serial.begin(9600); if (! rtc.begin()) { Serial.println("Couldn't find RTC"); while (1); } pinMode(filament_pin1, OUTPUT); pinMode(filament_pin2, OUTPUT); pinMode(dp_pin, OUTPUT); // Decimal point is not multiplexed so is too bright when fully analogWrite(dp_pin, 30); // powered with logic HIGH, so set PWM value to match brightness. pinMode(setHours_pin, INPUT_PULLUP); pinMode(setMins_pin, INPUT_PULLUP); for (int i = 0; i < 8; i++) { // Make all display segments LOW pinMode(segment_pins[i], OUTPUT); digitalWrite(segment_pins[i], LOW); } for (int i = 0; i < 5; i++) { // Make all grids LOW (grids are Hx10, H, Mx10, M). pinMode(grid_pins[i], OUTPUT); digitalWrite(grid_pins[i], LOW); } } void loop() { digitalWrite(filament_pin1, filament_flag); // Power display filament with one polatity. digitalWrite(filament_pin2, !filament_flag); filament_flag = !filament_flag; // Swap polarity next time around the loop. DateTime now = rtc.now(); // Get time from RTC. hours = now.hour(); mins = now.minute(); secs = now.second(); // Seconds will be needed if we set the time. theTime[0] = hours / 10; // Store the time so all digits can be recalled from the theTime[1] = hours % 10; // same RTC reading. theTime[2] = mins / 10; theTime[3] = mins % 10; // If pressed, only allow time-setting buttons to change the time once every 250 millisec. if ((digitalRead(setHours_pin) == LOW) && (millis() > (settingHours + 250))) { //Set Hours hours++; if (hours >= 24) hours = 0; theTime[0] = hours / 10; theTime[1] = hours % 10; rtc.adjust(DateTime(2019, 2, 15, hours, mins, secs)); // Retain existing seconds value. settingHours = millis(); // Reset the Hours button timer. } if ((digitalRead(setMins_pin) == LOW) && (millis() > (settingMinutes + 250))) { // Set Minutes mins++; if (mins >= 60) mins = 0; theTime[2] = mins / 10; theTime[3] = mins % 10; rtc.adjust(DateTime(2019, 2, 15, hours, mins, 0)); // Reset seconds to zero when minutes are set. settingMinutes = millis(); // Reset the Minutes button timer. } // Display the segments for one grid. for (int i = 0; i < 5; i++) { // Turn all grids off. digitalWrite(grid_pins[i], LOW); } // For the current grid, turn on the segments for which the number's bits are '1' (HIGH). for (int i = 0; i < 8; i++) { digitalWrite(segment_pins[i], numbers[theTime[grid]] & (1 << i)); } digitalWrite(grid_pins[grid], HIGH); // Turn the current grid on. grid++; // Advance to the next grid next time around. if (grid >= 4) grid = 0; }
|