RTOS homework 4

Dependencies:   C12832_lcd mbed

Revision:
0:1013288b8e43
Child:
1:5f41e2df0e85
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/main.cpp	Sun Aug 18 14:45:13 2013 +0000
@@ -0,0 +1,197 @@
+/*----------------------------------------------//------------------------------
+    student   : m-moore
+    class     : rtos
+    directory : RTOS_HW_03 part 1
+    file      : main.cpp
+----description---------------------------------//------------------------------
+    Joystick-Controlled Metronome
+    
+    features:
+    1. post-initialization functionality all timer-driven.
+    2. IRSs contain no blocking functions.
+    3. LED shows the metronome beat.
+    4. metronome speed controlled with up/down joystick.
+    5. rate-of-speed-change depends on how long the up/down has been active.
+    6. Beat-Per-Minute (BPM) shown on LCD display.
+    
+    controls:
+    1. joystick-up     - increase metronome rate.
+    2. joystick-down   - decrease metronome rate.
+    3. joystick-center - set metronome to 60BPM.
+    
+    notes:
+    
+    testing:
+    1. confirm ease of being able to adjust one BPM rate with joystick up/down.
+    2. confirm three joystick up/down change rates, if keeping the stick pressed.
+    3. confirm max/min BPS saturation & display.
+    4. confirm joystick up/down control works to change display & LED BPM.
+    5. confirm joystick center-press sets rate to 60BPM immediately.
+    6. confirm long-test does not result in a crash.
+       -> all items confirmed.
+
+-----includes-----------------------------------//----------------------------*/
+    #include "mbed.h"                           // mbed class.
+    #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 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.
+//--global_definitions--------------------------//------------------------------
+//--global_variables----------------------------//------------------------------ 
+    float fMetroDelay;                          // time between ticks, in seconds.
+    float fMetroDuty;                           // duration of metro high, in seconds.
+    int   dMetroBPM;                            // master parameter.
+    long  lUpDownHowMany;                       // count how long up/down joystick pressed.
+//--global_instances----------------------------//------------------------------ 
+    C12832_LCD  lcd;                            // LCD object.
+    
+    DigitalIn   joyStickUp    (p15);            // 1 if joystick up     pressed.
+    DigitalIn   joyStickDown  (p12);            // 1 if joystick down   pressed.
+    DigitalIn   joyStickCenter(p14);            // 1 if joystick middle pressed.
+
+    DigitalOut  led3(LED1);                     // leftmost LED.
+    
+    Ticker      tickerMetronome;                // blinking LED.
+    Ticker      tickerJoystickUD;               // joystick up/down sample.
+    Ticker      tickerLCD;                      // display ticker.
+    Timeout     timeoutDutyCycle;               // LED duty cycle delay.
+//-------prototypes-----------------------------//------------------------------
+    void initialization();                      // initialize settings.
+    void lcd_display();                         // display on LCD.
+    void interrupt_service_M();                 // metronome tick.
+    void interrupt_service_UD();                // joystick up/down sample.                
+    void led3_off();                            // attachable LED control.
+    void led3_on();                             // attachable LED control.
+//==============================================//==============================
+    int main(void) 
+    {
+      initialization();                         // initialize settings.
+      
+                                                // metronome ticker.
+      tickerMetronome.attach(&interrupt_service_M,fMetroDelay);
+      
+                                                // LCD ticker.
+      tickerLCD.attach(&lcd_display,LCDSAMPLERATE);       
+      
+                                                // up/down joystick sampling.
+      tickerJoystickUD.attach(&interrupt_service_UD,UDSAMPLERATE);
+      
+      while (1)                                 // main loop.
+      {
+        wait(10.0);                             // it's all interrupt-driven.
+      } 
+    }       
+/*----------------------------------------------//----------------------------*/
+    void initialization(void)                   // program initializations.
+    {
+      dMetroBPM      = 60;                      // initialize to 60BPM.      
+      fMetroDelay    = 60.0 / (float) (dMetroBPM);
+      fMetroDuty     = PULSELENGTH;             // initialize LED on-duration.
+      lUpDownHowMany = 0;
+    }
+/*----------------------------------------------//----------------------------*/
+    void lcd_display(void)                      // display metronome info.
+    {
+      lcd.cls();                                // clear display.
+      
+      LCD1;                                     // line 1.
+      lcd.printf("  METRONOME");
+
+      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 3 PART 1");
+    }
+/*----------------------------------------------//----------------------------*/
+//  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.
+    {        
+      tickerMetronome.detach();                 // only one attachment.  
+      tickerMetronome.attach(&interrupt_service_M,fMetroDelay);      
+      led3 = 1;
+      timeoutDutyCycle.attach(&led3_off,fMetroDuty);
+    }
+/*----------------------------------------------//----------------------------*/
+//  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 (joyStickUp)                           // 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 (joyStickDown)                         // 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 (joyStickCenter)
+      {
+        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.
+/*----------------------------------------------//----------------------------*/
\ No newline at end of file