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:
1:75827d765e34
Parent:
0:6d1742703713
Child:
2:ac0ed3d84d44
diff -r 6d1742703713 -r 75827d765e34 main.cpp
--- a/main.cpp	Tue Feb 13 13:30:08 2018 +0000
+++ b/main.cpp	Fri Feb 16 16:32:58 2018 +0000
@@ -1,42 +1,90 @@
-#include "mbed.h"
-#include <string>
-#include "max7219.h"
-#include "QEI.h"
+// GEO COUNTER V1 firmware
+//
+//  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 "mbed.h"       // global Mbed library (always needed)
+#include <string>       // strings management
+#include "QEI.h"        // Quadrature Encoder functions
+
+// definitions of fixed parameters
 
-#define TGATE   1
-#define MAX_VAL 999999
+#define DEC_MODE    0x09FF  // BCD decoding on all digits
+#define BRIGHTNESS  0x0A0F  // max brightness
+#define SCAN_LIM    0x0B07  // use all 8 digits  
+#define TURN_ON     0x0C01  // no shutdown (operating)
+#define SHUTDOWN    0x0C00  // shutdown
+#define TEST        0x0F00  // no test
+
+#define DT      1      // delay time in us for SPI emulation
+
+#define TGATE   10       // gate time (currently fixed for testing purpose)
+#define MAX_VAL 999999  // Max value managed by the 6-digits display
 
+
+#define CPM     0x01
+#define CPS     0x02
+#define PLS     0x04
+#define VOLTS   0x08
+#define CNT1    0x10
+#define CNT2    0x20
+#define HV      0x40
+#define MENU    0x80
+
+// definitions of the input/outputs (pins)
+DigitalOut  AUX   (D2);    // AUX control for GPS module
 InterruptIn TRIG1 (D3);    // Counter 1 trigger
 InterruptIn TRIG2 (D6);    // Counter 2 trigger
+DigitalIn   QEIPB (D9);    // Quadrature encoder pushbutton
 PwmOut      PWM   (D10);   // PWM output
-DigitalOut  BUZZ  (D2);    // Buzzer
-DigitalOut  AUX   (D2);    // AUX control for GPS module
-DigitalIn   QEIPB (D9);    // Quadrature encoder pushbutton
+DigitalOut  BUZZ  (D13);   // Buzzer
 
-QEI Wheel(D11, D12, NC, 16);    // Quadrature encoder
-I2C i2c(D4, D5);    // I2C port
-Ticker Sec_Beat;
-Max7219 Display(A6, A5, A4, A3); //LED diplay driver (MOSI, MISO, SCK, SS)
-Serial PC(USBTX, USBRX);    // Virtual COM via USB
-Serial GPS(D1, D0);
+AnalogIn    AIN0  (A0);    // ADC input 0 (High Voltage)
+AnalogIn    AIN1  (A1);    // ADC input 1 (aux)
+DigitalOut  CS2   (A2);    // 74HC595 RCLK (pin 12)
+DigitalOut  CS1   (A3);    // MAX7219 CS (pin 12)
+DigitalOut  SCK   (A4);    // 74HC595 SRCLK (pin 11) & MAX7219 SCK (pin 13)
+AnalogIn    KEYB  (A5);    // Keyboard input (SW2 & SW3) 
+DigitalOut  MOSI  (A6);    // 74HC595 SER (pin 14) & MAX7219 DIN (pin 1)
+DigitalIn   UN    (A7);    // Unused (in V1 PCB A5 and A7 must be connected)
+
+
+
+
+// definitions of peripherals and devices
+QEI     Wheel(D12, D11, NC, 16);    // Quadrature encoder
+I2C     i2c(D4, D5);                // I2C port
+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
-uint8_t Digit_Disp[8];
-uint16_t Stream;
-
-time_t seconds;     // RTC timestamp
+uint8_t     Disp_Digit[8]; // used to manage 8-digits through MAX7219
+uint16_t    Stream;        // used to stream out serial data to MAX7219
+time_t      seconds;       // Real-Time Clock (RTC) timestamp
+unsigned int value = 0;    // displayed value on the 6-digits of the display
+uint8_t     gate = TGATE;          // displayed value on the 2-digits display
+uint32_t    Count1, Count2;    // pulse counters (32-bit)
+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 = 1;        // status of counting activity
+double      ADC_val;    // used to read ADC value
 
