Charles Young's development fork. Going forward I only want to push mature code to main repository.
Fork of GEO_COUNTER_L432KC by
Diff: main.cpp
- 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: + } } //---------------------------------------------------------------------------