Code supports writing to the SD card as well as working with the Volckens group smartphone apps for the mbed HRM1017

Dependencies:   ADS1115 BLE_API BME280 Calibration CronoDot EEPROM LSM303 MCP40D17 NCP5623BMUTBG SDFileSystem SI1145 STC3100 mbed nRF51822

Fork of UPAS_BLE_and_USB by Volckens Group Sensors

Revision:
77:24fbeb2bfe05
Parent:
76:8130cb6776c6
Child:
78:a465de6cc47e
--- a/main.cpp	Tue Sep 01 02:10:13 2015 +0000
+++ b/main.cpp	Fri Sep 04 01:36:57 2015 +0000
@@ -10,8 +10,9 @@
 #include "CronoDot.h"
 #include "EEPROM.h"
 #include "US_Menu.h"
-#include "BLEDevice.h" 
+#include "BLEDevice.h"
 #include "BLE_Menu.h"
+#include "Calibration.h"
 
 #define BLE_UUID_TXRX_SERVICE            0x0000 /**< The UUID of the Nordic UART Service. */
 #define BLE_UUID_TX_CHARACTERISTIC       0x0002 /**< The UUID of the TX Characteristic. */
@@ -52,32 +53,14 @@
 CronoDot            RTC(p22, p20);
 EEPROM              E2PROM(p22, p20);
 US_Menu             Menu;
-//DigitalOut      GPS_EN(p4,0);                     //pin 4 is used to enable and disable the GPS, in order to recive serial communications
+DigitalOut          GPS_EN(p4,0);       //pin 4 is used to enable and disable the GPS, in order to recive serial communications
+Calibration         calibrations(1);     //Default serial/calibration if there are no values for the selected option
 
 Timeout         stop;   //This is the stop call back object
-Timeout         logg;    //This is the logging call back object
-int RunReady =0;
+Timeout         logg;   //This is the logging call back object
 
-//UPAS0012 CALIBRATION TRANSFER FUNCTION COEFFICIENTS FROM 'UPAS v2 OSU-calibration primary flow data.xlsx'
-//mass flow sensor output signal (x) vs. mass flow (y)
-//y = -0.6154x4 + 3.7873x3 - 7.2564x2 + 7.0202x - 1.9413
-float MF4 = -0.6154;
-float MF3 = 3.7873;
-float MF2 = -7.2564;
-float MF1 = 7.0202;
-float MF0 = -1.9413;
-//Mass flow sensor polynomial deviation limits
-float omronVMin = 0.425; //V
-float omronVMax = 2.005; //V
-float omronMFMin = 0.002; //g/L
-float omronMFMax = 3.544; //g/L
-//DIGITAL POTENTIOSTAT dig-pot vs m_dot POLYNOMIAL TRANSFER FUNCTION COEFFICIENTS FROM 'UPAS v2 OSU-calibration primary flow data.xlsx'
-//y = 5.3839x4 - 51.627x3 + 191.09x2 - 345.9x + 277.63
-float DP4 = 5.3839;
-float DP3 = -51.627;
-float DP2 = 191.09;
-float DP1 = -345.9;
-float DP0 = 277.63;
+uint16_t serial_num = 1;                // Default serial/calibration number
+int RunReady =0;
 
 
 float press;
@@ -128,7 +111,7 @@
 // variables are only place holders for the US_Menu //
 int refreshtime;
 float home_lat, home_lon, work_lat, work_lon;
-//*************************************************// 
+//*************************************************//
 
 //int refresh_Time = 10;   // refresh time in s, note calling read_GPS()(or similar) will still take how ever long it needs(hopefully < 1s)
 
@@ -156,7 +139,7 @@
         pbKill = 0; // this is were we shut everything down
     }
     stop.detach();
-    stop.attach(&check_stop, 9);    
+    stop.attach(&check_stop, 9);
 }
 
 
