· 6 years ago · Jun 15, 2019, 09:16 AM
1/*
2 * // file name harley_led.ino ( for SERJ )
3 * ----------------------------------------------------------------------------
4 * "THE BEER-WARE LICENSE" (Revision 00):
5 * <devgate.info эт gmail.com> wrote this file. As long as you retain this notice you
6 * can do whatever you want with this stuff. If we meet some day, and you think
7 * this stuff is worth it, you can buy me a beer in return.
8 * CHINGIZ THE FAIR SUN
9 * ----------------------------------------------------------------------------
10 *
11 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
12 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
13 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
14 * IN THE SOFTWARE.
15 *
16 * Date create: 2016.12.16
17 * Date change: 2017.01.13 10:51
18 * Date change: 2017.04.30 22:27 add level key detect
19 * ----------------------------------------------------------------------------
20 */
21const int PIN_LED_left = 7;
22const int PIN_LED_rigth = 8;
23
24#define count_left_led_auto_off 322
25#define count_rigth_led_auto_off 430
26
27#define led_ON 0
28#define led_OFF 1
29
30typedef enum {
31task_off_led_off = 0,
32task_executed,
33task_reset_off,
34task_reset_on ,
35task_off_led_on,
36task_init,
37} te_led_task_status;
38
39typedef enum {
40led_off = 0,
41led_left_exe = 1,
42led_rigth_exe = 2,
43led_both_exe_1 = 3,
44led_both_exe_2 = 4,
45led_merry_christmas = 5,
46
47} te_led_exe_status;
48
49//------------------------------------
50
51typedef struct
52{
53int pin_number;
54int time_debounce;
55unsigned long time_press ;
56unsigned long time_release;
57unsigned long time_last_press;
58unsigned long time_last_release;
59
60int press_level_detect;
61
62 bool status_press;
63 bool status_release;
64 bool interrupt_press;
65 bool interrupt_release;
66 bool need_release;
67 bool execute;
68
69} tdpkey;
70
71
72typedef struct
73{
74int pin_number;
75int invert_pin_number;
76int volume_off; // may be use PWM
77int volume_on; // may be use PWM
78unsigned long time_ON ;
79unsigned long time_OFF;
80int state;
81unsigned long now_timer;
82int step_exe;
83unsigned long disabled_count_interrupt;
84
85te_led_task_status status_led;
86bool tobe_executed;
87bool use_invert_pin;
88
89} td_pled;
90
91
92typedef enum {
93TIMER_EXE = 0,
94TIMER_DISABLED = 1,
95TIMER_RUN = 2,
96}TE_TIMER;
97
98//------------------------------------
99tdpkey key_left;
100tdpkey key_rigth;
101
102td_pled pled_left;
103td_pled pled_rigth;
104
105te_led_exe_status LED_STAT;
106
107// #undef DEBUG
108
109char debug_str[100];
110
111//------------------------------------
112TE_TIMER programm_count_down_uint32 ( unsigned long *timer , unsigned long shift )
113{
114 if (*timer > 0 )
115 {
116 if (*timer > shift )
117 {
118 *timer -= shift;
119 return TIMER_RUN;
120 }
121 else
122 {
123 *timer = 0;
124 return TIMER_EXE;
125 }
126 }
127 return TIMER_DISABLED;
128}
129
130
131void hall_effect_interrupt ( void )
132{
133
134 if ( TIMER_EXE == programm_count_down_uint32 (&pled_left.disabled_count_interrupt, 1 ) )
135 {
136 set_new_led_status ( led_off );
137 }
138
139 if ( TIMER_EXE == programm_count_down_uint32 (&pled_rigth.disabled_count_interrupt, 1 ) )
140 {
141 set_new_led_status ( led_off );
142 }
143
144}
145
146//------------------------------------
147void setup()
148{
149 // put your setup code here, to run once:
150 key_left.time_debounce = 50;
151 key_rigth.time_debounce = 50;
152
153 pled_left.volume_off = 1;
154 pled_left.volume_on = 0;
155
156 pled_left.pin_number = 7;
157 pled_left.status_led = task_init;
158 pled_left.use_invert_pin = false;
159
160 pled_rigth.volume_off = 1;
161 pled_rigth.volume_on = 0;
162
163 pled_rigth.pin_number = 8;
164 pled_rigth.status_led = task_init;
165
166 pled_rigth.use_invert_pin = false;
167
168
169 pled_rigth.invert_pin_number = pled_left.pin_number;
170 pled_left.invert_pin_number = pled_rigth.pin_number;
171 pled_rigth.use_invert_pin = false;
172 pled_left.use_invert_pin = false;
173
174
175
176 key_left.pin_number = 2;
177 key_rigth.pin_number = 4;
178 pinMode(key_left.pin_number, INPUT);
179 pinMode(key_rigth.pin_number, INPUT);
180 Serial.begin(9600); // setup serial
181
182 led_task(&pled_left, 0);
183 led_task(&pled_rigth,0);
184
185 key_rigth.need_release = true;
186 key_left.need_release = true;
187
188 key_rigth.press_level_detect = LOW;
189 key_left.press_level_detect = LOW;
190
191
192 set_new_led_status (led_off);
193
194 attachInterrupt(0, hall_effect_interrupt, RISING);
195 }
196//------------------------------------
197void clear_fkey_interrupt ( tdpkey *pkey )
198{
199pkey->interrupt_release = false;
200pkey->interrupt_press = false;
201pkey->need_release = true;
202}
203//------------------------------------
204
205void fKey (tdpkey *pkey, int time_elapsed )
206{
207
208
209
210 if ( digitalRead( pkey->pin_number) == pkey->press_level_detect )
211 {
212 pkey->time_press += time_elapsed;
213 }
214 else
215 {
216 pkey->time_release += time_elapsed;
217 }
218
219 // кнопка была отжата
220 if ( pkey->time_release > pkey->time_debounce )
221 {
222 if ( pkey->status_release == false )
223 {
224 pkey->time_press = 0;
225 pkey->status_release = true;
226 pkey->status_press = false;
227 pkey->interrupt_press = false;
228
229 if ( pkey->need_release == false )
230 {
231 pkey->interrupt_release = true;
232 }
233
234 pkey->need_release = false;
235 pkey->time_last_release = pkey->time_release;
236 pkey->time_release = 0;
237#ifdef DEBUG
238 sprintf ( debug_str,"key_release"); Serial.println ( debug_str );
239#endif
240 }
241 }
242
243if ( pkey->time_press > pkey->time_debounce )
244{
245 if ( pkey->status_press == false )
246 {
247 pkey->status_press = true;
248
249 pkey->need_release = false;
250 pkey->time_release = 0;
251 pkey->status_release = false;
252 pkey->interrupt_press = true;
253 pkey->interrupt_release = false;
254 pkey->time_last_release = pkey->time_release;
255 pkey->time_release = 0;
256#ifdef DEBUG
257 sprintf ( debug_str,"key_press"); Serial.println ( debug_str );
258#endif
259 }
260}
261 return;
262}
263
264void led_task ( td_pled *pled, int time_elapsed )
265{
266
267 TE_TIMER status;
268
269 switch ( pled->status_led )
270 {
271 case task_executed:
272 pled->tobe_executed = true;
273 break;
274
275 case task_init:
276 pinMode(pled->pin_number, OUTPUT);
277 digitalWrite(pled->pin_number, pled->volume_off);
278 if ( pled->use_invert_pin )
279 {
280 digitalWrite ( pled->invert_pin_number, pled->volume_on);
281 }
282 pled->tobe_executed = false;
283 break;
284
285 case task_off_led_off:
286 digitalWrite(pled->pin_number, pled->volume_off);
287 if ( pled->use_invert_pin )
288 {
289 digitalWrite ( pled->invert_pin_number, pled->volume_on);
290 }
291
292 pled->tobe_executed = false;
293 break;
294
295
296 case task_reset_off:
297 pled->step_exe = 1;
298 digitalWrite(pled->pin_number, pled->volume_off);
299 if ( pled->use_invert_pin )
300 {
301 digitalWrite ( pled->invert_pin_number, pled->volume_off);
302 }
303
304 pled->now_timer = pled->time_OFF;
305 time_elapsed = 0;
306
307 pled->status_led = task_executed;
308 pled->tobe_executed = true;
309 break;
310
311 case task_reset_on:
312 pled->step_exe = 0;
313 digitalWrite(pled->pin_number, pled->volume_on);
314 if ( pled->use_invert_pin )
315 {
316 digitalWrite ( pled->invert_pin_number, pled->volume_off);
317 }
318
319 pled->now_timer = pled->time_ON;
320 time_elapsed = 0;
321 pled->status_led = task_executed;
322 pled->tobe_executed = true;
323 break;
324
325 case task_off_led_on:
326 digitalWrite(pled->pin_number, pled->volume_on);
327 if ( pled->use_invert_pin )
328 {
329 digitalWrite ( pled->invert_pin_number, pled->volume_off);
330 }
331 pled->tobe_executed = false;
332 break;
333}
334
335if ( pled->tobe_executed )
336{
337
338 status = programm_count_down_uint32 (&pled->now_timer, time_elapsed);
339 switch ( status )
340 {
341 case TIMER_EXE:
342 // case TIMER_DISABLED:
343 switch ( pled->step_exe )
344 {
345 // led on
346 case 0:
347 pled->now_timer = pled->time_ON;
348 digitalWrite(pled->pin_number, pled->volume_on);
349 pled->step_exe = 1;
350
351 if ( pled->use_invert_pin )
352 {
353 digitalWrite ( pled->invert_pin_number, pled->volume_off);
354 }
355
356 break;
357
358 default:
359 case 1:
360 pled->now_timer = pled->time_OFF;
361 digitalWrite( pled->pin_number, pled->volume_off);
362 pled->step_exe = 0;
363 if ( pled->use_invert_pin )
364 {
365 digitalWrite ( pled->invert_pin_number, pled->volume_on);
366 }
367
368 break;
369 }
370 break;
371 }
372}
373
374}
375
376
377void set_new_led_status ( te_led_exe_status new_status )
378{
379if ( new_status == LED_STAT ) return;
380
381#ifdef DEBUG
382 sprintf ( debug_str,"set new state[%d]" , new_status );
383 Serial.println ( debug_str );
384#endif
385
386switch ( new_status )
387{
388 default:
389 case led_off:
390 pled_left.status_led = task_off_led_off;
391 pled_rigth.status_led = task_off_led_off;
392 pled_left.disabled_count_interrupt = 0;
393 pled_rigth.disabled_count_interrupt = 0;
394
395 break;
396
397 case led_left_exe:
398 pled_left.status_led = task_reset_on;
399 pled_left.time_ON = 200;
400 pled_left.time_OFF = 800;
401 pled_rigth.status_led = task_off_led_off;
402
403 pled_rigth.disabled_count_interrupt = 0;
404 pled_left.disabled_count_interrupt = count_left_led_auto_off;
405 break;
406
407 case led_rigth_exe:
408 pled_left.status_led = task_off_led_off;
409 pled_rigth.status_led = task_reset_on;
410 pled_rigth.time_ON = 200;
411 pled_rigth.time_OFF = 800;
412 pled_rigth.disabled_count_interrupt = count_rigth_led_auto_off;
413 pled_left.disabled_count_interrupt = 0;
414
415 break;
416
417 case led_both_exe_1:
418 pled_left.status_led = task_reset_on;
419 pled_left.time_ON = 200;
420 pled_left.time_OFF = 1000;
421
422 pled_rigth.status_led = task_reset_on;
423 pled_rigth.time_ON = 200;
424 pled_rigth.time_OFF = 1000;
425 pled_left.disabled_count_interrupt = 0;
426 pled_rigth.disabled_count_interrupt = 0;
427
428 break;
429
430 case led_both_exe_2:
431 pled_left.status_led = task_reset_on;
432 pled_left.time_ON = 100;
433 pled_left.time_OFF = 500;
434
435 pled_rigth.status_led = task_reset_on;
436 pled_rigth.time_ON = 100;
437 pled_rigth.time_OFF = 500;
438
439 pled_left.disabled_count_interrupt = 0;
440 pled_rigth.disabled_count_interrupt = 0;
441 break;
442
443 case led_merry_christmas:
444// pled_left.status_led = task_reset_on;
445// pled_left.time_ON = 200;
446// pled_left.time_OFF = 400;
447// pled_left.disabled_count_interrupt = 0;
448
449 pled_rigth.status_led = task_reset_on;
450 pled_rigth.time_ON = 300;
451 pled_rigth.time_OFF = 150;
452 pled_rigth.disabled_count_interrupt = 0;
453 pled_rigth.use_invert_pin = true;
454
455 break;
456
457 }
458
459 pled_left.tobe_executed = true;
460 pled_rigth.tobe_executed = true;
461
462
463 LED_STAT = new_status;
464}
465
466void loop() {
467//------------------------------
468static unsigned long sec;
469
470static unsigned long old_time;
471 unsigned long new_time;
472 unsigned long _time;
473//------------------------------
474 new_time = millis();
475 _time = new_time - old_time;
476 old_time = new_time;
477//------------------------------
478 fKey (&key_left , _time );
479 fKey (&key_rigth, _time );
480//--------------------------------
481// to be executed both led
482if ((key_left.interrupt_press )&&( key_rigth.status_press))
483{
484 set_new_led_status ( led_both_exe_1 );
485 clear_fkey_interrupt (&key_rigth);
486 clear_fkey_interrupt (&key_left);
487}
488
489if ((key_rigth.interrupt_press )&&( key_left.status_press))
490{
491 set_new_led_status ( led_both_exe_2 );
492 clear_fkey_interrupt (&key_rigth);
493 clear_fkey_interrupt (&key_left);
494}
495//-------------------------------------------------------------
496if ( key_left.interrupt_release )
497{
498 key_left.execute = true;
499 clear_fkey_interrupt (&key_left);
500 }
501
502if ( key_rigth.interrupt_release )
503{
504 key_rigth.execute = true;
505 clear_fkey_interrupt (&key_rigth);
506}
507
508
509// BMW
510if ( key_rigth.interrupt_press )
511{
512 if ( key_rigth.time_press > 1200 )
513 {
514 set_new_led_status ( led_both_exe_1 );
515 clear_fkey_interrupt (&key_rigth);
516 }
517}
518
519
520if ( key_left.interrupt_press )
521{
522 if ( key_left.time_press > 1200 )
523 {
524 set_new_led_status ( led_merry_christmas );
525 clear_fkey_interrupt (&key_left);
526 }
527}
528
529//--------------------
530 if ( key_left.execute )
531 {
532 key_left.execute = false;
533 switch ( LED_STAT )
534 {
535 case 0: set_new_led_status ( led_left_exe ); break;
536 default: set_new_led_status ( led_off ); break;
537 }
538 }
539//--------------------
540 if ( key_rigth.execute )
541 {
542 key_rigth.execute = false;
543 switch ( LED_STAT )
544 {
545 case 0: set_new_led_status ( led_rigth_exe ); break;
546 default: set_new_led_status ( led_off ); break;
547 }
548}
549//--------------------
550 if ( pled_left.tobe_executed == true )
551 {
552 led_task (&pled_left, _time);
553 }
554//--------------------
555 if ( pled_rigth.tobe_executed == true )
556 {
557 led_task (&pled_rigth,_time);
558 }
559//--------------------
560 /*
561 switch ( programm_count_down_uint32 (&sec, _time) )
562 {
563 case TIMER_EXE:
564 case TIMER_DISABLED:
565 sec = 5000;
566 #ifdef DEBUG
567 sprintf ( debug_str,"----" );
568 Serial.println ( debug_str );
569 #endif
570 break;
571 }
572*/
573}