Charles Young's development fork. Going forward I only want to push mature code to main repository.

Dependencies:   mbed

Fork of GEO_COUNTER_L432KC by Geo Electronics "Geo Counter"

Revision:
16:b2e77eb76ab4
Parent:
15:808e98afe32b
Child:
17:6eed17197004
--- a/main.cpp	Mon Sep 03 16:27:05 2018 +0000
+++ b/main.cpp	Mon Sep 03 10:12:02 2018 -0700
@@ -68,9 +68,19 @@
 // us which direction the wheel is moving (right or left) so that we can
 // use it to select the current mode.
 QEI     Wheel(D12, D11, NC, 16);    // Quadrature encoder
-int WheelCurrentState = 0;
 int WheelCurrent = 0;
 int WheelPrevious = 0;
+bool QEPBpressed = false; // only react to button when pressed
+enum WheelState {
+   WHEEL_INACTIVE       = 0,
+   WHEEL_MODE_SELECT    = 1,
+   WHEEL_SUBMODE_SELECT = 2
+};
+enum WheelStateEvent {
+   WHEEL_Pressed = 0,
+   WHEEL_Timeout = 1
+};
+WheelState currentWheelState;
 
 I2C     i2c(D4, D5);                // I2C port
 Ticker  Sec_Beat;                // 1 second ticker
@@ -91,7 +101,8 @@
 double      ADC_val;    // used to read ADC value
 
 // ----- Prototypes of routines (defined below the main) -------------------
-void Update(void);  // periodically called by the ticker
+void UpdateInput(void);  // periodically called by the ticker
+void UpdateOutput(void);  // periodically called by the ticker
 void Count1_up(void);  // called every time an edge is detected on TRIG1 pin
 void Count2_up(void); // called every time an edge is detected on TRIG2 pin
 void Beep(void);    // used to generate a short beep (buzzer)
@@ -136,7 +147,8 @@
     // set the 1 sec ticker to periodically call the Update() routine
     // NOTE: this is also the 1-sec time base for counters. A better approach
     // would replace the ticker with an interrupt from the RTC (to be implemented)
-    Sec_Beat.attach_us(&Update, 100000);  
+    Sec_Beat.attach_us(&UpdateInput,  100000);  
+    Sec_Beat.attach_us(&UpdateOutput, 1000000);  
     //RTC::attach(&Update, RTC::Second);
     //RTC::detach(RTC::Second);  
   
@@ -166,75 +178,123 @@
    PC.printf(" wheel %d %d", WheelCurrent, QEPB.read());
 }
 
