Mike Moore
/
RTOS_HW_04
RTOS homework 4
Revision 17:cd6c76be8046, committed 2013-08-18
- Comitter:
- gatedClock
- Date:
- Sun Aug 18 19:26:43 2013 +0000
- Parent:
- 16:d7bbd641929c
- Child:
- 18:f19721f1069e
- Commit message:
- improved on/off, and LCD.
Changed in this revision
main.cpp | Show annotated file Show diff for this revision Revisions of this file |
--- a/main.cpp Sun Aug 18 19:15:12 2013 +0000 +++ b/main.cpp Sun Aug 18 19:26:43 2013 +0000 @@ -41,6 +41,7 @@ #define METROMAX 800 // max. beats per minute. #define METROMIN 8 // min. beats per minute. + #define METROTIME 10.0 #define UDSAMPLERATE 0.1 // how often to sample U/D joystick. #define LCDSAMPLERATE 0.1 // how often to redraw the LCD. #define PULSELENGTH 0.0625 // how long the LED-on-time is. @@ -125,7 +126,7 @@ fMetroDelay = 60.0 / (float) (dMetroBPM); fMetroDuty = PULSELENGTH; // initialize LED on-duration. lUpDownHowMany = 0; - cMetronomeOn = 1; + cMetronomeOn = 0; } /*----------------------------------------------//----------------------------*/ void ISR_left_rising(void) // increase BPM. @@ -180,13 +181,14 @@ /*----------------------------------------------//----------------------------*/ void ISR_up(void) { + cMetronomeOn = 0; } /*----------------------------------------------//----------------------------*/ void ISR_down(void) { cMetronomeOn = 1; timeoutMetronome.detach(); - timeoutMetronome.attach(&turn_off_metronome,10.0); + timeoutMetronome.attach(&turn_off_metronome,METROTIME); } /*----------------------------------------------//----------------------------*/ void ISR_center(void) // set BPM = 60. @@ -200,6 +202,7 @@ lcd.cls(); // clear display. LCD1; // line 1. + if (cMetronomeOn) lcd.printf(" metronome ON"); else @@ -220,6 +223,86 @@ lcd.printf(" RTOS HW 4"); } /*----------------------------------------------//----------------------------*/ +// this metronome tick ISR will self-adjust to the current user-selected +// metronome rate. that has to be done here, and at the start of the function, +// in order to maintain a constant phase and to prevent a beat-skip. + + void interrupt_service_M() // metronome tick. + { + if (cMetronomeOn) + { + tickerMetronome.detach(); // only one attachment. + tickerMetronome.attach(&interrupt_service_M,fMetroDelay); + led3_on(); + timeoutDutyCycle.attach(&led3_off,fMetroDuty); + } else led3_off(); + } +/*----------------------------------------------//----------------------------*/ + void turn_off_metronome(void) + { + cMetronomeOn = 0; + } +/*----------------------------------------------//----------------------------*/ +// this routine measures the number of seconds for which the joystick is +// in the up or down position. for three ranges of time, three different +// BPM rates-of-change are used. This means that as the user controls the +// metronome rate using the joystick, at first it will change slowly, then +// it will change at a moderate speed, then it will change quickly. +// additionally, pressing the center joystick button will bring the metronome +// back to 60BPM immediately, breaking BPM phase continuity. + void interrupt_service_UD(void) // joystick up/down sample + { + int dPressedSeconds; // how many seconds joystick pressed. + int dMultiCount; // slow count rate. + char cDiscontinuity; // 1 = break phase & change BPM now. + + cDiscontinuity = 0; // don't break phase. + + // calculate slow rate period. + dMultiCount = (int) ((float) (1.0 / ((float) UDSAMPLERATE))); + + if (dJoyStickUp) // joystick up. + { + // rate-range calculations. + dPressedSeconds = (int) (((float) lUpDownHowMany) * UDSAMPLERATE); + if (dPressedSeconds < 5) {if (!(lUpDownHowMany % dMultiCount)) dMetroBPM ++;} + else + if (dPressedSeconds < 10) dMetroBPM++; + else dMetroBPM += 5; + lUpDownHowMany++; // joystick holddown time. + } + else + if (dJoyStickDown) // joystick down. + { + // rate-range calculations. + dPressedSeconds = (int) (((float) lUpDownHowMany) * UDSAMPLERATE); + if (dPressedSeconds < 5) {if (!(lUpDownHowMany % dMultiCount)) dMetroBPM --;} + else + if (dPressedSeconds < 10) dMetroBPM--; + else dMetroBPM -= 5; + lUpDownHowMany++; // joystick holddown time. + } + else lUpDownHowMany = 0; // clear when not up or down. + + if (dJoyStickCenter) + { + dMetroBPM = 60; // center-button -> 60BPM. + cDiscontinuity = 1; // pending phase-break. + } + // saturate metronome BPM. + if (dMetroBPM > METROMAX) dMetroBPM = METROMAX; + if (dMetroBPM < METROMIN) dMetroBPM = METROMIN; + + fMetroDelay = 60.0 / (float) (dMetroBPM); // calculate Ticker delay time. + + if (cDiscontinuity) // implement 60BPS now. + { + tickerMetronome.detach(); // only one attachment. + tickerMetronome.attach(&interrupt_service_M,fMetroDelay); + } + + } +/*----------------------------------------------//----------------------------*/ void led3_off(void) {led3 = 0;} // turn off the LED. /*----------------------------------------------//----------------------------*/ void led3_on( void) {led3 = 1;} // turn on the led.