Skip to content

Commit 3d4f675

Browse files
committed
Network bugfix; todo update
1 parent f5fb731 commit 3d4f675

File tree

7 files changed

+91
-102
lines changed

7 files changed

+91
-102
lines changed

TODO.md

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,21 @@
11
# To-dos
22

3-
* Persistent storage for EEPROM stuff on SAMD
3+
* Rename project to arduino-clock with first push of v2+ - replace instances of arduino-nixie within
4+
* Reintroduce nixie clean and scroll
5+
* Persistent storage on EEPROM - find a solution that writes to flash less often
46
* Network/NTP
7+
* Persistent storage for wi-fi credentials!
58
* Why does the page sometimes drop?
6-
* Persistent storage for wi-fi credentials
79
* wi-fi credential save fails if keys are part of the string?
810
* DST calc may behave unpredictably between 1–2am on fallback day
911
* Redo NTP on startup if it failed (networkStartWifi())
1012
* Handle 2038+ epochs
1113
* Notice when a leap second is coming and handle it
1214
* When setting page is used to set day counter and date, and the month changes, set date max. For 2/29 it should just do 3/1 probably.
15+
* Weather support
16+
* Input: support other IMU orientations
1317
* When day counter is set to count up from 12/31, override to display 365/366 on that date
14-
* Bitmask to enable/disable features
18+
* Bitmask to enable/disable features?
1519
* Option to display weekdays as Sun=0 or Sun=1 (per Portuguese!)
1620
* Is it possible to trip the chime *after* determining if we're in night shutoff or not
1721
* In display code, consider using `delayMicroseconds()` which, with its tighter resolution, may give better control over fades and dim levels

arduino-nixie/arduino-nixie.ino

Lines changed: 47 additions & 67 deletions
Original file line numberDiff line numberDiff line change
@@ -21,12 +21,12 @@ const bool vDev = 1;
2121
#if ENABLE_DATE_RISESET //this probably doesn't work, per the above, but ¯\_(ツ)_/¯
2222
#include <Dusk2Dawn.h> //DM Kishi - unlicensed - install in your Arduino IDE if needed - test without
2323
#endif
24-
#include "storage.h"; //for persistent storage - supports both AVR EEPROM and SAMD flash
24+
#include "storage.h" //for persistent storage - supports both AVR EEPROM and SAMD flash
2525
#include "dispNixie.h" //if DISP_NIXIE is defined in config - for a SN74141-multiplexed nixie array
2626
#include "dispMAX7219.h" //if DISP_MAX7219 is defined in config - for a SPI MAX7219 8x8 LED array
2727
#include "rtcDS3231.h" //if RTC_DS3231 is defined in config – for an I2C DS3231 RTC module
2828
#include "rtcMillis.h" //if RTC_MILLIS is defined in config – for a fake RTC based on millis
29-
#include "input.h"; //for Sel/Alt/Up/Dn - supports buttons, rotary control, and Nano 33 IoT IMU
29+
#include "input.h" //for Sel/Alt/Up/Dn - supports buttons, rotary control, and Nano 33 IoT IMU
3030
#include "network.h" //if not AVR – enables WiFi/web-based config/NTP sync on Nano 33 IoT WiFiNINA
3131

3232

@@ -155,10 +155,10 @@ unsigned int tempValDispLast = 0;
155155
////////// Main code control //////////
156156

