Program to control UPAS with MicroChip BLE chip + iPhone App

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

Revision:
3:122bfc998c4c
Parent:
2:88fcbfadec6a
--- a/main.cpp	Wed Feb 03 01:29:18 2016 +0000
+++ b/main.cpp	Mon Feb 08 22:49:54 2016 +0000
@@ -25,20 +25,86 @@
 LSM303              movementsensor(D14, D15);
 SI1145              lightsensor(D14, D15);
 NCP5623BMUTBG       RGB_LED(D14, D15);
-//CronoDot            RTC(D14, D15);
+CronoDot            RTC_UPAS(D14, D15);
 EEPROM              E2PROM(D14, D15);
 //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
+
+uint16_t serial_num = 1;                // Default serial/calibration number
+int RunReady =0;
+
+
+float press = 1.1;
+float temp = 75.5;
+float rh = 12.1;
+
+int uv = 8;
+int vis = 7;
+int ir = 6;
+
+float compass = 0.1;
+float accel_x = 0.2;
+float accel_y = 0.3;
+float accel_z = 0.4;
+float accel_comp = 0.5;
+float angle_x = 0.6;
+float angle_y = 0.7;
+float angle_z = 0.8;
+float mag_x = 0.9;
+float mag_y = 1.0;
+float mag_z = 1.2;
+
+int vInReading = 18;
+int vBlowerReading = 19;
+int omronDiff = 20;
+float omronVolt = 1.2; //V
+int omronReading = 100;
+float atmoRho = 1.5; //g/L
+
+float massflow = 87.6; //g/min
+float volflow = 88.8; //L/min
+float volflowSet = 1.0; //L/min
+int   logInerval = 10; //seconds
+double secondsD = 0;
+double lastsecondD = 0;
+float massflowSet = 19.2;
+float deltaVflow = 0.0;
+float deltaMflow = 0.0;
+float gainFlow = 98.1;
+float sampledVol = 2.0; //L, total sampled volume
+
+int digital_pot_setpoint = 5 ; //min = 0x7F, max = 0x00
+int digital_pot_set = 6;
+int digital_pot_change = 7;
+int digitalpotMax = 127;
+int digitalpotMin = 2;
+
+int dutyUp = 4;
+int dutyDown = 3;
+
+// variables are only place holders for the US_Menu //
+int refreshtime = 6;
+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)
+
+char filename[] = "/sd/XXXX0000LOG000000000000---------------.txt";
+
+SDFileSystem sd(D11, D12, D13, D10, "sd"); // I believe this matches Todd's pinout, let me know if this doesn't work. (p12, p13, p15, p14)
+
 void sendData(); 
 
-int timeout = 2;
+//int timeout = 2;
 
-void pc_recv(void){
-    while(pc.readable()){
-        pc.getc();
-    }
-}
+//void pc_recv(void){
+//    while(pc.readable()){
+//        pc.getc();
+//    }
+//}
 
 static uint8_t rx_buf[20];
 static uint8_t rx_len=0;
@@ -46,73 +112,80 @@
 static int transmissionValue = 0;
 uint8_t writeData[20] = {0,};
 static uint8_t dataLength = 0;
