Skip to content

Commit 0ae58a8

Browse files
committed
(Unfinished, see stopping place) Support for LED control; use eeprom update instead of write
1 parent fac650d commit 0ae58a8

File tree

2 files changed

+58
-27
lines changed

2 files changed

+58
-27
lines changed

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,7 @@ _Note: Many variations are possible, depending on your clock's hardware; but thi
5757
| 22. Last day of work week | 0–6 (Sunday–Saturday) |
5858
| 23. Work starts at | Time of day. |
5959
| 24. Work ends at | Time of day. |
60+
| 25. LED behavior | 0 = always off<br/>1 = always on<br/>2 = on, but follow day-off and night-off if enabled<br/>3 = off, but on when alarm/timer sounds</br>4 = off, but on with switched relay (if equipped – great for radios!)<br/>(Clocks with LED control only, UNDB v5.x+) |
6061

6162
To reset the options menu settings to "factory" defaults, hold **Select** while connecting the clock to power.
6263

sixtube_lm/sixtube_lm.ino

Lines changed: 57 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -67,14 +67,21 @@ const word switchDur = 7200; //sec - when alarm triggers switched relay, it's sw
6767
const word piezoPulse = 500; //ms - used with piezo via tone()
6868
const word relayPulse = 200; //ms - used with pulsed relay
6969

70+
//Soft power switches
7071
const byte enableSoftAlarmSwitch = 1;
7172
// 1 = yes. Alarm can be switched on and off when clock is displaying the alarm time (fnIsAlarm).
7273
// 0 = no. Alarm will be permanently on. Use with switched relay if the appliance has its own switch on this relay circuit.
7374
const byte enableSoftPowerSwitch = 1; //works with switched relay only
7475
// 1 = yes. Relay can be switched on and off directly when clock is displaying time of day (fnIsTime). 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).
7576
// 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.
7677

77-
const byte unoffDur = 10; //when display is dim/off, a press will light the tubes for this many seconds
78+
//LED circuit control
79+
const char ledPin = -1;
80+
// If running a v5.0 board with constantly powered LEDs, leave this set to -1 (disabled).
81+
// If running a v5.x board, LED control pin is X. An extra menu option will appear to let end user control LEDs.
82+
83+
//When display is dim/off, a press will light the tubes for how long?
84+
const byte unoffDur = 10; //sec
7885

7986
// How long (in ms) are the button hold durations?
8087
const word btnShortHold = 1000; //for setting the displayed feataure
@@ -118,7 +125,7 @@ Some are skipped when they wouldn't apply to a given clock's hardware config, se
118125
23 Alarm days
119126
24 Alarm snooze
120127
25 Timer interval mode - skipped when no piezo and relay is switch (start=0)
121-
( 26 is available )
128+
26 LED circuit behavior
122129
27 Night-off
123130
28-29 Night start, mins
124131
30-31 Night end, mins
@@ -138,11 +145,11 @@ Some are skipped when they wouldn't apply to a given clock's hardware config, se
138145
//Options menu options' EEPROM locations and default/min/max values.
139146
//Options' numbers may be changed by reordering these arrays (and changing readme accordingly).
140147
//Although these arrays are 0-index, the option number displayed (and listed in readme) is 1-index. (search for "fn-fnOpts+1")
141-
//1-index option number: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
142-
const byte optsLoc[] = {16,17,18,19,20,22,23,24,42,39,43,25,40,21,44,41,27, 28, 30,32,33,34, 35, 37};
143-
const word optsDef[] = { 2, 1, 0, 0, 5, 0, 0, 9, 0,61, 0, 0,61, 0, 0,61, 0,1320, 360, 0, 1, 5, 480,1020};
144-
const word optsMin[] = { 1, 1, 0, 0, 0, 0, 0, 0, 0,49, 0, 0,49, 0, 0,49, 0, 0, 0, 0, 0, 0, 0, 0};
145-
const word optsMax[] = { 2, 5, 3, 1,20, 6, 2,60, 1,88, 1, 1,88, 4, 1,88, 2,1439,1439, 2, 6, 6,1439,1439};
148+
//1-index option number: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
149+
const byte optsLoc[] = {16,17,18,19,20,22,23,24,42,39,43,25,40,21,44,41,27, 28, 30,32,33,34, 35, 37,26};
150+
const word optsDef[] = { 2, 1, 0, 0, 5, 0, 0, 9, 0,61, 0, 0,61, 0, 0,61, 0,1320, 360, 0, 1, 5, 480,1020, 1};
151+
const word optsMin[] = { 1, 1, 0, 0, 0, 0, 0, 0, 0,49, 0, 0,49, 0, 0,49, 0, 0, 0, 0, 0, 0, 0, 0, 0};
152+
const word optsMax[] = { 2, 5, 3, 1,20, 6, 2,60, 1,88, 1, 1,88, 4, 1,88, 2,1439,1439, 2, 6, 6,1439,1439, 4};
146153

