diff --git a/README.md b/README.md index 423d1c1..ddd29dc 100644 --- a/README.md +++ b/README.md @@ -67,7 +67,7 @@ This feature can count up (chrono) or down (timer), up to 100 hours each way. Wh > **Hardware variations** > * If your clock has a [switched relay](#hardware-configuration) and the chrono/timer is [set to use it](#optionstimer), it will switch on while the timer is running, like the “sleep” function on a clock radio. The runout options will still work, but won’t signal. > * If your clock does not have a beeper, the runout options cannot be set. -> * If your clock uses a rotary encoder for **Up/Down** rather than buttons, **Down** will stop the chrono/timer, and **Up** will display lap times (chrono) and cycle through runout options (timer). +> * If your clock uses a rotary encoder for **Up/Down** rather than buttons, while running, **Up** will display lap times (chrono) and cycle through runout options (timer), and **Down** will stop. To prevent accidental resets, **Down** does nothing while stopped. To reset to `0`, simply switch to another display while stopped. ## The Alt button @@ -150,11 +150,12 @@ You can also set the **defaults for the options menu** (in main code, currently) ## Compiling the sketch -**To compile the sketch,** ensure these libraries are added and enabled in your Arduino IDE, via the Library Manager: +**To compile the sketch,** ensure these libraries are installed in your Arduino IDE via Library Manager, as needed: * Wire (Arduino built-in) * EEPROM (Arduino built-in) -* DS3231 ([NorthernWidget](https://github.com/NorthernWidget/DS3231)) -* Dusk2Dawn ([dmkishi](https://github.com/dmkishi/Dusk2Dawn)) +* [DS3231](https://github.com/NorthernWidget/DS3231) by NorthernWidget +* [Dusk2Dawn](https://github.com/dmkishi/Dusk2Dawn) by DM Kishi - if sunrise/sunset display is enabled +* [Encoder](https://github.com/PaulStoffregen/Encoder) by Paul Stoffregen - if rotary encoder is equipped **To upload the sketch to your clock,** if it doesn’t appear in the IDE’s Ports menu (as a USB port), your UNDB may be equipped with an Arduino clone that requires [drivers for the CH340 chipset](https://sparks.gogo.co.nz/ch340.html). \ No newline at end of file diff --git a/arduino-nixie/arduino-nixie.ino b/arduino-nixie/arduino-nixie.ino index 1226468..bd64ce1 100644 --- a/arduino-nixie/arduino-nixie.ino +++ b/arduino-nixie/arduino-nixie.ino @@ -11,14 +11,19 @@ ////////// Software version ////////// const byte vMajor = 1; -const byte vMinor = 8; -const byte vPatch = 1; +const byte vMinor = 9; +const byte vPatch = 0; ////////// Other includes, global consts, and vars ////////// #include //Arduino - GNU LPGL #include //Arduino - GNU LPGL -#include //NorthernWidget - The Unlicense -#include //TODO not needed unless whatever +#include //NorthernWidget - The Unlicense - install in your Arduino IDE +#if ENABLE_DATE_RISESET + #include //DM Kiski - unlicensed - install in your Arduino IDE if needed +#endif +#if CTRL_UPDN_TYPE==2 //rotary encoder + #include //Paul Stoffregen - install in your Arduino IDE if needed +#endif /*EEPROM locations for non-volatile clock settings Don't change which location is associated with which setting; they should remain permanent to avoid the need for EEPROM initializations after code upgrades; and they are used directly in code. @@ -73,7 +78,7 @@ Some are skipped when they wouldn't apply to a given clock's hardware config, se 42 Alarm signal, 0=beeper, 1=relay - skipped when no relay (start=0) or no piezo (start=0) 43 Timer signal - skipped when no relay (start=0) or no piezo (start=1) 44 Strike signal - skipped when no pulse relay (start=0) or no piezo (start=1) - 45 Temperature format - skipped when !enableTemp TODO also useful for weather display + 45 Temperature format - skipped when !ENABLE_TEMP_FN TODO also useful for weather display 46 Anti-cathode poisoning 47 Alarm beeper pattern - skipped when no piezo 48 Timer beeper pattern - skipped when no piezo @@ -101,9 +106,10 @@ byte toddow; //stores the day of week (read separately from ds3231 dow counter) byte btnCur = 0; //Momentary button currently in use - only one allowed at a time byte btnCurHeld = 0; //Button hold thresholds: 0=none, 1=unused, 2=short, 3=long, 4=set by btnStop() unsigned long inputLast = 0; //When a button was last pressed -unsigned long inputLast2 = 0; //Second-to-last of above -//TODO the math between these two may fail very rarely due to millis() rolling over while setting. Need to find a fix. I think it only applies to the rotary encoder though. 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. +#if CTRL_UPDN_TYPE==2 //rotary encoder + Encoder rot(CTRL_DN,CTRL_UP); +#endif // Functions and pages // Unique IDs - see also fnScroll @@ -142,14 +148,14 @@ word signalRemain = 0; //alarm/timer signal timeout counter, seconds word snoozeRemain = 0; //snooze timeout counter, seconds byte timerState = 0; //bit 0 is stop/run, bit 1 is down/up, bit 2 is runout repeat / short signal, bit 3 is runout chrono, bit 4 is lap display word timerInitialMins = 0; //timer original duration setting, minutes - up to 99h 59m (5999m) -byte timerInitialSecs = 0; //timer original duration setting, seconds - up to 59s +word timerInitialSecs = 0; //timer original duration setting, seconds - up to 59s (could be a byte, but I had trouble casting to unsigned int when doing the math to set timerTime) unsigned long timerTime = 0; //timestamp of timer target / chrono origin (while running) or duration (while stopped) unsigned long timerLapTime = 0; const byte millisCorrectionInterval = 30; //used to calibrate millis() to RTC for timer/chrono purposes unsigned long millisAtLastCheck = 0; word unoffRemain = 0; //un-off (briefly turn on tubes during full night/away shutoff) timeout counter, seconds byte displayDim = 2; //dim per display or function: 2=normal, 1=dim, 0=off -byte cleanRemain = 0; //anti-cathode-poisoning clean timeout counter, increments at cleanSpeed ms (see loop()). Start at 11 to run at clock startup +byte cleanRemain = 0; //anti-cathode-poisoning clean timeout counter, increments at CLEAN_SPEED ms (see loop()). Start at 11 to run at clock startup int8_t scrollRemain = 0; //"frames" of scroll – signed byte - 0=not scrolling, >0=coming in, <0=going out, -128=scroll out at next change. byte versionRemain = 3; //display version at start @@ -161,37 +167,37 @@ void setup(){ Wire.begin(); initInputs(); delay(100); //prevents the below from firing in the event there's a capacitor stabilizing the input, which can read low falsely - 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 + initEEPROM(readInput(CTRL_SEL)==LOW); //Do a hard init of EEPROM if button is held; else do a soft init to make sure vals in range //Some options need to be set to a fixed value per the configuration. //These options will also be skipped in fnOptScroll so the user can't change them. - if(relayPin<0 || piezoPin<0) { //If no relay or no piezo, set each signal output to [if no relay, then piezo; else relay] - writeEEPROM(42,(relayPin<0?0:1),false); //alarm - writeEEPROM(43,(relayPin<0?0:1),false); //timer - writeEEPROM(44,(relayPin<0?0:1),false); //strike + if(RELAY_PIN<0 || PIEZO_PIN<0) { //If no relay or no piezo, set each signal output to [if no relay, then piezo; else relay] + writeEEPROM(42,(RELAY_PIN<0?0:1),false); //alarm + writeEEPROM(43,(RELAY_PIN<0?0:1),false); //timer + writeEEPROM(44,(RELAY_PIN<0?0:1),false); //strike } - if(piezoPin>=0 && relayMode==0) { //If piezo and switched relay + if(PIEZO_PIN>=0 && RELAY_MODE==0) { //If piezo and switched relay writeEEPROM(44,0,false); //strike forced to piezo } - if(piezoPin<0 && relayMode==0) { //If switched relay and no piezo + if(PIEZO_PIN<0 && RELAY_MODE==0) { //If switched relay and no piezo writeEEPROM(21,0,false); //turn off strike writeEEPROM(50,0,false); //turn off fibonacci mode } - if(!enableAlarm) alarmOn = 0; //if alarm is disabled in config - else if(!enableSoftAlarmSwitch) alarmOn = 1; //force alarm on if software switch is disabled + if(!ENABLE_ALARM_FN) alarmOn = 0; //if alarm is disabled in config + else if(!ENABLE_SOFT_ALARM_SWITCH) alarmOn = 1; //force alarm on if software switch is disabled else alarmOn = (readEEPROM(2,false)>0); //otherwise set alarm per EEPROM backup switch(readEEPROM(7,false)){ //if the preset is set to a function that is no longer enabled, use alarm if enabled, else use time - case fnIsDate: if(!enableDate) writeEEPROM(7,(enableAlarm?fnIsAlarm:fnIsTime),false); break; - case fnIsAlarm: if(!enableAlarm) writeEEPROM(7,fnIsTime,false); break; - case fnIsTimer: if(!enableTimer) writeEEPROM(7,(enableAlarm?fnIsAlarm:fnIsTime),false); break; - case fnIsTemp: if(!enableTemp) writeEEPROM(7,(enableAlarm?fnIsAlarm:fnIsTime),false); break; - case fnIsTest: if(!enableTest) writeEEPROM(7,(enableAlarm?fnIsAlarm:fnIsTime),false); break; - default: writeEEPROM(7,(enableAlarm?fnIsAlarm:fnIsTime),false); break; + case fnIsDate: if(!ENABLE_DATE_FN) writeEEPROM(7,(ENABLE_ALARM_FN?fnIsAlarm:fnIsTime),false); break; + case fnIsAlarm: if(!ENABLE_ALARM_FN) writeEEPROM(7,fnIsTime,false); break; + case fnIsTimer: if(!ENABLE_TIMER_FN) writeEEPROM(7,(ENABLE_ALARM_FN?fnIsAlarm:fnIsTime),false); break; + case fnIsTemp: if(!ENABLE_TEMP_FN) writeEEPROM(7,(ENABLE_ALARM_FN?fnIsAlarm:fnIsTime),false); break; + case fnIsTest: if(!ENABLE_TUBETEST_FN) writeEEPROM(7,(ENABLE_ALARM_FN?fnIsAlarm:fnIsTime),false); break; + default: writeEEPROM(7,(ENABLE_ALARM_FN?fnIsAlarm:fnIsTime),false); break; } - if(!enableAlarmAutoskip) writeEEPROM(23,0,false); //alarm autoskip off - if(!enableAlarmFibonacci) writeEEPROM(50,0,false); //fibonacci off - if(!enableChime) writeEEPROM(21,0,false); //chime off - if(!enableNightShutoff) writeEEPROM(27,0,false); //night shutoff off - if(!enableAwayShutoff) writeEEPROM(32,0,false); //away shutoff off + if(!ENABLE_ALARM_AUTOSKIP) writeEEPROM(23,0,false); //alarm autoskip off + if(!ENABLE_ALARM_FIBONACCI) writeEEPROM(50,0,false); //fibonacci off + if(!ENABLE_TIME_CHIME) writeEEPROM(21,0,false); //chime off + if(!ENABLE_SHUTOFF_NIGHT) writeEEPROM(27,0,false); //night shutoff off + if(!ENABLE_SHUTOFF_AWAY) writeEEPROM(32,0,false); //away shutoff off dstOn = (readEEPROM(15,false)>0); //set last known DST state per EEPROM backup //if LED circuit is not switched (v5.0 board), the LED menu setting (eeprom 26) doesn't matter findFnAndPageNumbers(); //initial values @@ -204,7 +210,9 @@ void loop(){ checkRTC(false); //if clock has ticked, decrement timer if running, and updateDisplay millisApplyDrift(); checkInputs(); //if inputs have changed, this will do things + updateDisplay as needed - doSetHold(false); //if inputs have been held, this will do more things + updateDisplay as needed + #if CTRL_UPDN_TYPE==1 //buttons + doSetHold(false); //if inputs have been held, this will do more things + updateDisplay as needed + #endif cycleTimer(); cycleDisplay(); //keeps the display hardware multiplexing cycle going cycleLEDs(); @@ -216,22 +224,26 @@ void loop(){ void initInputs(){ //TODO are there no "loose" pins left floating after this? per https://electronics.stackexchange.com/q/37696/151805 - pinMode(mainSel, INPUT_PULLUP); - pinMode(mainAdjUp, INPUT_PULLUP); - pinMode(mainAdjDn, INPUT_PULLUP); - pinMode(altSel, INPUT_PULLUP); - //rotary encoder init - //TODO encoder support + pinMode(CTRL_SEL, INPUT_PULLUP); + pinMode(CTRL_UP, INPUT_PULLUP); + pinMode(CTRL_DN, INPUT_PULLUP); + #if CTRL_ALT!=0 + pinMode(CTRL_ALT, INPUT_PULLUP); + #endif } void checkInputs(){ - //TODO can all this if/else business be defined at load instead of evaluated every sample? OR is it compiled that way? //TODO potential issue: if user only means to rotate or push encoder but does both? - //check button states - checkBtn(mainSel); //main select - if(mainAdjType==1) { checkBtn(mainAdjUp); checkBtn(mainAdjDn); } //if mainAdj is buttons - //if(mainAdjType==2) checkRot(); //if mainAdj is rotary encoder TODO encoder support - if(altSel!=0) checkBtn(altSel); //alt select (if equipped) + checkBtn(CTRL_SEL); //select + #if CTRL_UPDN_TYPE==1 //buttons + checkBtn(CTRL_UP); checkBtn(CTRL_DN); + #endif + #if CTRL_UPDN_TYPE==2 //rotary encoder + checkRot(); + #endif + #if CTRL_ALT!=0 //alt (if equipped) + checkBtn(CTRL_ALT); + #endif } bool readInput(byte pin){ @@ -245,16 +257,16 @@ void checkBtn(byte btn){ unsigned long now = millis(); //If the button has just been pressed, and no other buttons are in use... if(btnCur==0 && bnow==LOW) { - btnCur = btn; btnCurHeld = 0; inputLast2 = inputLast; inputLast = now; inputLastTODMins = tod.hour()*60+tod.minute(); + btnCur = btn; btnCurHeld = 0; inputLast = now; inputLastTODMins = tod.hour()*60+tod.minute(); ctrlEvt(btn,1); //hey, the button has been pressed } //If the button is being held... if(btnCur==btn && bnow==LOW) { - if((unsigned long)(now-inputLast)>=btnLongHold && btnCurHeld < 3) { //account for rollover + if((unsigned long)(now-inputLast)>=CTRL_HOLD_LONG_DUR && btnCurHeld < 3) { //account for rollover btnCurHeld = 3; ctrlEvt(btn,3); //hey, the button has been long-held } - else if((unsigned long)(now-inputLast)>=btnShortHold && btnCurHeld < 2) { + else if((unsigned long)(now-inputLast)>=CTRL_HOLD_SHORT_DUR && btnCurHeld < 2) { btnCurHeld = 2; ctrlEvt(btn,2); //hey, the button has been short-held } @@ -271,10 +283,28 @@ void btnStop(){ btnCurHeld = 4; } +bool rotVel = 0; //high velocity setting (x10 rather than x1) +#if CTRL_UPDN_TYPE==2 //rotary encoder +unsigned long rotLastStep = 0; //timestamp of last completed step (detent) +int rotLastVal = 0; void checkRot(){ - //Changes in rotary encoder. When rotation(s) occur, will call ctrlEvt to simulate btn presses. - //TODO rotary encoder support -}//end checkRot + //Changes in rotary encoder. When rotation(s) occur, will call ctrlEvt to simulate btn presses. During setting, ctrlEvt will take rotVel into account. + int rotCurVal = rot.read(); + if(rotCurVal!=rotLastVal){ //we've sensed a state change + rotLastVal = rotCurVal; + if(rotCurVal>=4 || rotCurVal<=-4){ //we've completed a step of 4 states (this library doesn't seem to drop states much, so this is reasonably reliable) + unsigned long now = millis(); + inputLast = now; inputLastTODMins = tod.hour()*60+tod.minute(); + if((unsigned long)(now-rotLastStep)<=ROT_VEL_START) rotVel = 1; //kick into high velocity setting (x10) + else if((unsigned long)(now-rotLastStep)>=ROT_VEL_STOP) rotVel = 0; //fall into low velocity setting (x1) + rotLastStep = now; + while(rotCurVal>=4) { rotCurVal-=4; ctrlEvt(CTRL_UP,1); } + while(rotCurVal<=-4) { rotCurVal+=4; ctrlEvt(CTRL_DN,1); } + rot.write(rotCurVal); + } + } +} //end checkRot() +#endif ////////// Input handling and value setting ////////// @@ -290,7 +320,7 @@ void ctrlEvt(byte ctrl, byte evt){ signalStop(); if(signalSource==fnIsAlarm) { //If this was the alarm //If the alarm is using the switched relay and this is the Alt button; or if alarm is *not* using the switched relay and this is Fibonacci mode; don't set the snooze - if((relayMode==0 && readEEPROM(42,false)==1 && altSel!=0 && ctrl==altSel) || (readEEPROM(50,false) && !(relayPin>=0 && relayMode==0 && readEEPROM(42,false)==1))) { + if((RELAY_MODE==0 && readEEPROM(42,false)==1 && CTRL_ALT!=0 && ctrl==CTRL_ALT) || (readEEPROM(50,false) && !(RELAY_PIN>=0 && RELAY_MODE==0 && readEEPROM(42,false)==1))) { quickBeep(64); //Short signal to indicate the alarm has been silenced until tomorrow displayBlink(); //to indicate this as well } else { //start snooze @@ -336,7 +366,7 @@ void ctrlEvt(byte ctrl, byte evt){ } //Is it a press for an un-off? - unoffRemain = unoffDur; //always do this so continued button presses during an unoff keep it alive + unoffRemain = UNOFF_DUR; //always do this so continued button presses during an unoff keep it alive if(displayDim==0 && evt==1) { updateDisplay(); btnStop(); @@ -345,7 +375,7 @@ void ctrlEvt(byte ctrl, byte evt){ if(fn < fnOpts) { //normal fn running/setting (not in options menu) - if(evt==3 && ctrl==mainSel) { //mainSel long hold: enter options menu + if(evt==3 && ctrl==CTRL_SEL) { //CTRL_SEL long hold: enter options menu btnStop(); fn = fnOpts; clearSet(); //don't need updateDisplay() here because this calls updateRTC with force=true @@ -353,7 +383,7 @@ void ctrlEvt(byte ctrl, byte evt){ } if(!fnSetPg) { //fn running - if(evt==2 && ctrl==mainSel) { //mainSel hold: enter setting mode + if(evt==2 && ctrl==CTRL_SEL) { //CTRL_SEL hold: enter setting mode switch(fn){ case fnIsTime: //set mins startSet((tod.hour()*60)+tod.minute(),0,1439,1); break; @@ -379,31 +409,31 @@ void ctrlEvt(byte ctrl, byte evt){ } return; } - else if((ctrl==mainSel && evt==0) || ((ctrl==mainAdjUp || ctrl==mainAdjDn) && evt==1)) { //sel release or adj press + else if((ctrl==CTRL_SEL && evt==0) || ((ctrl==CTRL_UP || ctrl==CTRL_DN) && evt==1)) { //sel release or adj press //we can't handle sel press here because, if attempting to enter setting mode, it would switch the fn first - if(ctrl==mainSel){ //sel release + if(ctrl==CTRL_SEL){ //sel release if(fn==fnIsTimer && !(timerState&1)) timerClear(); //if timer is stopped, clear it fnScroll(1); //Go to next fn in the cycle fnPg = 0; //reset page counter in case we were in a paged display checkRTC(true); //updates display } - else if(ctrl==mainAdjUp || ctrl==mainAdjDn) { - if(fn==fnIsAlarm) switchAlarm(ctrl==mainAdjUp?1:0); //switch alarm + else if(ctrl==CTRL_UP || ctrl==CTRL_DN) { + if(fn==fnIsAlarm) switchAlarm(ctrl==CTRL_UP?1:0); //switch alarm if(fn==fnIsTimer){ - if(ctrl==mainAdjUp){ + if(ctrl==CTRL_UP){ if(!(timerState&1)){ //stopped timerStart(); } else { //running - if(mainAdjType==2) { //rotary encoder + #if CTRL_UPDN_TYPE==2 //rotary encoder if((timerState>>1)&1) timerLap(); //chrono: lap else timerRunoutToggle(); //timer: runout option - } else { //button + #else //button timerStop(); - } + #endif } - } else { //mainAdjDown + } else { //CTRL_DN if(!(timerState&1)){ //stopped - if(mainAdjType!=2) { //button + #if CTRL_UPDN_TYPE==1 //buttons timerClear(); //if we wanted to reset to the previous time, we could use this; but sel hold is easy enough to get there // //same as //save timer secs @@ -413,14 +443,14 @@ void ctrlEvt(byte ctrl, byte evt){ // //timerStart(); //we won't automatically start, we'll let the user do that // } updateDisplay(); - } + #endif } else { //running - if(mainAdjType==2) { //rotary encoder + #if CTRL_UPDN_TYPE==2 //rotary encoder timerStop(); - } else { //button + #else if((timerState>>1)&1) timerLap(); //chrono: lap else timerRunoutToggle(); //timer: runout option - } + #endif } } } //end if fnIsTimer @@ -428,9 +458,9 @@ void ctrlEvt(byte ctrl, byte evt){ } //else do nothing } //end sel release or adj press - else if(altSel>0 && ctrl==altSel) { //alt sel press + else if(CTRL_ALT>0 && ctrl==CTRL_ALT) { //alt sel press //if switched relay, and soft switch enabled, we'll switch power. - if(enableSoftPowerSwitch && relayPin>=0 && relayMode==0) { switchPower(2); btnStop(); } + if(ENABLE_SOFT_POWER_SWITCH && RELAY_PIN>=0 && RELAY_MODE==0) { switchPower(2); btnStop(); } //Otherwise, this becomes our function preset. else { //On long hold, if this is not currently the preset, we'll set it, double beep, and btnStop. @@ -460,12 +490,12 @@ void ctrlEvt(byte ctrl, byte evt){ else { //fn setting if(evt==1) { //press - //TODO could we do release/shorthold on mainSel so we can exit without making changes? + //TODO could we do release/shorthold on CTRL_SEL so we can exit without making changes? //currently no, because we don't btnStop() when short hold goes into fn setting, in case long hold may go to options menu //so we can't handle a release because it would immediately save if releasing from the short hold. //Consider recording the btn start time when going into fn setting so we can distinguish its release from a future one - if(ctrl==mainSel) { //mainSel push: go to next option or save and exit setting mode - btnStop(); //not waiting for mainSelHold, so can stop listening here + if(ctrl==CTRL_SEL) { //CTRL_SEL push: go to next option or save and exit setting mode + btnStop(); //not waiting for CTRL_SELHold, so can stop listening here //We will set ds3231 time parts directly //con: potential for very rare clock rollover while setting; pro: can set date separate from time switch(fn){ @@ -549,12 +579,14 @@ void ctrlEvt(byte ctrl, byte evt){ break; default: break; } //end switch fn - } //end mainSel push - if(ctrl==mainAdjUp) doSet(inputLast-inputLast2255?true:false); @@ -577,23 +609,23 @@ void ctrlEvt(byte ctrl, byte evt){ } if(!fnSetPg){ //viewing option number - if(ctrl==mainSel && evt==0) { //mainSel release: enter option value setting + if(ctrl==CTRL_SEL && evt==0) { //CTRL_SEL release: enter option value setting startSet(readEEPROM(optsLoc[opt],optsMax[opt]>255?true:false),optsMin[opt],optsMax[opt],1); } - if(ctrl==mainAdjUp && evt==1) fnOptScroll(1); //next one up or cycle to beginning - if(ctrl==mainAdjDn && evt==1) fnOptScroll(0); //next one down or cycle to end? + if(ctrl==CTRL_UP && evt==1) fnOptScroll(1); //next one up or cycle to beginning + if(ctrl==CTRL_DN && evt==1) fnOptScroll(0); //next one down or cycle to end? updateDisplay(); } //end viewing option number else { //setting option value - if(ctrl==mainSel && evt==0) { //mainSel release: save and exit option value setting + if(ctrl==CTRL_SEL && evt==0) { //CTRL_SEL release: save and exit option value setting //Writes setting val to EEPROM if needed writeEEPROM(optsLoc[opt],fnSetVal,optsMax[opt]>255?true:false); clearSet(); } - if(evt==1 && (ctrl==mainAdjUp || ctrl==mainAdjDn)){ - if(ctrl==mainAdjUp) doSet(inputLast-inputLast20) if(fnSetValMax-fnSetVal0) if(fnSetValMax-fnSetVal=(((btnLongHold-btnShortHold)*2)/19)) { //(x*2)/19 = x/9.5 + if(start || (unsigned long)(now-doSetHoldLast)>=(((CTRL_HOLD_LONG_DUR-CTRL_HOLD_SHORT_DUR)*2)/19)) { //(x*2)/19 = x/9.5 doSetHoldLast = now; - if(fnSetPg!=0 && (mainAdjType==1 && (btnCur==mainAdjUp || btnCur==mainAdjDn)) ){ //if we're setting, and this is an adj btn - bool dir = (btnCur==mainAdjUp ? 1 : 0); + if(fnSetPg!=0 && (btnCur==CTRL_UP || btnCur==CTRL_DN) ){ //if we're setting, and this is an adj btn + bool dir = (btnCur==CTRL_UP ? 1 : 0); //If short hold, or long hold but high velocity isn't supported, use low velocity (delta=1) if(btnCurHeld==2 || (btnCurHeld==3 && fnSetValVel==false)) doSet(dir?1:-1); //else if long hold, use high velocity (delta=10) @@ -741,6 +774,7 @@ void doSetHold(bool start){ } } } +#endif void clearSet(){ //Exit set state startSet(0,0,0,0); fnSetValDid=false; @@ -754,7 +788,7 @@ void initEEPROM(bool hard){ //If hard, set EEPROM and clock to defaults //Otherwise, just make sure stuff is in range //First prevent the held button from doing anything else - btnCur = mainSel; btnStop(); + btnCur = CTRL_SEL; btnStop(); //If a hard init, set the clock if(hard) { ds3231.setYear(20); @@ -820,10 +854,10 @@ void writeEEPROM(int loc, int val, bool is2Byte){ void findFnAndPageNumbers(){ //Each function, and each page in a paged function, has a number. //TODO should pull from EEPROM 8 fnDatePages = 1; //date function always has a page for the date itself - if(enableDateCounter){ fnDatePages++; fnDateCounter=fnDatePages-1; } - if(enableDateSunriseSunset){ fnDatePages++; fnDateSunlast=fnDatePages-1; } + if(ENABLE_DATE_COUNTER){ fnDatePages++; fnDateCounter=fnDatePages-1; } + if(ENABLE_DATE_RISESET){ fnDatePages++; fnDateSunlast=fnDatePages-1; } if(false){ fnDatePages++; fnDateWeathernow=fnDatePages-1; } - if(enableDateSunriseSunset){ fnDatePages++; fnDateSunnext=fnDatePages-1; } + if(ENABLE_DATE_RISESET){ fnDatePages++; fnDateSunnext=fnDatePages-1; } if(false){ fnDatePages++; fnDateWeathernext=fnDatePages-1; } } @@ -841,17 +875,17 @@ void checkRTC(bool force){ //Things to do every time this is called: timeouts to reset display. These may force a tick. //Option/setting timeout: if we're in the options menu, or we're setting a value if(fnSetPg || fn>=fnOpts){ - if((unsigned long)(now-inputLast)>=timeoutSet*1000) { fnSetPg = 0; fn = fnIsTime; force=true; } //Time out after 2 mins + if((unsigned long)(now-inputLast)>=SETTING_TIMEOUT*1000) { fnSetPg = 0; fn = fnIsTime; force=true; } //Time out after 2 mins } //Paged-display function timeout //TODO change fnIsDate to consts? //TODO timeoutPageFn var - else if(fn==fnIsDate && (unsigned long)(now-inputLast)>=3000) { //3sec per date page + else if(fn==fnIsDate && (unsigned long)(now-inputLast)>=FN_PAGE_TIMEOUT*1000) { //3sec per date page //If a scroll in is going, fast-forward to end - see also ctrlEvt if(scrollRemain>0) { scrollRemain = 1; checkEffects(true); } //Here we just have to increment the page and decide when to reset. updateDisplay() will do the rendering - fnPg++; inputLast+=3000; //but leave inputLastTODMins alone so the subsequent page displays will be based on the same TOD + fnPg++; inputLast+=(FN_PAGE_TIMEOUT*1000); //but leave inputLastTODMins alone so the subsequent page displays will be based on the same TOD while(fnPg0))){ - if((unsigned long)(now-inputLast)>=(fn==fnIsTimer?3600:timeoutTempFn)*1000) { fnSetPg = 0; fn = fnIsTime; force=true; } + if((unsigned long)(now-inputLast)>=(fn==fnIsTimer?3600:FN_TEMP_TIMEOUT)*1000) { fnSetPg = 0; fn = fnIsTime; force=true; } } //Update things based on RTC @@ -883,7 +917,7 @@ void checkRTC(bool force){ //Serial.print("sr "); Serial.println(snoozeRemain,DEC); if(snoozeRemain<=0 && alarmOn) { fnSetPg = 0; fn = fnIsTime; - if((readEEPROM(50,false) && !(relayPin>=0 && relayMode==0 && readEEPROM(42,false)==1))) fibonacci(tod.hour(),tod.minute(),tod.second()); //fibonacci sequence + if((readEEPROM(50,false) && !(RELAY_PIN>=0 && RELAY_MODE==0 && readEEPROM(42,false)==1))) fibonacci(tod.hour(),tod.minute(),tod.second()); //fibonacci sequence else signalStart(fnIsAlarm,1); //regular alarm } } @@ -904,7 +938,7 @@ void checkRTC(bool force){ if(tod.second()==0 && tod.minute()==0 && tod.hour()==2) autoDST(); //Alarm check: at top of minute for normal alarm, or 23 seconds past for fibonacci (which starts 26m37s early) //Only do fibonacci if enabled and if the alarm is not using the switched relay - otherwise do regular - bool fibOK = readEEPROM(50,false) && !(relayPin>=0 && relayMode==0 && readEEPROM(42,false)==1); + bool fibOK = readEEPROM(50,false) && !(RELAY_PIN>=0 && RELAY_MODE==0 && readEEPROM(42,false)==1); if((tod.second()==0 && !fibOK) || (tod.second()==23 && fibOK)){ int alarmTime = readEEPROM(0,true); if(tod.second()==23){ alarmTime-=27; if(alarmTime<0) alarmTime+=1440; } //set min to n-27 with midnight rollover @@ -1220,7 +1254,7 @@ void timerLap(){ quickBeep(81); } void timerRunoutToggle(){ - if(piezoPin>=0){ //if piezo equipped + if(PIEZO_PIN>=0){ //if piezo equipped //cycle thru runout options: 00 stop, 01 repeat, 10 chrono, 11 chrono short signal timerState ^= (1<<2); //toggle runout repeat bit if(!((timerState>>2)&1)) timerState ^= (1<<3); //if it's 0, toggle runout chrono bit @@ -1247,16 +1281,16 @@ void cycleTimer(){ } else { //runout clear - clear timer, change display timerClear(); //If switched relay (radio sleep), go to time of day; otherwise go to empty timer to appear with signal - fnSetPg = 0; fn = (relayPin>=0 && relayMode==0 && readEEPROM(43,false)==1 ? fnIsTime: fnIsTimer); + fnSetPg = 0; fn = (RELAY_PIN>=0 && RELAY_MODE==0 && readEEPROM(43,false)==1 ? fnIsTime: fnIsTimer); updateDisplay(); } } //signal (if not switched relay) if((timerState>>2)&1){ //short signal (piggybacks on runout repeat flag) - if(relayPin<0 || relayMode!=0 || readEEPROM(43,false)!=1) signalStart(fnIsTimer,1); + if(RELAY_PIN<0 || RELAY_MODE!=0 || readEEPROM(43,false)!=1) signalStart(fnIsTimer,1); //using 1 instead of 0, because in signalStart, fnIsTimer "quick measure" has a custom pitch for runout option setting } else { //long signal - if(relayPin<0 || relayMode!=0 || readEEPROM(43,false)!=1) signalStart(fnIsTimer,signalDur); + if(RELAY_PIN<0 || RELAY_MODE!=0 || readEEPROM(43,false)!=1) signalStart(fnIsTimer,SIGNAL_DUR); } } } else { //If we are counting up, @@ -1282,8 +1316,8 @@ void cycleTimer(){ void timerSwitchSleepRelay(bool on){ //When timer is set to use switched relay, it's on while timer is running, "radio sleep" style. //This doesn't count as a signal (using signal methods) so that other signals might not interrupt it. TODO confirm - if(relayPin>=0 && relayMode==0 && readEEPROM(43,false)==1) { //start "radio sleep" - digitalWrite(relayPin,(on?LOW:HIGH)); updateLEDs(); //LOW = device on + if(RELAY_PIN>=0 && RELAY_MODE==0 && readEEPROM(43,false)==1) { //start "radio sleep" + digitalWrite(RELAY_PIN,(on?LOW:HIGH)); updateLEDs(); //LOW = device on // Serial.print(millis(),DEC); // if(on) Serial.println(F(" Relay on, timerSwitchSleepRelay (radio sleep)")); // else Serial.println(F(" Relay off, timerSwitchSleepRelay (radio sleep)")); @@ -1297,20 +1331,20 @@ byte displayNext[6] = {15,15,15,15,15,15}; //Internal representation of display. byte displayLast[6] = {11,11,11,11,11,11}; //for noticing changes to displayNext and fading the display to it byte scrollDisplay[6] = {15,15,15,15,15,15}; //For animating a value into displayNext from right, and out to left -unsigned long pollCleanLast = 0; //every cleanSpeed ms -unsigned long pollScrollLast = 0; //every scrollSpeed ms +unsigned long pollCleanLast = 0; //every CLEAN_SPEED ms +unsigned long pollScrollLast = 0; //every SCROLL_SPEED ms void checkEffects(bool force){ //control the cleaning/scrolling effects - similar to checkRTC but it has its own timings unsigned long now = millis(); - //If we're running a tube cleaning, advance it every cleanSpeed ms. - if(cleanRemain && (unsigned long)(now-pollCleanLast)>=cleanSpeed) { //account for rollover + //If we're running a tube cleaning, advance it every CLEAN_SPEED ms. + if(cleanRemain && (unsigned long)(now-pollCleanLast)>=CLEAN_SPEED) { //account for rollover pollCleanLast=now; cleanRemain--; if(cleanRemain<1) calcSun(tod.year(),tod.month(),tod.day()); //take this opportunity to perform a calculation that blanks the display for a bit updateDisplay(); } - //If we're scrolling an animation, advance it every scrollSpeed ms. - else if(scrollRemain!=0 && scrollRemain!=-128 && ((unsigned long)(now-pollScrollLast)>=scrollSpeed || force)) { + //If we're scrolling an animation, advance it every SCROLL_SPEED ms. + else if(scrollRemain!=0 && scrollRemain!=-128 && ((unsigned long)(now-pollScrollLast)>=SCROLL_SPEED || force)) { pollScrollLast=now; if(scrollRemain<0) { scrollRemain++; updateDisplay(); @@ -1327,7 +1361,7 @@ void updateDisplay(){ if(scrollRemain==-128) { //If the current display is flagged to be scrolled out, do it. This is kind of the counterpart to startScroll() for(byte i=0; i<6; i++) scrollDisplay[i] = displayNext[i]; //cache the current value in scrollDisplay[] just in case it changed - scrollRemain = (0-displaySize)-1; + scrollRemain = (0-DISPLAY_SIZE)-1; } if(cleanRemain) { //cleaning tubes @@ -1348,22 +1382,22 @@ void updateDisplay(){ 2: [ 1 2]3 4 1: [ 1 2 3]4 0/-128: [1 2 3 4] - -4: 1[2 3 4 ] tube[n] is source[n+displaySize+scrollRemain+1] unless that index >= displaySize, then blank + -4: 1[2 3 4 ] tube[n] is source[n+DISPLAY_SIZE+scrollRemain+1] unless that index >= DISPLAY_SIZE, then blank -3: 1 2[3 4 ] -2: 1 2 3[4 ] -1: 1 2 3 4[ ] 0: (scroll functions are skipped to display whatever's applicable) */ else if(scrollRemain>0) { //scrolling display: value coming in - these don't use editDisplay as we're going array to array - for(byte i=0; i=displaySize? 15: scrollDisplay[isrc]); //allow to fade + for(byte i=0; i=DISPLAY_SIZE? 15: scrollDisplay[isrc]); //allow to fade } } else if(versionRemain>0) { @@ -1385,10 +1419,10 @@ void updateDisplay(){ //If 6 tubes (0-5), display on 4-5 //If 4 tubes (0-3), dislpay on 2-3 blankDisplay(0, 3, false); - editDisplay(fnSetVal, (displaySize>4? 4: 2), (displaySize>4? 5: 3), true, false); + editDisplay(fnSetVal, (DISPLAY_SIZE>4? 4: 2), (DISPLAY_SIZE>4? 5: 3), true, false); } else if(fnSetValMax==88) { //A piezo pitch. Play a short demo beep. editDisplay(fnSetVal, 0, 3, false, false); - if(piezoPin>=0) { noTone(piezoPin); tone(piezoPin, getHz(fnSetVal), 100); } //Can't use signalStart since we need to specify pitch directly + if(PIEZO_PIN>=0) { noTone(PIEZO_PIN); tone(PIEZO_PIN, getHz(fnSetVal), 100); } //Can't use signalStart since we need to specify pitch directly } else if(fnOptCurLoc==47 || fnOptCurLoc==48 || fnOptCurLoc==49) { //Signal pattern. Play a demo measure. editDisplay(fnSetVal, 0, 3, false, false); signalPattern = fnSetVal; @@ -1400,7 +1434,7 @@ void updateDisplay(){ } else if(fnSetValMax==900 || fnSetValMax==1800) { //Lat/long in tenths of a degree //If 6 tubes (0-5), display degrees on 0-3 and tenths on 4, with 5 blank //If 4 tubes (0-3), display degrees on 0-2 and tenths on 3 - editDisplay(abs(fnSetVal), 0, (displaySize>4? 4: 3), fnSetVal<0, false); + editDisplay(abs(fnSetVal), 0, (DISPLAY_SIZE>4? 4: 3), fnSetVal<0, false); } else editDisplay(abs(fnSetVal), 0, 3, fnSetVal<0, false); //some other type of value - leading zeros for negatives } else if(fn >= fnOpts){ //options menu, but not setting a value @@ -1480,11 +1514,11 @@ void updateDisplay(){ ); byte tdc; tdc = (td%1000)/10; //capture hundredths (centiseconds) td = td/1000+(!((timerState>>1)&1)&&tdc!=0?1:0); //remove mils, and if countdown, round up - //Countdown shows H:M:S, but on displaySize<6 and H<1, M:S - //Countup shows H:M:S, but if H<1, M:S:C, but if displaySize<6 and M<1, S:C + //Countdown shows H:M:S, but on DISPLAY_SIZE<6 and H<1, M:S + //Countup shows H:M:S, but if H<1, M:S:C, but if DISPLAY_SIZE<6 and M<1, S:C bool lz; lz = readEEPROM(19,false)&1; if((timerState>>1)&1){ //count up - if(displaySize<6 && td<60){ //under 1 min, 4-tubers: [SS]CC-- + if(DISPLAY_SIZE<6 && td<60){ //under 1 min, 4-tubers: [SS]CC-- if(td>=1||lz) editDisplay(td,0,1,lz,true); else blankDisplay(0,1,true); //secs, leading per lz, fade editDisplay(tdc,2,3,td>=1||lz,false); //cents, leading if >=1sec or lz, no fade blankDisplay(4,5,true); //just in case 4-tube code's running on a 6-tube clock, don't look ugly @@ -1498,7 +1532,7 @@ void updateDisplay(){ editDisplay(td%60,4,5,true,true); //secs, leading, fade } } else { //count down - if(displaySize<6 && td<3600){ //under 1 hr, 4-tubers: [MM]SS-- + if(DISPLAY_SIZE<6 && td<3600){ //under 1 hr, 4-tubers: [MM]SS-- if(td>=60||lz) editDisplay(td/60,0,1,lz,true); else blankDisplay(0,1,true); //mins, leading per lz, fade if(td>=1||lz) editDisplay(td%60,2,3,td>=60||lz,true); else blankDisplay(2,3,true); //secs, leading if >=1min or lz, fade blankDisplay(4,5,true); //just in case 4-tube code's running on a 6-tube clock, don't look ugly @@ -1537,7 +1571,7 @@ void updateDisplay(){ // if(tod.second()<10) Serial.print(F("0")); // Serial.print(tod.second(),DEC); // Serial.print(F(" ")); - // for(byte i=0; i9) Serial.print(F("-")); //blanked tube // else Serial.print(displayNext[i],DEC); @@ -1551,9 +1585,19 @@ void updateDisplay(){ } //end updateDisplay() +// void serialPrintDate(int y, byte m, byte d){ +// Serial.print(y,DEC); Serial.print(F("-")); +// if(m<10) Serial.print(F("0")); Serial.print(m,DEC); Serial.print(F("-")); +// if(d<10) Serial.print(F("0")); Serial.print(d,DEC); +// } +// void serialPrintTime(int todMins){ +// if(todMins/60<10) Serial.print(F("0")); Serial.print(todMins/60,DEC); Serial.print(F(":")); +// if(todMins%60<10) Serial.print(F("0")); Serial.print(todMins%60,DEC); +// } + //A snapshot of sun times, in minutes past midnight, calculated at clean time and when the date or time is changed. //Need to capture this many, as we could be displaying these values at least through end of tomorrow depending on when cleaning happens. - +#if ENABLE_DATE_RISESET byte sunDate = 0; //date of month when calculated ("today") int sunSet0 = -1; //yesterday's set int sunRise1 = -1; //today rise @@ -1590,17 +1634,7 @@ void calcSun(int y, byte m, byte d){ sunRise3 = here.sunrise(y,m,d,isDST(y,m,d)); // serialPrintDate(y,m,d); // Serial.print(F(" Rise ")); serialPrintTime(sunRise3); Serial.println(); -} -// void serialPrintDate(int y, byte m, byte d){ -// Serial.print(y,DEC); Serial.print(F("-")); -// if(m<10) Serial.print(F("0")); Serial.print(m,DEC); Serial.print(F("-")); -// if(d<10) Serial.print(F("0")); Serial.print(d,DEC); -// } -// void serialPrintTime(int todMins){ -// if(todMins/60<10) Serial.print(F("0")); Serial.print(todMins/60,DEC); Serial.print(F(":")); -// if(todMins%60<10) Serial.print(F("0")); Serial.print(todMins%60,DEC); -// } - +} //end calcSun() void displaySun(byte which, int d, int tod){ //Displays sun times from previously calculated values //Old code to calculate sun at display time, with test serial output, is in commit 163ca33 @@ -1634,6 +1668,11 @@ void displaySun(byte which, int d, int tod){ blankDisplay(4, 4, true); editDisplay(evtIsRise, 5, 5, false, true); } +#else +//to give other fns something empty to call, when rise/set isn't enabled +void calcSun(int y, byte m, byte d){} +void displaySun(byte which, int d, int tod){} +#endif void displayWeather(byte which){ //shows high/low temp (for day/night respectively) on main tubes, and precipitation info on seconds tubes @@ -1667,7 +1706,7 @@ void blankDisplay(byte posStart, byte posEnd, byte fade){ void startScroll() { //To scroll a value in, call this after calling editDisplay as normal for(byte i=0; i<6; i++) scrollDisplay[i] = displayNext[i]; //cache the incoming value in scrollDisplay[] blankDisplay(0,5,true); - scrollRemain = displaySize+1; //this will trigger updateDisplay() to start scrolling. displaySize+1 adds blank frame at front + scrollRemain = DISPLAY_SIZE+1; //this will trigger updateDisplay() to start scrolling. DISPLAY_SIZE+1 adds blank frame at front } //end startScroll() @@ -1677,10 +1716,10 @@ void startScroll() { //To scroll a value in, call this after calling editDisplay //The anode channel determines which two tubes are powered, //and the two SN74141 cathode driver chips determine which digits are lit. //4 pins out to each SN74141, representing a binary number with values [1,2,4,8] -byte binOutA[4] = {outA1,outA2,outA3,outA4}; -byte binOutB[4] = {outB1,outB2,outB3,outB4}; +byte binOutA[4] = {OUT_A1,OUT_A2,OUT_A3,OUT_A4}; +byte binOutB[4] = {OUT_B1,OUT_B2,OUT_B3,OUT_B4}; //3 pins out to anode channel switches -byte anodes[3] = {anode1,anode2,anode3}; +byte anodes[3] = {ANODE_1,ANODE_2,ANODE_3}; const int fadeDur = 5; //ms - each multiplexed pair of digits appears for this amount of time per cycle const int dimDur = 4; //ms - portion of fadeDur that is left dark during dim times @@ -1693,12 +1732,12 @@ unsigned long displayBlinkStart = 0; //when nonzero, display should briefly blan void initOutputs() { for(byte i=0; i<4; i++) { pinMode(binOutA[i],OUTPUT); pinMode(binOutB[i],OUTPUT); } for(byte i=0; i<3; i++) { pinMode(anodes[i],OUTPUT); } - if(piezoPin>=0) pinMode(piezoPin, OUTPUT); - if(relayPin>=0) { - pinMode(relayPin, OUTPUT); digitalWrite(relayPin, HIGH); //LOW = device on + if(PIEZO_PIN>=0) pinMode(PIEZO_PIN, OUTPUT); + if(RELAY_PIN>=0) { + pinMode(RELAY_PIN, OUTPUT); digitalWrite(RELAY_PIN, HIGH); //LOW = device on quickBeep(71); //"primes" the beeper, seems necessary when relay pin is spec'd, otherwise first intentional beep doesn't happen TODO still true? } - if(ledPin>=0) pinMode(ledPin, OUTPUT); + if(LED_PIN>=0) pinMode(LED_PIN, OUTPUT); updateLEDs(); //set to initial value } @@ -1819,7 +1858,7 @@ void signalStart(byte sigFn, byte sigDur){ //sigFn isn't necessarily the current fn, just the one generating the signal //sigDur is the number of measures to put on signalRemain, // or 0 for a single "quick measure" as applicable (i.e. skipped in radio mode). - //Special case: if sigFn==fnIsAlarm, and sigDur>0, we'll use signalDur or switchDur as appropriate. + //Special case: if sigFn==fnIsAlarm, and sigDur>0, we'll use SIGNAL_DUR or SWITCH_DUR as appropriate. //If sigFn is given as -1 (255), we will use both the existing signalSource and signalPattern for purposes of configs and fibonacci. if(!(sigFn==255 && signalSource==fnIsTimer)) signalStop(); // if there is a signal going per the current signalSource, stop it - can only have one signal at a time – except if this is a forced fnIsTimer signal (for signaling runout options) which is cool to overlap timer sleep //except if this is a forced @@ -1843,12 +1882,12 @@ void signalStart(byte sigFn, byte sigDur){ signalMeasureStep = 1; //waiting to start a new measure if(sigDur!=0){ //long-duration signal (alarm, sleep, etc) - set signalRemain //If switched relay, except if this is a forced fnIsTimer signal (for signaling runout options) - if(getSignalOutput()==1 && relayPin>=0 && relayMode==0 && !(sigFn==255 && signalSource==fnIsTimer)) { //turn it on now - signalRemain = (sigFn==fnIsAlarm? switchDur: sigDur); //For alarm signal, use switched relay duration from config (eg 2hr) - digitalWrite(relayPin,LOW); updateLEDs(); //LOW = device on + if(getSignalOutput()==1 && RELAY_PIN>=0 && RELAY_MODE==0 && !(sigFn==255 && signalSource==fnIsTimer)) { //turn it on now + signalRemain = (sigFn==fnIsAlarm? SWITCH_DUR: sigDur); //For alarm signal, use switched relay duration from config (eg 2hr) + digitalWrite(RELAY_PIN,LOW); updateLEDs(); //LOW = device on //Serial.print(millis(),DEC); Serial.println(F(" Relay on, signalStart")); } else { //start pulsing. If there is no beeper or pulsed relay, this will have no effect since cycleSignal will clear it - signalRemain = (sigFn==fnIsAlarm? signalDur: sigDur); //For alarm signal, use signal duration from config (eg 2min) + signalRemain = (sigFn==fnIsAlarm? SIGNAL_DUR: sigDur); //For alarm signal, use signal duration from config (eg 2min) } } //cycleSignal will pick up from here @@ -1856,9 +1895,9 @@ void signalStart(byte sigFn, byte sigDur){ void signalStop(){ //stop current signal and clear out signal timer if applicable //Serial.println(F("signalStop")); signalRemain = 0; snoozeRemain = 0; signalMeasureStep = 0; - if(getSignalOutput()==0 && piezoPin>=0) noTone(piezoPin); - if(getSignalOutput()==1 && relayPin>=0){ - digitalWrite(relayPin,HIGH); updateLEDs(); //LOW = device on + if(getSignalOutput()==0 && PIEZO_PIN>=0) noTone(PIEZO_PIN); + if(getSignalOutput()==1 && RELAY_PIN>=0){ + digitalWrite(RELAY_PIN,HIGH); updateLEDs(); //LOW = device on //Serial.print(millis(),DEC); Serial.println(F(" Relay off, signalStop")); } } //end signalStop() @@ -1866,7 +1905,7 @@ void cycleSignal(){ //Called on every loop to control the signal. word measureDur = 1000; //interval between measure starts, ms - beep pattern can customize this if(signalMeasureStep){ //if there's a measure going (or waiting for a new one) - if((getSignalOutput()==0 || (signalRemain==0 && signalSource==fnIsTimer)) && piezoPin>=0) { // beeper, or single measure for fnIsTimer runout setting + if((getSignalOutput()==0 || (signalRemain==0 && signalSource==fnIsTimer)) && PIEZO_PIN>=0) { // beeper, or single measure for fnIsTimer runout setting //Since tone() handles the duration of each beep, //we only need to use signalMeasureStep to track beep starts; they'll stop on their own. byte bc = 0; //this many beeps @@ -1901,7 +1940,7 @@ void cycleSignal(){ ) ) ); - noTone(piezoPin); tone(piezoPin, piezoPitch, bd); + noTone(PIEZO_PIN); tone(PIEZO_PIN, piezoPitch, bd); //Serial.print(F("Starting beep, sPS ")); //Serial.print(signalMeasureStep,DEC); //Serial.print(F(" -> ")); @@ -1918,8 +1957,8 @@ void cycleSignal(){ } } } //end beeper - else if(getSignalOutput()==1 && relayPin>=0 && relayMode==1){ //pulsed relay - //We don't follow the beep pattern here, we simply energize the relay for relayPulse time + else if(getSignalOutput()==1 && RELAY_PIN>=0 && RELAY_MODE==1){ //pulsed relay + //We don't follow the beep pattern here, we simply energize the relay for RELAY_PULSE time //Unlike beeper, we need to use a signalMeasureStep (2) to stop the relay. //See if it's time to start a new measure if(signalMeasureStep==255 && (unsigned long)(ms()-signalMeasureStartTime)>=measureDur){ @@ -1929,13 +1968,13 @@ void cycleSignal(){ } //Upon new measure, start the pulse immediately if(signalMeasureStep==1){ - digitalWrite(relayPin,LOW); updateLEDs(); //LOW = device on + digitalWrite(RELAY_PIN,LOW); updateLEDs(); //LOW = device on //Serial.print(millis(),DEC); Serial.println(F(" Relay on, cycleSignal")); signalMeasureStep = 2; //set it up to stop } //See if it's time to stop the pulse - else if(signalMeasureStep==2 && (unsigned long)(ms()-signalMeasureStartTime)>=relayPulse) { - digitalWrite(relayPin,HIGH); updateLEDs(); //LOW = device on + else if(signalMeasureStep==2 && (unsigned long)(ms()-signalMeasureStartTime)>=RELAY_PULSE) { + digitalWrite(RELAY_PIN,HIGH); updateLEDs(); //LOW = device on //Serial.print(millis(),DEC); Serial.println(F(" Relay off, cycleSignal")); //Set up for the next event if(signalRemain) signalRemain--; //this measure is done @@ -1988,7 +2027,7 @@ void quickBeep(int pitch){ //B6 = 75 //second loudest //C7 = 76 //loudest //F7 = 81 - if(piezoPin>=0) { noTone(piezoPin); tone(piezoPin, getHz(pitch), 100); } + if(PIEZO_PIN>=0) { noTone(PIEZO_PIN); tone(PIEZO_PIN, getHz(pitch), 100); } } const byte ledFadeStep = 10; //fade speed – with every loop() we'll increment/decrement the LED brightness (between 0-255) by this amount @@ -1996,7 +2035,7 @@ byte ledStateNow = 0; byte ledStateTarget = 0; void updateLEDs(){ //Run whenever something is changed that might affect the LED state: initial (initOutputs), signal start/stop, relay on/off, setting change - if(ledPin>=0) { + if(LED_PIN>=0) { switch(readEEPROM(26,false)){ case 0: //always off ledStateTarget = 0; @@ -2015,14 +2054,14 @@ void updateLEDs(){ //Serial.print(signalRemain && (signalSource==fnIsAlarm || signalSource==fnIsTimer)?F("LEDs on"):F("LEDs off")); Serial.println(F(" per alarm/timer")); break; case 4: //off, but on with switched relay - if(relayPin>=0 && relayMode==0) { - ledStateTarget = (!digitalRead(relayPin)? 255: 0); //LOW = device on - //Serial.print(!digitalRead(relayPin)? F("LEDs on"): F("LEDs off")); Serial.println(F(" per switched relay")); + if(RELAY_PIN>=0 && RELAY_MODE==0) { + ledStateTarget = (!digitalRead(RELAY_PIN)? 255: 0); //LOW = device on + //Serial.print(!digitalRead(RELAY_PIN)? F("LEDs on"): F("LEDs off")); Serial.println(F(" per switched relay")); } break; default: break; } //end switch - } //if ledPin + } //if LED_PIN } //end updateLEDs void cycleLEDs() { //Allows us to fade the LEDs to ledStateTarget by stepping via ledFadeStep @@ -2036,6 +2075,6 @@ void cycleLEDs() { // Serial.print(ledStateNow,DEC); // Serial.print(F(" => ")); // Serial.println(ledStateTarget,DEC); - analogWrite(ledPin,ledStateNow); + analogWrite(LED_PIN,ledStateNow); } } \ No newline at end of file diff --git a/arduino-nixie/configs/v5-4tube.h b/arduino-nixie/configs/v5-4tube.h index 5d95fa4..5c5dec6 100644 --- a/arduino-nixie/configs/v5-4tube.h +++ b/arduino-nixie/configs/v5-4tube.h @@ -1,21 +1,21 @@ //UNDB v5, 4-tube display -const byte displaySize = 4; //number of tubes in display module. Small display adjustments are made for 4-tube clocks +#define DISPLAY_SIZE 4 //number of tubes in display module. Small display adjustments are made for 4-tube clocks // Which functionality is enabled in this clock? // Related options will also be enabled in the options menu. -const bool enableDate = true; -const bool enableDateCounter = true; // Adds a "page" to the date with an anniversary counter -const bool enableDateSunriseSunset = true; // Adds "pages" to the date with sunrise/sunset times -const bool enableAlarm = true; -const bool enableAlarmAutoskip = true; -const bool enableAlarmFibonacci = true; -const bool enableTimer = true; -const bool enableChime = true; -const bool enableNightShutoff = true; // If disabled, tubes will be full brightness all the time. -const bool enableAwayShutoff = true; // Requires night shutoff. -const bool enableTemp = false; //Temperature per DS3231 - will read high – leave false for production -const bool enableTest = false; //Cycles through all tubes – leave false for production +#define ENABLE_DATE_FN true // Date function, optionally including pages below +#define ENABLE_DATE_COUNTER true // Adds date page with an anniversary counter +#define ENABLE_DATE_RISESET true // Adds date pages with sunrise/sunset times. Requires DM Kichi's Dusk2Dawn library to be installed in IDE. +#define ENABLE_ALARM_FN true +#define ENABLE_ALARM_AUTOSKIP true +#define ENABLE_ALARM_FIBONACCI true +#define ENABLE_TIMER_FN true +#define ENABLE_TIME_CHIME true +#define ENABLE_SHUTOFF_NIGHT true // If disabled, tubes will be full brightness all the time. +#define ENABLE_SHUTOFF_AWAY true // Requires night shutoff. +#define ENABLE_TEMP_FN false //Temperature per DS3231 - will read high – leave false for production +#define ENABLE_TUBETEST_FN false //Cycles through all tubes – leave false for production // These are the UNDB v5 board connections to Arduino analog input pins. // S1/PL13 = Reset @@ -28,64 +28,64 @@ const bool enableTest = false; //Cycles through all tubes – leave false for pr // A6-A7 are analog-only pins that aren't quite as responsive and require a physical pullup resistor (1K to +5V), and can't be used with rotary encoders because they don't support pin change interrupts. // What input is associated with each control? -const byte mainSel = A2; //main select button - must be equipped -const byte mainAdjUp = A1; //main up/down buttons or rotary encoder - must be equipped -const byte mainAdjDn = A0; -const byte altSel = 0; //alt select button - if unequipped, set to 0 +#define CTRL_SEL A2 //main select button - must be equipped +#define CTRL_UP A1 //main up/down buttons or rotary encoder - must be equipped +#define CTRL_DN A0 +#define CTRL_ALT 0 //alt select button - if unequipped, set to 0 -// What type of adj controls are equipped? -// 1 = momentary buttons. 2 = quadrature rotary encoder. -const byte mainAdjType = 2; +// What type of up/down controls are equipped? +// 1 = momentary buttons. 2 = quadrature rotary encoder: requires Paul Stoffregen's Encoder library to be installed in IDE. +#define CTRL_UPDN_TYPE 1 +#define ROT_VEL_START 80 //Required if CTRL_UPDN_TYPE==2. If step rate falls below this, kick into high velocity set (x10) +#define ROT_VEL_STOP 500 //Required if CTRL_UPDN_TYPE==2. If encoder step rate rises above this, drop into low velocity set (x1) + +// How long (in ms) are the button hold durations? +#define CTRL_HOLD_SHORT_DUR 1000 //for entering setting mode, or hold-setting at low velocity (x1) +#define CTRL_HOLD_LONG_DUR 3000 //for entering options menu, or hold-setting at high velocity (x10) //What are the signal pin(s) connected to? -const char piezoPin = 10; -const char relayPin = -1; //don't change - not available until UNDB v8 -const byte relayMode = 0; //don't change - not available until UNDB v8 -const word signalDur = 180; //sec - when pulsed signal is going, pulses are sent once/sec for this period (e.g. 180 = 3min) -const word switchDur = 7200; //sec - when alarm triggers switched relay, it's switched on for this period (e.g. 7200 = 2hr) -const word piezoPulse = 250; //ms - used with piezo via tone() -const word relayPulse = 200; //ms - used with pulsed relay +#define PIEZO_PIN 10 +#define RELAY_PIN -1 //don't change - not available until UNDB v9 (or modded v8 - see v9 configs) +#define RELAY_MODE 0 //don't change - not available until UNDB v9 (or modded v8 - see v9 configs) +#define SIGNAL_DUR 180 //sec - when pulsed signal is going, pulses are sent once/sec for this period (e.g. 180 = 3min) +#define SWITCH_DUR 7200 //sec - when alarm triggers switched relay, it's switched on for this period (e.g. 7200 = 2hr) +#define PIEZO_PULSE 250 //ms - used with piezo via tone() +#define RELAY_PULSE 200 //ms - used with pulsed relay //Soft power switches -const byte enableSoftAlarmSwitch = 1; +#define ENABLE_SOFT_ALARM_SWITCH 1 // 1 = yes. Alarm can be switched on and off when clock is displaying the alarm time (fnIsAlarm). // 0 = no. Alarm will be permanently on. Use with switched relay if the appliance has its own switch on this relay circuit. -const byte enableSoftPowerSwitch = 0; //don't change - not available until UNDB v8 +#define ENABLE_SOFT_POWER_SWITCH 0 //don't change - not available until UNDB v9 (or modded v8 - see v9 configs) //LED circuit control -const char ledPin = -1; //don't change - not available until UNDB v8 +#define LED_PIN -1 //don't change - not available until UNDB v9 (or modded v8 - see v9 configs) //When display is dim/off, a press will light the tubes for how long? -const byte unoffDur = 10; //sec - -// How long (in ms) are the button hold durations? -const word btnShortHold = 1000; //for entering setting mode, or hold-setting at low velocity -const word btnLongHold = 3000; //for entering options menu, or hold-setting at high velocity -const word velThreshold = 0; //ms -// When an adj up/down input (btn or rot) follows another in less than this time, value will change more (10 vs 1). -// 0 to disable. Recommend ~150 for rotaries. If you want to use this feature with buttons, extend to ~300. +#define UNOFF_DUR 10 //sec // What is the "frame rate" of the tube cleaning and display scrolling? up to 65535 ms -const word cleanSpeed = 200; //ms -const word scrollSpeed = 100; //ms - e.g. scroll-in-and-out date at :30 +#define CLEAN_SPEED 200 //ms +#define SCROLL_SPEED 100 //ms - e.g. scroll-in-and-out date at :30 // What are the timeouts for setting and temporarily-displayed functions? up to 65535 sec -const unsigned long timeoutSet = 300; //sec -const unsigned long timeoutTempFn = 5; //sec +#define SETTING_TIMEOUT 300 //sec +#define FN_TEMP_TIMEOUT 5 //sec +#define FN_PAGE_TIMEOUT 3 //sec //This clock is 2x3 multiplexed: two tubes powered at a time. //The anode channel determines which two tubes are powered, //and the two SN74141 cathode driver chips determine which digits are lit. //4 pins out to each SN74141, representing a binary number with values [1,2,4,8] -const char outA1 = 2; -const char outA2 = 3; -const char outA3 = 4; -const char outA4 = 5; -const char outB1 = 6; -const char outB2 = 7; -const char outB3 = 8; -const char outB4 = 9; +#define OUT_A1 2 +#define OUT_A2 3 +#define OUT_A3 4 +#define OUT_A4 5 +#define OUT_B1 6 +#define OUT_B2 7 +#define OUT_B3 8 +#define OUT_B4 9 //3 pins out to anode channel switches -const char anode1 = 11; -const char anode2 = 12; -const char anode3 = 13; \ No newline at end of file +#define ANODE_1 11 +#define ANODE_2 12 +#define ANODE_3 13 \ No newline at end of file diff --git a/arduino-nixie/configs/v5-6tube-rotary.h b/arduino-nixie/configs/v5-6tube-rotary.h new file mode 100644 index 0000000..e501940 --- /dev/null +++ b/arduino-nixie/configs/v5-6tube-rotary.h @@ -0,0 +1,91 @@ +//UNDB v5, 6-tube display, with rotary controls + +#define DISPLAY_SIZE 6 //number of tubes in display module. Small display adjustments are made for 4-tube clocks + +// Which functionality is enabled in this clock? +// Related options will also be enabled in the options menu. +#define ENABLE_DATE_FN true // Date function, optionally including pages below +#define ENABLE_DATE_COUNTER true // Adds date page with an anniversary counter +#define ENABLE_DATE_RISESET true // Adds date pages with sunrise/sunset times. Requires DM Kichi's Dusk2Dawn library to be installed in IDE. +#define ENABLE_ALARM_FN true +#define ENABLE_ALARM_AUTOSKIP true +#define ENABLE_ALARM_FIBONACCI true +#define ENABLE_TIMER_FN true +#define ENABLE_TIME_CHIME true +#define ENABLE_SHUTOFF_NIGHT true // If disabled, tubes will be full brightness all the time. +#define ENABLE_SHUTOFF_AWAY true // Requires night shutoff. +#define ENABLE_TEMP_FN false //Temperature per DS3231 - will read high – leave false for production +#define ENABLE_TUBETEST_FN false //Cycles through all tubes – leave false for production + +// These are the UNDB v5 board connections to Arduino analog input pins. +// S1/PL13 = Reset +// S2/PL5 = A1 +// S3/PL6 = A0 +// S4/PL7 = A6 +// S5/PL8 = A3 +// S6/PL9 = A2 +// S7/PL14 = A7 +// A6-A7 are analog-only pins that aren't quite as responsive and require a physical pullup resistor (1K to +5V), and can't be used with rotary encoders because they don't support pin change interrupts. + +// What input is associated with each control? +#define CTRL_SEL A2 //main select button - must be equipped +#define CTRL_UP A1 //main up/down buttons or rotary encoder - must be equipped +#define CTRL_DN A0 +#define CTRL_ALT 0 //alt select button - if unequipped, set to 0 + +// What type of up/down controls are equipped? +// 1 = momentary buttons. 2 = quadrature rotary encoder: requires Paul Stoffregen's Encoder library to be installed in IDE. +#define CTRL_UPDN_TYPE 2 +#define ROT_VEL_START 80 //Required if CTRL_UPDN_TYPE==2. If step rate falls below this, kick into high velocity set (x10) +#define ROT_VEL_STOP 500 //Required if CTRL_UPDN_TYPE==2. If encoder step rate rises above this, drop into low velocity set (x1) + +// How long (in ms) are the button hold durations? +#define CTRL_HOLD_SHORT_DUR 1000 //for entering setting mode, or hold-setting at low velocity (x1) +#define CTRL_HOLD_LONG_DUR 3000 //for entering options menu, or hold-setting at high velocity (x10) + +//What are the signal pin(s) connected to? +#define PIEZO_PIN 10 +#define RELAY_PIN -1 //don't change - not available until UNDB v9 (or modded v8 - see v9 configs) +#define RELAY_MODE 0 //don't change - not available until UNDB v9 (or modded v8 - see v9 configs) +#define SIGNAL_DUR 180 //sec - when pulsed signal is going, pulses are sent once/sec for this period (e.g. 180 = 3min) +#define SWITCH_DUR 7200 //sec - when alarm triggers switched relay, it's switched on for this period (e.g. 7200 = 2hr) +#define PIEZO_PULSE 250 //ms - used with piezo via tone() +#define RELAY_PULSE 200 //ms - used with pulsed relay + +//Soft power switches +#define ENABLE_SOFT_ALARM_SWITCH 1 +// 1 = yes. Alarm can be switched on and off when clock is displaying the alarm time (fnIsAlarm). +// 0 = no. Alarm will be permanently on. Use with switched relay if the appliance has its own switch on this relay circuit. +#define ENABLE_SOFT_POWER_SWITCH 0 //don't change - not available until UNDB v9 (or modded v8 - see v9 configs) + +//LED circuit control +#define LED_PIN -1 //don't change - not available until UNDB v9 (or modded v8 - see v9 configs) + +//When display is dim/off, a press will light the tubes for how long? +#define UNOFF_DUR 10 //sec + +// What is the "frame rate" of the tube cleaning and display scrolling? up to 65535 ms +#define CLEAN_SPEED 200 //ms +#define SCROLL_SPEED 100 //ms - e.g. scroll-in-and-out date at :30 + +// What are the timeouts for setting and temporarily-displayed functions? up to 65535 sec +#define SETTING_TIMEOUT 300 //sec +#define FN_TEMP_TIMEOUT 5 //sec +#define FN_PAGE_TIMEOUT 3 //sec + +//This clock is 2x3 multiplexed: two tubes powered at a time. +//The anode channel determines which two tubes are powered, +//and the two SN74141 cathode driver chips determine which digits are lit. +//4 pins out to each SN74141, representing a binary number with values [1,2,4,8] +#define OUT_A1 2 +#define OUT_A2 3 +#define OUT_A3 4 +#define OUT_A4 5 +#define OUT_B1 6 +#define OUT_B2 7 +#define OUT_B3 8 +#define OUT_B4 9 +//3 pins out to anode channel switches +#define ANODE_1 11 +#define ANODE_2 12 +#define ANODE_3 13 \ No newline at end of file diff --git a/arduino-nixie/configs/v5-6tube.h b/arduino-nixie/configs/v5-6tube.h index b433838..ad914e4 100644 --- a/arduino-nixie/configs/v5-6tube.h +++ b/arduino-nixie/configs/v5-6tube.h @@ -1,21 +1,21 @@ //UNDB v5, 6-tube display -const byte displaySize = 6; //number of tubes in display module. Small display adjustments are made for 4-tube clocks +#define DISPLAY_SIZE 6 //number of tubes in display module. Small display adjustments are made for 4-tube clocks // Which functionality is enabled in this clock? // Related options will also be enabled in the options menu. -const bool enableDate = true; -const bool enableDateCounter = true; // Adds a "page" to the date with an anniversary counter -const bool enableDateSunriseSunset = true; // Adds "pages" to the date with sunrise/sunset times -const bool enableAlarm = true; -const bool enableAlarmAutoskip = true; -const bool enableAlarmFibonacci = true; -const bool enableTimer = true; -const bool enableChime = true; -const bool enableNightShutoff = true; // If disabled, tubes will be full brightness all the time. -const bool enableAwayShutoff = true; // Requires night shutoff. -const bool enableTemp = false; //Temperature per DS3231 - will read high – leave false for production -const bool enableTest = false; //Cycles through all tubes – leave false for production +#define ENABLE_DATE_FN true // Date function, optionally including pages below +#define ENABLE_DATE_COUNTER true // Adds date page with an anniversary counter +#define ENABLE_DATE_RISESET true // Adds date pages with sunrise/sunset times. Requires DM Kichi's Dusk2Dawn library to be installed in IDE. +#define ENABLE_ALARM_FN true +#define ENABLE_ALARM_AUTOSKIP true +#define ENABLE_ALARM_FIBONACCI true +#define ENABLE_TIMER_FN true +#define ENABLE_TIME_CHIME true +#define ENABLE_SHUTOFF_NIGHT true // If disabled, tubes will be full brightness all the time. +#define ENABLE_SHUTOFF_AWAY true // Requires night shutoff. +#define ENABLE_TEMP_FN false //Temperature per DS3231 - will read high – leave false for production +#define ENABLE_TUBETEST_FN false //Cycles through all tubes – leave false for production // These are the UNDB v5 board connections to Arduino analog input pins. // S1/PL13 = Reset @@ -28,64 +28,64 @@ const bool enableTest = false; //Cycles through all tubes – leave false for pr // A6-A7 are analog-only pins that aren't quite as responsive and require a physical pullup resistor (1K to +5V), and can't be used with rotary encoders because they don't support pin change interrupts. // What input is associated with each control? -const byte mainSel = A2; //main select button - must be equipped -const byte mainAdjUp = A1; //main up/down buttons or rotary encoder - must be equipped -const byte mainAdjDn = A0; -const byte altSel = 0; //alt select button - if unequipped, set to 0 +#define CTRL_SEL A2 //main select button - must be equipped +#define CTRL_UP A1 //main up/down buttons or rotary encoder - must be equipped +#define CTRL_DN A0 +#define CTRL_ALT 0 //alt select button - if unequipped, set to 0 -// What type of adj controls are equipped? -// 1 = momentary buttons. 2 = quadrature rotary encoder. -const byte mainAdjType = 1; +// What type of up/down controls are equipped? +// 1 = momentary buttons. 2 = quadrature rotary encoder: requires Paul Stoffregen's Encoder library to be installed in IDE. +#define CTRL_UPDN_TYPE 1 +#define ROT_VEL_START 80 //Required if CTRL_UPDN_TYPE==2. If step rate falls below this, kick into high velocity set (x10) +#define ROT_VEL_STOP 500 //Required if CTRL_UPDN_TYPE==2. If encoder step rate rises above this, drop into low velocity set (x1) + +// How long (in ms) are the button hold durations? +#define CTRL_HOLD_SHORT_DUR 1000 //for entering setting mode, or hold-setting at low velocity (x1) +#define CTRL_HOLD_LONG_DUR 3000 //for entering options menu, or hold-setting at high velocity (x10) //What are the signal pin(s) connected to? -const char piezoPin = 10; -const char relayPin = -1; //don't change - not available until UNDB v8 -const byte relayMode = 0; //don't change - not available until UNDB v8 -const word signalDur = 180; //sec - when pulsed signal is going, pulses are sent once/sec for this period (e.g. 180 = 3min) -const word switchDur = 7200; //sec - when alarm triggers switched relay, it's switched on for this period (e.g. 7200 = 2hr) -const word piezoPulse = 250; //ms - used with piezo via tone() -const word relayPulse = 200; //ms - used with pulsed relay +#define PIEZO_PIN 10 +#define RELAY_PIN -1 //don't change - not available until UNDB v9 (or modded v8 - see v9 configs) +#define RELAY_MODE 0 //don't change - not available until UNDB v9 (or modded v8 - see v9 configs) +#define SIGNAL_DUR 180 //sec - when pulsed signal is going, pulses are sent once/sec for this period (e.g. 180 = 3min) +#define SWITCH_DUR 7200 //sec - when alarm triggers switched relay, it's switched on for this period (e.g. 7200 = 2hr) +#define PIEZO_PULSE 250 //ms - used with piezo via tone() +#define RELAY_PULSE 200 //ms - used with pulsed relay //Soft power switches -const byte enableSoftAlarmSwitch = 1; +#define ENABLE_SOFT_ALARM_SWITCH 1 // 1 = yes. Alarm can be switched on and off when clock is displaying the alarm time (fnIsAlarm). // 0 = no. Alarm will be permanently on. Use with switched relay if the appliance has its own switch on this relay circuit. -const byte enableSoftPowerSwitch = 0; //don't change - not available until UNDB v8 +#define ENABLE_SOFT_POWER_SWITCH 0 //don't change - not available until UNDB v9 (or modded v8 - see v9 configs) //LED circuit control -const char ledPin = -1; //don't change - not available until UNDB v8 +#define LED_PIN -1 //don't change - not available until UNDB v9 (or modded v8 - see v9 configs) //When display is dim/off, a press will light the tubes for how long? -const byte unoffDur = 10; //sec - -// How long (in ms) are the button hold durations? -const word btnShortHold = 1000; //for entering setting mode, or hold-setting at low velocity -const word btnLongHold = 3000; //for entering options menu, or hold-setting at high velocity -const word velThreshold = 0; //ms -// When an adj up/down input (btn or rot) follows another in less than this time, value will change more (10 vs 1). -// 0 to disable. Recommend ~150 for rotaries. If you want to use this feature with buttons, extend to ~300. +#define UNOFF_DUR 10 //sec // What is the "frame rate" of the tube cleaning and display scrolling? up to 65535 ms -const word cleanSpeed = 200; //ms -const word scrollSpeed = 100; //ms - e.g. scroll-in-and-out date at :30 +#define CLEAN_SPEED 200 //ms +#define SCROLL_SPEED 100 //ms - e.g. scroll-in-and-out date at :30 // What are the timeouts for setting and temporarily-displayed functions? up to 65535 sec -const unsigned long timeoutSet = 300; //sec -const unsigned long timeoutTempFn = 5; //sec +#define SETTING_TIMEOUT 300 //sec +#define FN_TEMP_TIMEOUT 5 //sec +#define FN_PAGE_TIMEOUT 3 //sec //This clock is 2x3 multiplexed: two tubes powered at a time. //The anode channel determines which two tubes are powered, //and the two SN74141 cathode driver chips determine which digits are lit. //4 pins out to each SN74141, representing a binary number with values [1,2,4,8] -const char outA1 = 2; -const char outA2 = 3; -const char outA3 = 4; -const char outA4 = 5; -const char outB1 = 6; -const char outB2 = 7; -const char outB3 = 8; -const char outB4 = 9; +#define OUT_A1 2 +#define OUT_A2 3 +#define OUT_A3 4 +#define OUT_A4 5 +#define OUT_B1 6 +#define OUT_B2 7 +#define OUT_B3 8 +#define OUT_B4 9 //3 pins out to anode channel switches -const char anode1 = 11; -const char anode2 = 12; -const char anode3 = 13; \ No newline at end of file +#define ANODE_1 11 +#define ANODE_2 12 +#define ANODE_3 13 \ No newline at end of file diff --git a/arduino-nixie/configs/v8-4tube.h b/arduino-nixie/configs/v8-4tube.h index edc30b3..1665379 100644 --- a/arduino-nixie/configs/v8-4tube.h +++ b/arduino-nixie/configs/v8-4tube.h @@ -1,21 +1,21 @@ //Unmodified UNDB v8 with LED and relay disabled, and buttons as labeled, with 4-digit display. -const byte displaySize = 4; //number of tubes in display module. Small display adjustments are made for 4-tube clocks +#define DISPLAY_SIZE 4 //number of tubes in display module. Small display adjustments are made for 4-tube clocks // Which functionality is enabled in this clock? // Related options will also be enabled in the options menu. -const bool enableDate = true; -const bool enableDateCounter = true; // Adds a "page" to the date with an anniversary counter -const bool enableDateSunriseSunset = true; // Adds "pages" to the date with sunrise/sunset times -const bool enableAlarm = true; -const bool enableAlarmAutoskip = true; -const bool enableAlarmFibonacci = true; -const bool enableTimer = true; -const bool enableChime = true; -const bool enableNightShutoff = true; // If disabled, tubes will be full brightness all the time. -const bool enableAwayShutoff = true; // Requires night shutoff. -const bool enableTemp = false; //Temperature per DS3231 - will read high – leave false for production -const bool enableTest = false; //Cycles through all tubes – leave false for production +#define ENABLE_DATE_FN true // Date function, optionally including pages below +#define ENABLE_DATE_COUNTER true // Adds date page with an anniversary counter +#define ENABLE_DATE_RISESET true // Adds date pages with sunrise/sunset times. Requires DM Kichi's Dusk2Dawn library to be installed in IDE. +#define ENABLE_ALARM_FN true +#define ENABLE_ALARM_AUTOSKIP true +#define ENABLE_ALARM_FIBONACCI true +#define ENABLE_TIMER_FN true +#define ENABLE_TIME_CHIME true +#define ENABLE_SHUTOFF_NIGHT true // If disabled, tubes will be full brightness all the time. +#define ENABLE_SHUTOFF_AWAY true // Requires night shutoff. +#define ENABLE_TEMP_FN false //Temperature per DS3231 - will read high – leave false for production +#define ENABLE_TUBETEST_FN false //Cycles through all tubes – leave false for production // These are the RLB board connections to Arduino analog input pins. // S1/PL13 = Reset @@ -28,70 +28,64 @@ const bool enableTest = false; //Cycles through all tubes – leave false for pr // A6-A7 are analog-only pins that aren't quite as responsive and require a physical pullup resistor (1K to +5V), and can't be used with rotary encoders because they don't support pin change interrupts. // What input is associated with each control? -const byte mainSel = A1; //main select button - must be equipped -const byte mainAdjUp = A2; //main up/down buttons or rotary encoder - must be equipped -const byte mainAdjDn = A3; -const byte altSel = A0; //alt select button - if unequipped, set to 0 +#define CTRL_SEL A1 //main select button - must be equipped +#define CTRL_UP A2 //main up/down buttons or rotary encoder - must be equipped +#define CTRL_DN A3 +#define CTRL_ALT A0 //alt select button - if unequipped, set to 0 -// What type of adj controls are equipped? -// 1 = momentary buttons. 2 = quadrature rotary encoder. -const byte mainAdjType = 1; +// What type of up/down controls are equipped? +// 1 = momentary buttons. 2 = quadrature rotary encoder: requires Paul Stoffregen's Encoder library to be installed in IDE. +#define CTRL_UPDN_TYPE 1 +#define ROT_VEL_START 80 //Required if CTRL_UPDN_TYPE==2. If step rate falls below this, kick into high velocity set (x10) +#define ROT_VEL_STOP 500 //Required if CTRL_UPDN_TYPE==2. If encoder step rate rises above this, drop into low velocity set (x1) + +// How long (in ms) are the button hold durations? +#define CTRL_HOLD_SHORT_DUR 1000 //for entering setting mode, or hold-setting at low velocity (x1) +#define CTRL_HOLD_LONG_DUR 3000 //for entering options menu, or hold-setting at high velocity (x10) //What are the signal pin(s) connected to? -const char piezoPin = 10; -const char relayPin = -1; -// -1 to disable feature (no relay item equipped); A3 if equipped (UNDB v8) -const byte relayMode = 0; //If relay is equipped, what does it do? -// 0 = switched mode: the relay will be switched to control an appliance like a radio or light fixture. If used with timer, it will switch on while timer is running (like a "sleep" function). If used with alarm, it will switch on when alarm trips; specify duration of this in switchDur. -// 1 = pulsed mode: the relay will be pulsed, like the beeper is, to control an intermittent signaling device like a solenoid or indicator lamp. Specify pulse duration in relayPulse. -const word signalDur = 180; //sec - when pulsed signal is going, pulses are sent once/sec for this period (e.g. 180 = 3min) -const word switchDur = 7200; //sec - when alarm triggers switched relay, it's switched on for this period (e.g. 7200 = 2hr) -const word piezoPulse = 250; //ms - used with piezo via tone() -const word relayPulse = 200; //ms - used with pulsed relay +#define PIEZO_PIN 10 +#define RELAY_PIN -1 //don't change - not available until UNDB v9 (or modded v8 - see v9 configs) +#define RELAY_MODE 0 //don't change - not available until UNDB v9 (or modded v8 - see v9 configs) +#define SIGNAL_DUR 180 //sec - when pulsed signal is going, pulses are sent once/sec for this period (e.g. 180 = 3min) +#define SWITCH_DUR 7200 //sec - when alarm triggers switched relay, it's switched on for this period (e.g. 7200 = 2hr) +#define PIEZO_PULSE 250 //ms - used with piezo via tone() +#define RELAY_PULSE 200 //ms - used with pulsed relay //Soft power switches -const byte enableSoftAlarmSwitch = 1; +#define ENABLE_SOFT_ALARM_SWITCH 1 // 1 = yes. Alarm can be switched on and off when clock is displaying the alarm time (fnIsAlarm). // 0 = no. Alarm will be permanently on. Use with switched relay if the appliance has its own switch on this relay circuit. -const byte enableSoftPowerSwitch = 1; //works with switched relay only -// 1 = yes. Relay can be switched on and off directly with Alt button at any time (except in options menu). This is useful if connecting an appliance (e.g. radio) that doesn't have its own switch, or if replacing the clock unit in a clock radio where the clock does all the switching (e.g. Telechron). -// 0 = no. Use if the connected appliance has its own power switch (independent of this relay circuit) or does not need to be manually switched. In this case (and/or if there is no switched relay) Alt will act as a function preset. +#define ENABLE_SOFT_POWER_SWITCH 0 //don't change - not available until UNDB v9 (or modded v8 - see v9 configs) //LED circuit control -const char ledPin = -1; -// -1 to disable feature; A2 if equipped (UNDB v8) +#define LED_PIN -1 //don't change - not available until UNDB v9 (or modded v8 - see v9 configs) //When display is dim/off, a press will light the tubes for how long? -const byte unoffDur = 10; //sec - -// How long (in ms) are the button hold durations? -const word btnShortHold = 1000; //for entering setting mode, or hold-setting at low velocity -const word btnLongHold = 3000; //for entering options menu, or hold-setting at high velocity -const word velThreshold = 0; //ms -// When an adj up/down input (btn or rot) follows another in less than this time, value will change more (10 vs 1). -// 0 to disable. Recommend ~150 for rotaries. If you want to use this feature with buttons, extend to ~300. +#define UNOFF_DUR 10 //sec // What is the "frame rate" of the tube cleaning and display scrolling? up to 65535 ms -const word cleanSpeed = 200; //ms -const word scrollSpeed = 100; //ms - e.g. scroll-in-and-out date at :30 +#define CLEAN_SPEED 200 //ms +#define SCROLL_SPEED 100 //ms - e.g. scroll-in-and-out date at :30 // What are the timeouts for setting and temporarily-displayed functions? up to 65535 sec -const unsigned long timeoutSet = 300; //sec -const unsigned long timeoutTempFn = 5; //sec +#define SETTING_TIMEOUT 300 //sec +#define FN_TEMP_TIMEOUT 5 //sec +#define FN_PAGE_TIMEOUT 3 //sec //This clock is 2x3 multiplexed: two tubes powered at a time. //The anode channel determines which two tubes are powered, //and the two SN74141 cathode driver chips determine which digits are lit. //4 pins out to each SN74141, representing a binary number with values [1,2,4,8] -const char outA1 = 2; -const char outA2 = 3; -const char outA3 = 4; -const char outA4 = 5; -const char outB1 = 6; -const char outB2 = 7; -const char outB3 = 8; -const char outB4 = 9; +#define OUT_A1 2 +#define OUT_A2 3 +#define OUT_A3 4 +#define OUT_A4 5 +#define OUT_B1 6 +#define OUT_B2 7 +#define OUT_B3 8 +#define OUT_B4 9 //3 pins out to anode channel switches -const char anode1 = 11; -const char anode2 = 12; -const char anode3 = 13; \ No newline at end of file +#define ANODE_1 11 +#define ANODE_2 12 +#define ANODE_3 13 \ No newline at end of file diff --git a/arduino-nixie/configs/v8-6tube-simplified.h b/arduino-nixie/configs/v8-6tube-simplified.h new file mode 100644 index 0000000..9bfa6df --- /dev/null +++ b/arduino-nixie/configs/v8-6tube-simplified.h @@ -0,0 +1,91 @@ +//Unmodified UNDB v8 with LED and relay disabled, and buttons as labeled, with 6-digit display. + +#define DISPLAY_SIZE 6 //number of tubes in display module. Small display adjustments are made for 4-tube clocks + +// Which functionality is enabled in this clock? +// Related options will also be enabled in the options menu. +#define ENABLE_DATE_FN true // Date function, optionally including pages below +#define ENABLE_DATE_COUNTER false // Adds date page with an anniversary counter +#define ENABLE_DATE_RISESET false // Adds date pages with sunrise/sunset times. Requires DM Kichi's Dusk2Dawn library to be installed in IDE. +#define ENABLE_ALARM_FN true +#define ENABLE_ALARM_AUTOSKIP false +#define ENABLE_ALARM_FIBONACCI false +#define ENABLE_TIMER_FN false +#define ENABLE_TIME_CHIME true +#define ENABLE_SHUTOFF_NIGHT true // If disabled, tubes will be full brightness all the time. +#define ENABLE_SHUTOFF_AWAY false // Requires night shutoff. +#define ENABLE_TEMP_FN false //Temperature per DS3231 - will read high – leave false for production +#define ENABLE_TUBETEST_FN false //Cycles through all tubes – leave false for production + +// These are the RLB board connections to Arduino analog input pins. +// S1/PL13 = Reset +// S2/PL5 = A1 +// S3/PL6 = A0 +// S4/PL7 = A6 +// S5/PL8 = A3 +// S6/PL9 = A2 +// S7/PL14 = A7 +// A6-A7 are analog-only pins that aren't quite as responsive and require a physical pullup resistor (1K to +5V), and can't be used with rotary encoders because they don't support pin change interrupts. + +// What input is associated with each control? +#define CTRL_SEL A1 //main select button - must be equipped +#define CTRL_UP A2 //main up/down buttons or rotary encoder - must be equipped +#define CTRL_DN A3 +#define CTRL_ALT A0 //alt select button - if unequipped, set to 0 + +// What type of up/down controls are equipped? +// 1 = momentary buttons. 2 = quadrature rotary encoder: requires Paul Stoffregen's Encoder library to be installed in IDE. +#define CTRL_UPDN_TYPE 1 +#define ROT_VEL_START 80 //Required if CTRL_UPDN_TYPE==2. If step rate falls below this, kick into high velocity set (x10) +#define ROT_VEL_STOP 500 //Required if CTRL_UPDN_TYPE==2. If encoder step rate rises above this, drop into low velocity set (x1) + +// How long (in ms) are the button hold durations? +#define CTRL_HOLD_SHORT_DUR 1000 //for entering setting mode, or hold-setting at low velocity (x1) +#define CTRL_HOLD_LONG_DUR 3000 //for entering options menu, or hold-setting at high velocity (x10) + +//What are the signal pin(s) connected to? +#define PIEZO_PIN 10 +#define RELAY_PIN -1 //don't change - not available until UNDB v9 (or modded v8 - see v9 configs) +#define RELAY_MODE 0 //don't change - not available until UNDB v9 (or modded v8 - see v9 configs) +#define SIGNAL_DUR 180 //sec - when pulsed signal is going, pulses are sent once/sec for this period (e.g. 180 = 3min) +#define SWITCH_DUR 7200 //sec - when alarm triggers switched relay, it's switched on for this period (e.g. 7200 = 2hr) +#define PIEZO_PULSE 250 //ms - used with piezo via tone() +#define RELAY_PULSE 200 //ms - used with pulsed relay + +//Soft power switches +#define ENABLE_SOFT_ALARM_SWITCH 1 +// 1 = yes. Alarm can be switched on and off when clock is displaying the alarm time (fnIsAlarm). +// 0 = no. Alarm will be permanently on. Use with switched relay if the appliance has its own switch on this relay circuit. +#define ENABLE_SOFT_POWER_SWITCH 0 //don't change - not available until UNDB v9 (or modded v8 - see v9 configs) + +//LED circuit control +#define LED_PIN -1 //don't change - not available until UNDB v9 (or modded v8 - see v9 configs) + +//When display is dim/off, a press will light the tubes for how long? +#define UNOFF_DUR 10 //sec + +// What is the "frame rate" of the tube cleaning and display scrolling? up to 65535 ms +#define CLEAN_SPEED 200 //ms +#define SCROLL_SPEED 100 //ms - e.g. scroll-in-and-out date at :30 + +// What are the timeouts for setting and temporarily-displayed functions? up to 65535 sec +#define SETTING_TIMEOUT 300 //sec +#define FN_TEMP_TIMEOUT 5 //sec +#define FN_PAGE_TIMEOUT 3 //sec + +//This clock is 2x3 multiplexed: two tubes powered at a time. +//The anode channel determines which two tubes are powered, +//and the two SN74141 cathode driver chips determine which digits are lit. +//4 pins out to each SN74141, representing a binary number with values [1,2,4,8] +#define OUT_A1 2 +#define OUT_A2 3 +#define OUT_A3 4 +#define OUT_A4 5 +#define OUT_B1 6 +#define OUT_B2 7 +#define OUT_B3 8 +#define OUT_B4 9 +//3 pins out to anode channel switches +#define ANODE_1 11 +#define ANODE_2 12 +#define ANODE_3 13 \ No newline at end of file diff --git a/arduino-nixie/configs/v8-6tube.h b/arduino-nixie/configs/v8-6tube.h index 8a9bbf6..d15741e 100644 --- a/arduino-nixie/configs/v8-6tube.h +++ b/arduino-nixie/configs/v8-6tube.h @@ -1,21 +1,21 @@ //Unmodified UNDB v8 with LED and relay disabled, and buttons as labeled, with 6-digit display. -const byte displaySize = 6; //number of tubes in display module. Small display adjustments are made for 4-tube clocks +#define DISPLAY_SIZE 6 //number of tubes in display module. Small display adjustments are made for 4-tube clocks // Which functionality is enabled in this clock? // Related options will also be enabled in the options menu. -const bool enableDate = true; -const bool enableDateCounter = true; // Adds a "page" to the date with an anniversary counter -const bool enableDateSunriseSunset = true; // Adds "pages" to the date with sunrise/sunset times -const bool enableAlarm = true; -const bool enableAlarmAutoskip = true; -const bool enableAlarmFibonacci = true; -const bool enableTimer = true; -const bool enableChime = true; -const bool enableNightShutoff = true; // If disabled, tubes will be full brightness all the time. -const bool enableAwayShutoff = true; // Requires night shutoff. -const bool enableTemp = false; //Temperature per DS3231 - will read high – leave false for production -const bool enableTest = false; //Cycles through all tubes – leave false for production +#define ENABLE_DATE_FN true // Date function, optionally including pages below +#define ENABLE_DATE_COUNTER true // Adds date page with an anniversary counter +#define ENABLE_DATE_RISESET true // Adds date pages with sunrise/sunset times. Requires DM Kichi's Dusk2Dawn library to be installed in IDE. +#define ENABLE_ALARM_FN true +#define ENABLE_ALARM_AUTOSKIP true +#define ENABLE_ALARM_FIBONACCI true +#define ENABLE_TIMER_FN true +#define ENABLE_TIME_CHIME true +#define ENABLE_SHUTOFF_NIGHT true // If disabled, tubes will be full brightness all the time. +#define ENABLE_SHUTOFF_AWAY true // Requires night shutoff. +#define ENABLE_TEMP_FN false //Temperature per DS3231 - will read high – leave false for production +#define ENABLE_TUBETEST_FN false //Cycles through all tubes – leave false for production // These are the RLB board connections to Arduino analog input pins. // S1/PL13 = Reset @@ -28,70 +28,64 @@ const bool enableTest = false; //Cycles through all tubes – leave false for pr // A6-A7 are analog-only pins that aren't quite as responsive and require a physical pullup resistor (1K to +5V), and can't be used with rotary encoders because they don't support pin change interrupts. // What input is associated with each control? -const byte mainSel = A1; //main select button - must be equipped -const byte mainAdjUp = A2; //main up/down buttons or rotary encoder - must be equipped -const byte mainAdjDn = A3; -const byte altSel = A0; //alt select button - if unequipped, set to 0 +#define CTRL_SEL A1 //main select button - must be equipped +#define CTRL_UP A2 //main up/down buttons or rotary encoder - must be equipped +#define CTRL_DN A3 +#define CTRL_ALT A0 //alt select button - if unequipped, set to 0 -// What type of adj controls are equipped? -// 1 = momentary buttons. 2 = quadrature rotary encoder. -const byte mainAdjType = 1; +// What type of up/down controls are equipped? +// 1 = momentary buttons. 2 = quadrature rotary encoder: requires Paul Stoffregen's Encoder library to be installed in IDE. +#define CTRL_UPDN_TYPE 1 +#define ROT_VEL_START 80 //Required if CTRL_UPDN_TYPE==2. If step rate falls below this, kick into high velocity set (x10) +#define ROT_VEL_STOP 500 //Required if CTRL_UPDN_TYPE==2. If encoder step rate rises above this, drop into low velocity set (x1) + +// How long (in ms) are the button hold durations? +#define CTRL_HOLD_SHORT_DUR 1000 //for entering setting mode, or hold-setting at low velocity (x1) +#define CTRL_HOLD_LONG_DUR 3000 //for entering options menu, or hold-setting at high velocity (x10) //What are the signal pin(s) connected to? -const char piezoPin = 10; -const char relayPin = -1; -// -1 to disable feature (no relay item equipped); A3 if equipped (UNDB v8) -const byte relayMode = 0; //If relay is equipped, what does it do? -// 0 = switched mode: the relay will be switched to control an appliance like a radio or light fixture. If used with timer, it will switch on while timer is running (like a "sleep" function). If used with alarm, it will switch on when alarm trips; specify duration of this in switchDur. -// 1 = pulsed mode: the relay will be pulsed, like the beeper is, to control an intermittent signaling device like a solenoid or indicator lamp. Specify pulse duration in relayPulse. -const word signalDur = 180; //sec - when pulsed signal is going, pulses are sent once/sec for this period (e.g. 180 = 3min) -const word switchDur = 7200; //sec - when alarm triggers switched relay, it's switched on for this period (e.g. 7200 = 2hr) -const word piezoPulse = 250; //ms - used with piezo via tone() -const word relayPulse = 200; //ms - used with pulsed relay +#define PIEZO_PIN 10 +#define RELAY_PIN -1 //don't change - not available until UNDB v9 (or modded v8 - see v9 configs) +#define RELAY_MODE 0 //don't change - not available until UNDB v9 (or modded v8 - see v9 configs) +#define SIGNAL_DUR 180 //sec - when pulsed signal is going, pulses are sent once/sec for this period (e.g. 180 = 3min) +#define SWITCH_DUR 7200 //sec - when alarm triggers switched relay, it's switched on for this period (e.g. 7200 = 2hr) +#define PIEZO_PULSE 250 //ms - used with piezo via tone() +#define RELAY_PULSE 200 //ms - used with pulsed relay //Soft power switches -const byte enableSoftAlarmSwitch = 1; +#define ENABLE_SOFT_ALARM_SWITCH 1 // 1 = yes. Alarm can be switched on and off when clock is displaying the alarm time (fnIsAlarm). // 0 = no. Alarm will be permanently on. Use with switched relay if the appliance has its own switch on this relay circuit. -const byte enableSoftPowerSwitch = 1; //works with switched relay only -// 1 = yes. Relay can be switched on and off directly with Alt button at any time (except in options menu). This is useful if connecting an appliance (e.g. radio) that doesn't have its own switch, or if replacing the clock unit in a clock radio where the clock does all the switching (e.g. Telechron). -// 0 = no. Use if the connected appliance has its own power switch (independent of this relay circuit) or does not need to be manually switched. In this case (and/or if there is no switched relay) Alt will act as a function preset. +#define ENABLE_SOFT_POWER_SWITCH 0 //don't change - not available until UNDB v9 (or modded v8 - see v9 configs) //LED circuit control -const char ledPin = -1; -// -1 to disable feature; A2 if equipped (UNDB v8) +#define LED_PIN -1 //don't change - not available until UNDB v9 (or modded v8 - see v9 configs) //When display is dim/off, a press will light the tubes for how long? -const byte unoffDur = 10; //sec - -// How long (in ms) are the button hold durations? -const word btnShortHold = 1000; //for entering setting mode, or hold-setting at low velocity -const word btnLongHold = 3000; //for entering options menu, or hold-setting at high velocity -const word velThreshold = 0; //ms -// When an adj up/down input (btn or rot) follows another in less than this time, value will change more (10 vs 1). -// 0 to disable. Recommend ~150 for rotaries. If you want to use this feature with buttons, extend to ~300. +#define UNOFF_DUR 10 //sec // What is the "frame rate" of the tube cleaning and display scrolling? up to 65535 ms -const word cleanSpeed = 200; //ms -const word scrollSpeed = 100; //ms - e.g. scroll-in-and-out date at :30 +#define CLEAN_SPEED 200 //ms +#define SCROLL_SPEED 100 //ms - e.g. scroll-in-and-out date at :30 // What are the timeouts for setting and temporarily-displayed functions? up to 65535 sec -const unsigned long timeoutSet = 300; //sec -const unsigned long timeoutTempFn = 5; //sec +#define SETTING_TIMEOUT 300 //sec +#define FN_TEMP_TIMEOUT 5 //sec +#define FN_PAGE_TIMEOUT 3 //sec //This clock is 2x3 multiplexed: two tubes powered at a time. //The anode channel determines which two tubes are powered, //and the two SN74141 cathode driver chips determine which digits are lit. //4 pins out to each SN74141, representing a binary number with values [1,2,4,8] -const char outA1 = 2; -const char outA2 = 3; -const char outA3 = 4; -const char outA4 = 5; -const char outB1 = 6; -const char outB2 = 7; -const char outB3 = 8; -const char outB4 = 9; +#define OUT_A1 2 +#define OUT_A2 3 +#define OUT_A3 4 +#define OUT_A4 5 +#define OUT_B1 6 +#define OUT_B2 7 +#define OUT_B3 8 +#define OUT_B4 9 //3 pins out to anode channel switches -const char anode1 = 11; -const char anode2 = 12; -const char anode3 = 13; \ No newline at end of file +#define ANODE_1 11 +#define ANODE_2 12 +#define ANODE_3 13 \ No newline at end of file diff --git a/arduino-nixie/configs/v9-6tube-relay.h b/arduino-nixie/configs/v9-6tube-relay.h index f28e18a..7998e01 100644 --- a/arduino-nixie/configs/v9-6tube-relay.h +++ b/arduino-nixie/configs/v9-6tube-relay.h @@ -1,22 +1,22 @@ -//UNDB v9, relay enabled, buttons as labeled, with 6-digit display. +//UNDB v9, relay disabled, buttons as labeled, with 6-digit display. //Also for v8 modified to v9 spec (Sel/Alt on A6/A7, Up/Down on A0/A1, relay on A3, led on 9, and cathode B4 on A2) -const byte displaySize = 6; //number of tubes in display module. Small display adjustments are made for 4-tube clocks +#define DISPLAY_SIZE 6 //number of tubes in display module. Small display adjustments are made for 4-tube clocks // Which functionality is enabled in this clock? // Related options will also be enabled in the options menu. -const bool enableDate = true; -const bool enableDateCounter = true; // Adds a "page" to the date with an anniversary counter -const bool enableDateSunriseSunset = true; // Adds "pages" to the date with sunrise/sunset times -const bool enableAlarm = true; -const bool enableAlarmAutoskip = true; -const bool enableAlarmFibonacci = true; -const bool enableTimer = true; -const bool enableChime = true; -const bool enableNightShutoff = true; // If disabled, tubes will be full brightness all the time. -const bool enableAwayShutoff = true; // Requires night shutoff. -const bool enableTemp = false; //Temperature per DS3231 - will read high – leave false for production -const bool enableTest = false; //Cycles through all tubes – leave false for production +#define ENABLE_DATE_FN true // Date function, optionally including pages below +#define ENABLE_DATE_COUNTER true // Adds date page with an anniversary counter +#define ENABLE_DATE_RISESET true // Adds date pages with sunrise/sunset times. Requires DM Kichi's Dusk2Dawn library to be installed in IDE. +#define ENABLE_ALARM_FN true +#define ENABLE_ALARM_AUTOSKIP true +#define ENABLE_ALARM_FIBONACCI true +#define ENABLE_TIMER_FN true +#define ENABLE_TIME_CHIME true +#define ENABLE_SHUTOFF_NIGHT true // If disabled, tubes will be full brightness all the time. +#define ENABLE_SHUTOFF_AWAY true // Requires night shutoff. +#define ENABLE_TEMP_FN false //Temperature per DS3231 - will read high – leave false for production +#define ENABLE_TUBETEST_FN false //Cycles through all tubes – leave false for production // These are the RLB board connections to Arduino analog input pins. // S1/PL13 = Reset @@ -29,70 +29,68 @@ const bool enableTest = false; //Cycles through all tubes – leave false for pr // A6-A7 are analog-only pins that aren't quite as responsive and require a physical pullup resistor (1K to +5V), and can't be used with rotary encoders because they don't support pin change interrupts. // What input is associated with each control? -const byte mainSel = A6; -const byte mainAdjUp = A0; -const byte mainAdjDn = A1; -const byte altSel = A7; //if not equipped, set to 0 +#define CTRL_SEL A6 //main select button - must be equipped +#define CTRL_UP A0 //main up/down buttons or rotary encoder - must be equipped +#define CTRL_DN A1 +#define CTRL_ALT A7 //alt select button - if unequipped, set to 0 -// What type of adj controls are equipped? -// 1 = momentary buttons. 2 = quadrature rotary encoder (not currently supported). -const byte mainAdjType = 1; +// What type of up/down controls are equipped? +// 1 = momentary buttons. 2 = quadrature rotary encoder: requires Paul Stoffregen's Encoder library to be installed in IDE. +#define CTRL_UPDN_TYPE 1 +#define ROT_VEL_START 80 //Required if CTRL_UPDN_TYPE==2. If step rate falls below this, kick into high velocity set (x10) +#define ROT_VEL_STOP 500 //Required if CTRL_UPDN_TYPE==2. If encoder step rate rises above this, drop into low velocity set (x1) + +// How long (in ms) are the button hold durations? +#define CTRL_HOLD_SHORT_DUR 1000 //for entering setting mode, or hold-setting at low velocity (x1) +#define CTRL_HOLD_LONG_DUR 3000 //for entering options menu, or hold-setting at high velocity (x10) //What are the signal pin(s) connected to? -const char piezoPin = 10; -const char relayPin = A3; -// -1 to disable feature (no relay item equipped); A3 if equipped (UNDB v8) -const byte relayMode = 0; //If relay is equipped, what does it do? -// 0 = switched mode: the relay will be switched to control an appliance like a radio or light fixture. If used with timer, it will switch on while timer is running (like a "sleep" function). If used with alarm, it will switch on when alarm trips; specify duration of this in switchDur. -// 1 = pulsed mode: the relay will be pulsed, like the beeper is, to control an intermittent signaling device like a solenoid or indicator lamp. Specify pulse duration in relayPulse. -const word signalDur = 180; //sec - when pulsed signal is going, pulses are sent once/sec for this period (e.g. 180 = 3min) -const word switchDur = 7200; //sec - when alarm triggers switched relay, it's switched on for this period (e.g. 7200 = 2hr) -const word piezoPulse = 250; //ms - used with piezo via tone() -const word relayPulse = 200; //ms - used with pulsed relay +#define PIEZO_PIN 10 +#define RELAY_PIN A3 // -1 to disable feature (no relay item equipped); A3 if equipped (UNDB v9) +#define RELAY_MODE 0 //If relay is equipped, what does it do? +// 0 = switched mode: the relay will be switched to control an appliance like a radio or light fixture. If used with timer, it will switch on while timer is running (like a "sleep" function). If used with alarm, it will switch on when alarm trips; specify duration of this in SWITCH_DUR. +// 1 = pulsed mode: the relay will be pulsed, like the beeper is, to control an intermittent signaling device like a solenoid or indicator lamp. Specify pulse duration in RELAY_PULSE. +#define SIGNAL_DUR 180 //sec - when pulsed signal is going, pulses are sent once/sec for this period (e.g. 180 = 3min) +#define SWITCH_DUR 7200 //sec - when alarm triggers switched relay, it's switched on for this period (e.g. 7200 = 2hr) +#define PIEZO_PULSE 250 //ms - used with piezo via tone() +#define RELAY_PULSE 200 //ms - used with pulsed relay //Soft power switches -const byte enableSoftAlarmSwitch = 1; +#define ENABLE_SOFT_ALARM_SWITCH 1 // 1 = yes. Alarm can be switched on and off when clock is displaying the alarm time (fnIsAlarm). // 0 = no. Alarm will be permanently on. Use with switched relay if the appliance has its own switch on this relay circuit. -const byte enableSoftPowerSwitch = 1; //works with switched relay only +#define ENABLE_SOFT_POWER_SWITCH 1 //works with switched relay only // 1 = yes. Relay can be switched on and off directly with Alt button at any time (except in options menu). This is useful if connecting an appliance (e.g. radio) that doesn't have its own switch, or if replacing the clock unit in a clock radio where the clock does all the switching (e.g. Telechron). // 0 = no. Use if the connected appliance has its own power switch (independent of this relay circuit) or does not need to be manually switched. In this case (and/or if there is no switched relay) Alt will act as a function preset. -//LED circuit control with PWM -const char ledPin = 9; -// -1 to disable feature; 11 if equipped (UNDB v8 modded) +//LED circuit control +#define LED_PIN 9 // -1 to disable feature; 9 if equipped (UNDB v9) //When display is dim/off, a press will light the tubes for how long? -const byte unoffDur = 10; //sec - -// How long (in ms) are the button hold durations? -const word btnShortHold = 1000; //for entering setting mode, or hold-setting at low velocity -const word btnLongHold = 3000; //for entering options menu, or hold-setting at high velocity -const word velThreshold = 0; //ms -// When an adj up/down input (btn or rot) follows another in less than this time, value will change more (10 vs 1). -// 0 to disable. Recommend ~150 for rotaries. If you want to use this feature with buttons, extend to ~300. +#define UNOFF_DUR 10 //sec // What is the "frame rate" of the tube cleaning and display scrolling? up to 65535 ms -const word cleanSpeed = 200; //ms -const word scrollSpeed = 100; //ms - e.g. scroll-in-and-out date at :30 +#define CLEAN_SPEED 200 //ms +#define SCROLL_SPEED 100 //ms - e.g. scroll-in-and-out date at :30 // What are the timeouts for setting and temporarily-displayed functions? up to 65535 sec -const unsigned long timeoutSet = 300; //sec -const unsigned long timeoutTempFn = 5; //sec +#define SETTING_TIMEOUT 300 //sec +#define FN_TEMP_TIMEOUT 5 //sec +#define FN_PAGE_TIMEOUT 3 //sec //This clock is 2x3 multiplexed: two tubes powered at a time. //The anode channel determines which two tubes are powered, //and the two SN74141 cathode driver chips determine which digits are lit. //4 pins out to each SN74141, representing a binary number with values [1,2,4,8] -const char outA1 = 2; -const char outA2 = 3; -const char outA3 = 4; -const char outA4 = 5; -const char outB1 = 6; -const char outB2 = 7; -const char outB3 = 8; -const char outB4 = 16; //A2 - was 9 before PWM fix pt2 +#define OUT_A1 2 +#define OUT_A2 3 +#define OUT_A3 4 +#define OUT_A4 5 +#define OUT_B1 6 +#define OUT_B2 7 +#define OUT_B3 8 +#define OUT_B4 16 //aka A2 //3 pins out to anode channel switches -const char anode1 = 11; -const char anode2 = 12; -const char anode3 = 13; \ No newline at end of file +#define ANODE_1 11 +#define ANODE_2 12 +#define ANODE_3 13 \ No newline at end of file diff --git a/arduino-nixie/configs/v9-6tube-simplified.h b/arduino-nixie/configs/v9-6tube-simplified.h new file mode 100644 index 0000000..a31d026 --- /dev/null +++ b/arduino-nixie/configs/v9-6tube-simplified.h @@ -0,0 +1,96 @@ +//UNDB v9, relay disabled, buttons as labeled, with 6-digit display. +//Also for v8 modified to v9 spec (Sel/Alt on A6/A7, Up/Down on A0/A1, relay on A3, led on 9, and cathode B4 on A2) + +#define DISPLAY_SIZE 6 //number of tubes in display module. Small display adjustments are made for 4-tube clocks + +// Which functionality is enabled in this clock? +// Related options will also be enabled in the options menu. +#define ENABLE_DATE_FN true // Date function, optionally including pages below +#define ENABLE_DATE_COUNTER false // Adds date page with an anniversary counter +#define ENABLE_DATE_RISESET false // Adds date pages with sunrise/sunset times. Requires DM Kichi's Dusk2Dawn library to be installed in IDE. +#define ENABLE_ALARM_FN true +#define ENABLE_ALARM_AUTOSKIP false +#define ENABLE_ALARM_FIBONACCI false +#define ENABLE_TIMER_FN false +#define ENABLE_TIME_CHIME true +#define ENABLE_SHUTOFF_NIGHT true // If disabled, tubes will be full brightness all the time. +#define ENABLE_SHUTOFF_AWAY false // Requires night shutoff. +#define ENABLE_TEMP_FN false //Temperature per DS3231 - will read high – leave false for production +#define ENABLE_TUBETEST_FN false //Cycles through all tubes – leave false for production + +// These are the RLB board connections to Arduino analog input pins. +// S1/PL13 = Reset +// S2/PL5 = A1 +// S3/PL6 = A0 +// S4/PL7 = A6 +// S5/PL8 = A3 +// S6/PL9 = A2 +// S7/PL14 = A7 +// A6-A7 are analog-only pins that aren't quite as responsive and require a physical pullup resistor (1K to +5V), and can't be used with rotary encoders because they don't support pin change interrupts. + +// What input is associated with each control? +#define CTRL_SEL A6 //main select button - must be equipped +#define CTRL_UP A0 //main up/down buttons or rotary encoder - must be equipped +#define CTRL_DN A1 +#define CTRL_ALT A7 //alt select button - if unequipped, set to 0 + +// What type of up/down controls are equipped? +// 1 = momentary buttons. 2 = quadrature rotary encoder: requires Paul Stoffregen's Encoder library to be installed in IDE. +#define CTRL_UPDN_TYPE 1 +#define ROT_VEL_START 80 //Required if CTRL_UPDN_TYPE==2. If step rate falls below this, kick into high velocity set (x10) +#define ROT_VEL_STOP 500 //Required if CTRL_UPDN_TYPE==2. If encoder step rate rises above this, drop into low velocity set (x1) + +// How long (in ms) are the button hold durations? +#define CTRL_HOLD_SHORT_DUR 1000 //for entering setting mode, or hold-setting at low velocity (x1) +#define CTRL_HOLD_LONG_DUR 3000 //for entering options menu, or hold-setting at high velocity (x10) + +//What are the signal pin(s) connected to? +#define PIEZO_PIN 10 +#define RELAY_PIN -1 // -1 to disable feature (no relay item equipped); A3 if equipped (UNDB v9) +#define RELAY_MODE 0 //If relay is equipped, what does it do? +// 0 = switched mode: the relay will be switched to control an appliance like a radio or light fixture. If used with timer, it will switch on while timer is running (like a "sleep" function). If used with alarm, it will switch on when alarm trips; specify duration of this in SWITCH_DUR. +// 1 = pulsed mode: the relay will be pulsed, like the beeper is, to control an intermittent signaling device like a solenoid or indicator lamp. Specify pulse duration in RELAY_PULSE. +#define SIGNAL_DUR 180 //sec - when pulsed signal is going, pulses are sent once/sec for this period (e.g. 180 = 3min) +#define SWITCH_DUR 7200 //sec - when alarm triggers switched relay, it's switched on for this period (e.g. 7200 = 2hr) +#define PIEZO_PULSE 250 //ms - used with piezo via tone() +#define RELAY_PULSE 200 //ms - used with pulsed relay + +//Soft power switches +#define ENABLE_SOFT_ALARM_SWITCH 1 +// 1 = yes. Alarm can be switched on and off when clock is displaying the alarm time (fnIsAlarm). +// 0 = no. Alarm will be permanently on. Use with switched relay if the appliance has its own switch on this relay circuit. +#define ENABLE_SOFT_POWER_SWITCH 1 //works with switched relay only +// 1 = yes. Relay can be switched on and off directly with Alt button at any time (except in options menu). This is useful if connecting an appliance (e.g. radio) that doesn't have its own switch, or if replacing the clock unit in a clock radio where the clock does all the switching (e.g. Telechron). +// 0 = no. Use if the connected appliance has its own power switch (independent of this relay circuit) or does not need to be manually switched. In this case (and/or if there is no switched relay) Alt will act as a function preset. + +//LED circuit control +#define LED_PIN 9 // -1 to disable feature; 9 if equipped (UNDB v9) + +//When display is dim/off, a press will light the tubes for how long? +#define UNOFF_DUR 10 //sec + +// What is the "frame rate" of the tube cleaning and display scrolling? up to 65535 ms +#define CLEAN_SPEED 200 //ms +#define SCROLL_SPEED 100 //ms - e.g. scroll-in-and-out date at :30 + +// What are the timeouts for setting and temporarily-displayed functions? up to 65535 sec +#define SETTING_TIMEOUT 300 //sec +#define FN_TEMP_TIMEOUT 5 //sec +#define FN_PAGE_TIMEOUT 3 //sec + +//This clock is 2x3 multiplexed: two tubes powered at a time. +//The anode channel determines which two tubes are powered, +//and the two SN74141 cathode driver chips determine which digits are lit. +//4 pins out to each SN74141, representing a binary number with values [1,2,4,8] +#define OUT_A1 2 +#define OUT_A2 3 +#define OUT_A3 4 +#define OUT_A4 5 +#define OUT_B1 6 +#define OUT_B2 7 +#define OUT_B3 8 +#define OUT_B4 16 //aka A2 +//3 pins out to anode channel switches +#define ANODE_1 11 +#define ANODE_2 12 +#define ANODE_3 13 \ No newline at end of file diff --git a/arduino-nixie/configs/v9-6tube.h b/arduino-nixie/configs/v9-6tube.h index a82424e..9beada8 100644 --- a/arduino-nixie/configs/v9-6tube.h +++ b/arduino-nixie/configs/v9-6tube.h @@ -1,22 +1,22 @@ //UNDB v9, relay disabled, buttons as labeled, with 6-digit display. //Also for v8 modified to v9 spec (Sel/Alt on A6/A7, Up/Down on A0/A1, relay on A3, led on 9, and cathode B4 on A2) -const byte displaySize = 6; //number of tubes in display module. Small display adjustments are made for 4-tube clocks +#define DISPLAY_SIZE 6 //number of tubes in display module. Small display adjustments are made for 4-tube clocks // Which functionality is enabled in this clock? // Related options will also be enabled in the options menu. -const bool enableDate = true; -const bool enableDateCounter = true; // Adds a "page" to the date with an anniversary counter -const bool enableDateSunriseSunset = true; // Adds "pages" to the date with sunrise/sunset times -const bool enableAlarm = true; -const bool enableAlarmAutoskip = true; -const bool enableAlarmFibonacci = true; -const bool enableTimer = true; -const bool enableChime = true; -const bool enableNightShutoff = true; // If disabled, tubes will be full brightness all the time. -const bool enableAwayShutoff = true; // Requires night shutoff. -const bool enableTemp = false; //Temperature per DS3231 - will read high – leave false for production -const bool enableTest = false; //Cycles through all tubes – leave false for production +#define ENABLE_DATE_FN true // Date function, optionally including pages below +#define ENABLE_DATE_COUNTER true // Adds date page with an anniversary counter +#define ENABLE_DATE_RISESET true // Adds date pages with sunrise/sunset times. Requires DM Kichi's Dusk2Dawn library to be installed in IDE. +#define ENABLE_ALARM_FN true +#define ENABLE_ALARM_AUTOSKIP true +#define ENABLE_ALARM_FIBONACCI true +#define ENABLE_TIMER_FN true +#define ENABLE_TIME_CHIME true +#define ENABLE_SHUTOFF_NIGHT true // If disabled, tubes will be full brightness all the time. +#define ENABLE_SHUTOFF_AWAY true // Requires night shutoff. +#define ENABLE_TEMP_FN false //Temperature per DS3231 - will read high – leave false for production +#define ENABLE_TUBETEST_FN false //Cycles through all tubes – leave false for production // These are the RLB board connections to Arduino analog input pins. // S1/PL13 = Reset @@ -29,70 +29,68 @@ const bool enableTest = false; //Cycles through all tubes – leave false for pr // A6-A7 are analog-only pins that aren't quite as responsive and require a physical pullup resistor (1K to +5V), and can't be used with rotary encoders because they don't support pin change interrupts. // What input is associated with each control? -const byte mainSel = A6; -const byte mainAdjUp = A0; -const byte mainAdjDn = A1; -const byte altSel = A7; //if not equipped, set to 0 +#define CTRL_SEL A6 //main select button - must be equipped +#define CTRL_UP A0 //main up/down buttons or rotary encoder - must be equipped +#define CTRL_DN A1 +#define CTRL_ALT A7 //alt select button - if unequipped, set to 0 -// What type of adj controls are equipped? -// 1 = momentary buttons. 2 = quadrature rotary encoder (not currently supported). -const byte mainAdjType = 1; +// What type of up/down controls are equipped? +// 1 = momentary buttons. 2 = quadrature rotary encoder: requires Paul Stoffregen's Encoder library to be installed in IDE. +#define CTRL_UPDN_TYPE 1 +#define ROT_VEL_START 80 //Required if CTRL_UPDN_TYPE==2. If step rate falls below this, kick into high velocity set (x10) +#define ROT_VEL_STOP 500 //Required if CTRL_UPDN_TYPE==2. If encoder step rate rises above this, drop into low velocity set (x1) + +// How long (in ms) are the button hold durations? +#define CTRL_HOLD_SHORT_DUR 1000 //for entering setting mode, or hold-setting at low velocity (x1) +#define CTRL_HOLD_LONG_DUR 3000 //for entering options menu, or hold-setting at high velocity (x10) //What are the signal pin(s) connected to? -const char piezoPin = 10; -const char relayPin = -1; -// -1 to disable feature (no relay item equipped); A3 if equipped (UNDB v8) -const byte relayMode = 0; //If relay is equipped, what does it do? -// 0 = switched mode: the relay will be switched to control an appliance like a radio or light fixture. If used with timer, it will switch on while timer is running (like a "sleep" function). If used with alarm, it will switch on when alarm trips; specify duration of this in switchDur. -// 1 = pulsed mode: the relay will be pulsed, like the beeper is, to control an intermittent signaling device like a solenoid or indicator lamp. Specify pulse duration in relayPulse. -const word signalDur = 180; //sec - when pulsed signal is going, pulses are sent once/sec for this period (e.g. 180 = 3min) -const word switchDur = 7200; //sec - when alarm triggers switched relay, it's switched on for this period (e.g. 7200 = 2hr) -const word piezoPulse = 250; //ms - used with piezo via tone() -const word relayPulse = 200; //ms - used with pulsed relay +#define PIEZO_PIN 10 +#define RELAY_PIN -1 // -1 to disable feature (no relay item equipped); A3 if equipped (UNDB v9) +#define RELAY_MODE 0 //If relay is equipped, what does it do? +// 0 = switched mode: the relay will be switched to control an appliance like a radio or light fixture. If used with timer, it will switch on while timer is running (like a "sleep" function). If used with alarm, it will switch on when alarm trips; specify duration of this in SWITCH_DUR. +// 1 = pulsed mode: the relay will be pulsed, like the beeper is, to control an intermittent signaling device like a solenoid or indicator lamp. Specify pulse duration in RELAY_PULSE. +#define SIGNAL_DUR 180 //sec - when pulsed signal is going, pulses are sent once/sec for this period (e.g. 180 = 3min) +#define SWITCH_DUR 7200 //sec - when alarm triggers switched relay, it's switched on for this period (e.g. 7200 = 2hr) +#define PIEZO_PULSE 250 //ms - used with piezo via tone() +#define RELAY_PULSE 200 //ms - used with pulsed relay //Soft power switches -const byte enableSoftAlarmSwitch = 1; +#define ENABLE_SOFT_ALARM_SWITCH 1 // 1 = yes. Alarm can be switched on and off when clock is displaying the alarm time (fnIsAlarm). // 0 = no. Alarm will be permanently on. Use with switched relay if the appliance has its own switch on this relay circuit. -const byte enableSoftPowerSwitch = 1; //works with switched relay only +#define ENABLE_SOFT_POWER_SWITCH 1 //works with switched relay only // 1 = yes. Relay can be switched on and off directly with Alt button at any time (except in options menu). This is useful if connecting an appliance (e.g. radio) that doesn't have its own switch, or if replacing the clock unit in a clock radio where the clock does all the switching (e.g. Telechron). // 0 = no. Use if the connected appliance has its own power switch (independent of this relay circuit) or does not need to be manually switched. In this case (and/or if there is no switched relay) Alt will act as a function preset. -//LED circuit control with PWM -const char ledPin = 9; -// -1 to disable feature; 11 if equipped (UNDB v8 modded) +//LED circuit control +#define LED_PIN 9 // -1 to disable feature; 9 if equipped (UNDB v9) //When display is dim/off, a press will light the tubes for how long? -const byte unoffDur = 10; //sec - -// How long (in ms) are the button hold durations? -const word btnShortHold = 1000; //for entering setting mode, or hold-setting at low velocity -const word btnLongHold = 3000; //for entering options menu, or hold-setting at high velocity -const word velThreshold = 0; //ms -// When an adj up/down input (btn or rot) follows another in less than this time, value will change more (10 vs 1). -// 0 to disable. Recommend ~150 for rotaries. If you want to use this feature with buttons, extend to ~300. +#define UNOFF_DUR 10 //sec // What is the "frame rate" of the tube cleaning and display scrolling? up to 65535 ms -const word cleanSpeed = 200; //ms -const word scrollSpeed = 100; //ms - e.g. scroll-in-and-out date at :30 +#define CLEAN_SPEED 200 //ms +#define SCROLL_SPEED 100 //ms - e.g. scroll-in-and-out date at :30 // What are the timeouts for setting and temporarily-displayed functions? up to 65535 sec -const unsigned long timeoutSet = 300; //sec -const unsigned long timeoutTempFn = 5; //sec +#define SETTING_TIMEOUT 300 //sec +#define FN_TEMP_TIMEOUT 5 //sec +#define FN_PAGE_TIMEOUT 3 //sec //This clock is 2x3 multiplexed: two tubes powered at a time. //The anode channel determines which two tubes are powered, //and the two SN74141 cathode driver chips determine which digits are lit. //4 pins out to each SN74141, representing a binary number with values [1,2,4,8] -const char outA1 = 2; -const char outA2 = 3; -const char outA3 = 4; -const char outA4 = 5; -const char outB1 = 6; -const char outB2 = 7; -const char outB3 = 8; -const char outB4 = 16; //A2 - was 9 before PWM fix pt2 +#define OUT_A1 2 +#define OUT_A2 3 +#define OUT_A3 4 +#define OUT_A4 5 +#define OUT_B1 6 +#define OUT_B2 7 +#define OUT_B3 8 +#define OUT_B4 16 //aka A2 //3 pins out to anode channel switches -const char anode1 = 11; -const char anode2 = 12; -const char anode3 = 13; \ No newline at end of file +#define ANODE_1 11 +#define ANODE_2 12 +#define ANODE_3 13 \ No newline at end of file diff --git a/extras/encoder_test/encoder_test.ino b/extras/encoder_test/encoder_test.ino new file mode 100644 index 0000000..e530f17 --- /dev/null +++ b/extras/encoder_test/encoder_test.ino @@ -0,0 +1,176 @@ +// What input is associated with each control? +#define CTRL_SEL A2 //main select button - must be equipped +#define CTRL_UP A1 //main up/down buttons or rotary encoder - must be equipped +#define CTRL_DN A0 + +#define ROT_VEL_START 80 //if encoder step rate falls below this, kick into high velocity set (x10) +#define ROT_VEL_STOP 500 //if encoder step rate rises above this, drop into low velocity set (x1) + +//This clock is 2x3 multiplexed: two tubes powered at a time. +//The anode channel determines which two tubes are powered, +//and the two SN74141 cathode driver chips determine which digits are lit. +//4 pins out to each SN74141, representing a binary number with values [1,2,4,8] +#define OUT_A1 2 +#define OUT_A2 3 +#define OUT_A3 4 +#define OUT_A4 5 +#define OUT_B1 6 +#define OUT_B2 7 +#define OUT_B3 8 +#define OUT_B4 9 +//3 pins out to anode channel switches +#define ANODE_1 11 +#define ANODE_2 12 +#define ANODE_3 13 + + +#include +#include +Encoder rot(CTRL_DN,CTRL_UP); + + +byte theVal = 0; + + +////////// Main code control ////////// + +void setup(){ + Serial.begin(9600); + Wire.begin(); + initInputs(); + initOutputs(); + updateDisplay(); +} + +void loop(){ + checkInputs(); //if inputs have changed, this will do things + updateDisplay as needed + cycleDisplay(); //keeps the display hardware multiplexing cycle going + //TODO why isn't the display working +} + + +////////// Control inputs ////////// +void initInputs(){ + //TODO are there no "loose" pins left floating after this? per https://electronics.stackexchange.com/q/37696/151805 + pinMode(CTRL_SEL, INPUT_PULLUP); + pinMode(CTRL_UP, INPUT_PULLUP); + pinMode(CTRL_DN, INPUT_PULLUP); +} + +void checkInputs(){ + checkRot(); +} + +bool rotVel = 0; //high velocity setting (x10 rather than x1) +unsigned long rotLastStep = 0; //timestamp of last completed step (detent) +int rotLastVal = 0; +void checkRot(){ + int rotCurVal = rot.read(); + if(rotCurVal!=rotLastVal){ //we've sensed a state change + rotLastVal = rotCurVal; + Serial.println(rotCurVal,DEC); + if(rotCurVal>=4 || rotCurVal<=-4){ //we've completed a step of 4 states (this library doesn't seem to drop states much, so this is reasonably reliable) + unsigned long now = millis(); + if((unsigned long)(now-rotLastStep)<=ROT_VEL_START) rotVel = 1; //kick into high velocity setting (x10) + else if((unsigned long)(now-rotLastStep)>=ROT_VEL_STOP) rotVel = 0; //fall into low velocity setting (x1) + rotLastStep = now; + while(rotCurVal>=4) { rotCurVal-=4; theVal+=1; } + while(rotCurVal<=-4) { rotCurVal+=4; theVal-=1; } + rot.write(rotCurVal); + updateDisplay(); + } + } +} //end checkRot() + + +////////// Display data formatting ////////// + +byte displayNext[6] = {15,15,15,15,15,15}; +byte displayLast[6] = {15,15,15,15,15,15}; + +void updateDisplay(){ + Serial.print(F("---")); Serial.print(theVal,DEC); if(rotVel) Serial.print(F("!")); Serial.println(); + editDisplay(theVal,0,3,false,false); + blankDisplay(4,5,false); +} + +void editDisplay(word n, byte posStart, byte posEnd, bool leadingZeros, bool fade){ + //Splits n into digits, sets them into displayNext in places posSt-posEnd (inclusive), with or without leading zeros + //If there are blank places (on the left of a non-leading-zero number), uses value 15 to blank tube + //If number has more places than posEnd-posStart, the higher places are truncated off (e.g. 10015 on 4 tubes --> 0015) + word place; + for(byte i=0; i<=posEnd-posStart; i++){ + switch(i){ //because int(pow(10,1))==10 but int(pow(10,2))==99... + case 0: place=1; break; + case 1: place=10; break; + case 2: place=100; break; + case 3: place=1000; break; + case 4: place=10000; break; + case 5: place=100000; break; + default: break; + } + displayNext[posEnd-i] = (i==0&&n==0 ? 0 : (n>=place ? (n/place)%10 : (leadingZeros?0:15))); + if(!fade) displayLast[posEnd-i] = displayNext[posEnd-i]; //cycleDisplay will be none the wiser + } +} //end editDisplay() +void blankDisplay(byte posStart, byte posEnd, byte fade){ + for(byte i=posStart; i<=posEnd; i++) { displayNext[i]=15; if(!fade) displayLast[i]=15; } +} //end blankDisplay(); + + +////////// Hardware outputs ////////// + +byte binOutA[4] = {OUT_A1,OUT_A2,OUT_A3,OUT_A4}; +byte binOutB[4] = {OUT_B1,OUT_B2,OUT_B3,OUT_B4}; +byte anodes[3] = {ANODE_1,ANODE_2,ANODE_3}; + +const int fadeLastDur = 5; +const int fadeNextDur = 0; + +void initOutputs() { + for(byte i=0; i<4; i++) { pinMode(binOutA[i],OUTPUT); pinMode(binOutB[i],OUTPUT); } + for(byte i=0; i<3; i++) { pinMode(anodes[i],OUTPUT); } +} + +void cycleDisplay(){ + //Anode channel 0: tubes #2 (min x10) and #5 (sec x1) + setCathodes(displayLast[2],displayLast[5]); //Via d2b decoder chip, set cathodes to old digits + digitalWrite(anodes[0], HIGH); //Turn on tubes + delay(fadeLastDur); //Display for fade-out cycles + setCathodes(displayNext[2],displayNext[5]); //Switch cathodes to new digits + delay(fadeNextDur); //Display for fade-in cycles + digitalWrite(anodes[0], LOW); //Turn off tubes + + //Anode channel 1: tubes #4 (sec x10) and #1 (hour x1) + setCathodes(displayLast[4],displayLast[1]); + digitalWrite(anodes[1], HIGH); + delay(fadeLastDur); + setCathodes(displayNext[4],displayNext[1]); + delay(fadeNextDur); + digitalWrite(anodes[1], LOW); + + //Anode channel 2: tubes #0 (hour x10) and #3 (min x1) + setCathodes(displayLast[0],displayLast[3]); + digitalWrite(anodes[2], HIGH); + delay(fadeLastDur); + setCathodes(displayNext[0],displayNext[3]); + delay(fadeNextDur); + digitalWrite(anodes[2], LOW); +} //end cycleDisplay() + +void setCathodes(byte decValA, byte decValB){ + bool binVal[4]; //4-bit binary number with values [1,2,4,8] + decToBin(binVal,decValA); //have binary value of decVal set into binVal + for(byte i=0; i<4; i++) digitalWrite(binOutA[i],binVal[i]); //set bin inputs of SN74141 + decToBin(binVal,decValB); + for(byte i=0; i<4; i++) digitalWrite(binOutB[i],binVal[i]); //set bin inputs of SN74141 +} //end setCathodes() + +void decToBin(bool binVal[], byte i){ + //binVal is a reference (modify in place) of a binary number bool[4] with values [1,2,4,8] + if(i<0 || i>15) i=15; //default value, turns tubes off + binVal[3] = int(i/8)%2; + binVal[2] = int(i/4)%2; + binVal[1] = int(i/2)%2; + binVal[0] = i%2; +} //end decToBin() \ No newline at end of file