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-13
- Revision:
- 76:6b0d47c3027c
- Parent:
- 75:5af098188ebf
- Child:
- 77:87aac94b235a
File content as of revision 76:6b0d47c3027c:
// GEO COUNTER V1 firmware // This FW provides a basic operation of GEO-COUNTER // // Latest review: August 27, 2018 - Walter Trovo // // Sep 13, 2018: Charles Young: CNT1 and CNT2 smooth // Sep 9, 2018: Charles Young: CNT1 and CNT2 accurate except for jumping up // 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) #define CountAvg 4 uint32_t Count1Avg[CountAvg], Count2Avg[CountAvg]; // pulse counters (32-bit) uint8_t CountAvgIndex = 0; uint32_t Count1Save; uint32_t Count2Save; uint32_t TickerPeriod = 100000; uint32_t TickerPeriodCount = 0; const uint32_t TickerPeriodsPerSecond = 1000000/TickerPeriod; const uint32_t TickerTicksPerSecond = TickerPeriod*TickerPeriodsPerSecond; 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 lose 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); TRIG1.rise(&Count1_up); TRIG2.rise(&Count2_up); for (uint8_t i=0;i<CountAvg;i++) { Count1Avg[i] = 0; Count2Avg[i] = 0; } // main loop does nothing as all activities are interrupt driven while(1) { // somehow this makes it worse // // Manage user I/O outside Ticker interrupt for accuracy // wait_us(TickerPeriod); // if (TickerPeriodCount == 0) // UpdateOutput(); // UpdateInput(); } } //-------- 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) { // Capture the counts early so they will be more accurate Count1Avg[CountAvgIndex] = Count1; Count2Avg[CountAvgIndex] = Count2; CountAvgIndex = ++CountAvgIndex % CountAvg; // smooth counts while accounting for small roundoff error uint32_t Count1Sum = CountAvg-1, Count2Sum = CountAvg-1; for (uint8_t i=0;i<CountAvg;i++) { Count1Sum += Count1Avg[i]; Count2Sum += Count2Avg[i]; } Count1Save = Count1Sum / CountAvg; Count2Save = Count2Sum / CountAvg; Count1 = 0; Count2 = 0; TickerPeriodCount = 0; UpdateOutput(); } UpdateInput(); } void UpdateOutput() { 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) { } else if (direction < 0) { } 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 -------------- //==============================================================================