@@ -166,21 +149,21 @@
     logg.attach(&log_data, logInerval);
     RTC.get_time();
     secondsD = RTC.seconds;
-    while(fmod(secondsD,logInerval)!=0){
+    while(fmod(secondsD,logInerval)!=0) {
         RTC.get_time();
         secondsD = RTC.seconds;
-        }
-    
-    
+    }
+
+
     omronReading = ads.readADC_SingleEnded(0, 0xC583); // read channel 0 PGA = 2 : Full Scale Range = 2.048V
     omronVolt = (omronReading*4.096)/(32768*2);
 
-    if(omronVolt<=omronVMin) {
-        massflow = omronMFMin;
-    } else if(omronVolt>=omronVMax) {
-        massflow = omronMFMax;
+    if(omronVolt<=calibrations.omronVMin) {
+        massflow = calibrations.omronMFMin;
+    } else if(omronVolt>=calibrations.omronVMax) {
+        massflow = calibrations.omronMFMax;
     } else {
-        massflow = MF4*pow(omronVolt,(float)4)+MF3*pow(omronVolt,(float)3)+MF2*pow(omronVolt,(float)2)+MF1*omronVolt+MF0;
+        massflow = calibrations.MF4*pow(omronVolt,(float)4)+calibrations.MF3*pow(omronVolt,(float)3)+calibrations.MF2*pow(omronVolt,(float)2)+calibrations.MF1*omronVolt+calibrations.MF0;
     }
 
     atmoRho = ((press-((6.1078*pow((float)10,(float)((7.5*temp)/(237.3+temp))))*(rh/100)))*100)/(287.0531*(temp+273.15))+((6.1078*pow((float)10,(float)((7.5*temp)/(237.3+temp))))*(rh/100)*100)/(461.4964*(temp+273.15));
@@ -245,7 +228,7 @@
     //sd.unmount();
 
     //wait(1.2);
-    
+
 }
 
 int main()
@@ -253,48 +236,49 @@
 
 // Setup and Initialization
 //---------------------------------------------------------------------------------------------//
-    Menu.read_menu(E2PROM, logInerval,refreshtime, volflowSet, device_name, dutyUp, dutyDown, home_lat, home_lon, work_lat, work_lon, RunReady);   //Read all data from the EEPROM here
-    
+    Menu.read_menu(E2PROM, logInerval,refreshtime, volflowSet, device_name, dutyUp, dutyDown, home_lat, home_lon, work_lat, work_lon, RunReady, serial_num);   //Read all data from the EEPROM here
+
     //**************//BLE initialization//**************//
     //bleMenu.read_settings(E2PROM, device_name);
     uint8_t BLE_name[] = {device_name[0], device_name[1], device_name[2], device_name[3], device_name[4], device_name[5], device_name[6], device_name[7], device_name[8]};
-    ble.init(); 
-   // setup advertising 
+    ble.init();
+    // setup advertising
     ble.accumulateAdvertisingPayload(GapAdvertisingData::BREDR_NOT_SUPPORTED);
     ble.setAdvertisingType(GapAdvertisingParams::ADV_CONNECTABLE_UNDIRECTED);
     ble.accumulateAdvertisingPayload(GapAdvertisingData::SHORTENED_LOCAL_NAME,(const uint8_t *)BLE_name, sizeof(BLE_name) - 1); // ~8 char max!
     ble.accumulateAdvertisingPayload(GapAdvertisingData::COMPLETE_LIST_128BIT_SERVICE_IDS,(const uint8_t *)uart_base_uuid_rev, sizeof(uart_base_uuid));
-    // 100ms; in multiples of 0.625ms. 
+    // 100ms; in multiples of 0.625ms.
     ble.setAdvertisingInterval(160);
     ble.addService(uartService);
-    ble.startAdvertising();     
+    ble.startAdvertising();
     ble.onDisconnection(disconnectionCallback); //what happens when disconected
     ble.onDataWritten(WrittenHandler);          //what happens when the phone sends a message
     //**************//BLE initialization//**************//
