Reading SenseAir LP8 CO2 sensor over bluetooth low energy

Dependencies:   BLE_API mbed nRF51822

Revision:
3:933dd59ad44d
Parent:
2:d02255d8c36f
Child:
4:320febe026ed
diff -r d02255d8c36f -r 933dd59ad44d LP8.h
--- a/LP8.h	Mon Aug 14 20:52:48 2017 +0000
+++ b/LP8.h	Fri Aug 18 18:20:41 2017 +0000
@@ -15,7 +15,8 @@
      RES(res),
      lp8Wait(_timer)
     {
-        Device.baud(9600);                                                              //set baud rate to 9600 
+        Device.baud(9600);                                                              //set baud rate to 9600 Hz
+        Device.format(8, SerialBase::None, 2);                                          //set bits, parity and stop bits
             
         //initialize arrays with lp8 modbus commands. 
         //initial startup command:
@@ -44,15 +45,20 @@
         stateRead[3] = 0x80;                                                            //starting adress
         stateRead[4] = 0x2c;                                                            //number of bytes to read
         stateRead[5] = 0x00;                                                            //crc_l
-        stateRead[5] = 0x00;                                                            //crc_h
+        stateRead[6] = 0x00;                                                            //crc_h
+        
+        //communication confirmation sequence (response from lp8)
+        confirmation[0] = 0xfe;
+        confirmation[1] = 0x41;
+        confirmation[2] = 0x81;
+        confirmation[3] = 0xe0;
             
         //response buffer
         for(int k = 0; k < 60; k++) { response[k] = 0x00; }
 
         //variable initialization
-        co2     = 400;                                                                  //co2 value
-        counter = 0;                                                                    //
-        CRC     = 0x0000;                                                               //crc value
+        co2     = 400;                                                                      //
+        CRC     = 0x0000;                                                                   //
 
     };
 
@@ -60,66 +66,109 @@
 //LP8 Initialization and first message                  
     bool lp8Init(){
 
-//            //Reset LP8
-//            RES.write( 0 );                                                                 //reset
-//            timeIt( 1.2 );
-//            RES.write( 1 );                                                                 //enable
+            Device.format(8, SerialBase::None, 2); 
+            //Reset LP8
+            RES.write( 0 );                                                                 //reset
+            timeIt( 1.0 );
+            RES.write( 1 );                                                                 //enable
+            timeIt(0.2);
             
             //Enable Sensor      
             VBB_EN.write( 1 );                                                              //power on
+            
             //wait for rdy signal
-            timeIt( 0.35 );                                                                 //wait for lp8 rdy signal
+            timeIt( 0.30 );                                                               //wait for lp8 rdy signal
+//            while(RDY.read() != 0 ) { /* wait for rdy to go low */}
+            
+            //transmit first packet
             transmitPacket(firstWrite, 8);                                                  //Send out msg (and nr of bytes) over serial line
             Response( 4 );                                                                  //read 4 bytes response     
+            
+            //check response
+            if ( responseCompare() != true){
+                //VBB_EN.write( 0 );
+                return false;
+                }
+            
             //compute crc
             CRC = modbusCrc(stateRead, 5);
+            
             //add crc value to the transmit package
             stateRead[5] = (uint8_t)CRC;                                                    //crc_l
             stateRead[6] = (uint8_t)(CRC >> 8);                                             //crc_h
+            
             //wait for rdy
-            timeIt( 0.35 );                                                                 //
+            timeIt( 0.20 );                                                                 //
+//            while(RDY.read() != 1 ) { /*wait for rdy to go high */}
+
             transmitPacket(stateRead, 7);                                                   //transmit packet  
-            Response( 49 );                                                                 //read sensor state and co2 value(s)
+            Response( 49 );                                                                 //get sensor state and co2 value(s)
             VBB_EN.write( 0 );                                                              //power off lp8                 
 
-            //was the talk a success? (simple check...)
-            if ( getValue() < 1 ) {
-                return 1; }
-            else {
-                return 0; }
+            return true;
         };
     
 //send subsequent messages to the lp8
