@@ -160,7 +160,7 @@ Some are skipped when they wouldn't apply to a given clock's hardware config; se
160
160
const byte optsLoc[] = {16 ,17 ,18 ,19 ,20 ,22 ,23 ,24 ,39 ,25 ,40 ,21 ,41 ,27 , 28 , 30 ,32 ,33 ,34 , 35 , 37 };
161
161
const word optsDef[] = { 2 , 1 , 0 , 0 , 0 , 0 , 0 , 0 ,61 , 0 ,61 , 0 ,61 , 0 ,1320 , 360 , 0 , 1 , 5 , 480 ,1020 };
162
162
const word optsMin[] = { 1 , 1 , 0 , 0 , 0 , 0 , 0 , 0 ,49 , 0 ,49 , 0 ,49 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 };
163
- const word optsMax[] = { 2 , 5 , 3 , 1 ,50 , 6 , 2 ,60 ,88 , 1 ,88 , 4 ,88 , 2 ,1439 ,1439 , 2 , 6 , 6 ,1439 ,1439 };
163
+ const word optsMax[] = { 2 , 5 , 3 , 1 ,20 , 6 , 2 ,60 ,88 , 1 ,88 , 4 ,88 , 2 ,1439 ,1439 , 2 , 6 , 6 ,1439 ,1439 };
164
164
165
165
// RTC objects
166
166
DS3231 ds3231; // an object to access the ds3231 specifically (temp, etc)
@@ -231,12 +231,12 @@ void loop(){
231
231
}
232
232
}
233
233
// Check the RTC and inputs every every 50ms - avoids overpolling(?) and switch bounce(?)
234
- if (pollLast+50 <now) { // todo 20 vs 50
235
- pollLast=now;
236
- checkRTC (false ); // if clock has ticked, decrement timer if running, and updateDisplay
237
- checkInputs (); // if inputs have changed, this will do things + updateDisplay as needed
238
- doSetHold (); // if inputs have been held, this will do more things + updateDisplay as needed
239
- }
234
+ // if(pollLast+50<now) { //todo 20 vs 50
235
+ pollLast=now;
236
+ checkRTC (false ); // if clock has ticked, decrement timer if running, and updateDisplay
237
+ checkInputs (); // if inputs have changed, this will do things + updateDisplay as needed
238
+ doSetHold (); // if inputs have been held, this will do more things + updateDisplay as needed
239
+ // }
240
240
// Every loop cycle, cycle the display
241
241
cycleDisplay (); // keeps the display hardware multiplexing cycle going
242
242
}
@@ -1032,158 +1032,97 @@ byte binOutB[4] = {6,7,8,9};
1032
1032
// 3 pins out to anode channel switches
1033
1033
byte anodes[3 ] = {11 ,12 ,13 };
1034
1034
1035
- int displayIn[6 ]={11 ,11 ,11 ,11 ,11 ,11 };
1036
- int displayOut[6 ]={11 ,11 ,11 ,11 ,11 ,11 };
1037
-
1038
- // ms
1039
- /*
1040
- ------ ------ ------
1041
- full transition, let's say is 200ms
1042
- transition start is 10000ms
1043
- cycle = 6 (normal) or 3 (dim)
1044
- mils diff at 1st cycle is 0; nextDur = ((diff*(6-1))/200)+1 = 1; lastDur = (6-nextDur) = 5;
1045
- mils diff at 2nd cycle is 10; nextDur = 1....
1046
- 3rd - 20
1047
- 4th - 30
1048
- 5th - 40; nextDur = 2.... lastDur = 4......
1049
-
1050
- 1st - 0 - /0!!!!!!!!
1051
-
1052
- at 6ms per digit, 1ms change each time, 3 pairs of digits = 75ms transition.
1053
- =====- =====- =====-
1054
- ====-- ====-- ====--
1055
- ===--- ===--- ===---
1056
- ==---- ==---- ==----
1057
- =----- =----- =-----
1058
- at 4ms per digit, 4x4x3 = 48ms
1059
- at 3ms per digit, 3x3x3 = 27ms
1060
- at 6ms 6x6x3 = 108ms
1061
- */
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
- */
1035
+ byte displayLast[6 ]={11 ,11 ,11 ,11 ,11 ,11 }; // for noticing changes to displayNext and fading the display to it
1066
1036
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
1071
- unsigned long fadeStartLast = 0 ; // when the last digit fade was started
1072
- byte cycleStage = 0 ; // Which stage of the multiplexing cycle we're in
1073
- unsigned long cycleLast = 0 ; // when the last stage was started
1074
- int cycleDelay = 0 ; // how long until the next stage starts - set from fadeNextDur and fadeLastDur
1037
+ const int fadeDur = 5 ; // ms - each multiplexed pair of digits appears for this amount of time per cycle
1038
+ const int dimDur = 4 ; // ms - portion of fadeDur that is left dark during dim times
1039
+ int fadeNextDur = 0 ; // ms - during fade, incoming digit's portion of fadeDur
1040
+ int fadeLastDur = 0 ; // ms - during fade, outgoing digit's portion of fadeDur
1041
+ unsigned long fadeStartLast = 0 ; // millis - when the last digit fade was started
1075
1042
unsigned long setStartLast = 0 ; // to control flashing during start
1076
1043
1077
- word outputCounter = 0 ;
1078
-
1079
1044
void initOutputs () {
1080
1045
for (byte i=0 ; i<4 ; i++) { pinMode (binOutA[i],OUTPUT); pinMode (binOutB[i],OUTPUT); }
1081
1046
for (byte i=0 ; i<3 ; i++) { pinMode (anodes[i],OUTPUT); }
1082
1047
pinMode (10 , OUTPUT); // Alarm signal pin
1083
1048
}
1084
1049
1085
1050
void cycleDisplay (){
1086
- unsigned long mics = micros ();
1087
1051
unsigned long mils = millis ();
1088
1052
1089
- if (mics < cycleLast) { // because mics will overflow every 70 mins
1090
- cycleLast = 0 ;
1091
- // need some more elegant stuff here with fadeStartLast
1053
+ // Other display code decides whether we should dim per function or time of day
1054
+ bool dim = (displayDim==1 ?1 :0 );
1055
+ // But if we're setting, decide here to dim for every other 500ms since we started setting
1056
+ if (fnSetPg>0 ) {
1057
+ if (setStartLast==0 ) setStartLast = mils;
1058
+ dim = 1 -(((mils-setStartLast)/500 )%2 );
1059
+ } else {
1060
+ if (setStartLast>0 ) setStartLast=0 ;
1061
+ }
1062
+
1063
+ fadeLastDur = fadeDur-(dim?dimDur:0 ); // by default, last digit displays for entire fadeDur minus dim time
1064
+
1065
+ if (readEEPROM (20 ,false )==0 || dim) { // fading disabled or dim
1066
+ if (fadeStartLast) fadeStartLast = 0 ; // cancel any fade currently going - dim state doesn't have enough steps to fade well
1067
+ // TODO enable updateDisplay to configurably update both arrays to prevent fades
1068
+ for (byte i=0 ; i<6 ; i++) if (displayNext[i] != displayLast[i]) displayLast[i] = displayNext[i];
1092
1069
}
1093
- if (cycleLast+cycleDelay < mics) {
1094
- cycleLast = mics;
1095
-
1096
- // Other display code decides whether we should dim per function or time of day
1097
- bool dim = 0 ; // (displayDim==1?1:0); TODO undo
1098
- // But if we're setting, decide here to dim for every other 500ms since we started setting
1099
- if (fnSetPg>0 ) {
1100
- if (setStartLast==0 ) setStartLast = mils;
1101
- dim = 1 -(((mils-setStartLast)/500 )%2 );
1102
- } else {
1103
- if (setStartLast>0 ) setStartLast=0 ;
1070
+ else { // fading enabled
1071
+ if (fadeStartLast==0 ) { // not fading - time to fade?
1072
+ for (byte i=0 ; i<6 ; i++) if (displayNext[i] != displayLast[i]) { fadeStartLast = mils; break ; }
1104
1073
}
1074
+ if (fadeStartLast!=0 ) { // currently fading
1075
+ // let the next digit steal some display time from the last digit
1076
+ // ex: if fade time (from EEPROM) is 20ms, and fadeDur (next+last) is 6ms:
1077
+ // at 0ms, next = (( 0*(6-1))/20)+1 = 1; last = (6-nextDur) = 5;
1078
+ // at 10ms, next = ((10*(6-1))/20)+1 = 3; last = (6-nextDur) = 3; ...
1079
+ // at 20ms, next = ((20*(6-1))/20)+1 = 6; next = total, so fade is over!
1080
+ // TODO facilitate longer fades by writing a tweening function that smooths the frames, i.e. 111121222
1081
+ fadeNextDur = (((mils-fadeStartLast)*(fadeDur-1 ))/(readEEPROM (20 ,false )*10 ))+1 ;
1082
+ if (fadeNextDur >= fadeLastDur) { // fade is over
1083
+ fadeStartLast = 0 ;
1084
+ fadeNextDur = 0 ;
1085
+ fadeLastDur = fadeDur;
1086
+ for (byte j=0 ; j<6 ; j++) displayLast[j] = displayNext[j];
1087
+ } // end fade is over
1088
+ else { // shorten last digit display duration by subtracting next display duration from it
1089
+ fadeLastDur = fadeLastDur - fadeNextDur;
1090
+ }
1091
+ } // end curently fading
1092
+ } // end fading enabled
1105
1093
1106
- if (displayDim>0 ) { // if other display code says to shut off entirely, skip this part
1107
-
1108
- int fadeFullDur = 0 ; // readEEPROM(20,false)*10; //50 becomes 500. TODO can you cancel the fade when a change is made?
1109
-
1110
- switch (cycleStage){
1111
- case 0 : // off and delay for dim, if applicable - also shift the delays
1112
- cycleStage++;
1113
- digitalWrite (anodes[2 ], LOW);
1114
- for (byte a=0 ; a<6 ; a++) displayIn[a] = displayNext[a];
1115
- if (fadeFullDur>0 ) { // if fade enabled
1116
- if (fadeStartLast==0 ) { // If we've completely faded, check to see if new differs from old, then initiate a new fade
1117
- for (byte i=0 ; i<6 ; i++) if (displayIn[i] != displayOut[i]) { fadeStartLast = mils; break ; }
1118
- }
1119
- if (fadeStartLast!=0 ) { // If we're working on fading
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
1124
- fadeLastDur = fadeDur-(dim?dimDur:0 )-fadeNextDur; if (fadeLastDur > fadeDur) fadeLastDur = 0 ; // just in case it loops around (does this happen?)
1125
- }
1126
- } else { // no fade - we don't care about any of the fadeLast stuff, always go straight to next
1127
- fadeNextDur = fadeDur-(dim?dimDur:0 );
1128
- }
1129
- if (dim) { cycleDelay = dimDur; break ; } // otherwise continue
1130
- case 1 : // Anode channel 0: tubes #2 (min x10) and #5 (sec x1), outgoing digits on
1131
- cycleStage++;
1132
- setCathodes (displayOut[2 ],displayOut[5 ]); // Via d2b decoder chip, set cathodes to old digits
1133
- digitalWrite (anodes[0 ], HIGH); // Turn on tubes
1134
- if (fadeLastDur>0 ) { cycleDelay = fadeLastDur; break ; } // Display for fade-out cycles, if applicable //(displayOutFade[0]/(dim?4:1))
1135
- case 2 : // incoming digits on
1136
- cycleStage++;
1137
- setCathodes (displayIn[2 ],displayIn[5 ]); // Switch cathodes to new digits
1138
- cycleDelay = fadeNextDur; break ; // Display for fade-in cycles
1139
- case 3 : // off and pause for dim
1140
- cycleStage++;
1141
- digitalWrite (anodes[0 ], LOW); // Turn off tubes
1142
- if (dim) { cycleDelay = dimDur; break ; } // otherwise continue
1143
- case 4 : // Anode channel 1: tubes #1 (hour x1) and #4 (sec x10), outgoing digits on
1144
- cycleStage++;
1145
- setCathodes (displayOut[4 ],displayOut[1 ]);
1146
- digitalWrite (anodes[1 ], HIGH);
1147
- if (fadeLastDur>0 ) { cycleDelay = fadeLastDur; break ; }
1148
- case 5 : // incoming digits on
1149
- cycleStage++;
1150
- setCathodes (displayIn[4 ],displayIn[1 ]);
1151
- cycleDelay = fadeNextDur; break ;
1152
- case 6 : // off and pause for dim
1153
- cycleStage++;
1154
- digitalWrite (anodes[1 ], LOW);
1155
- if (dim) { cycleDelay = dimDur; break ; } // otherwise continue
1156
- case 7 : // Anode channel 2: tubes #0 (hour x10) and #3 (min x1), outgoing digits on
1157
- cycleStage++;
1158
- setCathodes (displayOut[0 ],displayOut[3 ]);
1159
- digitalWrite (anodes[2 ], HIGH);
1160
- if (fadeLastDur>0 ) { cycleDelay = fadeLastDur; break ; }
1161
- case 8 : // incoming digits on
1162
- cycleStage=0 ;
1163
- setCathodes (displayIn[0 ],displayIn[3 ]);
1164
- cycleDelay = fadeNextDur; break ;
1165
- default : break ;
1166
- } // 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
- // }
1179
-
1180
- } // end if displayDim>0
1181
- 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
1182
- fadeLastDur = 0 ; // force a full fade in to the new value...
1183
- for (byte k=0 ; k<6 ; k++) { displayOut[k] = 0 ; } // ...from a blank display
1184
- } // end if fadeLastDur>0
1094
+ if (displayDim>0 ) { // if other display code says to shut off entirely, skip this part
1095
+ // Anode channel 0: tubes #2 (min x10) and #5 (sec x1)
1096
+ setCathodes (displayLast[2 ],displayLast[5 ]); // Via d2b decoder chip, set cathodes to old digits
1097
+ digitalWrite (anodes[0 ], HIGH); // Turn on tubes
1098
+ delay (fadeLastDur);// -(dim?dimDur:0)); //Display for fade-out cycles
1099
+ setCathodes (displayNext[2 ],displayNext[5 ]); // Switch cathodes to new digits
1100
+ delay (fadeNextDur);// -(dim?dimDur:0)); //Display for fade-in cycles
1101
+ digitalWrite (anodes[0 ], LOW); // Turn off tubes
1102
+
1103
+ if (dim) delay (dimDur);
1104
+
1105
+ // Anode channel 1: tubes #4 (sec x10) and #1 (hour x1)
1106
+ setCathodes (displayLast[4 ],displayLast[1 ]);
1107
+ digitalWrite (anodes[1 ], HIGH);
1108
+ delay (fadeLastDur);
1109
+ setCathodes (displayNext[4 ],displayNext[1 ]);
1110
+ delay (fadeNextDur);
1111
+ digitalWrite (anodes[1 ], LOW);
1112
+
1113
+ if (dim) delay (dimDur);
1114
+
1115
+ // Anode channel 2: tubes #0 (hour x10) and #3 (min x1)
1116
+ setCathodes (displayLast[0 ],displayLast[3 ]);
1117
+ digitalWrite (anodes[2 ], HIGH);
1118
+ delay (fadeLastDur);
1119
+ setCathodes (displayNext[0 ],displayNext[3 ]);
1120
+ delay (fadeNextDur);
1121
+ digitalWrite (anodes[2 ], LOW);
1122
+
1123
+ if (dim) delay (dimDur);
1124
+ } // end if displayDim>0
1185
1125
1186
- } // end cycleLast cycle
1187
1126
} // end cycleDisplay()
1188
1127
1189
1128
void setCathodes (byte decValA, byte decValB){
0 commit comments