-    
- 
-    
+
+
+
     //Test for errors
     //RunReady = 0; //debug always open the menu
     //if(RTC.OSF()) {                 //Force the menu open if the RTC needs reset.
     //    RunReady = 0;
     //}
-    if(RunReady == 0){
+    if(RunReady == 0) {
         RGB_LED.set_led(0,1,1); // error code/color
         pc.printf("Change Name\r\n");
-        while(RunReady == 0){
+        while(RunReady == 0) {
             RGB_LED.set_led(0,1,1);   // error code/color
-            RunReady = Menu.Start(pc, E2PROM, RTC, logInerval, refreshtime, volflowSet, device_name, dutyUp, dutyDown, home_lat, home_lon, work_lat, work_lon, 513, 0.25);  //Forces you to open the menu
+            RunReady = Menu.Start(pc, E2PROM, RTC, logInerval, refreshtime, volflowSet, device_name, dutyUp, dutyDown, home_lat, home_lon, work_lat, work_lon, Menu.menu_ops, 0.25, serial_num, calibrations);  //Forces you to open the menu
             RGB_LED.set_led(0,10,10); // error code/color
             bleMenu.open_menu(txPayload, rxCharacteristic, E2PROM, RTC, logInerval, refreshtime, volflowSet, device_name, dutyUp, dutyDown, home_lat, home_lon, work_lat, work_lon, 9,RunReady, 0.25);
         }
-        //RunReady = 1;
-        Menu.save_menu(E2PROM, logInerval, refreshtime, volflowSet, device_name, dutyUp, dutyDown, home_lat, home_lon, work_lat, work_lon, RunReady);       //Save all data to the EEPROM
-        pbKill = 0;
+        if(Menu.crr == 0){
+            Menu.save_menu(E2PROM, logInerval, refreshtime, volflowSet, device_name, dutyUp, dutyDown, home_lat, home_lon, work_lat, work_lon, RunReady, serial_num);       //Save all data to the EEPROM
+            pbKill = 0;
+        }
     }
-    
+
     RunReady = 0;
-    Menu.save_menu(E2PROM, logInerval, refreshtime, volflowSet, device_name, dutyUp, dutyDown, home_lat, home_lon, work_lat, work_lon, RunReady);       //Save all data to the EEPROM      
+    Menu.save_menu(E2PROM, logInerval, refreshtime, volflowSet, device_name, dutyUp, dutyDown, home_lat, home_lon, work_lat, work_lon, RunReady, serial_num);       //Save all data to the EEPROM
 
     stop.attach(&check_stop, 60);    // check if we should shut down every 5 seconds, starting 60s after the start.
 
@@ -314,7 +298,7 @@
     atmoRho = ((press-((6.1078*pow((float)10,(float)((7.5*temp)/(237.3+temp))))*(rh/100)))*100)/(287.0531*(temp+273.15))+((6.1078*pow((float)10,(float)((7.5*temp)/(237.3+temp))))*(rh/100)*100)/(461.4964*(temp+273.15));
     massflowSet = volflowSet*atmoRho;
     //Digtal pot tf from file: UPAS v2 OSU-PrimaryFlowData FullSet 2015-05-29 CQ mods.xlsx
-    digital_pot_setpoint = (int)floor(DP4*pow(massflowSet,4)+DP3*pow(massflowSet,3)+DP2*pow(massflowSet,2)+DP1*massflowSet+DP0); //min = 0x7F, max = 0x00
+    digital_pot_setpoint = (int)floor(calibrations.DP4*pow(massflowSet,4)+calibrations.DP3*pow(massflowSet,3)+calibrations.DP2*pow(massflowSet,2)+calibrations.DP1*massflowSet+calibrations.DP0); //min = 0x7F, max = 0x00
 
     if(digital_pot_setpoint>=digitalpotMax) {
         digital_pot_setpoint = digitalpotMax;
@@ -325,75 +309,66 @@
     DigPot.writeRegister(digital_pot_setpoint);
     wait(1);
     blower = 1;
-
-    RTC.get_time();
-    f_sec = RTC.seconds;
-    f_min = RTC.minutes;
-    f_hour = RTC.hour;
-    if(RTC.month == 1 | RTC.month == 3 | RTC.month == 5 | RTC.month == 7 | RTC.month == 8 | RTC.month == 10){
-        if(RTC.date == 31){
-            f_date = 1;
-            f_month = RTC.month +1;
-            f_year = RTC.year; 
-            }
-        else{
-            f_date = RTC.date+1;
-            f_month = RTC.month;
-            f_year = RTC.year;
-            }
-        }
-    else if(RTC.month == 4 | RTC.month == 6 | RTC.month == 9 | RTC.month == 11){
-        if(RTC.date == 30){
-            f_date = 1;
-            f_month = RTC.month +1;
-            f_year = RTC.year; 
-            }
-        else{
-            f_date = RTC.date+1;
-            f_month = RTC.month;
-            f_year = RTC.year;
-            }
-        }
-    else if(RTC.month == 2){
-        if(RTC.year == 16 | RTC.year == 20 | RTC.year == 24| RTC.year == 28){
-            if(RTC.date == 29){
+    if(Menu.crr == 1) {
+        RTC.get_time();
+        f_sec = RTC.seconds;
+        f_min = RTC.minutes;
+        f_hour = RTC.hour;
+        if(RTC.month == 1 | RTC.month == 3 | RTC.month == 5 | RTC.month == 7 | RTC.month == 8 | RTC.month == 10) {
+            if(RTC.date == 31) {
                 f_date = 1;
                 f_month = RTC.month +1;
-                f_year = RTC.year; 
-                }
-            else{
+                f_year = RTC.year;
+            } else {
+                f_date = RTC.date+1;
+                f_month = RTC.month;
+                f_year = RTC.year;
+            }
+        } else if(RTC.month == 4 | RTC.month == 6 | RTC.month == 9 | RTC.month == 11) {
+            if(RTC.date == 30) {
+                f_date = 1;
+                f_month = RTC.month +1;
+                f_year = RTC.year;
+            } else {
                 f_date = RTC.date+1;
                 f_month = RTC.month;
                 f_year = RTC.year;
+            }
+        } else if(RTC.month == 2) {
+            if(RTC.year == 16 | RTC.year == 20 | RTC.year == 24| RTC.year == 28) {
+                if(RTC.date == 29) {
+                    f_date = 1;
+                    f_month = RTC.month +1;
+                    f_year = RTC.year;
+                } else {
+                    f_date = RTC.date+1;
+                    f_month = RTC.month;
+                    f_year = RTC.year;
+                }
+            } else {
+                if(RTC.date == 28) {
+                    f_date = 1;
+                    f_month = RTC.month +1;
+                    f_year = RTC.year;
+                } else {
+                    f_date = RTC.date+1;
+                    f_month = RTC.month;
+                    f_year = RTC.year;
                 }
             }
-        else{
-            if(RTC.date == 28){
+        } else if(RTC.month == 12) {
+            if(RTC.date == 31) {
                 f_date = 1;
-                f_month = RTC.month +1;
-                f_year = RTC.year; 
-                }
-            else{
+                f_month = 1;
+                f_year = RTC.year+1;
+            } else {
                 f_date = RTC.date+1;
                 f_month = RTC.month;
                 f_year = RTC.year;
-                }
-         }
+            }
         }
-    else if(RTC.month == 12){
-            if(RTC.date == 31){
-                    f_date = 1;
-                    f_month = 1;
-                    f_year = RTC.year+1; 
-                    }
-            else{
-                    f_date = RTC.date+1;
-                    f_month = RTC.month;
-                    f_year = RTC.year;
-                    }
-       }
-   
-    
+    }
+
     sprintf(filename, "/sd/UPAS0012LOG_%02d-%02d-%02d_%02d=%02d=%02d_%s.txt",RTC.year,RTC.month,RTC.date,RTC.hour,RTC.minutes,RTC.seconds,device_name);
     FILE *fp = fopen(filename, "w");
     fclose(fp);
@@ -406,12 +381,12 @@
 
     omronReading = ads.readADC_SingleEnded(0, 0xC583); // read channel 0 PGA = 2 : Full Scale Range = 2.048V
     omronVolt = (omronReading*4.096)/(32768*2);
-    if(omronVolt<=omronVMin) {
-        massflow = omronMFMin;
-    } else if(omronVolt>=omronVMax) {
-        massflow = omronMFMax;
+    if(omronVolt<=calibrations.omronVMin) {
+        massflow = calibrations.omronMFMin;
+    } else if(omronVolt>=calibrations.omronVMax) {
+        massflow = calibrations.omronMFMax;
     } else {
-        massflow = MF4*pow(omronVolt,(float)4)+MF3*pow(omronVolt,(float)3)+MF2*pow(omronVolt,(float)2)+MF1*omronVolt+MF0;
+        massflow = calibrations.MF4*pow(omronVolt,(float)4)+calibrations.MF3*pow(omronVolt,(float)3)+calibrations.MF2*pow(omronVolt,(float)2)+calibrations.MF1*omronVolt+calibrations.MF0;
     }
     deltaMflow = massflow-massflowSet;
     digital_pot_set = digital_pot_setpoint;
@@ -421,16 +396,16 @@
     //Sets the flow withen +-1.5% of the desired flow rate based on mass flow
 
     while(abs(deltaMflow)>.015) {
-    
+
         omronReading = ads.readADC_SingleEnded(0, 0xC583); // read channel 0 PGA = 2 : Full Scale Range = 2.048V
         omronVolt = (omronReading*4.096)/(32768*2);
         //Mass Flow tf from file: UPAS v2 OSU-PrimaryFlowData FullSet 2015-05-29 CQ mods.xlsx
-        if(omronVolt<=omronVMin) {
-            massflow = omronMFMin;
-        } else if(omronVolt>=omronVMax) {
-            massflow = omronMFMax;
+        if(omronVolt<=calibrations.omronVMin) {
+            massflow = calibrations.omronMFMin;
+        } else if(omronVolt>=calibrations.omronVMax) {
+            massflow = calibrations.omronMFMax;
         } else {
-            massflow = MF4*pow(omronVolt,(float)4)+MF3*pow(omronVolt,(float)3)+MF2*pow(omronVolt,(float)2)+MF1*omronVolt+MF0;
+            massflow = calibrations.MF4*pow(omronVolt,(float)4)+calibrations.MF3*pow(omronVolt,(float)3)+calibrations.MF2*pow(omronVolt,(float)2)+calibrations.MF1*omronVolt+calibrations.MF0;
         }
 
         atmoRho = ((press-((6.1078*pow((float)10,(float)((7.5*temp)/(237.3+temp))))*(rh/100)))*100)/(287.0531*(temp+273.15))+((6.1078*pow((float)10,(float)((7.5*temp)/(237.3+temp))))*(rh/100)*100)/(461.4964*(temp+273.15));
@@ -455,7 +430,7 @@
 
     sampledVol = 0.0;
     RGB_LED.set_led(0,1,0);
-    
+
 
 
     //** end of initalization **//
@@ -472,7 +447,7 @@
         //__enable_irq();   // Enable Interrupts
         //secondsD = (double)RTC.seconds;
         //if(fmod(secondsD,logInerval)==0) {
-            //log_data();
+        //log_data();
         //}
     }