Skip to content

Commit 535f697

Browse files
committed
A somewhat unsuccessful attempt to control display cycling with millis() polling instead of delays. It gets brightness-flickery because I think the duty cycling durations are not consistent.
1 parent 14f4e10 commit 535f697

File tree

1 file changed

+52
-107
lines changed

1 file changed

+52
-107
lines changed

sixtube_lm/sixtube_lm.ino

Lines changed: 52 additions & 107 deletions
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,7 @@ const byte signalType = 0; //What is the signal pin connected to?
6363
// 0 = Piezo. When alarm and timer go off, it will output a beep pattern with tone() for signalDur seconds.
6464
// 1 = Relay, signal style. Same as above, but it will simply switch the pin, for e.g. a solenoid striking a bell.
6565
// 2 = Relay, radio style. When alarm goes off, output will stay on for signalDur seconds (e.g. clock radio or appliance timer). When timer is running, output will stay on until timer runs down (e.g. clock radio "sleep" function) – but note that if the connected device has its own switch (see below), this will only work if the device is switched on.
66-
const word signalDur = 180; //Per above. Use e.g. 180 secs (3min) for signalType 0/1, 7200 secs (2hr) for signalType 2. Up to 65535 secs (just over 18 hrs).
66+
6767
const word signalBeepDur = 500; //With signalType 0/1, "beeps" happen once per second; how long is each beep in ms?
6868
//Particularly when driving a solenoid with signalType 1, this should be set to a comfortable activation duration for the solenoid.
6969

@@ -206,7 +206,7 @@ void setup(){
206206
Wire.begin();
207207
initOutputs();
208208
initInputs();
209-
if(readInput(mainSel)==LOW) initEEPROM();
209+
//if(readInput(mainSel)==LOW) initEEPROM(); TODO why is this firing so much
210210
}
211211

212212
unsigned long pollLast = 0; //every 50ms
@@ -1032,7 +1032,8 @@ byte binOutB[4] = {6,7,8,9};
10321032
//3 pins out to anode channel switches
10331033
byte anodes[3] = {11,12,13};
10341034

1035-
int displayLast[6]={11,11,11,11,11,11}; //What is currently being displayed. We slowly fade away from this.
1035+
int displayIn[6]={11,11,11,11,11,11};
1036+
int displayOut[6]={11,11,11,11,11,11};
10361037

10371038
//ms
10381039
/*
@@ -1058,14 +1059,19 @@ at 4ms per digit, 4x4x3 = 48ms
10581059
at 3ms per digit, 3x3x3 = 27ms
10591060
at 6ms 6x6x3 = 108ms
10601061
*/
1061-
const char fadeDur = 6; //each multiplexed pair of digits appears for this amount of time: partly next digit, partly last digit, partly dim (if applicable)
1062-
const char dimDur = 4; //half of fadeDur for half brightness? don't go over fadeDur-2
1063-
char fadeNextDur = 0; //Fading in displayNext values --TODO put back at 0
1064-
char fadeLastDur = 6; //Fading out displayLast values
1062+
1063+
/*
1064+
I'm thinking this can't be done with ms polling, because at 6ms it's flickery enough to see it, and at 4ms it's not, because if we use polling, the actual lighting durations may not be as consistent as they need to be, mils() are not precise enough. durations may not necessarily be the same every time, but I don't think the durations are the same every time. So the alternative is to use delay()
1065+
*/
1066+
1067+
const int fadeDur = 4; //each multiplexed pair of digits appears for this amount of time: partly next digit, partly last digit, partly dim (if applicable)
1068+
const int dimDur = 2; //half of fadeDur for half brightness? don't go over fadeDur-2
1069+
int fadeNextDur = 0; //Fading in displayNext values
1070+
int fadeLastDur = 0; //Fading out displayOut values
10651071
unsigned long fadeStartLast = 0; //when the last digit fade was started
10661072
byte cycleStage = 0; //Which stage of the multiplexing cycle we're in
10671073
unsigned long cycleLast = 0; //when the last stage was started
1068-
char cycleDelay = 0; //how long until the next stage starts - set from fadeNextDur and fadeLastDur
1074+
int cycleDelay = 0; //how long until the next stage starts - set from fadeNextDur and fadeLastDur
10691075
unsigned long setStartLast = 0; //to control flashing during start
10701076