157157
void setup(){
158-
//Serial.begin(9600);
159-
//#ifndef __AVR__ //SAMD only
160-
//while(!Serial);
161-
//#endif
158+
Serial.begin(9600);
159+
#ifndef __AVR__ //SAMD only
160+
while(!Serial);
161+
#endif
162162
rtcInit();
163163
initStorage(); //pulls persistent storage data into volatile vars - see storage.cpp
164164
byte changed = initEEPROM(false); //do a soft init to make sure vals in range
@@ -168,9 +168,7 @@ void setup(){
168168
versionShowing = 1;
169169
//skip network for now, since wifi connect hangs - we'll do it after version is done
170170
} else {
171-
#ifdef NETWORK_SUPPORTED
172-
initNetwork();
173-
#endif
171+
if(networkSupported()) initNetwork();
174172
}
175173

176174
//Some settings need to be set to a fixed value per the configuration.
@@ -221,9 +219,7 @@ void loop(){
221219
checkRTC(false); //if clock has ticked, decrement timer if running, and updateDisplay
222220
millisApplyDrift();
223221
checkInputs(); //if inputs have changed, this will do things + updateDisplay as needed
224-
#ifdef NETWORK_SUPPORTED
225-
cycleNetwork();
226-
#endif
222+
if(networkSupported()) cycleNetwork();
227223
cycleTimer();
228224
cycleDisplay(displayDim,fnSetPg); //keeps the display hardware multiplexing cycle going
229225
cycleBacklight();
@@ -246,9 +242,7 @@ void ctrlEvt(byte ctrl, byte evt, byte evtLast, bool velocity){
246242
if(ctrl==CTRL_SEL && (evt==0 || evt==5)){ //SEL release or superlong hold
247243
if(evt==5){ initEEPROM(true); commitEEPROM(); } //superlong hold: reset EEPROM
248244
versionShowing = false; inputStop(); updateDisplay();
249-
#ifdef NETWORK_SUPPORTED
250-
initNetwork(); //we didn't do this earlier since the wifi connect makes the clock hang
251-
#endif
245+
if(networkSupported()) initNetwork(); //we didn't do this earlier since the wifi connect makes the clock hang
252246
return;
253247
} else {
254248
return; //ignore other controls
@@ -308,18 +302,18 @@ void ctrlEvt(byte ctrl, byte evt, byte evtLast, bool velocity){
308302
return;
309303
}
310304

311-
#ifdef NETWORK_SUPPORTED
312-
//Short hold, Alt; or very long hold, Sel if no Alt: start admin
313-
if((evt==2 && ctrl==CTRL_ALT)||(evt==4 && ctrl==CTRL_SEL && CTRL_ALT<=0)) {
314-
networkStartAdmin();
315-
return;
316-
}
317-
//Super long hold, Alt, or Sel if no Alt: start AP (TODO would we rather it forget wifi?)
318-
if(evt==5 && (ctrl==CTRL_ALT || (ctrl==CTRL_SEL && CTRL_ALT<=0))) {
319-
networkStartAP();
320-
return;
305+
if(networkSupported()){
306+
//Short hold, Alt; or very long hold, Sel if no Alt: start admin
307+
if((evt==2 && ctrl==CTRL_ALT)||(evt==4 && ctrl==CTRL_SEL && CTRL_ALT<=0)) {
308+
networkStartAdmin();
309+
return;
310+
}
311+
//Super long hold, Alt, or Sel if no Alt: start AP (TODO would we rather it forget wifi?)
312+
if(evt==5 && (ctrl==CTRL_ALT || (ctrl==CTRL_SEL && CTRL_ALT<=0))) {
313+
networkStartAP();
314+
return;
315+
}
321316
}
322-
#endif
323317

324318
if(fn < FN_OPTS) { //normal fn running/setting (not in settings menu)
325319

@@ -410,15 +404,12 @@ void ctrlEvt(byte ctrl, byte evt, byte evtLast, bool velocity){
410404
else if(CTRL_ALT>0 && ctrl==CTRL_ALT) {
411405
//if soft power switch, we'll switch on release - but only if not held past activating settings page/AP
412406
if(ENABLE_SOFT_POWER_SWITCH && SWITCH_PIN>=0) {
413-
if(evt==0
414-
#ifdef NETWORK_SUPPORTED
415-
&& evtLast<2 //if holds are used to activate settings page/AP, do not switch. If not, switch no matter how long held.
416-
#endif
417-
) switchPower(2);
407+
//If holds are used to activate network stuff, and we've passed those thresholds, do not switch.
408+
//Otherwise, switch no matter how long held.
409+
if(evt==0 && !(networkSupported() && evtLast<2)) switchPower(2);
418410
}
419-
#ifndef NETWORK_SUPPORTED
420411
//If neither soft power switch nor network support, this becomes our function preset
421-
else {
412+
else if(!networkSupported()) {
422413
//On long hold, if this is not currently the preset, we'll set it, double beep, and inputStop.
423414
//(Decided not to let this button set things, because then it steps on the toes of Sel's functionality.)
424415
if(evt==2) {
@@ -441,7 +432,6 @@ void ctrlEvt(byte ctrl, byte evt, byte evtLast, bool velocity){
441432
updateDisplay();
442433
}
443434
}
444-
#endif
445435
} //end alt
446436
} //end fn running
447437

@@ -460,9 +450,7 @@ void ctrlEvt(byte ctrl, byte evt, byte evtLast, bool velocity){
460450
case FN_TOD: //save in RTC
461451
if(fnSetValDid){ //but only if the value was actually changed
462452
rtcSetTime(fnSetVal/60,fnSetVal%60,0);
463-
#ifdef NETWORK_SUPPORTED
464-
ntpSyncLast = 0;
465-
#endif
453+
if(networkSupported()) clearNTPSyncLast();
466454
millisAtLastCheck = 0; //see ms()
467455
calcSun();
468456
isDSTByHour(rtcGetYear(),rtcGetMonth(),rtcGetDate(),fnSetVal/60,true);
@@ -482,9 +470,7 @@ void ctrlEvt(byte ctrl, byte evt, byte evtLast, bool velocity){
482470
case 3: //write year/month/date to RTC
483471
rtcSetDate(fnSetValDate[0],fnSetValDate[1],fnSetVal,
484472
dayOfWeek(fnSetValDate[0],fnSetValDate[1],fnSetVal));
485-
#ifdef NETWORK_SUPPORTED
486-
ntpSyncLast = 0;
487-
#endif
473+
if(networkSupported()) clearNTPSyncLast();
488474
calcSun();
489475
isDSTByHour(fnSetValDate[0],fnSetValDate[1],fnSetVal,rtcGetHour(),true);
490476
clearSet(); break;
@@ -752,9 +738,7 @@ bool initEEPROM(bool hard){
752738
if(hard) {
753739
rtcSetDate(2021,1,1,dayOfWeek(2021,1,1));
754740
rtcSetTime(0,0,0);
755-
#ifdef NETWORK_SUPPORTED
756-
ntpSyncLast = 0;
757-
#endif
741+
if(networkSupported()) clearNTPSyncLast();
758742
}
759743
//The vars outside the settings menu
760744
if(hard || readEEPROM(0,true)>1439) changed += writeEEPROM(0,420,true,false); //0-1: alarm at 7am
@@ -767,24 +751,24 @@ bool initEEPROM(bool hard){
767751
//8: TODO functions/pages enabled (bitmask)
768752
if(hard || readEEPROM(9,false)>1) changed += writeEEPROM(9,1,false,false); //9: NTP sync on
769753
if(hard) changed += writeEEPROM(15,0,false,false); //15: last known DST on flag - clear on hard reset (to match the reset RTC/auto DST/anti-poisoning settings to trigger midnight tubes as a tube test)
770-
#ifdef NETWORK_SUPPORTED
771-
if(hard){ //everything in here needs no range testing
772-
//51-54 NTP server IP address (4 bytes) - e.g. from https://tf.nist.gov/tf-cgi/servers.cgi
773-
//Serial.println(F("setting IP address in eeprom"));
774-
//Serial.print(readEEPROM(51,false),DEC); Serial.print(F(".")); Serial.print(readEEPROM(52,false),DEC); Serial.print(F(".")); Serial.print(readEEPROM(53,false),DEC); Serial.print(F(".")); Serial.println(readEEPROM(54,false),DEC);
775-
changed += writeEEPROM(51,129,false,false);
776-
changed += writeEEPROM(52, 6,false,false);
777-
changed += writeEEPROM(53, 15,false,false);
778-
changed += writeEEPROM(54, 27,false,false);
779-
//Serial.print(readEEPROM(51,false),DEC); Serial.print(F(".")); Serial.print(readEEPROM(52,false),DEC); Serial.print(F(".")); Serial.print(readEEPROM(53,false),DEC); Serial.print(F(".")); Serial.println(readEEPROM(54,false),DEC);
780-
//55-86 Wi-Fi SSID (32 bytes)
781-
//TODO
782-
//87-150 Wi-Fi WPA passphrase/key or WEP key (64 bytes)
783-
//TODO
784-
}
785-
//151 Wi-Fi WEP key index
786-
if(hard || readEEPROM(151,false)>3) changed += writeEEPROM(151,0,false,false);
787-
#endif
754+
if(networkSupported()){
755+
if(hard){ //everything in here needs no range testing
756+
//51-54 NTP server IP address (4 bytes) - e.g. from https://tf.nist.gov/tf-cgi/servers.cgi
757+
//Serial.println(F("setting IP address in eeprom"));
758+
//Serial.print(readEEPROM(51,false),DEC); Serial.print(F(".")); Serial.print(readEEPROM(52,false),DEC); Serial.print(F(".")); Serial.print(readEEPROM(53,false),DEC); Serial.print(F(".")); Serial.println(readEEPROM(54,false),DEC);
759+
changed += writeEEPROM(51,129,false,false);
760+
changed += writeEEPROM(52, 6,false,false);
761+
changed += writeEEPROM(53, 15,false,false);
762+
changed += writeEEPROM(54, 27,false,false);
763+
//Serial.print(readEEPROM(51,false),DEC); Serial.print(F(".")); Serial.print(readEEPROM(52,false),DEC); Serial.print(F(".")); Serial.print(readEEPROM(53,false),DEC); Serial.print(F(".")); Serial.println(readEEPROM(54,false),DEC);
764+
//55-86 Wi-Fi SSID (32 bytes)
765+
//TODO
766+
//87-150 Wi-Fi WPA passphrase/key or WEP key (64 bytes)
767+
//TODO
768+
}
769+
//151 Wi-Fi WEP key index
770+
if(hard || readEEPROM(151,false)>3) changed += writeEEPROM(151,0,false,false);
771+
} //end network supported
788772
//The vars inside the settings menu
789773
bool isInt = false;
790774
for(byte opt=0; opt<sizeof(optsLoc); opt++) {
@@ -945,13 +929,11 @@ void checkRTC(bool force){
945929
// }
946930
}
947931

948-
#ifdef NETWORK_SUPPORTED
949932
//NTP cue at :59:00
950-
if(readEEPROM(9,false) && rtcGetMinute()==59){
933+
if(rtcGetMinute()==59 && networkSupported() && readEEPROM(9,false)){
951934
if(rtcGetSecond()==0) cueNTP();
952935
if(rtcGetSecond()==30 && ntpSyncAgo()>=30000) cueNTP(); //if at first you don't succeed...
953936
}
954-
#endif
955937

956938
//Strikes - only if fn=clock, not setting, not signaling/snoozing, not night/away. Setting 21 will be off if signal type is no good
957939
//The six pips
@@ -1418,9 +1400,7 @@ void updateDisplay(){
14181400
editDisplay(hr, 0, 1, readEEPROM(19,false), true);
14191401
editDisplay(rtcGetMinute(), 2, 3, true, true);
14201402
//Serial.print(millis(),DEC); Serial.println(F("show display per regular (hours/mins at least)"));
1421-
#ifdef NETWORK_SUPPORTED
1422-
if(readEEPROM(9,false) && ntpSyncAgo()>=86400000){ blankDisplay(4,5,true); break; }
1423-
#endif
1403+
if(networkSupported() && readEEPROM(9,false) && ntpSyncAgo()>=86400000){ blankDisplay(4,5,true); break; }
14241404
if(readEEPROM(18,false)==1) editDisplay(rtcGetDate(), 4, 5, readEEPROM(19,false), true); //date
14251405
else editDisplay(rtcGetSecond(), 4, 5, true, true); //seconds
14261406
break;

arduino-nixie/configs/led-iot.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@
3232
///// Inputs /////
3333
//If using IMU motion sensor on Nano 33 IoT:
3434
//To use, tilt clock: backward=Sel, forward=Alt, left=Down, right=Up
35-
//This is mutually exclusive with the button/rotary controls. TODO make it possible to use both together by renaming the functions or abstracting basic input functionality
35+
//This is mutually exclusive with the button/rotary controls.
3636
#define INPUT_IMU
3737
//Which side of the IMU/Arduino faces clock front/side? 0=bottom, 1=top, 2=left side, 3=right side, 4=USB end, 5=butt end
3838
#define IMU_FRONT 0 //(UNDB: 0)

arduino-nixie/dispMAX7219.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ void initDisplay(){
1717
for(int i=0; i<NUM_MAX; i++) { lc.shutdown(i,false); lc.setIntensity(i,curBrightness); }
1818
}
1919

20-
//TODO can we move this into flash?
20+
//TODO can we move this into flash with e.g. PROGMEM? or does that happen already?
2121
const char bignumWidth = 5;
2222
byte bignum[50]={ //First four digits - chicagolike 5x8
2323
B01111110, B11111111, B10000001, B11111111, B01111110, // 0

arduino-nixie/network.cpp

Lines changed: 24 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@
33

44
#ifndef __AVR__ //TODO better sensor
55
//do stuff for wifinina
6-
#define NETWORK_SUPPORTED
76

87
#include "network.h"
98
#include <WiFiNINA.h>
@@ -33,10 +32,20 @@ WiFiServer server(80);
3332
#define NTP_MINFREQ 5000 //how long to enforce a wait between request starts (NIST requires at least 4sec between requests or will ban the client)
3433
#define NTPOK_THRESHOLD 3600000 //if no sync within 60 minutes, the time is considered stale
3534

36-
//Declare a few functions so I can put them out of order
37-
//Placed here so I can avoid making header files for the moment
38-
void cueNTP();
39-
bool checkNTP();
35+
bool networkSupported(){ return true; }
36+
37+
void initNetwork(){
38+
Serial.println(F("Hello world from network.cpp"));
39+
//Check status of wifi module up front
40+
//if(WiFi.status()==WL_NO_MODULE){ Serial.println(F("Communication with WiFi module failed!")); while(true); }
41+
//else if(WiFi.firmwareVersion()<WIFI_FIRMWARE_LATEST_VERSION) Serial.println(F("Please upgrade the firmware"));
42+
networkStartWiFi();
43+
}
44+
void cycleNetwork(){
45+
checkClients();
46+
checkNTP();
47+
checkForWiFiStatusChange();
48+
}
4049

4150
int statusLast;
4251
void checkForWiFiStatusChange(){
@@ -61,7 +70,7 @@ void checkForWiFiStatusChange(){
6170

6271
void networkStartWiFi(){
6372
WiFi.end(); //if AP is going, stop it
64-
if(wssid==F("")) return; //don't try to connect if there's no creds
73+
if(wssid==F("")){ Serial.println(F("no start wifi")); return; } //don't try to connect if there's no creds
6574
checkForWiFiStatusChange(); //just for serial logging
6675
//Serial.print(millis(),DEC); Serial.println(F("blank display per start wifi"));
6776
blankDisplay(0,5,false); //I'm guessing if it hangs, nixies won't be able to display anyway
@@ -283,6 +292,11 @@ bool checkNTP(){ //Called on every cycle to see if there is an ntp response to h
283292
}
284293
} //end fn checkNTP
285294

295+
void clearNTPSyncLast(){
296+
//called when other code divorces displayed time from NTP sync
297+
ntpSyncLast = 0;
298+
}
299+
286300
unsigned long adminInputLast = 0; //for noticing when the admin page hasn't been interacted with in 2 minutes, so we can time it (and AP if applicable) out
287301

288302
void networkStartAdmin(){
@@ -878,16 +892,8 @@ void checkClients(){
878892
}
879893
}
880894

881-
void initNetwork(){
882-
//Check status of wifi module up front
883-
//if(WiFi.status()==WL_NO_MODULE){ Serial.println(F("Communication with WiFi module failed!")); while(true); }
884-
//else if(WiFi.firmwareVersion()<WIFI_FIRMWARE_LATEST_VERSION) Serial.println(F("Please upgrade the firmware"));
885-
networkStartWiFi();
886-
}
887-
void cycleNetwork(){
888-
checkClients();
889-
checkNTP();
890-
checkForWiFiStatusChange();
891-
}
895+
#else
896+
897+
bool networkSupported(){ return false; }
892898

893-
#endif
899+
#endif //__AVR__ (network supported)

arduino-nixie/network.h

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,7 @@
11
#ifndef NETWORK_H
22
#define NETWORK_H
33

4-
//#ifndef __AVR__ //TODO better sensor
5-
4+
bool networkSupported();
65
void checkForWiFiStatusChange();
76
void networkStartWiFi();
87
void networkStartAP();
@@ -11,12 +10,11 @@ unsigned long ntpSyncAgo();
1110
void cueNTP();
1211
int startNTP(bool synchronous);
1312
bool checkNTP();
13+
void clearNTPSyncLast();
1414
void networkStartAdmin();
1515
void networkStopAdmin();
1616
void checkClients();
1717
void initNetwork();
1818
void cycleNetwork();
1919

20-
//#endif //ifndef __AVR__
21-
2220
#endif //NETWORK_H

0 commit comments

Comments
 (0)