-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathreadjukekeys.ino
360 lines (325 loc) · 13.8 KB
/
readjukekeys.ino
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
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
// functions to read and debounce keys
// wallbox uses up/down buttons for volume control
// also latches the electric magnet to latch keys, jukebox uses a magnet latch
// the magnet latch (solenoid) on the Rockola is drive by 12 volts. I use a 12V power spupply for everything with a stepdown converter to 5V for the ESP32
// the magnet works on 12V and is switched with a optocoupler fet driver. these can be found in the usual places.
int AdcConvert(int value)
{ // converts an analog input value and return the key pressed
// in series connected resistors that are all normally closed by the unpressed keys - a classic voltage divider
// by measuring the voltage on the analog input pin, we can figure out which key is pressed
// top resistor is 560 ohm
// S10 no resistor
// S9 4K7
// S8 2K2
// S7 1K5
// S6 820 ohm
// S5 560 ohm
// S4 390 ohm
// S3 220 ohm
// S2 150 ohm
// S1 68 ohm
//
// no
// resistor
// +3V3 ----[560]---+ here +--[4K7]--+--[2K2]--+--[1K5]--+--[820]--+--[560]--+--[390]--+--[220]--+--[150]--+---[68]--+
// | | | | | | | | | | |
// NC CONTACTS +----=----+----=----+----=----+----=----+----=----+----=----+----=----+----=----+----=----+----=----+
// KEY ROW | 10 9 8 7 6 5 4 3 2 1 |
// | |
// +--------> to analog input pin ESP32 D36 +--------> to GND
//
//
// no
// resistor
// +3V3 ----[560]---+ here +--[4K7]--+--[2K2]--+--[1K5]--+--[820]--+--[560]--+--[390]--+--[220]--+--[150]--+---[68]--+
// | | | | | | | | | | |
// NC CONTACTS +----=----+----=----+----=----+----=----+----=----+----=----+----=----+----=----+----=----+----=----+
// KEY ROW | K J H G F E D C B A |
// | |
// +--------> to analog input pin ESP32 D39 +--------> to GND
//
// wallbox only - control of volume and skip/next
// skip/nect button has multiple functions - long press to switch between radio and jukebox, >20 seconds press to start webmanager portal.
//
//
// +3V3 ----[560]---+ +--[4K7]--+--[2K2]--+ +---[68]--+
// | | | | | |
// NC CONTACTS +---------+----=----+----=----+-----------------------------------------------------------+----=----+
// KEY ROW | V+ V- S |
// | K |
// +--------> to analog input pin ESP32 I +--------> to GND
// P
//
// +------------------+
// +12V --+ +------> +5V ESP32
// | Stepdown 12V-5V |
// GND ---+ +------> GND ESP32
// +------------------+
//
// +--------------+ +----------------+
// +12V --+ solenoid +---------+ +----------> ESP32 D21 SOLENOID
// +--------------+ + FET DRIVER +
// +---+ +---+
// | +----------------+ |
// | |
// +------------------------+------> GND
//
//
if(value>3864)return 10;
if(value>3364)return 9;
if(value>2846)return 8;
if(value>2421)return 7;
if(value>2051)return 6;
if(value>1673)return 5;
if(value>1227)return 4;
if(value>815)return 3;
if(value>459)return 2;
if(value>127)return 1;
return 0; // no key pressed, all closed
}
#define DEBOUNCE 5
// task to read the keys at a regular interval
void ReadJukeKeys(void * pvParameters)
{ int analog_leftvalue;
int analog_rightvalue;
int analog_controlvalue; // only wallbox which uses up/down button for volume control
int act_left_key;
int act_right_key;
int act_control_key;
int act_cancel_button;
int act_blue_button;
int act_encoder_button;
int blue_button_changed = 0;
int cancel_button_changed = 0;
int encoder_button_changed = 0;
int left_changed = 0;
int right_changed = 0;
int control_changed = 0;
while(1)
{ analog_leftvalue = analogRead(ANALOG_LEFT);
act_left_key = AdcConvert(analog_leftvalue);
analog_rightvalue = analogRead(ANALOG_RIGHT);
act_right_key = AdcConvert(analog_rightvalue);
analog_controlvalue = analogRead(ANALOG_CONTROL);
act_control_key = AdcConvert(analog_controlvalue);
act_cancel_button = digitalRead(CANCEL_BUTTON);
act_blue_button = digitalRead(BLUE_BUTTON);
act_encoder_button = digitalRead(ENCODER_BUTTON);
if (P.displayAnimate())
{
if (newMessageAvailable)
{
strcpy(curMessage, newMessage);
newMessageAvailable = false;
}
P.displayReset();
}
if(DeviceType == WALLBOX)
{ if(act_control_key == 1) // skip button also used to switch between radio/jukebox when pressed long
{ act_cancel_button = 1;
}
else act_cancel_button = 0;
}
// debounce encoder button
if(act_encoder_button != deb_encoder_button)
{ if(encoder_button_changed<DEBOUNCE)encoder_button_changed++;
else
{ deb_encoder_button = act_encoder_button;
encoder_buttonf = deb_encoder_button;
encoder_button_changed = 0;
}
}
else encoder_button_changed = 0;
if(deb_encoder_button==0) // pressed?
{ encoder_button_very_long_pressed++; // use that to activate portal wifi manager
}
else
{ encoder_button_very_long_pressed = 0;
}
// debounce blue
if(act_blue_button != deb_blue_button)
{ if(blue_button_changed<DEBOUNCE)blue_button_changed++;
else
{ deb_blue_button = act_blue_button;
blue_buttonf = deb_blue_button;
blue_button_changed = 0;
}
}
else blue_button_changed = 0;
// debounce cancel - resets wrong key pressed
if(act_cancel_button != deb_cancel_button)
{ if(cancel_button_changed<DEBOUNCE)cancel_button_changed++;
else
{ deb_cancel_button = act_cancel_button;
cancel_buttonf = deb_cancel_button;
cancel_button_changed = 0;
if(DeviceMode == SELECTSONG)
{ MagnetPower10mS = 0;
Show45RPM10mS = 0; // removes artwork display
}
else ShowRadio10mS = 0;
}
}
else cancel_button_changed = 0;
// debounce left
if(act_left_key != deb_left_key)
{ if(left_changed<DEBOUNCE)left_changed++;
else
{ deb_left_key = act_left_key;
left_keyf = deb_left_key;
left_changed = 0;
}
}
else left_changed = 0;
// debounce right
if(act_right_key != deb_right_key)
{ if(right_changed<DEBOUNCE)right_changed++;
else
{ deb_right_key = act_right_key;
right_keyf = deb_right_key;
right_changed = 0;
}
}
else right_changed = 0;
// debounce control
if(act_control_key != deb_control_key)
{ if(control_changed<DEBOUNCE)control_changed++;
else
{ deb_control_key = act_control_key;
control_keyf = deb_control_key;
control_changed = 0;
}
}
else control_changed = 0;
if(deb_cancel_button)
{ if(CancelButtonEnabled)cancel_button_long_pressed++;
cancel_button_very_long_pressed++;
}
else
{ cancel_button_long_pressed = 0;
CancelButtonEnabled = 1;
cancel_button_very_long_pressed = 0;
}
if(!MagnetDeadTime10mS)
{ if(left_keyf == deb_left_key)
{ left_keyf = 1234;
// Serial.print("L ");
// Serial.println(deb_left_key);
// Serial.println(analog_leftvalue);
// Serial.println(analog_rightvalue);
if(deb_right_key == 0) // first key pressed
{ if(deb_left_key>0) // key L1-L10
{ if(DeviceMode == SELECTRADIO)
{ if(DeviceType == JUKEBOX)
{ NewRadioStation = deb_left_key; // radio choice will be picked up in loop()
OldRadioStation = 0; // forces the made choice no matter what is playing
MagnetPower10mS = 150; // first key pressed, release key after 1.5 seconds
ShowRadio10mS = 300; // display a retro radio to confirm selection
}
}
else
{ MagnetPower10mS = 700; // unlatch the key after 7 seconds if no 2nd key is pressed
Show45RPM10mS = 700; // display 45rpm vinyl record
}
}
else MagnetPower10mS = 0;
}
else
{ // second key pressed
if(deb_left_key>0) // key L1-L10
{ MagnetPower10mS = 200; // release keys after 2 seconds
MagnetDeadTime10mS = 250;
selectedsong = (deb_left_key - 1) * 10 + deb_right_key;
if(DeviceType == WALLBOX)
{ DeviceMode = SELECTSONG;
SonosSourceMode = SONOS_SOURCE_FILE; // forces quicker update of lcd
}
if(DeviceMode == SELECTSONG)
{ Actual45RPMShown = selectedsong;
Show45RPM10mS = 200; // keep the display for two seconds
}
// Serial.print("S");
// Serial.println(selectedsong);
}
else MagnetPower10mS = 700; // usually between 0-700, but when releasing a half pressed button back to7 seconds
}
}
if( right_keyf == deb_right_key)
{ right_keyf = 1234;
// Serial.print("R");
// Serial.println(deb_right_key);
// Serial.println(analog_leftvalue);
// Serial.println(analog_rightvalue);
if(deb_left_key == 0) // first key pressed
{ if(deb_right_key>0)
{ if(DeviceMode == SELECTRADIO)
{ if(DeviceType == JUKEBOX)
{ NewRadioStation = deb_right_key + 10; // radio choice will be picked up in loop()
OldRadioStation = 0; // forces the made choice no matter what is playing
MagnetPower10mS = 150; // first key pressed, release key after 1.5 seconds
ShowRadio10mS = 300; // display a retro radio to confirm selection
}
}
else
{ MagnetPower10mS = 700; // unlatch the key after 7 seconds if no 2nd key is pressed
Show45RPM10mS = 700; // display 45rpm vinyl record
}
}
else MagnetPower10mS = 0;
}
else
{ // second key pressed
if(deb_right_key>0) // toets R1-R10
{ MagnetPower10mS = 200; // release keys after 2 seconds
MagnetDeadTime10mS = 250;
selectedsong = (deb_left_key - 1) * 10 + deb_right_key;
if(DeviceType == WALLBOX)
{ DeviceMode = SELECTSONG;
SonosSourceMode = SONOS_SOURCE_FILE; // forces quicker update of lcd
}
if(DeviceMode == SELECTSONG)
{ Actual45RPMShown = selectedsong;
Show45RPM10mS = 200; // keep the display for two seconds
}
// Serial.print("S");
// Serial.println(selectedsong);
}
else MagnetPower10mS = 700; // usually between 0-700, but when releasing a half pressed button back to7 seconds
}
}
if(DeviceType == WALLBOX)
{ if( control_keyf == deb_control_key)
{ control_keyf = 1234;
// Serial.print("C");
// Serial.println(deb_control_key);
// Serial.println(analog_controlvalue);
if(deb_control_key>0) // key C1-C10
{ if(deb_control_key==1)
{ SonosSkipRequest = 1;
}
else if(deb_control_key==8) // volume down
{ if((ActualVolumeFromSonos>0) && (ActualVolumeFromSonos<90))
{ //Serial.print("Volume-down ");
//Serial.println(ActualVolumeFromSonos);
NewVolumeForSonos = ActualVolumeFromSonos -5;
NewVolumeForSonos = rotary_loop(NewVolumeForSonos);
AsyncVolumeForSonos = NewVolumeForSonos;
}
}
else if(deb_control_key==9) // volume up
{ if((ActualVolumeFromSonos>0) && (ActualVolumeFromSonos<90))
{ //Serial.print("Volume-up ");
//Serial.println(ActualVolumeFromSonos);
NewVolumeForSonos = ActualVolumeFromSonos +5;
NewVolumeForSonos = rotary_loop(NewVolumeForSonos);
AsyncVolumeForSonos = NewVolumeForSonos;
}
}
}
}
}
}
vTaskDelay(20 / portTICK_PERIOD_MS); // portTICK_PERIOD_MS = 1 ;-)
}
}
// end of file