Skip to content

Commit 04a10d1

Browse files
committed
Add additional functionality switches in config (v8 6tube only)
Also extend running time of clean cycles and date pages
1 parent afa79bf commit 04a10d1

File tree

2 files changed

+79
-33
lines changed

2 files changed

+79
-33
lines changed

arduino-nixie/arduino-nixie.ino

Lines changed: 60 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -106,7 +106,8 @@ unsigned long inputLast2 = 0; //Second-to-last of above
106106
int inputLastTODMins = 0; //time of day, in minutes past midnight, when button was pressed. Used in paginated functions so they all reflect the same TOD.
107107

108108
const byte fnOpts = 201; //fn values from here to 255 correspond to options in the options menu
109-
byte fn = fnIsTime; //currently displayed fn (per fnsEnabled)
109+
byte fn = fnIsTime; //currently displayed fn per fnsEnabled in config
110+
byte fnsOn = 0; //which fns are enabled per fnsEnabled in config - one bit per fn unique ID - this limits the available fn unique IDs to 0–7; otherwise it could be 0–200 – if you need more than 7, change from a byte to a bigger data type
110111
byte fnPg = 0; //allows a function to have multiple pages
111112
byte fnSetPg = 0; //whether this function is currently being set, and which option/page it's on
112113
int fnSetVal; //the value currently being set, if any
@@ -154,7 +155,7 @@ void setup(){
154155
initInputs();
155156
delay(100); //prevents the below from firing in the event there's a capacitor stabilizing the input, which can read low falsely
156157
initEEPROM(readInput(mainSel)==LOW); //Do a hard init of EEPROM if button is held; else do a soft init to make sure vals in range
157-
//Some options need to be set to a fixed value per the hardware configuration.
158+
//Some options need to be set to a fixed value per the configuration.
158159
//These options will also be skipped in fnOptScroll so the user can't change them.
159160
if(relayPin<0 || piezoPin<0) { //If no relay or no piezo, set each signal output to [if no relay, then piezo; else relay]
160161
writeEEPROM(42,(relayPin<0?0:1),false); //alarm
@@ -166,11 +167,37 @@ void setup(){
166167
}
167168
if(piezoPin<0 && relayMode==0) { //If switched relay and no piezo
168169
writeEEPROM(21,0,false); //turn off strike
169-
//writeEEPROM(25,0,false); //turn off timer interval mode
170170
writeEEPROM(50,0,false); //turn off fibonacci mode
171171
}
172-
if(!enableSoftAlarmSwitch) alarmOn = 1; //force alarm on if software switch is disabled
172+
//Check to see which functions are enabled
173+
for(byte fnct=0; fnct<sizeof(fnsEnabled); fnct++){
174+
switch(fnsEnabled[fnct]){
175+
case fnIsTime: bitWrite(fnsOn,fnIsTime,1); break;
176+
case fnIsDate: bitWrite(fnsOn,fnIsDate,1); break;
177+
case fnIsAlarm: bitWrite(fnsOn,fnIsAlarm,1); break;
178+
case fnIsTimer: bitWrite(fnsOn,fnIsTimer,1); break;
179+
case fnIsTemp: bitWrite(fnsOn,fnIsTemp,1); break;
180+
case fnIsTubeTester: bitWrite(fnsOn,fnIsTubeTester,1); break;
181+
default: break;
182+
}
183+
}
184+
if(!((fnsOn>>fnIsAlarm)&1)) alarmOn = 0; //if alarm is disabled in config
185+
else if(!enableSoftAlarmSwitch) alarmOn = 1; //force alarm on if software switch is disabled
173186
else alarmOn = (readEEPROM(2,false)>0); //otherwise set alarm per EEPROM backup
187+
switch(readEEPROM(7,false)){ //if the preset is set to a function that is no longer enabled, use alarm if enabled, else use time
188+
case fnIsDate: if(!((fnsOn>>fnIsDate)&1)) writeEEPROM(7,(((fnsOn>>fnIsAlarm)&1)?fnIsAlarm:fnIsTime),false); break;
189+
case fnIsAlarm: if(!((fnsOn>>fnIsAlarm)&1)) writeEEPROM(7,fnIsTime,false); break;
190+
case fnIsTimer: if(!((fnsOn>>fnIsTimer)&1)) writeEEPROM(7,(((fnsOn>>fnIsAlarm)&1)?fnIsAlarm:fnIsTime),false); break;
191+
case fnIsTemp: if(!((fnsOn>>fnIsTemp)&1)) writeEEPROM(7,(((fnsOn>>fnIsAlarm)&1)?fnIsAlarm:fnIsTime),false); break;
192+
case fnIsTubeTester: if(!((fnsOn>>fnIsTubeTester)&1)) writeEEPROM(7,(((fnsOn>>fnIsAlarm)&1)?fnIsAlarm:fnIsTime),false); break;
193+
}
194+
if(!enableAlarmAutoskip) writeEEPROM(23,0,false); //alarm autoskip off
195+
if(!enableAlarmFibonacci) writeEEPROM(50,0,false); //fibonacci off
196+
if(!enableChime) writeEEPROM(21,0,false); //chime off
197+
if(!enableNightShutoff) writeEEPROM(27,0,false); //night shutoff off
198+
if(!enableAwayShutoff) writeEEPROM(32,0,false); //away shutoff off
199+
//TODO if fnAlarm is not enabled, force alarm off, else
200+
174201
dstOn = (readEEPROM(15,false)>0); //set last known DST state per EEPROM backup
175202
//if LED circuit is not switched (v5.0 board), the LED menu setting (eeprom 26) doesn't matter
176203
findFnAndPageNumbers(); //initial values
@@ -342,9 +369,9 @@ void ctrlEvt(byte ctrl, byte evt){
342369
} else if(fnPg==fnDateCounter){ //month, date, direction
343370
startSet(readEEPROM(5,false),1,12,1);
344371
} else if(fnPg==fnDateSunlast || fnPg==fnDateSunnext){ //lat and long
345-
//TODO these pages will need different IDs to be told apart from fnDateCounter
372+
//TODO
346373
} else if(fnPg==fnDateWeathernow || fnDateWeathernext){ //temperature units??
347-
//TODO these pages will need different IDs to be told apart from fnDateCounter
374+
//TODO
348375
} break;
349376
case fnIsAlarm: //set mins
350377
startSet(readEEPROM(0,true),0,1439,1); break;
@@ -594,22 +621,32 @@ void fnOptScroll(byte dir){
594621
byte posLast = fnOpts+sizeof(optsLoc)-1;
595622
if(dir==1) fn = (fn==posLast? fnOpts: fn+1);
596623
if(dir==0) fn = (fn==fnOpts? posLast: fn-1);
597-
//Certain options don't apply to some hardware configurations; skip those
624+
//Certain options don't apply to some configurations; skip those.
598625
byte optLoc = optsLoc[fn-fnOpts];
599626
if(
627+
//Hardware config
600628
(piezoPin<0 && (optLoc==39||optLoc==40||optLoc==41||optLoc==47||optLoc==48||optLoc==49)) //no piezo: no signal pitches or alarm/timer/strike beeper pattern
601-
|| ((piezoPin<0 && relayMode==0) && (optLoc==21||optLoc==25||optLoc==50)) //no piezo, and relay is switch: no strike, timer interval mode, or alarm fibonacci mode
629+
|| ((piezoPin<0 && relayMode==0) && (optLoc==21||optLoc==50)) //no piezo, and relay is switch: no strike, or alarm fibonacci mode
602630
|| ((relayPin<0 || piezoPin<0) && (optLoc==42||optLoc==43||optLoc==44)) //no relay or no piezo: no alarm/timer/strike signal
603631
|| ((relayMode==0) && (optLoc==44)) //relay is switch: no strike signal
604632
|| ((ledPin<0) && (optLoc==26)) //no led pin: no led control
633+
|| ((ledPin<0) && (optLoc==26)) //no led pin: no led control
634+
//Functions disabled
635+
|| (!((fnsOn>>fnIsDate)&1) && (optLoc==17||optLoc==18||optLoc==10||optLoc==12||optLoc==14)) //date fn disabled in config: skip date and geography options
636+
|| (!((fnsOn>>fnIsAlarm)&1) && (optLoc==23||optLoc==42||optLoc==39||optLoc==47||optLoc==24||optLoc==50)) //alarm fn disabled in config: skip alarm options
637+
|| (!((fnsOn>>fnIsTimer)&1) && (optLoc==43||optLoc==40||optLoc==48)) //timer fn disabled in config: skip timer options
638+
|| (!((fnsOn>>fnIsTemp)&1) && (optLoc==45)) //temp fn disabled in config: skip temp format TODO good for weather also
639+
//Other functionality disabled
640+
|| (!enableDateSunriseSunset && (optLoc==10||optLoc==12||optLoc==14)) //date rise/set disabled in config: skip geography
641+
|| (!enableAlarmAutoskip && (optLoc==23)) //alarm autoskip disabled in config: skip autoskip switch
642+
|| (!enableAlarmFibonacci && (optLoc==50)) //fibonacci mode disabled in config: skip fibonacci switch
643+
|| (!enableChime && (optLoc==21||optLoc==44||optLoc==41||optLoc==49)) //chime disabled in config: skip chime
644+
|| (!enableNightShutoff && (optLoc==27||optLoc==28||optLoc==30)) //night shutoff disabled in config: skip night
645+
|| ((!enableNightShutoff || !enableAwayShutoff) && (optLoc==32||optLoc==35||optLoc==37)) //night or away shutoff disabled in config: skip away (except workweek)
646+
|| ((!enableNightShutoff || !enableAwayShutoff) && (!enableAlarmAutoskip || !((fnsOn>>fnIsAlarm)&1)) && (optLoc==33||optLoc==34)) //(night or away) and alarm autoskip disabled: skip workweek
605647
) {
606648
fnOptScroll(dir);
607649
}
608-
if(optLoc==45) { //temp not in fnsEnabled: skip temp format option (and calib if we get to it TODO)
609-
bool found = 0;
610-
for(byte fnct=0; fnct<sizeof(fnsEnabled); fnct++) if(fnsEnabled[fnct]==fnIsTemp) found = 1;
611-
if(found==0) fnOptScroll(dir);
612-
}
613650
}
614651

615652
void switchAlarm(byte dir){
@@ -681,9 +718,9 @@ void doSetHold(bool start){
681718
//TODO integrate this with checkInputs?
682719
unsigned long now = millis();
683720
//The interval used to be 250, but in order to make the value change by a full 9 values between btnShortHold and btnLongHold,
684-
//the interval is now that difference divided by 9. TODO divisor may need to be a bit higher in case btnLongHold ever fires before 9th.
721+
//the interval is now that difference divided by 9. TODO divisor may need to be a bit higher in case btnLongHold ever fires before 9th - it seems indeed it did, so 9.5.
685722
//It may be weird not being exactly quarter-seconds, but it doesn't line up with the blinking anyway.
686-
if(start || (unsigned long)(now-doSetHoldLast)>=((btnLongHold-btnShortHold)/9)) {
723+
if(start || (unsigned long)(now-doSetHoldLast)>=(((btnLongHold-btnShortHold)*2)/19)) { //(x*2)/19 = x/9.5
687724
doSetHoldLast = now;
688725
if(fnSetPg!=0 && (mainAdjType==1 && (btnCur==mainAdjUp || btnCur==mainAdjDn)) ){ //if we're setting, and this is an adj btn
689726
bool dir = (btnCur==mainAdjUp ? 1 : 0);
@@ -774,10 +811,10 @@ void writeEEPROM(int loc, int val, bool is2Byte){
774811
void findFnAndPageNumbers(){
775812
//Each function, and each page in a paged function, has a number. //TODO should pull from EEPROM 8
776813
fnDatePages = 1; //date function always has a page for the date itself
777-
if(true){ fnDatePages++; fnDateCounter=fnDatePages-1; }
778-
if(true){ fnDatePages++; fnDateSunlast=fnDatePages-1; }
814+
if(enableDateCounter){ fnDatePages++; fnDateCounter=fnDatePages-1; }
815+
if(enableDateSunriseSunset){ fnDatePages++; fnDateSunlast=fnDatePages-1; }
779816
if(false){ fnDatePages++; fnDateWeathernow=fnDatePages-1; }
780-
if(true){ fnDatePages++; fnDateSunnext=fnDatePages-1; }
817+
if(enableDateSunriseSunset){ fnDatePages++; fnDateSunnext=fnDatePages-1; }
781818
if(false){ fnDatePages++; fnDateWeathernext=fnDatePages-1; }
782819
}
783820

@@ -798,9 +835,9 @@ void checkRTC(bool force){
798835
if((unsigned long)(now-inputLast)>=timeoutSet*1000) { fnSetPg = 0; fn = fnIsTime; force=true; } //Time out after 2 mins
799836
}
800837
//Paged-display function timeout //TODO change fnIsDate to consts? //TODO timeoutPageFn var
801-
else if(fn==fnIsDate && (unsigned long)(now-inputLast)>=2500) {
838+
else if(fn==fnIsDate && (unsigned long)(now-inputLast)>=3000) { //3sec per date page
802839
//Here we just have to increment the page and decide when to reset. updateDisplay() will do the rendering
803-
fnPg++; inputLast+=2500; //but leave inputLastTODMins alone so the subsequent page displays will be based on the same TOD
840+
fnPg++; inputLast+=3000; //but leave inputLastTODMins alone so the subsequent page displays will be based on the same TOD
804841
if(fnPg >= fnDatePages){ fnPg = 0; fn = fnIsTime; }
805842
force=true;
806843
}
@@ -883,15 +920,15 @@ void checkRTC(bool force){
883920
if(readEEPROM(27,false)>0? //is night shutoff enabled?
884921
tod.second()==0 && tod.hour()*60+tod.minute()==readEEPROM(28,true): //if so, at start of night shutoff (at second :00 before dim is in effect)
885922
tod.second()==1 && tod.hour()*60+tod.minute()==0) //if not, at 00:00:01
886-
cleanRemain = 51; //run routine for five cycles
923+
cleanRemain = 151; //run routine for fifteen cycles
887924
break;
888925
case 1: //every hour
889926
if(tod.second()==1 && tod.minute()==0) //at min/sec :00:01
890-
cleanRemain = 51; //run routine for five cycles
927+
cleanRemain = 101; //run routine for ten cycles
891928
break;
892929
case 2: //every minute
893930
if(tod.second()==1) //at second :01
894-
cleanRemain = 11; //run routine for one cycle
931+
cleanRemain = 21; //run routine for two cycles
895932
break;
896933
default: break;
897934
}

arduino-nixie/configs/v8-6tube.h

Lines changed: 19 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -2,16 +2,25 @@
22

33
const byte displaySize = 6; //number of tubes in display module. Small display adjustments are made for 4-tube clocks
44

5-
// available clock functions, and unique IDs (between 0 and 200)
6-
const byte fnIsTime = 0;
7-
const byte fnIsDate = 1;
8-
const byte fnIsAlarm = 2;
9-
const byte fnIsTimer = 3;
10-
const byte fnIsTemp = 4;
11-
const byte fnIsTubeTester = 5; //cycles all digits on all tubes 1/second, similar to anti-cathode-poisoning cleaner
12-
// functions enabled in this clock, in their display order. Only fnIsTime is required
13-
const byte fnsEnabled[] = {fnIsTime, fnIsDate, fnIsAlarm, fnIsTimer}; //, fnIsTemp, fnIsTubeTester
14-
// To control which of these display persistently vs. switch back to Time after a few seconds, search "Temporary-display function timeout"
5+
// available clock functions (and unique IDs between 0 and 7)
6+
const byte fnIsTime = 0; //time of day
7+
const byte fnIsDate = 1; //date, with optional day counter and sunrise/sunset (per below)
8+
const byte fnIsAlarm = 2; //alarm time
9+
const byte fnIsTimer = 3; //countdown timer and chronograph
10+
const byte fnIsTemp = 4; //temperature per DS3231 – will likely read high
11+
const byte fnIsTubeTester = 5; //simply cycles all tubes
12+
13+
// Which functions are enabled in this clock, and in what order? (fnIsTime is required)
14+
const byte fnsEnabled[] = {fnIsTime, fnIsDate, fnIsAlarm, fnIsTimer};
15+
16+
// Additional functionality
17+
const bool enableDateCounter = true; // Adds a "page" to the date with an anniversary counter
18+
const bool enableDateSunriseSunset = true; // Adds "pages" to the date with sunrise/sunset times
19+
const bool enableAlarmAutoskip = true;
20+
const bool enableAlarmFibonacci = true;
21+
const bool enableChime = true;
22+
const bool enableNightShutoff = true; // If disabled, tubes will be full brightness all the time.
23+
const bool enableAwayShutoff = true; // Requires night shutoff.
1524

1625
// These are the RLB board connections to Arduino analog input pins.
1726
// S1/PL13 = Reset

0 commit comments

Comments
 (0)