147154
//RTC objects
148155
DS3231 ds3231; //an object to access the ds3231 specifically (temp, etc)
@@ -183,7 +190,6 @@ char scrollRemain = 0; //"frames" of scroll – 0=not scrolling, >0=coming in, <
183190
void setup(){
184191
Serial.begin(9600);
185192
Wire.begin();
186-
initOutputs();
187193
initInputs();
188194
delay(100); //prevents the below from firing in the event there's a capacitor stabilizing the input, which can read low falsely
189195
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
@@ -202,6 +208,7 @@ void setup(){
202208
writeEEPROM(25,0,false); //turn off timer interval mode
203209
}
204210
if(!enableSoftAlarmSwitch) writeEEPROM(2,1,false); //force alarm on if software switch is disabled
211+
initOutputs(); //depends on some EEPROM settings
205212
}
206213

207214
unsigned long pollLast = 0; //every 50ms
@@ -449,6 +456,8 @@ void ctrlEvt(byte ctrl, byte evt){
449456
if(relayPin>=0 && relayMode==0 && readEEPROM(43,false)==1) { //if switched relay, and timer signal is set to it
450457
if(relayPin!=127) digitalWrite(relayPin,HIGH);
451458
Serial.print(millis(),DEC); Serial.println(F(" Relay on, timer set"));
459+
if(readEEPROM(26,false)==4) switchLEDs(1); //LEDs following switch relay
460+
//TODO will this cancel properly? especially if alarm interrupts?
452461
}
453462
clearSet(); break;
454463
case fnIsDayCount: //set like date, save in eeprom like finishOpt
@@ -608,23 +617,18 @@ word readEEPROM(int loc, bool isWord){
608617
}
609618
void writeEEPROM(int loc, int val, bool isWord){
610619
if(isWord) {
611-
Serial.print(F("EEPROM write word:"));
612-
Serial.print(F(" loc ")); Serial.print(loc,DEC);
613-
if(EEPROM.read(loc)!=highByte(val)) {
614-
EEPROM.write(loc,highByte(val));
615-
Serial.print(F(" val ")); Serial.print(highByte(val),DEC);
616-
} else Serial.print(F(" unchanged (no write)."));
617-
Serial.print(F(" loc ")); Serial.print(loc+1,DEC);
618-
if(EEPROM.read(loc+1)!=lowByte(val)) {
619-
EEPROM.write(loc+1,lowByte(val));
620-
Serial.print(F(" val ")); Serial.print(lowByte(val),DEC);
621-
} else Serial.print(F(" unchanged (no write)."));
620+
// Serial.print(F("EEPROM write word:"));
621+
// Serial.print(F(" loc ")); Serial.print(loc,DEC); Serial.print(F(" val "));
622+
// if(EEPROM.read(loc)!=highByte(val)) { Serial.print(highByte(val),DEC); } else { Serial.print(F("no change")); }
623+
EEPROM.update(loc,highByte(val));
624+
// Serial.print(F(" loc ")); Serial.print(loc+1,DEC); Serial.print(F(" val "));
625+
// if(EEPROM.read(loc+1)!=lowByte(val)) { Serial.print(lowByte(val),DEC); } else { Serial.print(F("no change")); }
626+
EEPROM.update(loc+1,lowByte(val));
622627
} else {
623-
Serial.print(F("EEPROM write byte:"));
624-
Serial.print(F(" loc ")); Serial.print(loc,DEC);
625-
if(EEPROM.read(loc)!=val) { EEPROM.write(loc,val);
626-
Serial.print(F(" val ")); Serial.print(val,DEC);
627-
} else Serial.print(F(" unchanged (no write)."));
628+
// Serial.print(F("EEPROM write byte:"));
629+
// Serial.print(F(" loc ")); Serial.print(loc,DEC); Serial.print(F(" val "));
630+
// if(EEPROM.read(loc)!=val) { Serial.print(val,DEC); } else { Serial.print(F("no change")); }
631+
EEPROM.update(loc,val);
628632
}
629633
Serial.println();
630634
}
@@ -828,9 +832,11 @@ void switchAlarm(char dir){
828832
void switchPower(char dir){
829833
if(enableSoftPowerSwitch && relayPin>=0 && relayMode==0) { //if switched relay, and soft switch enabled
830834
//signalStop(); could use this instead of the below to turn the radio off
835+
if(dir==0) dir = !digitalRead(relayPin);
831836
if(relayPin!=127) {
832-
digitalWrite(relayPin,(dir==1?HIGH:(dir==-1?LOW:!digitalRead(relayPin))));
837+
digitalWrite(relayPin,(dir==1?HIGH:LOW));
833838
}
839+
if(readEEPROM(26,false)==4) switchLEDs(dir); //LEDs following switch relay
834840
Serial.print(millis(),DEC);
835841
Serial.print(F(" Relay "));
836842
if(dir==0) { Serial.print(F("toggled")); if(relayPin!=127) { Serial.print(digitalRead(relayPin)==HIGH?F(" on"):F(" off")); } }
@@ -1007,7 +1013,7 @@ void updateDisplay(){
10071013
editDisplay(tod.second(),5,5,true,false);
10081014
default: break;
10091015
}//end switch
1010-
}
1016+
} //end if fn running
10111017
} //end updateDisplay()
10121018

10131019
void editDisplay(word n, byte posStart, byte posEnd, bool leadingZeros, bool fade){
@@ -1060,6 +1066,8 @@ void initOutputs() {
10601066
for(byte i=0; i<3; i++) { pinMode(anodes[i],OUTPUT); }
10611067
if(piezoPin>=0) pinMode(piezoPin, OUTPUT);
10621068
if(relayPin>=0 && relayPin!=127) pinMode(relayPin, OUTPUT);
1069+
if(ledPin>=0) pinMode(ledPin, OUTPUT);
1070+
updateLEDs(); //set to initial value
10631071
}
10641072

10651073
void cycleDisplay(){
@@ -1171,16 +1179,20 @@ void signalStart(byte sigFn, byte sigDur, word pulseDur){ //make some noise! or
11711179
if(getSignalOutput()==1 && relayPin>=0 && relayMode==0) { //switched relay: turn it on now
11721180
if(relayPin!=127) digitalWrite(relayPin,HIGH);
11731181
Serial.print(millis(),DEC); Serial.println(F(" Relay on, signalStart"));
1182+
if(readEEPROM(26,false)==4) switchLEDs(1); //LEDs following switch relay
11741183
}
11751184
}
1185+
if(readEEPROM(26,false)==3) switchLEDs(1); //LEDs following signal
11761186
}
11771187
void signalStop(){ //stop current signal and clear out signal timer if applicable
11781188
signalRemain = 0; snoozeRemain = 0;
11791189
signalPulseStop(); //piezo or pulsed relay: stop now
11801190
if(getSignalOutput()==1 && relayPin>=0 && relayMode==0) { //switched relay: turn it off now
11811191
if(relayPin!=127) digitalWrite(relayPin,LOW);
11821192
Serial.print(millis(),DEC); Serial.println(F(" Relay off, signalStop"));
1193+
if(readEEPROM(26,false)==4) switchLEDs(0); //LEDs following switch relay
11831194
}
1195+
if(readEEPROM(26,false)==3) switchLEDs(0); //LEDs following relay
11841196
}
11851197
//beep start and stop should only be called by signalStart/signalStop and checkRTC
11861198
void signalPulseStart(word pulseDur){
@@ -1216,4 +1228,22 @@ word getHz(byte note){
12161228
}
12171229
char getSignalOutput(){ //for current signal: time, timer, or (default) alarm: 0=piezo, 1=relay
12181230
return readEEPROM((signalSource==fnIsTime?44:(signalSource==fnIsTimer?43:42)),false);
1219-
}
1231+
}
1232+
1233+
void updateLEDs(){
1234+
//Run whenever something is changed that might affect the LED state
1235+
if(ledPin>=0) switch(readEEPROM(26,false)){
1236+
case 0: //always off
1237+
digitalWrite(ledPin,LOW); break;
1238+
case 1: //always on
1239+
digitalWrite(ledPin,HIGH); break;
1240+
case 2: //on, but follow day-off and night-off
1241+
digitalWrite(ledPin,(displayDim<2?LOW:HIGH)); break;
1242+
case 3: //off, but on when alarm/timer sounds
1243+
digitalWrite(ledPin,(signalRemain && (signalSource==fnIsAlarm || signalSource==fnIsTimer)?HIGH:LOW)); break;
1244+
case 4: //off, but on with switched relay
1245+
if(relayPin>=0 && relayPin<127 && relayMode==0) digitalWrite(ledPin,digitalRead(relayPin)); break;
1246+
//Stopping place: Change all the updateLEDs to not have a polarity, add some more, and hide menu 25 when not equipped, and value 4 when not equipped
1247+
default: break;
1248+
}
1249+
} //end updateLEDs

0 commit comments

Comments
 (0)