-    void lp8Talk(uint8_t ccByte){
+    bool lp8Talk(uint8_t inc_ccByte){
 
+        static const uint8_t A[] = {0xFE,0x41,0x00,0x80,0x20,0x00,0x00,0x02,0x04,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+                                    0x00,0x7F,0xFF,0x00,0x00,0x95,0xED,0x00,0x03,0x29,0x00,0x27,0x8C, 0xf5, 0x63};
+    
+            Device.format(8, SerialBase::None, 2); 
             //transfer previous sensor state to the new msg out
             for (int u = 4; u < 23+4; u++) {
                 stateWrite[u+2] = response[u];
                 }
-            //Set Calibration Control Byte (see end of page for explantion)
-            stateWrite[5] = ccByte;
+            //Set Calibration Control Byte (see end of page for explantion), 
+            /* remove this statement if you want to be able to send anything to lp8 calculation control */
+            if( inc_ccByte != 0x20 ){ /* 0x52 is "simple recalibration, needs only one sample */
+                stateWrite[5] = inc_ccByte;    
+                }
+            else {
+                stateWrite[5] = 0x20;
+                }
+            
+            
             //compute new crc value
-            CRC = modbusCrc(stateWrite, 29);
+            CRC = modbusCrc((uint8_t*)stateWrite, 29);
+            
             //add new crc value to send list
             stateWrite[29] = (uint8_t)CRC;   
             stateWrite[30] = (uint8_t)(CRC >> 8);
 
             //initialize new transfer sequence    
             VBB_EN.write( 1 );                                                              //power on sensor
+
             timeIt( 0.35 );
-            transmitPacket(stateWrite, 31);                                                 //Send out msg with previous state (and nr of elements) over serial line
-            Response( 4 );                                                                  //read 4 bytes response     
+//            while(RDY.read() != 0 ) { /* wait for rdy */}
+                        
+            transmitPacket(/*(uint8_t*)A*/(uint8_t*)stateWrite, 31);                                  //Send out msg with previous state (and nr of elements) over serial line
+            Response( 4 );                                                                  //read 4 bytes response
+            
+            //compare to confirmation sequence
+            if ( responseCompare() != true){
+                    //VBB_EN.write( 0 );
+                    return false;
+                 }
+                 
             //compute crc
             CRC = modbusCrc(stateRead, 5);
+            
             //add crc value to the read request transmit package
             stateRead[5] = (uint8_t)CRC;                                                    //crc_l
             stateRead[6] = (uint8_t)(CRC >> 8);                                             //crc_h
-            timeIt( 0.35 );
+
+            timeIt( 0.20 );
+//            while(RDY.read() != 1 ) { /* wait for rdy to go high */}
+            
             //send read request
             transmitPacket(stateRead, 7);                                                   //transmit packet  
+            
             //read sensor response
-            Response( 49 );                                                                 //read sensor state and co2 value(s)
-            VBB_EN.write( 0 );                                                              //power off        
+            Response( 49 );                                                                 //get sensor state
+            VBB_EN.write( 0 );                                                              //power off 
+            
+            return true;       
        };
         
 //get value from lp8 response    
@@ -132,21 +181,22 @@
         return val;
     }
     
-    double getTempValue()
+    float getTempValue()
     {
         int h    = response[33];
         int l    = response[34]; 
         unsigned long _temp = h * 256 + l; 
         
-        double _tempVal = 0.01 * _temp;
+        float _tempVal = 0.01 * _temp;
           
         return _tempVal;
     }
     
+    /* get Vcap value for at current measurement, [35],[36] is previous Vcap value */
     int getVcapValue(){
         
-        int hB    = response[35];
-        int lB    = response[36]; 
+        int hB    = response[37];
+        int lB    = response[38]; 
         unsigned long temp = hB * 256 + lB; 
         
         return temp;
@@ -165,8 +215,8 @@
     
     //get calculation Control byte from lp8 response
     uint8_t getCCbyte(){
-        uint8_t responseCCbyte = response[0];
-        return responseCCbyte;    
+        uint8_t rCCbyte = stateWrite[5];
+        return rCCbyte;    
     }
     
 
@@ -177,21 +227,20 @@
         for (int j = 0; j < bytesToPurge; j++) {
                 response[j] = 0x00;
             }
+        //for(int k = 6; k < 31; k++) { stateWrite[k] = 0x00; }   //purge sensor state
         };
             
-//read response from lp8 (not energy efficient...)   
-    void Response(int bytesToRead ){
-        lp8Wait.start();                    //poll rx line for 0.5 seconds
+//read response from lp8  
+    void Response( int bytesToRead ){
+        int Count = 0;
         do {
             if(Device.readable()) {
-                response[counter] = Device.getc(); 
-                counter++;
+                response[Count] = Device.getc(); 
+                Count++;
+                --bytesToRead;
                 }
             }
-        while( lp8Wait.read() < 0.2 );
-        counter = 0;
-        lp8Wait.stop();
-        lp8Wait.reset();                                                        
+        while( bytesToRead > 0);                                                  
     };
     
 //transmit data over serial lines    
@@ -233,6 +282,23 @@
       return crc;  
     };
     
+    bool responseCompare(){
+        
+        short seq = 0;
+        
+        for(int j=0; j < 4; j++){
+            if(response[j] == confirmation[j]){
+                seq++;
+                }
+        }
+    //return false if check sequence fails
+        if( seq != 4 ){
+            return false;
+        } 
+    
+        return true;    
+    }
+    
 //variables and buffers
 private:
     //pins
@@ -244,15 +310,17 @@
     Timer       &lp8Wait;
     
     //msg containers 
+    
     uint8_t  firstWrite[8];     
-    uint8_t  stateWrite[31]; 
+    volatile uint8_t  stateWrite[31]; 
     uint8_t  stateRead[7];
-    uint8_t  response[60];
-
+    uint8_t  confirmation[4];
+    
+    volatile uint8_t  response[60];
+    
     //    
     int         co2;                                                                       //CO2 initial value 
     int         tempValue;  
-    int         counter;                                                                   //simple counter 
     uint16_t    CRC;                                                                       //modbus crc value