Charles Young's development fork. Going forward I only want to push mature code to main repository.
Fork of GEO_COUNTER_L432KC by
main.cpp
- Committer:
- Charles David Young
- Date:
- 2018-09-08
- Revision:
- 59:f96a503bd228
- Parent:
- 58:d15adb224e5a
- Child:
- 60:6ae1a2390600
File content as of revision 59:f96a503bd228:
// GEO COUNTER V1 firmware // This FW provides a basic operation of GEO-COUNTER // // Latest review: August 27, 2018 - Walter Trovo // // Sep 6, 2018: Charles Young: Functioning mode selection - modes partially implemented // Sep 5, 2018: Charles Young: Created LED7segDisplay class // Sep 5, 2018: Charles Young: Still developing mode selection. LEDs turn off // when not in mode selection. Pressing once enters mode selection. // Pressing again enters submode. Temporarily the rotary switch // adjusts the display brightness. This is just for testing. // Sep 4, 2018: Charles Young: Created RotarySwitch class to manage mode selection // Feb 14, 2018: initial release aimed to test the counters, the serial port // the PWM output and the MAX7219 operation. // Feb 15, 2018: Removed MAX7219 libray (replaced with custom routine). // Added 74HC595 routine. Added beep. Added Gate_write // // this block includes key libraries #include <string> // strings management #include "RotarySwitch.hpp" #include "LED7segDisplay.hpp" // Everything associated with the rotary switch and the associated LEDs // is hidden in this class. RotarySwitch ModeSwitch; LED7segDisplay DigitsDisplay; enum Modes { CNT1, CNT2, PROSPECT, NULL1, NULL2, VOLTS, VOLUME, DIM, NumberOfModes }; uint8_t currentMode = CNT1; uint8_t currentModeToDisplay = CNT1; // LED on processor board DigitalOut led1(LED1); // definitions of peripherals and devices I2C i2c(D4, D5); // I2C port Ticker SecTenth_Beat; // .1 second ticker Ticker Sec_Beat; // 1 second ticker Serial PC(USBTX, USBRX); // Virtual COM via USB (PC connection) Serial GPS(D1, D0); // Serial port for GPS module // Global variables time_t seconds; // Real-Time Clock (RTC) timestamp unsigned int value = 0; // displayed value on the 6-digits of the display uint32_t Count1, Count2; // pulse counters (32-bit) int32_t TickerCorrection = 0; uint32_t TickerPeriod = 100000; uint32_t TickerPeriodCount = 0; const uint32_t TickerPeriodsPerSecond = 1000000/TickerPeriod; const int16_t TickerCorrectionMax = 99; const int16_t TickerCorrectionMin = -99; char Text[40]=""; // used to send messages over the serial port uint8_t Disp_mode = 0x01, Disp_unit = 0xA0; // status of 1st row and 2nd rows of LEDs bool Stopped = 0; // status of counting activity bool StartStopPressed = 0;// status of counting activity double ADC_val; // used to read ADC value float direction = 0; #define maxVolume 10 uint8_t volume = maxVolume; // ----- Prototypes of routines (defined below the main) ------------------- void UpdateInput(void); // periodically called by the ticker void UpdateOutput(void); // periodically called by the ticker void UpdateIO(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) //============================================================================== //============================================================================== int main() { PC.baud(115200); // set baud-rate of virtual COM port (PC connection) PC.printf("\nGEO COUNTER V1 2108"); PC.printf(__DATE__); PC.printf(" "); PC.printf(__TIME__); GPS.baud(9600); // set the baud-rate of the serial port dedicated to the GPS CS1 = 1; // presets CS of MAX7219 CS2 = 1; // preset CS of 74HC595 DigitsDisplay.Display_6D_write(0x543210); DigitsDisplay.Display_2D_write(0); // RTC is supposed to be loose time at power down (no backup battery) // An initialization is performed anyway set_time(0); // Set time PWM.period_ms(3); // set the PWM period PWM.write(0.8); // set the PWM duty-cycle Beep(); // initial beep // 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) SecTenth_Beat.attach_us(&UpdateIO, TickerPeriod); //RTC::attach(&Update, RTC::Second); //RTC::detach(RTC::Second); // main loop does nothing as all activities are interrupt driven while(1) { // dance (or drink a beer) } } //-------- END OF MAIN -------------- //============================================================================== // Definition of routines //--------------------------------------------------------------------------- // Update values to be displayed void logToPC() { PC.printf("\nADC: %.02f", ADC_val); PC.printf(Stopped ? " stopped" : " started"); // Timestamp to PC (debug) seconds = time(NULL); // get current time strftime(Text, 50, "%H:%M:%S", localtime(&seconds)); PC.printf(" RTC: %s, CNT1: %7d CNT2: %7d",Text, Count1, Count2); PC.printf(" wheel %f", direction); } void UpdateIO() { if (++TickerPeriodCount >= TickerPeriodsPerSecond) { TickerPeriodCount = 0; UpdateOutput(); } UpdateInput(); } void UpdateOutput() { // Capture the counts early so they will be more accurate uint32_t Count1Save = Count1; uint32_t Count2Save = Count2; Count1 = 0; Count2 = 0; if(Stopped) { // disable interrupts on TRIG1 and TRIG2 TRIG1.rise(NULL); TRIG2.rise(NULL); } // This must be called periodically to update the LEDs ModeSwitch.UpdateOutput(); switch (currentModeToDisplay) { case CNT1: DigitsDisplay.Display_6D_write(Count1Save); DigitsDisplay.Display_2D_Blank(); break; case CNT2: DigitsDisplay.Display_6D_write(Count2Save); DigitsDisplay.Display_2D_Blank(); break; case PROSPECT: if (Count1Save) DigitsDisplay.Display_6D_write(Count1Save); else DigitsDisplay.Display_6D_write(Count2Save); DigitsDisplay.Display_2D_Blank(); break; case NULL1: DigitsDisplay.Display_6D_write(0); DigitsDisplay.Display_2D_Blank(); break; case NULL2: DigitsDisplay.Display_6D_write(0); DigitsDisplay.Display_2D_Blank(); break; case VOLTS: DigitsDisplay.Display_6D_write(0); DigitsDisplay.Display_2D_Blank(); break; case VOLUME: case DIM: default: break; } } void UpdateInput() { // This must be called periodically to monitor switch input direction = ModeSwitch.UpdateInput(); currentMode = ModeSwitch.GetPosition(); switch (currentMode) { case CNT1: case CNT2: currentModeToDisplay = currentMode; if ( (direction > 0) && (TickerCorrection < TickerCorrectionMax)) { TickerCorrection++; Sec_Beat.attach_us(&UpdateOutput, 1000000 + 1000*TickerCorrection); DigitsDisplay.Display_2D_write(TickerCorrection); } else if ( (direction < 0) && (TickerCorrection > TickerCorrectionMin)) { TickerCorrection--; Sec_Beat.attach_us(&UpdateOutput, 1000000 + 1000*TickerCorrection); DigitsDisplay.Display_2D_write(TickerCorrection); } break; case PROSPECT: case VOLTS: currentModeToDisplay = currentMode; break; case NULL1: case NULL2: break; case VOLUME: if ( (direction > 0) && (volume < maxVolume)) volume++; else if ( (direction < 0) && (volume > 0)) volume--; DigitsDisplay.Display_2D_write(volume); break; case DIM: if (direction > 0) DigitsDisplay.Display_brightness_up(); else if (direction < 0) DigitsDisplay.Display_brightness_down(); DigitsDisplay.Display_2D_write(DigitsDisplay.GetBrightness()); break; default: break; } ADC_val = KEYB.read(); // read voltage from keyboard if ( (ADC_val<0.1) // START/STOP pushbutton pressed && (!StartStopPressed)) { StartStopPressed = true; if (Stopped) { // Enable interrupts on rising edge of digital inputs TRIG1 & TRIG2 TRIG1.rise(&Count1_up); TRIG2.rise(&Count2_up); } 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; } //logToPC(); return; } //--------------------------------------------------------------------------- // Increment CNT1 every time a rising edge is detected on TRIG1 (interrupt) void Count1_up(void) { //Beep(); Count1++; return; } //--------------------------------------------------------------------------- // Increment CNT1 every time a rising edge is detected on TRIG2 (interrupt) void Count2_up(void) { //Beep(); Count2++; return; } //--------------------------------------------------------------------------- //Generates a short beep via BUZZ void Beep(void) { BUZZ = 1; // turn-on the buzzer wait_us(100); // wait BUZZ = 0; // turn-off the buzzer return; } //-------- END OF FILE -------------- //==============================================================================