Just a simple Arduino project for the last day of the year: a Count Down Clock showing the time left until New Year.
Time is derived from a DS1307 RTC module and displayed on a 8×32 LED Matrix Module. At 23:00 hours, the initial HH:MM format will switch to MM:SS.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 |
/* When started on 31 December, shows the time left until New Year on an 8x32 LED matrix. Uses a DS1307 or DS3231 RTC module) Matrix: pin 12 is connected to the Din pin 11 is connected to the CLK pin 10 is connected to CS RTC Module: SDA to A4 SCL to A5 VCC of both modules to 5 volt */ #include "LedControl.h" #include <Wire.h> const int DS1307 = 0x68; // Address of DS1307 see data sheets static int nMods = 4; LedControl lc=LedControl(12,11,10,nMods); int j, k, m; int c[4]; // (moduleindex,kolomindex} van rechterkolom voor de vier cijferposities int rpos[4][2] = { {0,1}, // Hh {1,3}, // hH {2,1}, // Mm {3,3} // mM }; // elk cijfer (1-ste index) beschreven van links naar rechts (5 kolommen) static int digits[10][5] = { { 0x7c, 0xa2, 0x92, 0x8a, 0x7c}, // 0 { 0x00, 0x84, 0xfe, 0x80, 0x00}, // 1 { 0xc4, 0xa2, 0x92, 0x92, 0x8c}, // 2 { 0x44, 0x82, 0x92, 0x92, 0x6c}, // 3 { 0x30, 0x28, 0x24, 0xfe, 0x20}, // 4 { 0x4e, 0x8a, 0x8a, 0x8a, 0x72}, // 5 { 0x78, 0x94, 0x92, 0x92, 0x60}, // 6 { 0x02, 0xe2, 0x12, 0x0a, 0x06}, // 7 { 0x6c, 0x92, 0x92, 0x92, 0x6c}, // 8 { 0x0c, 0x92, 0x92, 0x52, 0x3c} // 9 }; // Initializes all values: byte second = 0; byte minute = 0; byte hour = 0; byte second2 = 0; byte minute2 = 0; byte hour2 = 0; byte weekday = 0; byte monthday = 0; byte month = 0; byte year = 0; void setup() { Wire.begin(); delay(2000); // This delay allows the MCU to read the current date and time. for (j=0;j<nMods;j++) { lc.shutdown(j,false); lc.setIntensity(j,1); lc.clearDisplay(j); } } void loop() { readTime(); if (hour==0 && minute==0 && second==0) { // Flashing New Year in endless loop int y[4]; y[0] = 2; y[1] = 0; y[3] = year%10; y[2] = (year-y[3])/10; while(1) { for(m=0;m<4;m++) { k=0; for (j=m+4;j>=m;j--) { lc.setColumn(m,j,digits[y[m]][k]); k++; } } delay(500); for (j=0;j<4;j++) { lc.clearDisplay(j); } delay(500); } } // Not there yet: calculate the hours, minutes and seconds until midnight /* Just for the challenge, I decided not to use any 'if...then' loops for this. I figured out how it can be done with using abs(), max() and min() instead. */ second2=(60-second)%60; minute2=(60-minute-abs(min(0,-second))/max(abs(-second),1))%60; hour2=(24-hour-abs(min(0,-minute-abs(min(0,-second))/max(abs(-second),1)))/max(abs(-minute-abs(min(0,-second))/max(abs(-second),1)),1))%24; // display mode selection (there are only 4 digits) if (hour != 23) { // Display HH:MM c[1] = hour2%10; c[0]= (hour2-c[1])/10; c[3] = minute2%10; c[2] =(minute2-c[3])/10; } else { // Display MM:SS c[1] = minute2%10; c[0]= (minute2-c[1])/10; c[3] = second2%10; c[2] =(second2-c[3])/10; } for (int p=3;p>=0;p--) { m = rpos[p][0]; //moduleindex rechterkolom van het cijfer op positie p (zero offset) k = rpos[p][1]; //kolomindex rechterkolom van het cijfer op positie p (zero offset) for (j=4;j>=0;j--) { lc.setColumn(m,k,digits[c[p]][j]); k++; if (k>7) { k=0; m--; } } } // scheidingsteken lc.setColumn(1,0,0x44); delay(20); } byte decToBcd(byte val) { return ((val/10*16) + (val%10)); } byte bcdToDec(byte val) { return ((val/16*10) + (val%16)); } void readTime() { Wire.beginTransmission(DS1307); Wire.write(byte(0)); Wire.endTransmission(); Wire.requestFrom(DS1307, 7); second = bcdToDec(Wire.read()); minute = bcdToDec(Wire.read()); hour = bcdToDec(Wire.read()); weekday = bcdToDec(Wire.read()); monthday = bcdToDec(Wire.read()); month = bcdToDec(Wire.read()); year = bcdToDec(Wire.read()); } |