-void Update()   
+void UpdateOutput()   
 {               
-    LEDs_write(LED_statuses[LED_status_index]);
+   if(Stopped)
+   {    
+      // disable interrupts on TRIG1 and TRIG2
+        
+      TRIG1.rise(NULL);      
+      TRIG2.rise(NULL); 
+        
+      // show zero gate time   
+      gate = 0;                   
+      Display_2D_write(gate);
+        
+      // show selected content on main display
+      value = (int)(Count1/TGATE);
+      Display_6D_write(value);    // refresh the main display              
+   }
+    
+   else
+   {
+      // Enable interrupts on rising edge of digital inputs TRIG1 & TRIG2
+      TRIG1.rise(&Count1_up);     
+      TRIG2.rise(&Count2_up);         
+        
+      if(gate==0) // show the counter value at the end of the gate time
+      {
+         value = (int)(Count1/TGATE);
+                
+         Display_6D_write(value);    // refresh the main display 
         
-    ADC_val = KEYB.read();  // read voltage from keyboard
-    if (   (ADC_val<0.1)    // START/STOP pushbutton pressed
-        && (!StartStopPressed))
-    {
-        StartStopPressed = true;
-        Stopped=!Stopped;           // toggle status
-    }
-    else
-        StartStopPressed = false;
+         Count1 = 0;     // clear both counters
+         Count2 = 0;
+         gate = TGATE;// and reload the gate time
+
+      }
+
+      Display_2D_write(gate);     // show gate time countdown 
+      gate--;
+   }
+}
+
+void UpdateInput()   
+{               
+   LEDs_write(LED_statuses[LED_status_index]);
+        
+   ADC_val = KEYB.read();  // read voltage from keyboard
+   if (   (ADC_val<0.1)    // START/STOP pushbutton pressed
+       && (!StartStopPressed))
+   {
+      StartStopPressed = true;
+      Stopped=!Stopped;           // toggle status
+   }
+   else
+      StartStopPressed = false;
     
-    if((ADC_val>0.6)&&(ADC_val<0.7))    // CLEAR pushbutton pressed
-    { 
-        Count1 = 0; // clear counters     
-        Count2 = 0;              
+   if((ADC_val>0.6)&&(ADC_val<0.7))    // CLEAR pushbutton pressed
+   { 
+      Count1 = 0; // clear counters     
+      Count2 = 0;              
    }
 
-    if(Stopped)
-    {    
-        // disable interrupts on TRIG1 and TRIG2
-        
-        TRIG1.rise(NULL);      
-        TRIG2.rise(NULL); 
-        
-        // show zero gate time   
-        gate = 0;                   
-        Display_2D_write(gate);
-        
-        // show selected content on main display
-        value = (int)(Count1/TGATE);
-        Display_6D_write(value);    // refresh the main display              
-    }
+   if (   (WHEEL_MODE_SELECT    == currentWheelState)
+       || (WHEEL_SUBMODE_SELECT == currentWheelState))
+   {
+      WheelCurrent      = int(Wheel.getPulses());
+      if (WheelCurrent > WheelPrevious)
+         LED_status_index = ++LED_status_index % sizeof(LED_statuses);
+      else
+         if (WheelCurrent < WheelPrevious)
+            LED_status_index = --LED_status_index % sizeof(LED_statuses);
+      WheelPrevious = WheelCurrent;
+   }
+
+   // detect when wheel button is pressed but wait until it is released
+   // before doing anything
+   bool QEPBbutton = QEPB.read();
+   if (   (QEPBbutton)
+       && (!QEPBpressed))
+   {
+      QEPBpressed = true;
+   }
+   else
+      if (   (!QEPBbutton)
+          && (QEPBpressed))
+      {
+         QEPBpressed = false;
+         WheelStateMachine(WHEEL_Pressed);
+      }
     
-    else
-    {
-        // Enable interrupts on rising edge of digital inputs TRIG1 & TRIG2
-        TRIG1.rise(&Count1_up);     
-        TRIG2.rise(&Count2_up);         
-        
-        if(gate==0) // show the counter value at the end of the gate time
-        {
-            value = (int)(Count1/TGATE);
-                
-            Display_6D_write(value);    // refresh the main display 
-        
-            Count1 = 0;     // clear both counters
-            Count2 = 0;
-            gate = TGATE;// and reload the gate time
+   logToPC();
+   return;
+}
 
-        }
-
-        Display_2D_write(gate);     // show gate time countdown 
-        gate--;
-    }
-        
-    WheelCurrent      = int(Wheel.getPulses());
-    WheelCurrentState = int(Wheel.getCurrentState());
-    if (WheelCurrent > WheelPrevious)
-       LED_status_index = ++LED_status_index % sizeof(LED_statuses);
-    else
-       if (WheelCurrent < WheelPrevious)
-          LED_status_index = --LED_status_index % sizeof(LED_statuses);
-    WheelPrevious = WheelCurrent;
-    
-    logToPC();
-    return;
+void WheelStateMachine(WheelStateEvent event)
+{                       
+   switch currentWheelState
+   {
+      WHEEL_INACTIVE:
+      if (WHEEL_Pressed == event)
+         currentWheelState = WHEEL_MODE_SELECT;
+      break;
+      WHEEL_MODE_SELECT:
+      if (WHEEL_Pressed == event)
+         currentWheelState = WHEEL_SUBMODE_SELECT;
+      else
+         if (WHEEL_Timeout == event)
+            currentWheelState = WHEEL_INACTIVE;
+      break;
+      WHEEL_SUBMODE_SELECT:
+      if (WHEEL_Pressed == event)
+         currentWheelState = WHEEL_MODE_SELECT;
+      else
+         if (WHEEL_Timeout == event)
+            currentWheelState = WHEEL_INACTIVE;
+      break;
+      default:
+   }
 }
 
 //---------------------------------------------------------------------------