+static int runReady = 0;
+static uint8_t startAndEndTime[12] = {0,};
 
 void uartMicro(void){
-
-    haltBLE = 2;
-    //if(transmissionValue==4)pc.printf("DEBUG");
-    while(microChannel.readable()){
-        rx_buf[rx_len++] = microChannel.getc();
-        
-        //Code block to verify what is being transmitted.  To function correctly, all data must terminate with \0 or \n
-        if(transmissionValue==0){
+    if(runReady!=1){
+        haltBLE = 2;
+        while(microChannel.readable()){
+            rx_buf[rx_len++] = microChannel.getc();
             
-            if     (rx_buf[0] == 0x01)transmissionValue = 1;      //rtc
-            else if(rx_buf[0] == 0x02)transmissionValue = 2; //sample start and end times
-            else if(rx_buf[0] == 0x03)transmissionValue = 3; //sample name
-            else if(rx_buf[0] == 0x04)transmissionValue = 4; //Run Check
+            //Code block to verify what is being transmitted.  To function correctly, all data must terminate with \0 or \n
+            if(transmissionValue==0){
+                
+                if     (rx_buf[0] == 0x01)transmissionValue = 1;      //rtc
+                else if(rx_buf[0] == 0x02)transmissionValue = 2; //sample start and end times
+                else if(rx_buf[0] == 0x03)transmissionValue = 3; //sample name
+                else if(rx_buf[0] == 0x04)transmissionValue = 4; //Send Data Check
+    
+                else if(rx_buf[0] == 0x05)transmissionValue = 5; //log interval
+                else if(rx_buf[0] == 0x06)transmissionValue = 6; //Flow Rate
+                else if(rx_buf[0] == 0x07)transmissionValue = 7; //Serial Number
+                else if(rx_buf[0] == 0x08)transmissionValue = 8; //Run Enable
+                else                      transmissionValue = 100; //Not useful data
+            }
+            
+            if(rx_buf[rx_len-1]=='\0' || rx_buf[rx_len-1]=='\n' || rx_buf[rx_len-1] == 0xff){
+                if((transmissionValue == 1 || transmissionValue == 2 || transmissionValue == 3 || transmissionValue == 4 || transmissionValue == 5 ||
+                    transmissionValue == 6 || transmissionValue == 7) &&  rx_buf[rx_len-1] != 0xff)
+                {}else{
+                    if(transmissionValue == 4 ) sendData();
+                    if(transmissionValue == 8){
+                         runReady = 1;
+                         microChannel.attach(NULL,microChannel.RxIrq);
+                     }
+                    haltBLE = 1;
+                    transmissionValue = 0;
+                    dataLength = 0;
 
-            else if(rx_buf[0] == 0x05)transmissionValue = 5; //log interval
-            else if(rx_buf[0] == 0x06)transmissionValue = 6; //Flow Rate
-            else if(rx_buf[0] == 0x07)transmissionValue = 7; //Serial Number
-            else                      transmissionValue = 100; //Not useful data
-        }
-        
-        if(rx_buf[rx_len-1]=='\0' || rx_buf[rx_len-1]=='\n' || rx_buf[rx_len-1] == 0xff){
-            if((transmissionValue == 1 || transmissionValue == 2 || transmissionValue == 3 || transmissionValue == 4 || transmissionValue == 5 ||
-                transmissionValue == 6 || transmissionValue == 7) &&  rx_buf[rx_len-1] != 0xff)
-            {}else{
-                if(transmissionValue == 4)sendData();
-                haltBLE = 1;
-                transmissionValue = 0;
-                dataLength = 0;
+                }
             }
         }
-    }
-    if(haltBLE!=1){
-        
-        if((transmissionValue!=100) && (dataLength!= 0)) writeData[dataLength-1] = rx_buf[0];
-        
-        if(transmissionValue ==100){
-            pc.putc(rx_buf[0]); 
-        
-        }else if(transmissionValue ==1){ //process and store RTC values
+        if(haltBLE!=1){
             
-           // if(dataLength==6)RTC.set_time(writeData[0],writeData[1],writeData[2],writeData[3],writeData[3],writeData[4],writeData[5]);
-
-        }else if(transmissionValue ==2){ //process and store sample start/end 
-            if(dataLength ==12)E2PROM.write(0x00015, writeData, 12);
+            if((transmissionValue!=100) && (dataLength!= 0)) writeData[dataLength-1] = rx_buf[0];
+            
+            if(transmissionValue ==100){
+                //pc.putc(rx_buf[0]); 
             
-        }else if(transmissionValue ==3){ //process and store sample name
-            if(dataLength ==8)E2PROM.write(0x00001,writeData,8);  
-        }else if(transmissionValue ==4){ //process and store Run Check
-            //if(dataLength==1)E2PROM.write(0x00033,writeData,1);
-            
-            
+            }else if(transmissionValue ==1){ //process and store RTC values
+                
+                if(dataLength==6)RTC_UPAS.set_time(writeData[0],writeData[1],writeData[2],writeData[3],writeData[3],writeData[4],writeData[5]);
+    
+            }else if(transmissionValue ==2){ //process and store sample start/end 
+                if(dataLength ==12)E2PROM.write(0x00015, writeData, 12);
+                
+            }else if(transmissionValue ==3){ //process and store sample name
+                if(dataLength ==8)E2PROM.write(0x00001,writeData,8);  
+    
+            }else if(transmissionValue ==5){ //process and store Log Interval
+                 if(dataLength ==1)E2PROM.write(0x00014,writeData,1);
             
-        }else if(transmissionValue ==5){ //process and store Log Interval
-             if(dataLength ==1)E2PROM.write(0x00014,writeData,1);
-        
-        }else if(transmissionValue ==6){ //process and store Flow Rate
-            if(dataLength ==4)E2PROM.write(0x00010,writeData,4);
-            
-        }else if(transmissionValue ==7){ //process and store Serial Number
-            if(dataLength ==2)E2PROM.write(0x00034,writeData,2);
+            }else if(transmissionValue ==6){ //process and store Flow Rate
+                if(dataLength ==4)E2PROM.write(0x00010,writeData,4);
+                
+            }else if(transmissionValue ==7){ //process and store Serial Number
+                if(dataLength ==2)E2PROM.write(0x00034,writeData,2);
+            }
+            dataLength++;        
         }
-        dataLength++;        
-    }
-    //
-    rx_len = 0;  
+
+        rx_len = 0;
+    }else{
+        while(microChannel.readable())
+         uint8_t extract = microChannel.getc();
+    }  
     
 }
 void sendData(){
@@ -145,37 +218,187 @@
     for(int i=0; i<5; i++){
         microChannel.putc(flowRateOriginal[i]);        
     } 
-    //pc.printf("End of data");
 
     
 } 
+
+void check_stop()   // this checks if it's time to stop and shutdown
+{
+    
+    if(RTC_UPAS.compare(startAndEndTime[6], startAndEndTime[7], startAndEndTime[8], startAndEndTime[9], startAndEndTime[10], startAndEndTime[11])) {
+        pbKill = 0; // this is were we shut everything down
+        pc.printf("If you're reading this something has gone very wrong.");
+    }
+    stop.detach();
+    stop.attach(&check_stop, 9);
+    
+}
+    int r = 1;
+    int g = 0;
+    int b = 1;
+
+void log_data()
+{
+
+
+    RGB_LED.set_led(r,g,b);
+    logg.detach();
+    logg.attach(&log_data, logInerval);     // reading and logging data must take significintly less than 0.5s. This can be increased.
+    
+    RTC_UPAS.get_time();
+    
+    secondsD = RTC_UPAS.seconds;
+    lastsecondD = secondsD;
+
+    omronVolt = (omronReading*4.096)/(32768*2);
+
+    FILE *fp = fopen(filename, "a");
+    fprintf(fp, "%02d,%02d,%02d,%02d,%02d,%02d,",RTC_UPAS.year, RTC_UPAS.month,RTC_UPAS.date,RTC_UPAS.hour,RTC_UPAS.minutes,RTC_UPAS.seconds);
+    fprintf(fp, "%1.3f,%1.3f,%2.2f,%4.2f,%2.1f,%1.3f,", omronVolt,massflow,temp,press,rh,atmoRho);
+    fprintf(fp, "%1.3f,%5.1f,%1.1f,%1.1f,%1.1f,%1.1f,", volflow, sampledVol, accel_x, accel_y, accel_z, accel_comp);
+    fprintf(fp, "%.1f,%.1f,%.1f,%.3f,%.3f,%.3f,%.1f,", angle_x,angle_y,angle_z,mag_x, mag_y, mag_z,compass);
+    fprintf(fp, "%d,%d,%d,%d,%d,%d," ,uv,omronReading, vInReading, vBlowerReading, omronDiff,gasG.getAmps());
+    fprintf(fp, "%d,%d,%d,%1.3f,%1.3f\r\n", gasG.getVolts(), gasG.getCharge(),digital_pot_set, deltaMflow, deltaVflow);
+    fclose(fp);
+    //wait_ms(5);
+    
+}
  
 int main(){
     
     pc.baud(115200);  // set what you want here depending on your terminal program speed
     pc.printf("\f\n\r-------------Startup-------------\n\r");
     wait(0.5);
-    timeout=2;
+    //timeout=2;
+    uint8_t serialNumberAndType[6] = {0x50,0x53};
+    E2PROM.read(0x00034,serialNumberAndType+2,2);
+    int tempSerialNum = serialNumberAndType[2]+serialNumberAndType[3];
+    int serialNumDigits[4];
+    serialNumDigits[0] = tempSerialNum / 1000 % 10;
+    serialNumDigits[1] = tempSerialNum / 100 % 10;
+    serialNumDigits[2] = tempSerialNum / 10 % 10;
+    serialNumDigits[3] = tempSerialNum  % 10;
+    
+    serialNumberAndType[2] = serialNumDigits[0]+48;
+    serialNumberAndType[3] = serialNumDigits[1]+48;
+    serialNumberAndType[4] = serialNumDigits[2]+48;
+    serialNumberAndType[5] = serialNumDigits[3]+48;
 
-    pc.attach(pc_recv);
+    //pc.attach(pc_recv);
     microChannel.attach(uartMicro,microChannel.RxIrq);
-    microChannel.baud(115200);   // change this to the new ESP8266 baudrate if it is changed at any time.
+    microChannel.baud(115200);  
 
-    //uint8_t tempBuf[20] = {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0A,0x0B,0x0C,0x0D,0x0E,0x0F,0x10,0x11,0x12,0x13};
     microChannel.printf("$$$");
-    wait(1);
-    microChannel.printf("SN, JakeMicroX\r");
-    wait(1);
+    wait(0.5);
+    microChannel.printf("SN,");
+    for(int i=0;i<6;i++)microChannel.putc(serialNumberAndType[i]);
+    microChannel.printf("\r");
+    wait(0.5);
     microChannel.printf("A\r");
-    wait(1);
+    wait(0.5);
     microChannel.printf("---\r");
-    wait(2);
+    wait(0.5);
     
 
         
     
     RGB_LED.set_led(1,1,1);
-    while(1) {
-        for(int i=0;i<10000000;i++);
+    while(runReady!=1) {
+        wait(1);
+        //pc.printf("Waiting for BLE instruction");
+    
+    }
+    
+    
+    //wait(1);
+    
+    E2PROM.read(0x00015, startAndEndTime, 12); //Grab start and end times from EEPROM
+    RGB_LED.set_led(0,1,0);
+    while(!RTC_UPAS.compare(startAndEndTime[0], startAndEndTime[1], startAndEndTime[2], startAndEndTime[3], startAndEndTime[4], startAndEndTime[5])) {  // this while waits for the start time by looping until the start time
+            wait(0.5);
+            
+            RTC_UPAS.get_time(); 
+
+    }
+    
+    
+    //Get the proper serial number
+    uint8_t serialBytes[2] = {0,};
+    E2PROM.read(0x00034, serialBytes,2);    
+    serial_num = ((uint16_t)serialBytes[1] << 8) | serialBytes[0];
+    calibrations.initialize(serial_num);
+    
+    uint8_t logByte[1] = {0,};
+    E2PROM.read(0x00014,logByte,1);
+    logInerval = logByte[0];
+    
+    stop.attach(&check_stop, 30);    // check if we should shut down every 9 seconds, starting 60s after the start.
+
+    //Use the flow rate value stored in eeprom
+    uint8_t flowRateBytes[4] = {0,};
+    E2PROM.read(0x00010,flowRateBytes,4);
+    E2PROM.byteToFloat(flowRateBytes, &volflowSet);
+    
+    if(volflowSet<=1.0) {
+        gainFlow = 100;
+    } else if(volflowSet>=2.0) {
+        gainFlow = 25;
+    } else {
+        gainFlow = 25;
     }
+
+    RGB_LED.set_led(1,0,0);
+    press = bmesensor.getPressure();
+    temp = bmesensor.getTemperature();
+    rh = bmesensor.getHumidity();
+
+    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
+
+
+
+
+    DigPot.writeRegister(digital_pot_setpoint);
+    wait(1);
+    blower = 1;
+
+    uint8_t subjectLabelOriginal[8] = {0,};
+    E2PROM.read(0x00001, subjectLabelOriginal,8);        
+    sprintf(filename, "/sd/UPAS%04dLOG_%02d-%02d-%02d_%02d=%02d=%02d_%c%c%c%c%c%c%c%c.txt",serial_num,RTC_UPAS.year,RTC_UPAS.month,RTC_UPAS.date,RTC_UPAS.hour,RTC_UPAS.minutes,RTC_UPAS.seconds,subjectLabelOriginal[0],subjectLabelOriginal[1],subjectLabelOriginal[2],subjectLabelOriginal[3],subjectLabelOriginal[4],subjectLabelOriginal[5],subjectLabelOriginal[6],subjectLabelOriginal[7]);
+    FILE *fp = fopen(filename, "w");
+    fclose(fp);
+
+    //---------------------------------------------------------------------------------------------//
+    //Following lines are needed to enter into the initiallization flow control loop
+
+    wait(5);
+
+
+    sampledVol = 0.0;
+    RGB_LED.set_led(0,1,0);
+
+
+
+    //** end of initalization **//
+    //---------------------------------------------------------------------------------------------//
+    //---------------------------------------------------------------------------------------------//
+    // Main Control Loop
+
+
+    //logg.attach(&log_data, 30); // uses callbacks or block Interrupts for anything that uses i2c
+    while(!RTC_UPAS.compare(startAndEndTime[6], startAndEndTime[7], startAndEndTime[8], startAndEndTime[9], startAndEndTime[10], startAndEndTime[11])){
+        wait(logInerval);
+        RGB_LED.set_led(1,1,0);
+        FILE *fp = fopen(filename, "a");
+        fprintf(fp, "%02d,%02d,%02d,%02d,%02d,%02d,",RTC_UPAS.year, RTC_UPAS.month,RTC_UPAS.date,RTC_UPAS.hour,RTC_UPAS.minutes,RTC_UPAS.seconds);
+        fprintf(fp, "%1.3f,%1.3f,%2.2f,%4.2f,%2.1f,%1.3f,", omronVolt,massflow,temp,press,rh,atmoRho);
+        fprintf(fp, "%1.3f,%5.1f,%1.1f,%1.1f,%1.1f,%1.1f,", volflow, sampledVol, accel_x, accel_y, accel_z, accel_comp);
+        fprintf(fp, "%.1f,%.1f,%.1f,%.3f,%.3f,%.3f,%.1f,", angle_x,angle_y,angle_z,mag_x, mag_y, mag_z,compass);
+        fprintf(fp, "%d,%d,%d,%d,%d,%d," ,uv,omronReading, vInReading, vBlowerReading, omronDiff,gasG.getAmps());
+        fprintf(fp, "%d,%d,%d,%1.3f,%1.3f\r\n", gasG.getVolts(), gasG.getCharge(),digital_pot_set, deltaMflow, deltaVflow);
+        fclose(fp);
+    }
+    RGB_LED.set_led(1,0,0);
+
 }