1
- // //////// Configuration consts //////////
2
-
3
- // These are the RLB board connections to Arduino analog input pins.
4
- // S1/PL13 = Reset
5
- // S2/PL5 = A1
6
- // S3/PL6 = A0
7
- // S4/PL7 = A6
8
- // S5/PL8 = A3
9
- // S6/PL9 = A2
10
- // S7/PL14 = A7
11
- // A6-A7 are analog-only pins that aren't as responsive and require a physical pullup resistor (1K to +5V).
12
-
13
- // What input is associated with each control?
14
- const byte mainAdjA = A1; // main up/down buttons or rotary encoder - must be equipped
15
- const byte mainAdjB = A0;
16
- const byte mainAdjType = 2 ;
17
-
18
- // //////// Function prototypes, global consts and vars //////////
1
+ // #include <EEPROM.h>
2
+ // #include <Wire.h>
3
+ // #include <RTClib.h>
4
+ // RTC_DS1307 rtc;
5
+ #include < Encoder.h> // https://www.pjrc.com/teensy/td_libs_Encoder.html
19
6
20
- // Hardware inputs
21
- // unsigned long inputSampleLast = 0; //millis() of last time inputs (and RTC) were sampled
22
- // const byte inputSampleDur = 50; //input sampling frequency (in ms) to avoid bounce
23
- // unsigned long inputLast = 0; //When a button was last pressed / knob was last turned
24
- // unsigned long inputLast2 = 0; //Second-to-last of above
25
- // byte btnCurHeld = 0; //Button hold thresholds: 0=none, 1=unused, 2=short, 3=long, 4=set by btnStop()
26
- bool mainRotLast[2 ] = {0 ,0 }; // last state of main rotary encoder inputs
27
- void initInputs (); // Set pinModes for inputs; capture initial state of knobs (rotary encoders, if equipped).
28
- void checkInputs (); // Run at sample rate. Calls checkBtn() for each eligible button and ctrlEvt() for each knob event.
29
- bool readInput (byte pin); // Does analog or digital read depending on which type of pin it is.
30
- // void checkBtn(byte btn); //Calls ctrlEvt() for each button event
31
- // void btnStop(); //Stops further events from a button until it's released, to prevent unintended behavior after an event is handled.
32
- void checkRot (byte rotA, byte rotB, bool last[], bool triggerEvent);
7
+ Encoder mainRot (A1,A0);
8
+ const byte rotCount = 4 ; // values per detent. We will set each encoder to a "resting" value of rotCount, and sense moves between detents when the rot value reaches 0 (left) or rotCount*2 (right).
9
+ byte mainRotLast = -999 ;
10
+ word val = 500 ;
33
11
34
12
// Display formatting
35
13
byte displayNext[6 ] = {15 ,15 ,15 ,15 ,15 ,15 }; // Internal representation of display. Blank to start. Change this to change tubes.
@@ -55,11 +33,7 @@ void setCathodes(byte decValA, byte decValB);
55
33
void decToBin (bool binVal[], byte i);
56
34
57
35
58
- // //////// Includes and main code control //////////
59
- // #include <EEPROM.h>
60
- // #include <Wire.h>
61
- // #include <RTClib.h>
62
- // RTC_DS1307 rtc;
36
+ // //////// Main code control //////////
63
37
64
38
void setup (){
65
39
// Serial.begin(57600);
@@ -68,6 +42,11 @@ void setup(){
68
42
// if(!rtc.isrunning()) rtc.adjust(DateTime(2017,1,1,0,0,0)); //TODO test
69
43
initOutputs ();
70
44
initInputs ();
45
+
46
+ mainRot.write (rotCount);
47
+
48
+ editDisplay (val,0 ,3 ,false );
49
+
71
50
// initEEPROM(readInput(mainSel)==LOW);
72
51
// debugEEPROM();
73
52
// setCaches();
@@ -76,7 +55,26 @@ void setup(){
76
55
void loop (){
77
56
// Things done every "clock cycle"
78
57
// checkRTC(); //if clock has ticked, decrement timer if running, and updateDisplay
79
- checkInputs (); // if inputs have changed, this will do things + updateDisplay as needed
58
+ // checkInputs(); //if inputs have changed, this will do things + updateDisplay as needed
59
+
60
+ long mainRotNew = mainRot.read ();
61
+ if (mainRotNew != mainRotLast){
62
+ if (mainRotNew <= 0 ) { // down one detent
63
+ val--;
64
+ editDisplay (val,0 ,3 ,false );
65
+ mainRotLast = rotCount;
66
+ mainRot.write (rotCount);
67
+ } else if (mainRotNew >= rotCount*2 ) {
68
+ val++;
69
+ editDisplay (val,0 ,3 ,false );
70
+ mainRotLast = rotCount;
71
+ mainRot.write (rotCount);
72
+ } else {
73
+ mainRotLast = mainRotNew;
74
+ }
75
+ editDisplay (mainRotLast,4 ,5 ,false );
76
+ }
77
+
80
78
// doSetHold(); //if inputs have been held, this will do more things + updateDisplay as needed
81
79
cycleDisplay (); // keeps the display hardware multiplexing cycle going
82
80
}
@@ -85,95 +83,20 @@ void loop(){
85
83
// //////// Control inputs //////////
86
84
void initInputs (){
87
85
// TODO are there no "loose" pins left floating after this? per https://electronics.stackexchange.com/q/37696/151805
88
- pinMode (A0, INPUT_PULLUP);
89
- pinMode (A1, INPUT_PULLUP);
86
+ // Buttons
87
+ // pinMode(A0, INPUT_PULLUP);
88
+ // pinMode(A1, INPUT_PULLUP);
90
89
pinMode (A2, INPUT_PULLUP);
91
90
pinMode (A3, INPUT_PULLUP);
92
- // 4 and 5 used for I2C
93
91
pinMode (A6, INPUT); digitalWrite (A6, HIGH);
94
92
pinMode (A7, INPUT); digitalWrite (A7, HIGH);
93
+
94
+ // Encoders
95
95
// If using rotary encoders, capture their initial state
96
- if (mainAdjType==2 ) checkRot (mainAdjA,mainAdjB,mainRotLast,false );
96
+ // if(mainAdjType==2) checkRot(mainAdjA,mainAdjB,mainRotLast,false);
97
97
// if(altAdjType==2) checkRot(altAdjA,altAdjB,altRotLast,false);
98
98
}
99
99
100
- void checkInputs (){
101
- // TODO can all this if/else business be defined at load instead of evaluated every sample?
102
- // if(millis() >= inputSampleLast+inputSampleDur) { //time for a sample
103
- // inputSampleLast = millis();
104
- // potential issue: if user only means to rotate or push encoder but does both?
105
- // checkBtn(mainSel); //main select
106
- // if(mainAdjType==2)
107
- checkRot (mainAdjA,mainAdjB,mainRotLast,true ); // main rotary encoder
108
- // else {
109
- // checkBtn(mainAdjA); checkBtn(mainAdjB);//main adj buttons
110
- // }
111
- // if(altSel!=0) checkBtn(altSel); //alt select (if equipped)
112
- // if(altAdjType==2) checkRot(altAdj,altRotLast,true); //alt rotary encoder (if equipped)
113
- // else
114
- // if(altAdjType==1) { checkBtn(altAdjA); checkBtn(altAdjB); } //alt adj buttons
115
- // } //end if time for a sample
116
- }
117
- bool readInput (byte pin){
118
- if (pin==A6 || pin==A7) return analogRead (pin)<100 ?0 :1 ; // analog-only pins
119
- else return digitalRead (pin);
120
- }
121
-
122
- word numMoves = 0 ;
123
- void checkRot (byte rotA, byte rotB, bool last[], bool triggerEvent){
124
- // Changes in rotary encoders.
125
- // When an encoder has changed, will call ctrlEvt(ctrl,1)
126
- // mimicking an up/down adj button press
127
- // TODO do we need to watch the rotation direction w/ last2[] to accommodate for inputs changing faster than we sample?
128
- // if(btnCur==0) { //only do if a button isn't pressed
129
- bool newA = readInput (rotA);
130
- bool newB = readInput (rotB);
131
- // if(newA != last[0] && triggerEvent) ctrlEvt(newA==last[1] ? rotA : rotB, 1);
132
- // If A changed, we'll pretend B didn't - see TODO above
133
- // else if(newB != last[1] && triggerEvent) ctrlEvt(newB==last[0] ? rotB : rotA, 1);
134
-
135
- if (newA!=last[0 ] || newB!=last[1 ]) {
136
- numMoves++;
137
- // Big tubes: show the number of moves we've had
138
- editDisplay (numMoves,0 ,3 ,false );
139
- // Small tubes: show the state of each of the encoder's pins
140
- editDisplay (newA,4 ,4 ,false );
141
- editDisplay (newB,5 ,5 ,false );
142
- }
143
-
144
- last[0 ] = newA;
145
- last[1 ] = newB;
146
- // }//end if button isn't pressed
147
- }// end checkRot
148
-
149
-
150
-
151
- // //////// Display data formatting //////////
152
- // void updateDisplay(){
153
- // //Run as needed to update display when the value being shown on it has changed
154
- // //(Ticking time and date are an exception - see checkRTC() )
155
- // //This formats the new value and puts it in displayNext[] for cycleDisplay() to pick up
156
- // if(fnSet) { //setting
157
- // //little tubes:
158
- // if(fn==255) editDisplay(fnSet, 4, 5, false); //setup menu: current option key
159
- // else blankDisplay(4, 5); //fn setting: blank
160
- // //big tubes:
161
- // if(fnSetValMax==1439) { //value is a time of day
162
- // editDisplay(fnSetVal/60, 0, 1, EEPROM.read(optsLoc[4])); //hours with leading zero
163
- // editDisplay(fnSetVal%60, 2, 3, true);
164
- // } else editDisplay(fnSetVal, 0, 3, false); //some other type of value
165
- // }
166
- // else { //fn running
167
- // switch(fn){
168
- // //case 0: //time taken care of by checkRTC()
169
- // //case 1: //date taken care of by checkRTC()
170
- // case 2: //alarm
171
- // case 3: //timer
172
- // break;
173
- // }
174
- // }
175
- // } //end updateDisplay()
176
-
177
100
void editDisplay (word n, byte posStart, byte posEnd, bool leadingZeros){
178
101
// Splits n into digits, sets them into displayNext in places posSt-posEnd (inclusive), with or without leading zeros
179
102
// If there are blank places (on the left of a non-leading-zero number), uses value 15 to blank tube
0 commit comments