Components and supplies
2x6 Flip-disc Binary Clock
Tools and machines
Soldering kit
Optional 3D Printer
Apps and platforms
Arduino IDE 2.0 (beta)
Project description
Code
Flip-disc Binary Clock Code
cpp
Flip-disc Binary Clock Code
1/*-----------------------------------------------------------------------------------------------* 2 * Flip-disc 2x6 Binary Clock by Marcin Saj https://flipo.io * 3 * https://github.com/marcinsaj/Flipo-Binary-Clock-2x6-Flip-Disc-Display * 4 * * 5 * Final Flip-disc Clock 4x7-Segment * 6 * Setting Options: * 7 * - hour format 12/24 * 8 * - time, hours & minutes * 9 * * 10 * Attention!!! - Firmware update only for intermediate users! * 11 * The heart of the clock is the ATmega 328 microcontroller (default 16 MHz external crystal) * 12 * The clock code was written in the Arduino IDE and uses MiniCore * 13 * * 14 * If you want to upload your own code, there is an ISP connector on board for programming. * 15 * If you use a programmer that allows you to power the microcontroller to be programmed, * 16 * all you have to do is turn off (slide switch) the clock during programming. * 17 * If the programmer (e.g. Atmel-ICE ISP) requires an additional power supply for * 18 * the microcontroller to be programmed, the clock controller board should be disconnected * 19 * from the 2x6 flip-disc display board during programming - this is very important because * 20 * the flip-disc display may be damaged during programming. * 21 * * 22 * MiniCore - https://github.com/MCUdude/MiniCore * 23 * Clock schematic - https://bit.ly/BC-SCH * 24 *-----------------------------------------------------------------------------------------------*/ 25 26#include <FlipDisc.h> // https://github.com/marcinsaj/FlipDisc 27#include <RTC_RX8025T.h> // https://github.com/marcinsaj/RTC_RX8025T 28#include <TimeLib.h> // https://github.com/PaulStoffregen/Time 29#include <Wire.h> // https://arduino.cc/en/Reference/Wire (included with Arduino IDE) 30#include <OneButton.h> // https://github.com/mathertel/OneButton 31#include <EEPROM.h> // https://www.arduino.cc/en/Reference/EEPROM (included with Arduino IDE) 32 33 34// Pin declaration for binary clock controller 35#define EN_PIN 10 36#define CH_PIN A1 37#define PL_PIN A0 38 39// Buttons 40#define B1_PIN A3 // Right button 41#define B2_PIN A2 // Left button 42 43// RTC 44#define RTC_PIN 2 // RTC interrupt input 45 46// Display rows 47static const uint8_t TOP_ROW = 2; 48static const uint8_t BOT_ROW = 1; 49 50// Aliases for individual option settings 51static const uint8_t HR12 = 0; // Display time in 12 hour format 52static const uint8_t HR24 = 1; // Display time in 24 hour format 53 54// "0" - all discs are cleared 55// "63" - all discs are set 56static const uint8_t CLR_ALL = 0; 57static const uint8_t SET_ALL = 63; 58 59// Declare structure that allows convenient access to the time elements: 60// - tm.Hour - hours 61// - tm.Minute - minutes 62tmElements_t tm; 63 64// Initialize a new OneButton instance for a buttons 65// BUTTON_PIN - Input pin for the button 66// true - Button is active low 67// true - Enable internal pull-up resistor 68OneButton button1(B1_PIN, true, true); 69OneButton button2(B2_PIN, true, true); 70 71// Flags for storing button press status 72bool shortPressButton1Status = false; 73bool shortPressButton2Status = false; 74bool longPressButton1Status = false; 75bool longPressButton2Status = false; 76 77// RTC interrupt flag 78volatile bool interruptRtcStatus = false; 79 80uint8_t binaryTopRowAR[6]; 81uint8_t binaryBotRowAR[6]; 82 83int hour_time = 0; 84int minute_time = 0; 85int time_hr = 0; 86 87// Eeprom address where time format is stored 88static const uint16_t ee_time_hr_address = 0; // Time format 12/24 hour 89 90uint32_t flipDelay = 5; 91bool settingsStatus = false; 92 93 94// Interrupt from RTC 95void rtcInterruptISR(void) 96{ 97 interruptRtcStatus = true; 98} 99 100void setup() 101{ 102 Flip.Pin(EN_PIN, CH_PIN, PL_PIN); 103 Flip.Init(D2X6); 104 105 pinMode(RTC_PIN, INPUT_PULLUP); 106 107 // RTC RX8025T initialization 108 RTC_RX8025T.init(); 109 110 // Time update interrupt initialization. Interrupt generated by RTC (INT output): 111 // "INT_SECOND" - every second, 112 // "INT_MINUTE" - every minute. 113 RTC_RX8025T.initTUI(INT_MINUTE); 114 115 // "INT_ON" - turn ON interrupt generated by RTC (INT output), 116 // "INT_OFF" - turn OFF interrupt. 117 RTC_RX8025T.statusTUI(INT_ON); 118 119 // Assign an interrupt handler to the RTC output, 120 // an interrupt will be generated every minute to display the time 121 attachInterrupt(digitalPinToInterrupt(RTC_PIN), rtcInterruptISR, FALLING); 122 123 // Link the button functions 124 button1.attachClick(ShortPressButton1); 125 button2.attachClick(ShortPressButton2); 126 button1.attachLongPressStart(LongPressButton1); 127 // button2.attachLongPressStart(LongPressButton2); 128 129 DelayTime(3000); 130 131 // If the read values are different from expected, set the time format to 12 hours. 132 time_hr = EEPROM.read(ee_time_hr_address); 133 if(time_hr != HR12 && time_hr != HR24) time_hr = HR12; // Set the time display to 12 hour format 134 135 DisplayTime(); 136} 137 138 139void loop() 140{ 141 WatchButtons(); 142 if(interruptRtcStatus == true) DisplayTime(); 143 if(longPressButton1Status == true) SetTime(); 144 145 // Maybe for future settings 146 // if(longPressButton2Status == true) DisplaySequence(); 147} 148 149void DisplaySequence(void) 150{ 151 // Maybe for future settings 152} 153 154void DisplayTime(void) 155{ 156 GetRtcTime(); 157 158 DisplayData(BOT_ROW, minute_time); 159 DisplayData(TOP_ROW, hour_time); 160 161 interruptRtcStatus = false; 162} 163 164 165void GetRtcTime(void) 166{ 167 // Get the time from the RTC and save it to the tm structure 168 RTC_RX8025T.read(tm); 169 170 hour_time = tm.Hour; 171 minute_time = tm.Minute; 172 173 // 12-Hour conversion 174 if(time_hr == HR12) 175 { 176 if(hour_time > 12) hour_time = hour_time - 12; 177 if(hour_time == 0) hour_time = 12; 178 } 179} 180 181 182void DisplayData(uint8_t row, uint8_t data) 183{ 184 uint32_t waitTime = 0; 185 186 if(settingsStatus == true) waitTime = 0; 187 else waitTime = flipDelay; 188 189 if(row == BOT_ROW) 190 { 191 DecToBinary(data, binaryBotRowAR); 192 for(int i = 1; i <= 6 ; i++) 193 { 194 Flip.Disc_2x6(1, i, binaryBotRowAR[i-1]); 195 DelayTime(waitTime); 196 } 197 } 198 199 if(row == TOP_ROW) 200 { 201 DecToBinary(data, binaryTopRowAR); 202 for(int i = 1; i <= 6; i++) 203 { 204 Flip.Disc_2x6(1, i+6, binaryTopRowAR[i-1]); 205 DelayTime(waitTime); 206 } 207 } 208} 209 210// Time settings, 12/24 format, hours and minutes 211void SetTime(void) 212{ 213 ClearPressButtonFlags(); 214 settingsStatus = true; 215 216 uint8_t time_settings_level = 1; 217 bool updateDisplay = true; 218 219 do // Stay in settings until all values are set 220 { 221 WatchButtons(); 222 223 if(shortPressButton1Status == true || shortPressButton2Status == true) 224 { 225 if(shortPressButton1Status == true) 226 { 227 if(time_settings_level == 2) time_hr++; 228 if(time_settings_level == 4) hour_time++; 229 if(time_settings_level == 6) minute_time++; 230 } 231 232 if(shortPressButton2Status == true) 233 { 234 if(time_settings_level == 2) time_hr--; 235 if(time_settings_level == 4) hour_time--; 236 if(time_settings_level == 6) minute_time--; 237 } 238 239 ClearPressButtonFlags(); 240 updateDisplay = true; 241 } 242 243 if(longPressButton1Status == true) 244 { 245 time_settings_level++; 246 if(time_settings_level > 6) time_settings_level = 0; // Exit settings 247 if(time_settings_level <= 6) 248 { 249 updateDisplay = true; 250 } 251 252 ClearPressButtonFlags(); 253 } 254 255 if(updateDisplay == true) 256 { 257 if(time_settings_level == 1) 258 { 259 DisplayData(TOP_ROW, SET_ALL); 260 DisplayData(BOT_ROW, SET_ALL); 261 DelayTime(1000); 262 time_settings_level = 2; 263 } 264 265 if(time_settings_level == 2) 266 { 267 // HR12 = 0; HR24 = 1; 268 if(time_hr > 1) time_hr = 0; 269 if(time_hr < 0) time_hr = 1; 270 if(time_hr == HR12) DisplayData(TOP_ROW, 12); 271 if(time_hr == HR24) DisplayData(TOP_ROW, 24); 272 } 273 274 if(time_settings_level == 3) 275 { 276 DisplayData(TOP_ROW, SET_ALL); 277 DisplayData(BOT_ROW, SET_ALL); 278 DelayTime(1000); 279 GetRtcTime(); 280 time_settings_level = 4; 281 } 282 283 if(time_settings_level == 4) 284 { 285 if(time_hr == HR12) 286 { 287 if(hour_time > 12) hour_time = 1; 288 if(hour_time <= 0) hour_time = 12; 289 } 290 291 if(time_hr == HR24) 292 { 293 if(hour_time > 23) hour_time = 0; 294 if(hour_time < 0) hour_time = 23; 295 } 296 297 DisplayData(TOP_ROW, hour_time); 298 } 299 300 if(time_settings_level == 5) 301 { 302 DisplayData(TOP_ROW, SET_ALL); 303 DisplayData(BOT_ROW, SET_ALL); 304 DelayTime(1000); 305 time_settings_level = 6; 306 } 307 308 if(time_settings_level == 6) 309 { 310 if(minute_time > 59) minute_time = 0; 311 if(minute_time < 0) minute_time = 59; 312 313 DisplayData(BOT_ROW, minute_time); 314 } 315 316 updateDisplay = false; 317 } 318 } while(time_settings_level > 0); 319 320 // setTime(hh, mm, ss, day, month, year) 321 // The date is skipped and the seconds are set by default to 1 322 // We are only interested in hours and minutes 323 setTime(hour_time, minute_time, 0, 1, 1, 1); 324 325 // Set the RTC from the system time 326 RTC_RX8025T.set(now()); 327 328 EEPROM.write(ee_time_hr_address, time_hr); 329 330 settingsStatus = false; 331 DisplayTime(); 332} 333 334// Better delay function 335void DelayTime(uint32_t delayTime) 336{ 337 uint32_t millis_time_now = millis(); 338 do 339 { 340 // do nothing 341 } while(millis() - millis_time_now < delayTime); 342} 343 344// Converting decimal values to binary 345void DecToBinary(uint8_t decValue, uint8_t binaryArray[]) 346{ 347 for(int i = 0; i < 6; i++) 348 { 349 binaryArray[i] = decValue & B00000001; 350 decValue = decValue >> 1; 351 } 352} 353 354// Keep watching the buttons 355void WatchButtons(void) 356{ 357 button1.tick(); 358 button2.tick(); 359} 360 361// Button flags clearing function 362void ClearPressButtonFlags(void) 363{ 364 shortPressButton1Status = false; 365 shortPressButton2Status = false; 366 longPressButton1Status = false; 367 longPressButton2Status = false; 368} 369 370// Button press handling functions 371void ShortPressButton1(void){shortPressButton1Status = true;} 372void ShortPressButton2(void){shortPressButton2Status = true;} 373void LongPressButton1(void){longPressButton1Status = true;} 374void LongPressButton2(void){longPressButton2Status = true;}
Flip-disc Binary Clock Repository
Flip-disc Binary Clock Repository
Downloadable files
2x6 Flip-disc Display Schematic
2x6 Flip-disc Display Schematic
Flip-disc-2x6-Display-Schematic.pdf
Flip-disc 2x6 Binary Clock Schematic
Flip-disc-2x6-Binary-Clock-Schematic.pdf
Flip-disc Specification
Flip-disc Specification
Flipo-Flip-Disc-Specification.pdf
2x6 Flip-disc Display Dimensions
2x6 Flip-disc Display Dimensions
Flip-disc-2x6-Display-Dimensions.pdf
2x6 Flip-disc Display Pinout
2x6 Flip-disc Display Pinout
Flip-disc-2x6-Display-Pinout.pdf
Documentation
3d printed casing - design no.1
3d printed casing - design no.1
https://www.printables.com/model/1025287-no1-3d-printed-casing-for-flip-disc-binary-clock
3d printed casing - design no.2
3d printed casing - design no.2
https://www.printables.com/model/1025303-no2-3d-printed-casing-for-flip-disc-binary-clock
3d printed casing - design no.3
3d printed casing - design no.3
https://www.printables.com/model/1027025-no3-3d-printed-casing-for-flip-disc-binary-clock
Flip-disc Binary Clock Repository
Flip-disc Binary Clock Repository
https://github.com/marcinsaj/Flipo-Binary-Clock-2x6-Flip-Disc-Display
Arduino MiniCore
An Arduino core for the ATmega328
https://github.com/MCUdude/MiniCore
Flipdisc Arduino Library
Arduino Library for Flip-disc Displays
https://github.com/marcinsaj/FlipDisc
2x6 Flip-disc Display Repository
2x6 Flip-disc Display Repository
https://github.com/marcinsaj/Flipo-2x6-Flip-Disc-Display
Comments
Only logged in users can leave comments