-unsigned int value = 0;
-uint32_t    CNT1, CNT2;   // pulse counters
-uint8_t gate;
-char Text[40]="";
-
-// ------------------- Prototypes -----------------------
-void RefreshDisplay(void);
-void Update(void);
-void CNT1_count(void);
-void CNT2_count(void);
-
+// ----- Prototypes of routines (defined below the main) -------------------
+void Update(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)
+void LEDs_write(unsigned short);    // write to 74HC595 (8x LEDs)
+void Display_init(void);    // initialize MAX7219
+void Display_6D_write(uint8_t);    // write to MAX7219 (Main 6-digits display)
+void Display_2D_write(unsigned short);    // write to MAX7219 (Gate 2-digits display)
 
 //==============================================================================
 //==============================================================================
@@ -44,149 +92,340 @@
 int main() 
 {
     
-    PC.baud(115200);
-    PC.printf("Connected...\n");
-    GPS.baud(9600);
+    PC.baud(115200);        // set baud-rate of virtual COM port (PC connection)
+    PC.printf("GEO COUNTER V1 2108\n");
+    PC.printf(__DATE__);
+    PC.printf("  ");
+    PC.printf(__TIME__);
+    PC.printf("\nReady...\n");
+    
+    GPS.baud(9600); // set tyhe baud-rate of the serial port dedicated to the GPS
     
-    max7219_configuration_t cfg = {
-         .device_number = 1,            
-         .decode_mode = 0xFF,
-         .intensity = Max7219::MAX7219_INTENSITY_F, // max brightness
-         .scan_limit = Max7219::MAX7219_SCAN_6      // 6 digits
-     };
+    CS1 = 1;    // presets CS of MAX7219
+    CS2 = 1;    // preset CS of 74HC595
+
+    Display_6D_write(0);
+    Display_2D_write(TGATE);
+    Display_init(); // initialize MAX7219
 
-     Display.init_device(cfg);      
-     Display.enable_device(1);
-     Display.device_all_on(1);
-
-    set_time(1256729737); // Set time to Wed, 28 Oct 2009 11:35:37
+    // RTC is supposed to be loose time at power down (no backup battery)
+    // An initialization is performed anyway 
+    set_time(0); // Set time
  
+    Wheel.reset();        // clear the variable associated to the encoder    
+    
+    PWM.period_ms(3);    // set the PWM period
+    PWM.write(0.8);      // set the PWM duty-cycle
+    
+    LEDs_write(0x00);   // initialize LEDs (CPM and CNT1 on)
+    Beep(); // initial beep    
+    
+    uint8_t LED_status = CNT1 | CPS;
+    LEDs_write(LED_status);
+        
+    // 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(&Update, 1);  
     //RTC::attach(&Update, RTC::Second);
-    //RTC::detach(RTC::Second);
-    
-    Wheel.reset();        // clear encoder    
-    
-    PWM.period_ms(3);         // set LCD backlight PWM
-    PWM.write(0.8);      
-    /*
-    BUZZ.period_ms(30);         // set LCD backlight PWM
-    BUZZ.write(0.2);  
-    */
-    Sec_Beat.attach(&Update, 1);
-
-    // enable & attach interrupts on rising edge of digital inputs
-    TRIG1.rise(&CNT1_count);     
-    TRIG2.rise(&CNT2_count);     
-    
-          
+    //RTC::detach(RTC::Second);  
+  
+    // main loop does nothing as all activities are interrupt driven    
     while(1) 
     {
-        // do nothing
-                            
+        // dance (or do nothing)                
     }
 }
 
 
-// ------------- Refresh Display ------------------------
-
-void RefreshDisplay(void)
-{
-    Display.write_digit(1, 1, Digit_Disp[6]);   // device, digit, data
-    Display.write_digit(1, 2, Digit_Disp[5]);   // device, digit, data
-    Display.write_digit(1, 3, Digit_Disp[4]);   // device, digit, data
-    Display.write_digit(1, 4, Digit_Disp[3]);   // device, digit, data
-    Display.write_digit(1, 5, Digit_Disp[2]);   // device, digit, data
-    Display.write_digit(1, 6, Digit_Disp[1]);   // device, digit, data
-    Display.write_digit(1, 7, Digit_Disp[0]);   // device, digit, data
-        
-  return;
-}
-
-
-
+//-------- END OF MAIN --------------
 //==============================================================================
 
