charles young / Mbed 2 deprecated GEO_COUNTER_L432KC

Dependencies:   mbed

Fork of GEO_COUNTER_L432KC by Geo Electronics "Geo Counter"

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers main.cpp Source File

main.cpp

00001 //  GEO COUNTER V1 firmware
00002 //  This FW provides a basic operation of GEO-COUNTER
00003 //
00004 //  Latest review: August 27, 2018 - Walter Trovo
00005 //
00006 //  Sep 13, 2018: Charles Young: CNT1 and CNT2 smooth
00007 //  Sep  9, 2018: Charles Young: CNT1 and CNT2 accurate except for jumping up
00008 //  Sep  6, 2018: Charles Young: Functioning mode selection - modes partially implemented
00009 //  Sep  5, 2018: Charles Young: Created LED7segDisplay class
00010 //  Sep  5, 2018: Charles Young: Still developing mode selection.  LEDs turn off
00011 //                when not in mode selection.  Pressing once enters mode selection.
00012 //                Pressing again enters submode.  Temporarily the rotary switch
00013 //                adjusts the display brightness.  This is just for testing.
00014 //  Sep  4, 2018: Charles Young: Created RotarySwitch class to manage mode selection
00015 //  Feb 14, 2018: initial release aimed to test the counters, the serial port
00016 //                the PWM output and the MAX7219 operation.
00017 //  Feb 15, 2018: Removed MAX7219 libray (replaced with custom routine). 
00018 //                Added 74HC595 routine. Added beep. Added Gate_write
00019 //
00020 
00021 
00022 // this block includes key libraries
00023 #include <string>       // strings management
00024 #include "RotarySwitch.hpp"
00025 #include "LED7segDisplay.hpp"
00026 
00027 // Everything associated with the rotary switch and the associated LEDs
00028 // is hidden in this class.
00029 RotarySwitch ModeSwitch;
00030 LED7segDisplay DigitsDisplay;
00031 
00032 enum Modes {
00033    CNT1,
00034    CNT2,
00035    PROSPECT,
00036    NULL1,
00037    NULL2,
00038    VOLTS,
00039    VOLUME,
00040    DIM,
00041    NumberOfModes
00042 };
00043 uint8_t currentMode          = CNT1;
00044 uint8_t currentModeToDisplay = CNT1;
00045 
00046 // LED on processor board
00047 DigitalOut led1(LED1);
00048 
00049 // definitions of peripherals and devices
00050 
00051 I2C     i2c(D4, D5);             // I2C port
00052 Ticker  SecTenth_Beat;           // .1 second ticker
00053 Ticker  Sec_Beat;                // 1 second ticker
00054 
00055 Serial  PC(USBTX, USBRX);        // Virtual COM via USB (PC connection)
00056 Serial  GPS(D1, D0);             // Serial port for GPS module
00057 
00058 // Global variables
00059 time_t      seconds;       // Real-Time Clock (RTC) timestamp
00060 unsigned int value = 0;    // displayed value on the 6-digits of the display
00061 
00062 uint32_t Count1, Count2;    // pulse counters (32-bit)
00063 #define  CountAvg 4
00064 uint32_t Count1Avg[CountAvg], Count2Avg[CountAvg];    // pulse counters (32-bit)
00065 uint8_t  CountAvgIndex = 0;
00066 uint32_t Count1Save;
00067 uint32_t Count2Save;
00068 
00069 uint32_t    TickerPeriod = 100000;
00070 uint32_t    TickerPeriodCount = 0;
00071 const uint32_t TickerPeriodsPerSecond = 1000000/TickerPeriod;
00072 const uint32_t TickerTicksPerSecond   = TickerPeriod*TickerPeriodsPerSecond;
00073 
00074 char        Text[40]="";   // used to send messages over the serial port
00075 uint8_t     Disp_mode = 0x01, Disp_unit = 0xA0;   // status of 1st row and 2nd rows of LEDs
00076 bool        Stopped = 0;        // status of counting activity
00077 bool        StartStopPressed = 0;// status of counting activity
00078 double      ADC_val;    // used to read ADC value
00079 float       direction = 0;
00080 
00081 #define maxVolume 10
00082 uint8_t     volume = maxVolume;
00083 
00084 // ----- Prototypes of routines (defined below the main) -------------------
00085 void UpdateInput(void);  // periodically called by the ticker
00086 void UpdateOutput(void);  // periodically called by the ticker
00087 void UpdateIO(void);  // periodically called by the ticker
00088 void Count1_up(void);  // called every time an edge is detected on TRIG1 pin
00089 void Count2_up(void); // called every time an edge is detected on TRIG2 pin
00090 void Beep(void);    // used to generate a short beep (buzzer)
00091 
00092 //==============================================================================
00093 //==============================================================================
00094 
00095 int main() 
00096 {
00097     
00098    PC.baud(115200);        // set baud-rate of virtual COM port (PC connection)
00099    PC.printf("\nGEO COUNTER V1 2108");
00100    PC.printf(__DATE__);
00101    PC.printf("  ");
00102    PC.printf(__TIME__);
00103     
00104    GPS.baud(9600); // set the baud-rate of the serial port dedicated to the GPS
00105     
00106    CS1 = 1;    // presets CS of MAX7219
00107    CS2 = 1;    // preset CS of 74HC595
00108 
00109    DigitsDisplay.Display_6D_write(0x543210);
00110    DigitsDisplay.Display_2D_write(0);
00111 
00112    // RTC is supposed to lose time at power down (no backup battery)
00113    // An initialization is performed anyway 
00114    set_time(0); // Set time
00115     
00116    PWM.period_ms(3);    // set the PWM period
00117    PWM.write(0.8);      // set the PWM duty-cycle
00118     
00119    Beep(); // initial beep    
00120     
00121    // set the 1 sec ticker to periodically call the Update() routine
00122    // NOTE: this is also the 1-sec time base for counters. A better approach
00123    // would replace the ticker with an interrupt from the RTC (to be implemented)
00124    SecTenth_Beat.attach_us(&UpdateIO,  TickerPeriod);
00125    //RTC::attach(&Update, RTC::Second);
00126    //RTC::detach(RTC::Second);  
00127 
00128    TRIG1.fall(&Count1_up);     
00129    TRIG2.fall(&Count2_up);         
00130 
00131    for (uint8_t i=0;i<CountAvg;i++)
00132    {
00133       Count1Avg[i] = 0;
00134       Count2Avg[i] = 0;
00135    }
00136 
00137    // main loop does nothing as all activities are interrupt driven    
00138    while(1) 
00139    {
00140       // somehow this makes it worse
00141       // // Manage user I/O outside Ticker interrupt for accuracy
00142       // wait_us(TickerPeriod);
00143       // if (TickerPeriodCount == 0)
00144       //    UpdateOutput();
00145       // UpdateInput();
00146    }
00147 }
00148 
00149 
00150 //-------- END OF MAIN --------------
00151 //==============================================================================
00152 
00153 // Definition of routines
00154 
00155 //---------------------------------------------------------------------------
00156 // Update values to be displayed  
00157 void logToPC()
00158 {               
00159    PC.printf("\nADC: %.02f", ADC_val); 
00160    PC.printf(Stopped ? " stopped" : " started");
00161    // Timestamp to PC (debug)
00162    seconds = time(NULL);   // get current time 
00163    strftime(Text, 50, "%H:%M:%S", localtime(&seconds));
00164    PC.printf(" RTC: %s, CNT1: %7d CNT2: %7d",Text, Count1, Count2);
00165    PC.printf(" wheel %f", direction);
00166 }
00167 
00168 void UpdateIO()   
00169 {
00170    if (++TickerPeriodCount >= TickerPeriodsPerSecond)
00171    {
00172       // Capture the counts early so they will be more accurate
00173       Count1Avg[CountAvgIndex] = Count1;
00174       Count2Avg[CountAvgIndex] = Count2;
00175       CountAvgIndex = ++CountAvgIndex % CountAvg;
00176 
00177       // smooth counts while accounting for small roundoff error
00178       uint32_t Count1Sum = 1, Count2Sum = 1;
00179       for (uint8_t i=0;i<CountAvg;i++)
00180       {
00181          Count1Sum += Count1Avg[i];
00182          Count2Sum += Count2Avg[i];
00183       }
00184       Count1Save = Count1Sum / CountAvg;
00185       Count2Save = Count2Sum / CountAvg;
00186       Count1 = 0;
00187       Count2 = 0;
00188 
00189       TickerPeriodCount = 0;
00190 
00191       UpdateOutput();
00192    }
00193    UpdateInput();
00194 }
00195 
00196 void UpdateOutput()
00197 {
00198    if(Stopped)
00199    {    
00200       // disable interrupts on TRIG1 and TRIG2
00201       TRIG1.fall(NULL);      
00202       TRIG2.fall(NULL); 
00203    }
00204 
00205    // This must be called periodically to update the LEDs
00206    ModeSwitch.UpdateOutput();
00207       
00208    switch (currentModeToDisplay) {
00209       case CNT1:
00210          DigitsDisplay.Display_6D_write(Count1Save);
00211          DigitsDisplay.Display_2D_Blank();
00212          break;
00213       case CNT2:
00214          DigitsDisplay.Display_6D_write(Count2Save);
00215          DigitsDisplay.Display_2D_Blank();
00216          break;
00217       case PROSPECT:
00218          if (Count1Save)
00219             DigitsDisplay.Display_6D_write(Count1Save);
00220          else
00221             DigitsDisplay.Display_6D_write(Count2Save);
00222          DigitsDisplay.Display_2D_Blank();
00223          break;
00224       case NULL1:
00225          DigitsDisplay.Display_6D_write(0);
00226          DigitsDisplay.Display_2D_Blank();
00227          break;
00228       case NULL2:
00229          DigitsDisplay.Display_6D_write(0);
00230          DigitsDisplay.Display_2D_Blank();
00231          break;
00232       case VOLTS:
00233          DigitsDisplay.Display_6D_write(0);
00234          DigitsDisplay.Display_2D_Blank();
00235          break;
00236       case VOLUME:
00237       case DIM:
00238       default:
00239          break;
00240    }
00241 }
00242 
00243 void UpdateInput()   
00244 {
00245    // This must be called periodically to monitor switch input
00246    direction   = ModeSwitch.UpdateInput();
00247    currentMode = ModeSwitch.GetPosition();
00248         
00249    switch (currentMode) {
00250       case CNT1:
00251       case CNT2:
00252          currentModeToDisplay = currentMode;
00253 
00254          if (direction > 0)
00255          {
00256          }
00257          else
00258             if (direction < 0)
00259             {
00260             }
00261          break;
00262       case PROSPECT:
00263       case VOLTS:
00264          currentModeToDisplay = currentMode;
00265          break;
00266       case NULL1:
00267       case NULL2:
00268          break;
00269       case VOLUME:
00270          if (   (direction > 0)
00271              && (volume < maxVolume))
00272             volume++;
00273          else
00274             if (   (direction < 0)
00275                 && (volume > 0))
00276                volume--;
00277 
00278          DigitsDisplay.Display_2D_write(volume);
00279          break;
00280       case DIM:
00281          if (direction > 0)
00282             DigitsDisplay.Display_brightness_up();
00283          else
00284             if (direction < 0)
00285                DigitsDisplay.Display_brightness_down();
00286 
00287          DigitsDisplay.Display_2D_write(DigitsDisplay.GetBrightness());
00288          break;
00289       default:
00290          break;
00291    }
00292 
00293    // ADC_val = KEYB.read();  // read voltage from keyboard
00294    // if (   (ADC_val<0.1)    // START/STOP pushbutton pressed
00295    //     && (!StartStopPressed))
00296    // {
00297    //    StartStopPressed = true;
00298    //    if (Stopped)
00299    //    {
00300    //       // Enable interrupts on rising edge of digital inputs TRIG1 & TRIG2
00301    //       TRIG1.rise(&Count1_up);     
00302    //       TRIG2.rise(&Count2_up);         
00303    //    }
00304    //    Stopped=!Stopped;           // toggle status
00305    // }
00306    // else
00307    //    StartStopPressed = false;
00308     
00309    // if((ADC_val>0.6)&&(ADC_val<0.7))    // CLEAR pushbutton pressed
00310    // { 
00311    //    Count1 = 0; // clear counters     
00312    //    Count2 = 0;              
00313    // }
00314    //logToPC();
00315    return;
00316 }
00317 
00318 //---------------------------------------------------------------------------
00319 // Increment CNT1 every time a rising edge is detected on TRIG1 (interrupt)
00320 
00321 void Count1_up(void)
00322 {                       
00323    //Beep();
00324    Count1++;                        
00325    return; 
00326 }
00327 
00328 //---------------------------------------------------------------------------
00329 // Increment CNT1 every time a rising edge is detected on TRIG2 (interrupt)
00330 
00331 void Count2_up(void)
00332 {                      
00333    //Beep();
00334    Count2++;                        
00335    return; 
00336 }
00337 
00338 
00339 //---------------------------------------------------------------------------
00340 //Generates a short beep via BUZZ
00341 
00342 void Beep(void)       
00343 {                       
00344    BUZZ = 1;         // turn-on the buzzer
00345    wait_us(100);     // wait
00346    BUZZ = 0;         // turn-off the buzzer   
00347    return; 
00348 }
00349 
00350 //-------- END OF FILE --------------
00351 //==============================================================================