Mike Moore
/
RTOS_HW_04
RTOS homework 4
main.cpp
- Committer:
- gatedClock
- Date:
- 2013-08-18
- Revision:
- 19:0db1451d19ef
- Parent:
- 18:f19721f1069e
- Child:
- 20:64f1671c57ec
File content as of revision 19:0db1451d19ef:
/*----------------------------------------------//------------------------------ student : m-moore class : rtos directory : RTOS_HW_04 file : main.cpp ----description---------------------------------//------------------------------ Joystick-Controlled Metronome features: 1. joystick-controlled. 2. turns off after one minute. 3. ISR's for all joystick inputs. 4. joystick debounce. 5. LED and LCD displays. 6. BPM rate adjustable even when metronome is off. 7. BPM saturates at defined lower/upper bounds. controls: 1. joystick-left - increase metronome rate. 2. joystick-right - decrease metronome rate. 3. joystick-down - start metronome. 4. joystick-up - stop metronome. 5. joystick-center - set metronome to 60BPM. notes: 1. adding the mbed-rtos library to this project prevents the LED from blinking and the LCD from displaying, even if there is no #include "rtos.h" statement. 2. i was considering having the BPM up/down ISRs set up self- ending threads for continuous button press for rapid rate change, but again, rtos.h was causing trouble. 3. I'm making use of disable-interrupts for bounce suppression. this could microscopically delay the metronome while its BPM is being adjusted, since I can't turn off only the interrupt involved with joystick input. testing: 1. start metronome - verify it blinks, and stops after a minute. 2. stop metronome - verity it stops metronome. 3. verify display indicates ON and OFF state. 4. verify display indicates BPM rate. 5. operate left/right joystick, inspect for BPM jumps (bounce). 6. verify lower/upper BPM bounds. (only lower-bound tested). -----includes-----------------------------------//----------------------------*/ #include "mbed.h" // mbed class. // #include "rtos.h" #include "C12832_lcd.h" // LCD class. //---defines------------------------------------//------------------------------ #define LCD1 lcd.locate(0, 0); // LCD line 1. #define LCD2 lcd.locate(0,11); // LCD line 2. #define LCD3 lcd.locate(0,22); // LCD line 3. #define METROMAX 800 // max. beats per minute. #define METROMIN 8 // min. beats per minute. #define METROTIME 60.0 // metronome on-time in seconds. #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. #define DEBOUNCE 0.16 // debounce pause duration in S. //--global_definitions--------------------------//------------------------------ //--global_variables----------------------------//------------------------------ float fMetroDelay; // time between ticks, in seconds. float fMetroDuty; // duration of metro high, in seconds. int dMetroBPM; // master parameter. char cMetronomeOn; // 1 = allow blink. //--global_instances----------------------------//------------------------------ C12832_LCD lcd; // LCD object. InterruptIn iJoyStickUp (p15); // joystick up rising edge. InterruptIn iJoyStickDown (p12); // joystick down rising edge. InterruptIn iJoyStickLeft (p13); // joystick left rising edge. InterruptIn iJoyStickRight (p16); // joystick right rising edge. InterruptIn iJoyStickCenter(p14); // 1 if joystick middle pressed. DigitalOut led3(LED1); // leftmost LED. Ticker tickerMetronome; // blinking LED. Ticker tickerLCD; // display ticker. Timeout timeoutDutyCycle; // LED duty cycle delay. Timeout timeoutMetronome; //-------prototypes-----------------------------//------------------------------ void initialization(); // initialize settings. void lcd_display(); // display on LCD. void interrupt_service_M(); // metronome tick. void led3_off(); // attachable LED control. void led3_on(); // attachable LED control. void ISR_up(); // stop metronome. void ISR_down(); // start metronome. void ISR_right_rising(); // decrease BPM. void ISR_right_falling(); // bounce protection. void ISR_left_rising(); // increase BPM. void ISR_left_falling(); // bounce protection. void ISR_center(); // set to 60BPM. void turn_off_metronome(); // turn off blinker. //==============================================//============================== int main(void) { iJoyStickUp.rise (&ISR_up); // metronome stop. iJoyStickDown.rise (&ISR_down); // metronome start. iJoyStickLeft.rise (&ISR_left_rising); // increase BPM. iJoyStickLeft.fall (&ISR_left_falling); // anti-bounce. iJoyStickRight.rise(&ISR_right_rising); // decrease BPM. iJoyStickRight.fall(&ISR_right_falling); // anti-bounce. iJoyStickCenter.rise(&ISR_center); // 60BPM. initialization(); // initialize variables. // metronome ticker. tickerMetronome.attach(&interrupt_service_M,fMetroDelay); // LCD ticker. tickerLCD.attach(&lcd_display,LCDSAMPLERATE); while(1) // all timer/interrupt driven. { wait(10.0); } } /*----------------------------------------------//----------------------------*/ void initialization(void) // program initializations. { dMetroBPM = 60; // initialize to 60BPM. fMetroDelay = 60.0 / (float) (dMetroBPM); fMetroDuty = PULSELENGTH; // initialize LED on-duration. cMetronomeOn = 0; } /*----------------------------------------------//----------------------------*/ void ISR_left_rising(void) // increase BPM. { __disable_irq(); // anti-bounce. dMetroBPM++; // increase BPM. // saturate metronome BPM. if (dMetroBPM > METROMAX) dMetroBPM = METROMAX; if (dMetroBPM < METROMIN) dMetroBPM = METROMIN; wait(DEBOUNCE); // debounce time. __enable_irq(); // safe by now. } /*----------------------------------------------//----------------------------*/ void ISR_left_falling(void) // ignore rising after falling edge. { __disable_irq(); // anti-bounce. wait(DEBOUNCE); // debounce time. __enable_irq(); // safe by now. } /*----------------------------------------------//----------------------------*/ void ISR_right_rising(void) // decrease BPM. { __disable_irq(); // anti-bounce. dMetroBPM--; // decrease BPM. // saturate metronome BPM. if (dMetroBPM > METROMAX) dMetroBPM = METROMAX; if (dMetroBPM < METROMIN) dMetroBPM = METROMIN; wait(DEBOUNCE); // debounce time. __enable_irq(); // safe by now. } /*----------------------------------------------//----------------------------*/ void ISR_right_falling(void) // ignore rising after falling edge. { __disable_irq(); // anti-bounce. wait(DEBOUNCE); // debounce time. __enable_irq(); // safe by now. } /*----------------------------------------------//----------------------------*/ void ISR_up(void) // turn off metronome. { cMetronomeOn = 0; } /*----------------------------------------------//----------------------------*/ void ISR_down(void) // metronome on with timeout. { cMetronomeOn = 1; timeoutMetronome.detach(); timeoutMetronome.attach(&turn_off_metronome,METROTIME); } /*----------------------------------------------//----------------------------*/ void ISR_center(void) // set BPM = 60. { dMetroBPM = 60; tickerMetronome.detach(); // change BPM immediately. tickerMetronome.attach(&interrupt_service_M,fMetroDelay); } /*----------------------------------------------//----------------------------*/ void lcd_display(void) // display metronome info. { lcd.cls(); // clear display. LCD1; // line 1. if (cMetronomeOn) lcd.printf(" metronome ON"); else lcd.printf(" metronome OFF"); LCD2; // line 2. if (dMetroBPM == METROMIN) // BPM, with saturation notification. lcd.printf(" %5.2d BPM minimum",dMetroBPM); else if (dMetroBPM == METROMAX) lcd.printf(" %5.2d BPM maximum",dMetroBPM); else lcd.printf(" %5.2d BPM",dMetroBPM); LCD3; // line 3. 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) // turn off metronome. { cMetronomeOn = 0; } /*----------------------------------------------//----------------------------*/ void led3_off(void) {led3 = 0;} // turn off the LED. /*----------------------------------------------//----------------------------*/ void led3_on( void) {led3 = 1;} // turn on the led. /*----------------------------------------------//----------------------------*/