Components and supplies
12v AC-AC Power Adapter
Apps and platforms
uno
Project description
Code
One Tube Nixie Clock
cpp
Displays the time on a single nixie tube.
1/* 2 ONE-TUBE NIXIE CLOCK for Arduino UNO - - - - - - - - - - - - L. Thomas -- August 2023 3 - Displays the time by repeatedly sequencing the digits each 2.5 seconds. 4 - Uses interrupt (pin 2) to detect each cycle of 60Hz AC power. This is used to 5 count seconds, and time the sequencing of each digit. 6 - Has leading zero blanking. 7 - Jumper (pin 6) can be cut to run the clock in 24-hour format. 8 - A short blink between digits separates them. This is needed for the eye to catch 9 double digits such as 11 or 22. 10 - Nixie digits 0-9 are displayed according to the hex value of pins 8-11. 11 - A hexadecimal value greater than 9 will cause none of the nixie digits to illuminate. 12 - Output pin 12 is used to turn the decimal point ON and OFF. 13 - The decimal point is turned on during display of hours digit(s). 14 - The clock is frozen at zero seconds when the RUN/SET switch is in SET position. This 15 allows the clock to start immediately at zero seconds when switched from SET to RUN. 16 - At start-up or reset, all ten digits are displayed & decimal point blinks as a test. 17 - At start-up or reset, the clock begins at 12:59 (requires setting to correct time). 18 19*/ 20int ACint = 2; // pin 2 is the interrupt from the 60Hz AC line (INT0) 21int HRSBTN = 3; // pin 3 senses press of the Hours button (adds 1) 22int MINBTN = 4; // pin 4 senses press of the Minutes button (adds 1) 23int RUNSET = 5; // pin 5 senses if in the Set mode (low) 24int JUMPER = 6; // pin 6 senses if time should be displayed in 24-hour format (HIGH) 25int hexA = 8; // pin 8 is the LSD - used to display one of the nixie digits 26int hexB = 9; // pin 9 - used to display one of the nixie digits 27int hexC = 10; // pin 10 - used to display one of the nixie digits 28int hexD = 11; // pin 11 is the MSD - used to display one of the nixie digits 29int Dpoint = 12; // pin 12 turns the nixie decimal point on and off 30int TestPt = 13; // pin 13 has an on-board LED and is used as a visual test indicator 31// 32int timeH = 12; // Stores the HOURS value 33int timeM = 59; // Stores the MINUTES value 34int SUBsec = 0; // Accumulates AC cycles for each second 35int Seconds = 0; // Accumulate seconds up to 60 36int Dcounter = 0; // Runs from 0 to 149 to organize nixie display sequence timing 37int Flag = 0; // Set to 1 when interrupt occurs 38int Temp1 = 0; // Temporary register 1 39int Temp2 = 0; // Temporary register 2 40int INstatus = LOW; // Used to capture status of a digital input - HIGH or LOW 41int LASTs3 = HIGH; // Used to debounce Hours setting button 42int LASTs2 = HIGH; // Used to debounce Minutes setting button 43int Dstatus = 5; // Defines the current status (case number) for nixie display 44// 45// The setup routine runs once during start-up or when RESET is pressed. 46void setup() 47{ pinMode(HRSBTN, INPUT); // 3 48 pinMode(MINBTN, INPUT); // 4 49 pinMode(RUNSET, INPUT); // 5 50 pinMode(JUMPER, INPUT); // 6 51 pinMode(hexA, OUTPUT); // 8 52 pinMode(hexB, OUTPUT); // 9 53 pinMode(hexC, OUTPUT); // 10 54 pinMode(hexD, OUTPUT); // 11 55 pinMode(Dpoint, OUTPUT); // 12 56 pinMode(TestPt, OUTPUT); // 13 (LED) 57// **** Display all ten digits and flash the decimal point **** 58 digitalWrite(hexA, LOW); 59 digitalWrite(hexB, LOW); 60 digitalWrite(hexC, LOW); 61 digitalWrite(hexD, LOW); // This will display "0" 62 digitalWrite(Dpoint, HIGH); // Decimal point ON 63 delay(400); // Show each digit for 800ms 64 digitalWrite(Dpoint, LOW); //Decimal point OFF 65 delay(400); 66 digitalWrite(hexA, HIGH); //Display "1" 67 digitalWrite(Dpoint, HIGH); //Decimal point ON 68 delay(400); 69 digitalWrite(Dpoint, LOW); //Decimal point OFF 70 delay(400); 71 digitalWrite(hexA, LOW); 72 digitalWrite(hexB, HIGH); //Display "2" 73 digitalWrite(Dpoint, HIGH); //Decimal point ON 74 delay(400); 75 digitalWrite(Dpoint, LOW); //Decimal point OFF 76 delay(400); 77 digitalWrite(hexA, HIGH); 78 digitalWrite(hexB, HIGH); //Display "3" 79 digitalWrite(Dpoint, HIGH); //Decimal point ON 80 delay(400); 81 digitalWrite(Dpoint, LOW); //Decimal point OFF 82 delay(400); 83 digitalWrite(hexA, LOW); 84 digitalWrite(hexB, LOW); 85 digitalWrite(hexC, HIGH); //Display "4" 86 digitalWrite(Dpoint, HIGH); //Decimal point ON 87 delay(400); 88 digitalWrite(Dpoint, LOW); //Decimal point OFF 89 delay(400); 90 digitalWrite(hexA, HIGH); //Display "5" 91 digitalWrite(Dpoint, HIGH); //Decimal point ON 92 delay(400); 93 digitalWrite(Dpoint, LOW); //Decimal point OFF 94 delay(400); 95 digitalWrite(hexA, LOW); 96 digitalWrite(hexB, HIGH); //Display "6" 97 digitalWrite(Dpoint, HIGH); //Decimal point ON 98 delay(400); 99 digitalWrite(Dpoint, LOW); //Decimal point OFF 100 delay(400); 101 digitalWrite(hexA, HIGH); 102 digitalWrite(hexB, HIGH); //Display "7" 103 digitalWrite(Dpoint, HIGH); //Decimal point ON 104 delay(400); 105 digitalWrite(Dpoint, LOW); //Decimal point OFF 106 delay(400); 107 digitalWrite(hexA, LOW); 108 digitalWrite(hexB, LOW); 109 digitalWrite(hexC, LOW); 110 digitalWrite(hexD, HIGH); //Display "8" 111 digitalWrite(Dpoint, HIGH); //Decimal point ON 112 delay(400); 113 digitalWrite(Dpoint, LOW); //Decimal point OFF 114 delay(400); 115 digitalWrite(hexA, HIGH); //Display "9" 116 digitalWrite(Dpoint, HIGH); //Decimal point ON 117 delay(400); 118 digitalWrite(Dpoint, LOW); //Decimal point OFF 119 delay(400); 120 digitalWrite(hexB, HIGH); //All nixie digits now OFF 121 delay(800); 122 attachInterrupt(0, ClkUpdate, RISING); //Enable the interrupt. 123} 124// 125// **** MAIN LOOP *************************************************************** 126void loop () 127{ 128 INstatus = digitalRead(RUNSET); //Is the clock being set? 129 if (Seconds >= 60 && Flag == 1 && INstatus == HIGH) 130// Just update the display if not true. 131 { 132 Seconds = 0; //ELSE Seconds = 60 so adjust for a new minute 133 timeM = timeM + 1; //Add a minute to the time 134 if (timeM >= 60) //Do we also have a new hour? 135 { 136 timeM = 0; //Yes-Reset the minutes 137 timeH = timeH + 1; // and add an hour 138 INstatus = digitalRead(JUMPER); //Read the jumper 139 if (INstatus == LOW && timeH > 12) //Back to 1:00 (if 12-hour format) 140 timeH = 1; //Yes-reset to 1:00 141 if (timeH > 23) //Reset to 0:00 (if 24-hour format) 142 timeH = 0; //Yes-reset to 0:00 143 }} 144// Now update the display according to Case 1 through Case 5 ******************** 145 if (Flag == 1) //Recent interrupt? 146// If not, nothing else, done with loop. 147 { 148 Flag = 0; //Yes-so reset Flag and update display 149 Dstatus = 5; //Start with nixie off 150 if (Dcounter < 96) //If true display Minutes-ones 151 Dstatus = 4; //Case 4 152 if (Dcounter < 77) //If true nixie off 153 Dstatus = 5; //Case 5 154 if (Dcounter < 74) //If true display Minutes-tens 155 Dstatus = 3; //Case 3 156 if (Dcounter < 55) //If true nixie off 157 Dstatus = 5; //Case 5 158 if (Dcounter < 41) //If true display Hours-ones + DP 159 Dstatus = 2; //Case 2 160 if (Dcounter < 22) //If true nixie off 161 Dstatus = 5; //Case 5 162 if (Dcounter < 19) //If true display Hours-tens + DP 163 Dstatus = 1; //Case 1 164// 165 switch (Dstatus) 166 { 167 case 1: //Displays Hours-tens digit 168 Temp1 = timeH % 10; //Temp1 now has the remainder (0,1,or 2) 169 Temp2 = (timeH - Temp1)/10; //Temp2 now has the Hours-tens value 170 if (Temp2 == 0) //Check for leading zero blanking 171 Temp2 = 10; //Yes-Set Temp2 to blank leading zero 172 break; 173 case 2: //Displays Hours-ones digit 174 Temp2 = timeH % 10; //Temp2 now has the Hours-one value 175 break; 176 case 3: //Displays Minutes-tens digit 177 Temp1 = timeM % 10; //Temp1 now has the remainder (0-9) 178 Temp2 = (timeM - Temp1)/10; //Temp2 now has the Minutes-tens value 179 break; 180 case 4: //Displays Minutes-ones digit 181 Temp2 = timeM % 10; //Temp2 now has the Minutes-one value 182 break; 183 case 5: //Turns the nixie off (including DP) 184 Temp2 = 10; 185 break; 186 } 187// 188 if (Dstatus == 1 || Dstatus == 2) //Should the DP be turned on? 189 { 190 digitalWrite(Dpoint, HIGH); //ON - Yes-Dstatus was a 1 or 2 191 } 192 else 193 { 194 digitalWrite(Dpoint, LOW); //OFF - No-Dstatus was not a 1 or 2 195 } 196// 197// **** Set outputs 8,9,10,11 & 12 according to Temp2 *************************** 198// 199 if (Temp2 > 7 && Temp2 < 10) //Is it 8 or 9? 200 { 201 digitalWrite(hexD, HIGH); //Yes-Turn on the "8" bit 202 Temp2 = (Temp2 - 8); //prepare for next test 203 } 204 else 205 { 206 digitalWrite(hexD, LOW); //No -Turn off the "8" bit 207 } 208 if (Temp2 > 3 && Temp2 < 8) //Is it 4,5,6, or 7? 209 { 210 digitalWrite(hexC, HIGH); //Yes-Turn on the "4" bit 211 Temp2 = (Temp2 - 4); //prepare for next test 212 } 213 else 214 { 215 digitalWrite(hexC, LOW); //No -Turn off the "4" bit 216 } 217 if (Temp2 > 1 && Temp2 < 4) //Is it 2 or 3? 218 { 219 digitalWrite(hexB, HIGH); //Yes-Turn on the "2" bit 220 Temp2 = (Temp2 - 2); //prepare for next test 221 } 222 else 223 { 224 digitalWrite(hexB, LOW); //No -Turn off the "2" bit 225 } 226 if (Temp2 == 1) //Is it now 1? 227 { 228 digitalWrite(hexA, HIGH); //Yes-Turn on the "1" bit 229 } 230 else 231 { 232 digitalWrite(hexA, LOW); //No -Turn off the "1" bit 233 } 234 if (Temp2 == 10) //Turn the nixie off and DP off 235 { 236 digitalWrite(hexA, LOW); //The nixie will be off if output value 237 digitalWrite(hexB, HIGH); // is 10 or greater 238 digitalWrite(hexC, LOW); 239 digitalWrite(hexD, HIGH); //Output value is now 10 (decimal) 240 digitalWrite(Dpoint, LOW); //The decimal point is now off 241 // De-bounce the Minutes and Hours setting buttons 242 INstatus = digitalRead(MINBTN); //Read the Minutes button status 243 if (INstatus != LASTs2) //Determine if status has changed 244 LASTs2 = HIGH; //NOT equal- it did change 245 INstatus = digitalRead(HRSBTN); //Now read the Hours button status 246 if (INstatus != LASTs3) //Determine if status has changed 247 LASTs3 = HIGH; //NOT equal- it did change 248 }}} //End of Loop here ************************* 249// 250// 251// 252// Interrupt Service - Accumulates Seconds and Detects Clock Setting ************ 253 void ClkUpdate (void) 254 { 255 SUBsec = SUBsec + 1; //Add 1 towards accumulating 1 second 256 INstatus = digitalRead(RUNSET); //Read the RUN/SET switch status 257 if (INstatus == LOW) //LOW if switch is in SET positon 258 { 259 SUBsec = 0; //RUN/SET switch is in the SET position 260 Seconds = 0; //This freezes the clock at zero seconds 261 // Now check the clock setting buttons: 262 INstatus = digitalRead(MINBTN); //Read the MINUTES button status 263 if (INstatus == LOW && INstatus != LASTs2) //Must be a NEW low status 264 { 265 timeM = timeM + 1; // Button was pressed - add a minute 266 LASTs2 = INstatus; // Save the button status to LASTs2 267 if (timeM > 59) // Roll over back to zero? 268 timeM = 0; // Yes 269 } 270 INstatus = digitalRead(HRSBTN); //Read the HOURS button status 271 if (INstatus == LOW && INstatus != LASTs3) //Must be a NEW low status 272 { 273 timeH = timeH + 1; // Button was pressed - add an hour 274 LASTs3 = INstatus; // Save the button status to LASTs3 275 INstatus = digitalRead(JUMPER); //Read the jumper 276 if (INstatus == LOW && timeH > 12) //Back to 1:00 (if 12-hour format) 277 timeH = 1; //Yes-reset to 1:00 278 if (timeH > 23) //Reset to 0:00 (if 24-hour format) 279 timeH = 0; //Yes-reset to 0:00 280 }} 281 if (SUBsec == 5) //Skips to here if not setting the clock 282 digitalWrite(TestPt, LOW); //Turn off the test LED (short blink) 283 if (SUBsec > 59) //Have we accumulated 1 second yet? 284 { 285 SUBsec = 0; //Yes-so reset for the next one 286 Seconds = Seconds + 1; // and increment the seconds 287 digitalWrite(TestPt, HIGH); // and turn on the test point & LED 288 } 289 Dcounter = Dcounter + 1; //Also increment the display counter 290 if (Dcounter > 149) //At the end of the display cycle? 291 Dcounter = 0; //Yes- so reset for next cycle 292 Flag = 1; //Now show that we have been here 293 } 294// End of Interrupt Service: ****************************************************
Documentation
UNO Nixie Tube Shield Info
Assembly and programming notes, schematic, & more.
UNO Nixie Tube Shield-Info.pdf
Comments
Only logged in users can leave comments