10711077
word outputCounter = 0;
@@ -1077,96 +1083,18 @@ void initOutputs() {
10771083
}
10781084

10791085
void cycleDisplay(){
1086+
unsigned long mics = micros();
10801087
unsigned long mils = millis();
10811088

1082-
//Other display code decides whether we should dim per function or time of day
1083-
bool dim = (displayDim==1?1:0);
1084-
//But if we're setting, decide here to dim for every other 500ms since we started setting
1085-
if(fnSetPg>0) {
1086-
if(setStartLast==0) setStartLast = mils;
1087-
dim = 1-(((mils-setStartLast)/500)%2);
1088-
} else {
1089-
if(setStartLast>0) setStartLast=0;
1089+
if(mics < cycleLast) { //because mics will overflow every 70 mins
1090+
cycleLast = 0;
1091+
//need some more elegant stuff here with fadeStartLast
10901092
}
1091-
1092-
// Loop thru and update all the arrays, and fades.
1093-
fadeLastDur = fadeDur-(dim?dimDur:0); //default value
1094-
if(readEEPROM(20,false)==0) { //fading disabled
1095-
for(byte i=0; i<6; i++) if(displayNext[i] != displayLast[i]) displayLast[i] = displayNext[i];
1096-
} else { //fading enabled
1097-
if(fadeStartLast==0) { //not fading - time to fade?
1098-
for(byte i=0; i<6; i++) if(displayNext[i] != displayLast[i]) { fadeStartLast = mils; break; }
1099-
}
1100-
if(fadeStartLast!=0) { //currently fading
1101-
fadeNextDur = (((mils-fadeStartLast)*(fadeDur-(dim?dimDur:0)-1))/(readEEPROM(20,false)*10))+1; //partial based on time since fadeStatLast and EEPROM overall digit fade setting
1102-
fadeLastDur = fadeDur - fadeNextDur;
1103-
if(fadeNextDur >= fadeDur) { //fade is over
1104-
fadeStartLast = 0;
1105-
fadeNextDur = 0;
1106-
fadeLastDur = fadeDur;
1107-
for(byte j=0; j<6; j++) displayLast[j] = displayNext[j];
1108-
} //end fade is over
1109-
} //end curently fading
1110-
} //end fading enabled
1111-
1112-
if(displayDim>0) { //if other display code says to shut off entirely, skip this part
1113-
//Anode channel 0: tubes #2 (min x10) and #5 (sec x1)
1114-
setCathodes(displayLast[2],displayLast[5]); //Via d2b decoder chip, set cathodes to old digits
1115-
digitalWrite(anodes[0], HIGH); //Turn on tubes
1116-
delay(fadeLastDur-(dim?dimDur:0)); //Display for fade-out cycles
1117-
setCathodes(displayNext[2],displayNext[5]); //Switch cathodes to new digits
1118-
delay(fadeNextDur-(dim?dimDur:0)); //Display for fade-in cycles
1119-
digitalWrite(anodes[0], LOW); //Turn off tubes
1120-
1121-
if(dim) delay(dimDur);
1122-
1123-
//Anode channel 1: tubes #4 (sec x10) and #1 (hour x1)
1124-
setCathodes(displayLast[4],displayLast[1]);
1125-
digitalWrite(anodes[1], HIGH);
1126-
delay(fadeLastDur);
1127-
setCathodes(displayNext[4],displayNext[1]);
1128-
delay(fadeNextDur);
1129-
digitalWrite(anodes[1], LOW);
1130-
1131-
if(dim) delay(dimDur);
1132-
1133-
//Anode channel 2: tubes #0 (hour x10) and #3 (min x1)
1134-
setCathodes(displayLast[0],displayLast[3]);
1135-
digitalWrite(anodes[2], HIGH);
1136-
delay(fadeLastDur);
1137-
setCathodes(displayNext[0],displayNext[3]);
1138-
delay(fadeNextDur);
1139-
digitalWrite(anodes[2], LOW);
1140-
1141-
if(dim) delay(dimDur);
1142-
} //end if displayDim>0
1143-
1144-
1145-
1146-
// if(outputCounter<20) {
1147-
// Serial.print(fadeStartLast,DEC);
1148-
// Serial.print(F(" "));
1149-
// Serial.print(fadeLastDur,DEC);
1150-
// Serial.print(F(" "));
1151-
// Serial.print(fadeNextDur,DEC);
1152-
// Serial.print(F(" "));
1153-
// for(byte k=0; k<6; k++) { Serial.print(displayLast[k]); Serial.print(F(",")); }
1154-
// Serial.print(F(" "));
1155-
// for(byte l=0; l<6; l++) { Serial.print(displayNext[l]); Serial.print(F(",")); }
1156-
// Serial.println();
1157-
// outputCounter++;
1158-
// }
1159-
1160-
} //end cycleDisplay()
1161-
1162-
void cycleDisplayNew(){
1163-
unsigned long mils = millis();
1164-
1165-
if(cycleLast < mils+cycleDelay) {
1166-
cycleLast = mils;
1093+
if(cycleLast+cycleDelay < mics) {
1094+
cycleLast = mics;
11671095

11681096
//Other display code decides whether we should dim per function or time of day
1169-
bool dim = (displayDim==1?1:0);
1097+
bool dim = 0; //(displayDim==1?1:0); TODO undo
11701098
//But if we're setting, decide here to dim for every other 500ms since we started setting
11711099
if(fnSetPg>0) {
11721100
if(setStartLast==0) setStartLast = mils;
@@ -1177,65 +1105,82 @@ void cycleDisplayNew(){
11771105

11781106
if(displayDim>0) { //if other display code says to shut off entirely, skip this part
11791107

1108+
int fadeFullDur = 0; //readEEPROM(20,false)*10; //50 becomes 500. TODO can you cancel the fade when a change is made?
1109+
11801110
switch(cycleStage){
11811111
case 0: //off and delay for dim, if applicable - also shift the delays
11821112
cycleStage++;
11831113
digitalWrite(anodes[2], LOW);
1184-
if(readEEPROM(20,false)>0) { //if fade enabled
1114+
for(byte a=0; a<6; a++) displayIn[a] = displayNext[a];
1115+
if(fadeFullDur>0) { //if fade enabled
11851116
if(fadeStartLast==0) { //If we've completely faded, check to see if new differs from old, then initiate a new fade
1186-
for(byte i=0; i<6; i++) if(displayNext[i] != displayLast[i]) { fadeStartLast = mils; break; }
1117+
for(byte i=0; i<6; i++) if(displayIn[i] != displayOut[i]) { fadeStartLast = mils; break; }
11871118
}
11881119
if(fadeStartLast!=0) { //If we're working on fading
1189-
fadeNextDur = ((mils-fadeStartLast*(fadeDur-(dim?dimDur:0)-1))/(readEEPROM(20,false)*10))+1; //partial based on time since fadeStatLast and EEPROM overall digit fade setting
1190-
if(fadeNextDur >= fadeDur) { fadeNextDur = fadeDur; fadeStartLast = 0; for(byte j=0; j<6; j++) displayLast[j] = displayNext[j]; } //end of the fade
1120+
// ( (diff*(6-1)) / 200 )+1 = 1;
1121+
fadeNextDur = ( ((mils-fadeStartLast)*(fadeDur-(dim?dimDur:0)-1)) / fadeFullDur )+1;
1122+
//partial based on time since fadeStatLast and EEPROM overall digit fade setting
1123+
if(fadeNextDur >= fadeDur) { fadeNextDur = fadeDur; fadeStartLast = 0; for(byte j=0; j<6; j++) displayOut[j] = displayIn[j]; } //end of the fade
11911124
fadeLastDur = fadeDur-(dim?dimDur:0)-fadeNextDur; if(fadeLastDur > fadeDur) fadeLastDur = 0; //just in case it loops around (does this happen?)
11921125
}
1193-
} else { //no fade - we don't care about any of the last stuff, always go straight to next
1126+
} else { //no fade - we don't care about any of the fadeLast stuff, always go straight to next
11941127
fadeNextDur = fadeDur-(dim?dimDur:0);
11951128
}
11961129
if(dim) { cycleDelay = dimDur; break; } //otherwise continue
11971130
case 1: //Anode channel 0: tubes #2 (min x10) and #5 (sec x1), outgoing digits on
11981131
cycleStage++;
1199-
setCathodes(displayLast[2],displayLast[5]); //Via d2b decoder chip, set cathodes to old digits
1132+
setCathodes(displayOut[2],displayOut[5]); //Via d2b decoder chip, set cathodes to old digits
12001133
digitalWrite(anodes[0], HIGH); //Turn on tubes
1201-
if(fadeLastDur>0) { cycleDelay = fadeLastDur; break; } //Display for fade-out cycles, if applicable //(displayLastFade[0]/(dim?4:1))
1134+
if(fadeLastDur>0) { cycleDelay = fadeLastDur; break; } //Display for fade-out cycles, if applicable //(displayOutFade[0]/(dim?4:1))
12021135
case 2: //incoming digits on
12031136
cycleStage++;
1204-
setCathodes(displayNext[2],displayNext[5]); //Switch cathodes to new digits
1137+
setCathodes(displayIn[2],displayIn[5]); //Switch cathodes to new digits
12051138
cycleDelay = fadeNextDur; break; //Display for fade-in cycles
12061139
case 3: //off and pause for dim
12071140
cycleStage++;
12081141
digitalWrite(anodes[0], LOW); //Turn off tubes
12091142
if(dim) { cycleDelay = dimDur; break; } //otherwise continue
1210-
case 4: //Anode channel 1: tubes #4 (sec x10) and #1 (hour x1), outgoing digits on
1143+
case 4: //Anode channel 1: tubes #1 (hour x1) and #4 (sec x10), outgoing digits on
12111144
cycleStage++;
1212-
setCathodes(displayLast[4],displayLast[1]);
1145+
setCathodes(displayOut[4],displayOut[1]);
12131146
digitalWrite(anodes[1], HIGH);
12141147
if(fadeLastDur>0) { cycleDelay = fadeLastDur; break; }
12151148
case 5: //incoming digits on
12161149
cycleStage++;
1217-
setCathodes(displayNext[4],displayNext[1]);
1150+
setCathodes(displayIn[4],displayIn[1]);
12181151
cycleDelay = fadeNextDur; break;
12191152
case 6: //off and pause for dim
12201153
cycleStage++;
12211154
digitalWrite(anodes[1], LOW);
12221155
if(dim) { cycleDelay = dimDur; break; } //otherwise continue
12231156
case 7: //Anode channel 2: tubes #0 (hour x10) and #3 (min x1), outgoing digits on
12241157
cycleStage++;
1225-
setCathodes(displayLast[0],displayLast[3]);
1158+
setCathodes(displayOut[0],displayOut[3]);
12261159
digitalWrite(anodes[2], HIGH);
12271160
if(fadeLastDur>0) { cycleDelay = fadeLastDur; break; }
12281161
case 8: //incoming digits on
12291162
cycleStage=0;
1230-
setCathodes(displayNext[0],displayNext[3]);
1163+
setCathodes(displayIn[0],displayIn[3]);
12311164
cycleDelay = fadeNextDur; break;
12321165
default: break;
12331166
} //end switch(cycleStage)
1167+
1168+
// if(outputCounter < 50) {
1169+
// outputCounter++;
1170+
// Serial.print(outputCounter,DEC);
1171+
// Serial.print(F(" "));
1172+
// Serial.print(cycleLast,DEC);
1173+
// Serial.print(F(" "));
1174+
// Serial.print(cycleStage,DEC);
1175+
// Serial.print(F(" "));
1176+
// Serial.print(cycleDelay,DEC);
1177+
// Serial.println();
1178+
// }
12341179

12351180
} //end if displayDim>0
12361181
else if(fadeLastDur>0) { //if we've just shut off the display in the middle of a fade (does this ever happen?), set things up for when display comes back
12371182
fadeLastDur = 0; //force a full fade in to the new value...
1238-
for(byte k=0; k<6; k++) { displayLast[k] = 0; } //...from a blank display
1183+
for(byte k=0; k<6; k++) { displayOut[k] = 0; } //...from a blank display
12391184
} //end if fadeLastDur>0
12401185

12411186
} //end cycleLast cycle

0 commit comments

Comments
 (0)