1
1
/* ----------------------------------------------------------------------------------*
2
- A simple clock that reads from a DS1302 RTC and shows the time on 4 x 7-segment displays
2
+ A simple clock that reads the time from the internet and shows the time on 4 x 7-segment displays
3
3
Example connection diagram: https://bit.ly/4x7SEG-3x1DOT
4
4
5
5
The MIT License
25
25
The declaration of DIN (MOSI) and CLK (SCK) is not necessary,
26
26
because the SPI.h library handles the SPI hardware pins. */
27
27
28
+ // Use "NodeMCU 0.9 (ESP-12) to program (NOT Generic8266)
29
+ #include < ESP8266WiFi.h>
30
+ #include < time.h>
31
+ #include < coredecls.h> // required for settimeofday_cb()
28
32
#include < FlipDisc.h> // https://github.com/marcinsaj/FlipDisc
29
- #include < RtcDS1302.h>
30
33
31
- ThreeWire myWire (2 , 3 , 4 ); // IO, SCLK, CE
32
- RtcDS1302<ThreeWire> Rtc (myWire);
34
+ #include " config.h"
35
+ const char * ssid = SECRET_SSID;
36
+ const char * pass = SECRET_PWD;
33
37
34
- // Standard pin declaration for Arduino Uno and PSPS module
35
- #define EN_PIN 10
36
- #define CH_PIN 8
37
- #define PL_PIN 9
38
+ // Pin definitions for the 7-segment clock
39
+ #define EN_PIN D1
40
+ #define CH_PIN D2
41
+ #define PL_PIN D3
38
42
39
- // Note, MOSI (DataIn), Clk (SCK) are defaulted to 11 and 13, respectively.
40
-
41
- RtcDateTime last;
43
+ // Note, MOSI (DataIn), Clk (SCK) are defaulted to D7 and D5, respectively on the 8266 I have
42
44
43
45
void setup ()
44
46
{
45
- Serial.begin (57600 );
47
+ // use only the WiFi 'station' mode
48
+ WiFi.mode (WIFI_STA);
46
49
47
- Serial.print (" compiled: " );
48
- Serial.print (__DATE__);
49
- Serial.println (__TIME__);
50
+ Serial.begin (115200 );
51
+ Serial.println (" Hello 4x7seg-flip-disc-clock-wifi" );
50
52
51
53
/* Flip.Pin(); it is the most important function and first to call before everything else.
52
54
The function is used to declare pin functions. Before starting the device, double check
@@ -74,74 +76,73 @@ void setup()
74
76
Flip.Test ();
75
77
delay (500 );
76
78
77
- Flip.Matrix_7Seg (I, N, I, T);
78
- delay (500 );
79
- Flip.Matrix_7Seg (R, T, C, CLR);
80
- delay (500 );
79
+ // send credentials
80
+ WiFi.begin (ssid, pass);
81
+
82
+ Serial.println (" Connecting" );
83
+ Flip.Matrix_7Seg (C, O, N, N);
84
+ int dot = 0 ;
85
+ // wait for connection
86
+ while (WiFi.status () != WL_CONNECTED) {
87
+ delay (500 );
88
+ Flip.Disc_7Seg (1 , dot % 23 , dot % 2 ); // last argument can be 0 to turn off
89
+ dot++;
90
+ Serial.print (" ." );
91
+ }
92
+ Serial.println (" Connected" );
93
+ Flip.Matrix_7Seg (G, O, O, D);
94
+ delay (1000 );
81
95
82
- Rtc.Begin ();
96
+ // implement NTP update of timekeeping (with automatic hourly updates)
97
+ configTime (0 , 0 , " 0.pool.ntp.org" );
83
98
84
- RtcDateTime compiled = RtcDateTime (__DATE__, __TIME__);
85
- printDateTime (compiled);
86
- Serial.println ();
99
+ // info to convert UNIX time to local time (including automatic DST update)
100
+ setenv (" TZ" , " EST+5EDT,M3.2.0/2:00:00,M11.1.0/2:00:00" , 1 );
87
101
88
- if (!Rtc.IsDateTimeValid ())
89
- {
90
- // Common Causes:
91
- // 1) first time you ran and the device wasn't running yet
92
- // 2) the battery on the device is low or even missing
102
+ time_t last = time (nullptr );
93
103
94
- Serial.println (" RTC lost confidence in the DateTime!" );
95
- Flip.Matrix_7Seg (S, E, T, CLR);
96
- delay (1000 );
97
- Rtc.SetDateTime (compiled);
98
- }
104
+ // convert the system (UNIX) time to a local date and time in a configurable format
105
+ struct tm * last_tm = localtime (&last); // break down the timestamp
106
+ showTime (last_tm->tm_hour , last_tm->tm_min );
99
107
100
- if (Rtc.GetIsWriteProtected ())
101
- {
102
- Serial.println (" RTC was write protected, enabling writing now" );
103
- Rtc.SetIsWriteProtected (false );
104
- Flip.Matrix_7Seg (R, T, W, P);
105
- delay (1000 );
106
- }
108
+ // register a callback (execute whenever an NTP update has occurred)
109
+ settimeofday_cb (timeUpdated);
110
+ }
107
111
108
- if (!Rtc.GetIsRunning ())
109
- {
110
- Serial.println (" RTC was not actively running, starting now" );
111
- Rtc.SetIsRunning (true );
112
- Flip.Matrix_7Seg (S, T, R, T);
113
- delay (1000 );
114
- }
112
+ int last_hour;
113
+ int last_min;
115
114
116
- RtcDateTime now = Rtc.GetDateTime ();
117
- if (now < compiled)
118
- {
119
- Serial.println (" RTC is older than compile time! (Updating DateTime)" );
120
- Rtc.SetDateTime (compiled);
121
- Flip.Matrix_7Seg (R, T, U, P);
122
- delay (1000 );
123
- }
124
- else if (now > compiled)
125
- {
126
- Serial.println (" RTC is newer than compile time. (this is expected)" );
127
- }
128
- last = Rtc.GetDateTime ();
129
- showTime (last);
130
- }
115
+ // callback routine - arrive here whenever a successful NTP update has occurred
116
+ void timeUpdated () {
117
+ time_t last = time (nullptr ); // get UNIX timestamp
118
+ struct tm *last_tm = localtime (&last); // convert to local time and break down
119
+ showTime (last_tm->tm_hour , last_tm->tm_min );
131
120
132
- void showTime (RtcDateTime now) {
133
- printDateTime (now);
134
- Serial.println ();
121
+ char UPDATE_TIME[50 ]; // buffer for use by strftime()
122
+ strftime (UPDATE_TIME, sizeof (UPDATE_TIME), " %T" , last_tm); // extract just the 'time' portion
135
123
136
- int hour = now.Hour ();
124
+ Serial.print (" -------- NTP update at " );
125
+ Serial.print (UPDATE_TIME);
126
+ Serial.println (" --------" );
127
+ }
128
+
129
+ // Show the time; update the globals with the "last time shown"
130
+ void showTime (int hour, int minute) {
131
+ last_hour = hour;
132
+ last_min = minute;
137
133
if (hour > 12 ) {
138
134
hour -= 12 ;
139
135
}
140
136
int hr10 = hour / 10 ;
141
137
int hr1 = hour % 10 ;
142
- int min10 = now.Minute () / 10 ;
143
- int min1 = now.Minute () % 10 ;
144
- Serial.print (" Clock is: " ); Serial.print (hr10); Serial.print (hr1); Serial.print (" :" ); Serial.print (min10); Serial.println (min1);
138
+ int min10 = minute / 10 ;
139
+ int min1 = minute % 10 ;
140
+ Serial.print (" Clock is: " );
141
+ Serial.print (hr10);
142
+ Serial.print (hr1);
143
+ Serial.print (" :" );
144
+ Serial.print (min10);
145
+ Serial.println (min1);
145
146
146
147
// Clear first digit if zero.
147
148
if (hr10 == 0 ) {
@@ -154,91 +155,48 @@ void showTime(RtcDateTime now) {
154
155
This function allows you to display numbers and symbols
155
156
Flip.Matrix_7Seg(data1,data2,data3,data4,data5,data6,data7,data8); */
156
157
Flip.Matrix_7Seg (hr10, hr1, min10, min1);
158
+ Serial.println (" showTime End" );
157
159
}
158
160
159
- void loop ()
160
- {
161
- RtcDateTime now = Rtc.GetDateTime ();
162
- if (now.Hour () != last.Hour () || now.Minute () != last.Minute ()) {
161
+ // Main loop: get the current time; if it's different than last shown time, show it.
162
+ void loop () {
163
+ time_t now_t = time (nullptr );
164
+ // convert the system (UNIX) time to a local date and time in a configurable format
165
+ struct tm *now = localtime (&now_t );
166
+ if (now->tm_hour != last_hour) {
167
+ Serial.println (" different hours" );
168
+ }
169
+ if (now->tm_min != last_min) {
170
+ Serial.println (" different min" );
171
+ }
172
+ if (now->tm_hour != last_hour || now->tm_min != last_min) {
163
173
// Hour or minute is different; update the whole clock.
164
- showTime (now);
165
- last = now;
166
- } else if (now.Second () != last.Second ()) {
167
- /* An example of calling the function to set disc no.19 of the first 7-Segment display */
168
- /* 0 1 2 3 4
169
- 19 5
170
- 18 6
171
- 17 20 21 22 7
172
- 16 8
173
- 15 9
174
- 14 13 12 11 10 */
175
- // Flip one disc in the leftmost column to indicate 10s of seconds
176
- for (int i = 0 ; i <= now.Second () / 10 ; i++) {
177
- Flip.Disc_7Seg (1 , 14 + i, 1 ); // last argument can be 0 to turn off
178
- }
174
+ Serial.print (" last_tm: " );
175
+ Serial.print (last_hour);
176
+ Serial.print (" :" );
177
+ Serial.println (last_min);
178
+
179
+ Serial.print (" now: " );
180
+ Serial.print (now->tm_hour );
181
+ Serial.print (" :" );
182
+ Serial.print (now->tm_min );
183
+ Serial.print (" :" );
184
+ Serial.println (now->tm_sec );
185
+
186
+ showTime (now->tm_hour , now->tm_min );
179
187
}
180
188
181
- /* 7-Segment displays allow the display of numbers and symbols.
182
- Symbols can be displayed using their code name or number e.g. 37/DEG - "°" Degree symbol
183
- The full list of symbols can be found in the FlipDisc.h library repository https://github.com/marcinsaj/FlipDisc
184
- Code names for symbols:
185
- - 0-9
186
- - 1/VLR - " |" - Vertical line - right
187
- - 8/ALL - Set all discs
188
- - 10/CLR - Clear display
189
- - 11/A
190
- - 12/B
191
- - 13/C
192
- - 14/D
193
- - 15/E
194
- - 16/F
195
- - 17/G
196
- - 18/H
197
- - 19/I
198
- - 20/J
199
- - 21/K
200
- - 22/L
201
- - 23/M
202
- - 24/N
203
- - 25/O
204
- - 26/P
205
- - 27/Q
206
- - 28/R
207
- - 29/S
208
- - 30/T
209
- - 31/U
210
- - 32/V
211
- - 33/W
212
- - 34/X
213
- - 35/Y
214
- - 36/Z
215
- - 37/DEG - "°" - Degree symbol
216
- - 37/PFH - "%" - Percent first half symbol
217
- - 38/PSH - "%" - Percent second half symbol
218
- - 39/HLU - "¯" - Horizontal line - upper
219
- - 40/HLM - "-" - Horizontal line - middle
220
- - 41/HLL - "_" - Horizontal line - lower
221
- - 42/HLT - "=" - Horizontal line - upper & lower
222
- - 43/HLA - "≡" - All three lines
223
- - 40/MIN - "-" - Minus symbol
224
- - 44/VLL - "| " - Vertical line - left
225
- - 45/VLA - "||" - All Vertical lines */
226
- }
227
-
228
- #define countof (a ) (sizeof (a) / sizeof (a[0 ]))
229
-
230
- void printDateTime (const RtcDateTime& dt)
231
- {
232
- char datestring[26 ];
233
-
234
- snprintf_P (datestring,
235
- countof (datestring),
236
- PSTR (" %02u/%02u/%04u %02u:%02u:%02u" ),
237
- dt.Month (),
238
- dt.Day (),
239
- dt.Year (),
240
- dt.Hour (),
241
- dt.Minute (),
242
- dt.Second () );
243
- Serial.print (datestring);
189
+ /* An example of calling the function to set disc no.19 of the first 7-Segment display */
190
+ /* 0 1 2 3 4
191
+ 19 5
192
+ 18 6
193
+ 17 20 21 22 7
194
+ 16 8
195
+ 15 9
196
+ 14 13 12 11 10 */
197
+ // Flip one disc in the leftmost column to indicate 10s of seconds. I don't love this.
198
+ for (int i = 0 ; i <= now->tm_sec / 10 ; i++) {
199
+ Flip.Disc_7Seg (1 , 14 + i, 1 ); // last argument can be 0 to turn off
200
+ }
201
+ delay (250 );
244
202
}
0 commit comments