-void Update()   // refresh display data
-{
-    char TextString[9];
-    gate++;
-    
-    if(QEIPB)
-        AUX = 1;
-    else
-        AUX = 0;
+// Definition of routines
+
+//---------------------------------------------------------------------------
+// Update values to be displayed  
+
+void Update()   
+{               
+    ADC_val = KEYB.read();  // read voltage from keyboard
     
-    if(gate==TGATE)
-    {
-        //value = (int)(CNT1/TGATE);
-        value = int(Wheel.getPulses());
-        
-        if(value<MAX_VAL)
-        {
-            snprintf(TextString, 8, "%7d", value);   // int to string
-            seconds = time(NULL); 
-            strftime(Text, 50, "%d-%b-%Y  %H:%M:%S", localtime(&seconds));
-            PC.printf("RTC: %s, CNT1: %7d CNT2: %7d\n",Text, CNT1, CNT2);
+    if(ADC_val<0.1) // RESET pushbutton pressed
+    {    
+        Count1 = 0; // clear counters     
+        Count2 = 0;              
+    }        
+    
+    if((ADC_val>0.4)&&(ADC_val<0.6))    // START/STOP pushbutton pressed
+            Stopped=!Stopped;           // toggle status
+    
+    if(Stopped)
+    {    
+        // disable interrupts on TRIG1 and TRIG2
+        TRIG1.rise(NULL);      
+        TRIG2.rise(NULL); 
         
-            for(uint8_t i=0; i<7; i++)
-            {   
-                if(TextString[i]==' ')  // blanking empty digits
-                    TextString[i]= 0xFF;
-                else
-                    TextString[i]=TextString[i]-'0';
-                
-                Digit_Disp[i] = TextString[i];   
-                  
-            }         
-        }
+        // show zero gate time   
+        gate = 0;                   
+        Display_2D_write(gate);
         
-        else
-        {
-            for(uint8_t i=0; i<7; i++)  // all minus
-                Digit_Disp[i] = 10;   
-        }    
-        
-        RefreshDisplay(); 
+        // show selected content on main display
+        value = (int)(Count1/TGATE);
+        Display_6D_write(value);    // refresh the main display              
+    }
     
-        CNT1=0;
-        CNT2=0;                
-        gate = 0;
-    }
     else
     {
-       value = TGATE - gate;
-       snprintf(TextString, 8, "%7d", value);
-        for(uint8_t i=6; i<8; i++)
-        {   
-            if(TextString[i]==' ')  // blanking empty digits
-                TextString[i]= 0xFF;
-            else
-                TextString[i]=TextString[i]-'0';        
-        } 
-                    
-        //Digit_Disp[1] = TextString[6];         
-        //Digit_Disp[0] = TextString[7];         
+        // 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);
+            //value = int(Wheel.getPulses());
                 
-       RefreshDisplay(); 
+            Display_6D_write(value);    // refresh the main display 
+        
+            Count1 = 0;     // clear both counters
+            Count2 = 0;
+            gate = TGATE;// and reload the gate time
+
+        }
+
+        Display_2D_write(gate);     // show gate time countdown 
+        gate--;
+        
+        // Timestamp to PC (debug)
+        seconds = time(NULL);   // get current time 
+        //strftime(Text, 50, "%d-%b-%Y  %H:%M:%S", localtime(&seconds));
+        strftime(Text, 50, "%H:%M:%S", localtime(&seconds));
+        PC.printf("RTC: %s, CNT1: %7d CNT2: %7d\n",Text, Count1, Count2);
+    
     }
+        
     
-
     return;
 }
 
 //---------------------------------------------------------------------------
-void CNT1_count(void)
-{                       //function to call upon interrupt
-    CNT1++;                      //increment counter object   
+// Increment CNT1 every time a rising edge is detected on TRIG1 (interrupt)
+
+void Count1_up(void)
+{                       
+    Count1++;                        
+    return; 
+}
+
+
+//---------------------------------------------------------------------------
+// Increment CNT1 every time a rising edge is detected on TRIG2 (interrupt)
+
+void Count2_up(void)
+{                      
+    Count2++;                        
+    return; 
+}
+
+
+//---------------------------------------------------------------------------
+//Generates a short beep via BUZZ
+
+void Beep(void)       
+{                       
+    BUZZ = 1;         // turn-on the buzzer
+    wait(0.3);        // wait
+    BUZZ = 0;         // turn-off the buzzer   
     return; 
 }
 
 
 //---------------------------------------------------------------------------
-void CNT2_count(void)
-{                       //function to call upon interrupt
-    CNT2++;                      //increment counter object    
+//Write to 74HC595 (LEDs) - Take care to avoid conflict with MAX7219
+
+void LEDs_write(unsigned short data_val)       
+{                       
+    // Update 74HC595 shift registers 
+    unsigned short mask;
+    
+    SCK = 0;
+    wait_us(DT);
+    CS2 = 0;    
+    
+    for(mask = 0x80; mask!= 0; mask>>= 1)
+    {
+      wait_us(DT);
+      SCK = 0;
+      if(mask & data_val)
+        MOSI = 0;
+      else
+        MOSI = 1;
+      wait_us(DT);
+      SCK = 1;
+    }
+    
+    SCK = 0;
+    wait_us(DT);
+    CS2 = 1;
+
     return; 
 }
 
 
+//---------------------------------------------------------------------------
+// Initialize the MAX7219
+
+void Display_init(void)
+{
+    uint8_t i;
+    uint16_t mask;
+    uint16_t data_to_send[6] = {SHUTDOWN, TURN_ON, DEC_MODE, BRIGHTNESS, SCAN_LIM, TEST};
+             //{SHUTDOWN, TURN_ON, DEC_MODE, BRIGHTNESS, SCAN_LIM, TEST};
+    for(i = 0; i <6; i++)
+    {
+        CS1 = 0;
+      
+        for(mask = 0x8000; mask!= 0; mask>>= 1)
+        {
+            wait_us(DT);
+            SCK = 0;
+            if(mask & data_to_send[i])
+                MOSI = 1;
+            else
+                MOSI = 0;
+            wait_us(DT);    
+            SCK = 1;
+        }
+        
+        wait_us(DT);
+        SCK = 0;
+        wait_us(DT);
+        CS1 = 1;
+    }
+    
+  return;
+}
+
+
+//---------------------------------------------------------------------------
+// Refresh the 6 digits of the main display
+
+void Display_6D_write(uint8_t value)
+{
+ 
+    uint8_t digit;
+    uint16_t mask, data_to_send;
+    char TextString[6];
+    
+    // int to string, then string to digits
+    
+    sprintf(TextString, "%6d", value);   // int to string
+    
+    for(uint8_t i=0; i<6; i++)
+    {   
+        if(TextString[i] == ' ')  // blank empty digits
+            Disp_Digit[i] = 0xFF;
+        else
+            Disp_Digit[i] = TextString[i]-'0';      
+    }
+
+    // write to chip
+
+    SCK = 0;
+    wait_us(DT);    
+    
+    for(digit = 1; digit <7; digit++)
+    {
+        // each stream consists of digit address and data to show
+        data_to_send = 7-digit;
+        data_to_send<<=8;
+        data_to_send = data_to_send | Disp_Digit[digit-1];
+        
+        CS1 = 0;
+        
+        for(mask = 0x8000; mask!= 0; mask>>= 1)
+        {
+            wait_us(DT);
+            SCK = 0;
+            if(mask & data_to_send)
+                MOSI = 1;
+            else
+                MOSI = 0;
+                
+            wait_us(DT);
+            SCK = 1;
+        }
+        
+        wait_us(DT);    
+        SCK = 0;
+        wait_us(DT);
+        CS1 = 1;
+    }
+    
+  return;
+}
+
+
+//---------------------------------------------------------------------------
+// Refresh the 2 digits of the gate display
+
+void Display_2D_write(unsigned short value)
+{
+ 
+    uint8_t digit;
+    uint16_t mask, data_to_send;
+    char TextString[2];
+
+    // int to string, then string to digits
+    
+    sprintf(TextString, "%2d", value);   // int to string
+
+    if(TextString[0] == ' ')  // blank empty digits
+        Disp_Digit[7] = 0xFF;    
+    else
+        Disp_Digit[7] = TextString[0] - '0';
+    
+    Disp_Digit[6] = TextString[1] - '0';
+
+    // write to chip
+    
+    SCK = 0;
+    wait_us(DT);    
+    
+    for(digit = 7; digit <9; digit++)
+    {
+        // each stream consists of digit address and data to show
+        data_to_send = digit;
+        data_to_send<<=8;
+        data_to_send = data_to_send | Disp_Digit[digit-1];
+        
+        CS1 = 0;
+        
+        for(mask = 0x8000; mask!= 0; mask>>= 1)
+        {
+            wait_us(DT);
+            SCK = 0;
+            
+            if(mask & data_to_send)
+                MOSI = 1;
+            else
+                MOSI = 0;
+                
+            wait_us(DT);
+            SCK = 1;
+        }
+        
+        wait_us(DT);    
+        SCK = 0;
+        wait_us(DT);
+        CS1 = 1;
+    }
+    
+  return;
+}
+
+//-------- END OF FILE --------------
+//==============================================================================
+
+
+