Private Private / Mbed 2 deprecated SenseAirLP8

Dependencies:   BLE_API mbed nRF51822

Fork of SenseAirLP8 by Jonas Skalman

Files at this revision

API Documentation at this revision

Comitter:
jony1401
Date:
Mon Jun 05 11:10:28 2017 +0000
Parent:
0:ee3787c8e209
Child:
2:d02255d8c36f
Commit message:
Reading Senseair LP8 CO2 sensor over bluetooth low energy with readbearlabs ble nano.

Changed in this revision

LP8.h Show annotated file Show diff for this revision Revisions of this file
main.cpp Show annotated file Show diff for this revision Revisions of this file
--- a/LP8.h	Fri Apr 21 13:26:06 2017 +0000
+++ b/LP8.h	Mon Jun 05 11:10:28 2017 +0000
@@ -1,159 +1,139 @@
 #ifndef LP8_H
 #define LP8_H
 
+/* To initialize the lp8 object, you need to pass a serial (tx, rx), an DigitalOut signal for the en_vbb,
+an DigitalIn for the ready signal and a timer object. */
+
 class LP8 
 {
 public:
-
-    //constructor
-    LP8(Serial &device, DigitalOut &vbb, DigitalOut &vbb_en, DigitalIn &rdy, Timer &_timer):                  /* initiate class object */
-        Device(device),
-        VBB(vbb),
-        VBB_EN(vbb_en),
-        RDY(rdy),
-        lp8Wait(_timer)
-        {
-            Device.baud(9600);                                                              //set baud rate to 9600 
+//constructor
+    LP8(Serial &device, DigitalOut &vbb_en, DigitalIn &rdy, Timer &_timer):  
+     Device(device),
+     VBB_EN(vbb_en),
+     RDY(rdy),
+     lp8Wait(_timer)
+    {
+        Device.baud(9600);                                                              //set baud rate to 9600 
             
-            //initialize arrays with modbus commands. 
-            //initial startup command
-            firstWrite[0] = 0xfe;
-            firstWrite[1] = 0x41;
-            firstWrite[2] = 0x00;
-            firstWrite[3] = 0x80;
-            firstWrite[4] = 0x01;
-            firstWrite[5] = 0x10;
-            firstWrite[6] = 0x28;
-            firstWrite[7] = 0x7e;
+        //initialize arrays with lp8 modbus commands. 
+        //initial startup command:
+        firstWrite[0] = 0xfe;                                                           //device adress
+        firstWrite[1] = 0x41;                                                           //write to ram
+        firstWrite[2] = 0x00;                                                           //
+        firstWrite[3] = 0x80;                                                           //starting adress
+        firstWrite[4] = 0x01;                                                           //nr of bytes to send
+        firstWrite[5] = 0x10;                                                           //calculation control byte  
+        firstWrite[6] = 0x28;                                                           //crc low
+        firstWrite[7] = 0x7e;                                                           //crc high
             
-            //write sensor state to lp8 command
-            stateWrite[0] = 0xfe;                                                   //device adress
-            stateWrite[1] = 0x41;                                                   //read/write
-            stateWrite[2] = 0x00;                                                   //
-            stateWrite[3] = 0x80;                                                   //starting adress
-            stateWrite[4] = 0x18;                                                   //nr of bytes to send
-            stateWrite[5] = 0x20;                                                   //Calculation Control 
-            for(int k = 6; k < 31; k++) { stateWrite[k] = 0x00; }
+        //write previous sensor state to lp8, command:
+        stateWrite[0] = 0xfe;                                                           //device adress
+        stateWrite[1] = 0x41;                                                           //write to ram
+        stateWrite[2] = 0x00;                                                           //
+        stateWrite[3] = 0x80;                                                           //starting adress
+        stateWrite[4] = 0x18;                                                           //nr of bytes to send
+        stateWrite[5] = 0x20;                                                           //Calculation Control 
+        for(int k = 6; k < 31; k++) { stateWrite[k] = 0x00; }                           //
             
-            //read lp8 state command
-            stateRead[0] = 0xfe;        
-            stateRead[1] = 0x44;
-            stateRead[2] = 0x00;
-            stateRead[3] = 0x80;
-            stateRead[4] = 0x2c;
-            stateRead[5] = 0x00;
-            stateRead[5] = 0x00;
-            //response buffer
-            for(int k = 0; k < 60; k++) { response[k] = 0x00; }
+        //read request from the lp8:
+        stateRead[0] = 0xfe;                                                            //adress
+        stateRead[1] = 0x44;                                                            //read from ram
+        stateRead[2] = 0x00;                                                            //
+        stateRead[3] = 0x80;                                                            //starting adress
+        stateRead[4] = 0x2c;                                                            //number of bytes to read
+        stateRead[5] = 0x00;                                                            //crc_l
+        stateRead[5] = 0x00;                                                            //crc_h
+            
+        //response buffer
+        for(int k = 0; k < 60; k++) { response[k] = 0x00; }
 
-
-//            gC      = 0x00;
-            co2     = 400;                                                              
-            counter = 0;                                                                 
-            CRC     = 0x0000;
-            _timeMe = 0.3;
-        };
+        //variable initialization
+        co2     = 400;                                                                  //co2 value
+        counter = 0;                                                                    //
+        CRC     = 0x0000;                                                               //crc value
+        _timeMe = 0.350;                                                                //wait timer(ms)
+    };
 
     
-    //send startup msg                 .
+//LP8 Initialization                  .
     bool lp8Init(){
-            VBB.write( 1 );
             VBB_EN.write( 1 );                                                              //power on
-            timeIt( _timeMe );
-            
-            transmitPacket(firstWrite, 8);                                                  //Send out msg (and nr of elements) over serial line
+            //wait for rdy signal
+            timeIt( _timeMe );                                                              //wait for lp8 rdy signal
+            transmitPacket(firstWrite, 8);                                                  //Send out msg (and nr of bytes) over serial line
             Response( 4 );                                                                  //read 4 bytes response     
-            
-            if( RDY.read() == 0 ) {
-                lp8Wait.start();
-                while( lp8Wait.read() < 0.5 ) { /* spin */ }
-                lp8Wait.stop();
-                lp8Wait.reset(); 
-            }          
-            
-//compute crc
+            //compute crc
             CRC = modbusCrc(stateRead, 5);
-//add crc value to the transmit package
-            stateRead[5] = (uint8_t)CRC;                                                    //crc_H
-            stateRead[6] = (uint8_t)(CRC >> 8);                                             //crc_L
-            timeIt( _timeMe );                                                              //wait for message to be sent and processed
+            //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( _timeMe );                                                              //
             transmitPacket(stateRead, 7);                                                   //transmit packet  
             Response( 49 );                                                                 //read sensor state and co2 value(s)
- 
-            VBB_EN.write( 0 );                                                              //power off
-            VBB.write( 0 );           
-                        
-//was the talk a success?
+            VBB_EN.write( 0 );                                                              //power off lp8                 
+            //was the talk a success? (simple check...)
             if ( getValue() < 1 ) {
                 return 1; }
             else {
                 return 0; }
-            
         };
     
-    
-    //send subsequent messages to the lp8
-    void lp8Talk(){
-
+//send subsequent messages to the lp8
+    void lp8Talk(uint8_t ccByte){
             //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;
             //compute new crc value
             CRC = modbusCrc(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.write( 1 );
             VBB_EN.write( 1 );                                                              //power on sensor
             timeIt( _timeMe );
-            
             transmitPacket(stateWrite, 31);                                                 //Send out msg with previous state (and nr of elements) over serial line
             Response( 4 );                                                                  //read 4 bytes response     
-
             //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( _timeMe );
             //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
-            VBB.write( 0 );
+            VBB_EN.write( 0 );                                                              //power off        
        };
-    
-    
-    
-    //get co2 value from lp8 response    
+        
+//get co2 value from lp8 response    
     unsigned long getValue()
     {
-        int high = response[29];
-        int low = response[30]; 
+        int high    = response[29];
+        int low     = response[30]; 
         unsigned long val = high * 256 + low; 
     
         return val;
     }
 
-        
-        
-    /************************************************* Helper Functions ********************************************/
-    /*************************************************                  ********************************************/
+
+/************************************************* Helper Functions ********************************************/
+/*************************************************                  ********************************************/
+//purge response buffer
     void responsePurge(int bytesToPurge){
         for (int j = 0; j < bytesToPurge; j++) {
                 response[j] = 0x00;
             }
         };
-        
-    
-    //read from the lp8    
+            
+//read from the lp8    
     void Response(int bytesToRead ){
-        lp8Wait.start();                    //poll rx line for x seconds
+        lp8Wait.start();                    //poll rx line for 0.5 seconds
         do {
             if(Device.readable()) {
                 response[counter] = Device.getc(); 
@@ -166,6 +146,7 @@
         lp8Wait.reset();                                                        
     };
     
+//transmit data over serial lines    
     void transmitPacket(uint8_t msg[], int le ){
             //Send out msg over serial line:
             while(!Device.writeable() ) { /* wait for serial available*/ }
@@ -175,7 +156,7 @@
             
         };
     
-    //timer
+//timer
     void timeIt(float &timeMe){
             //start amd stop timer...
             lp8Wait.start();
@@ -184,7 +165,7 @@
             lp8Wait.reset();
         };
     
-    // Computation for the modbus 16-bit crc
+// Computation for the modbus 16-bit crc
     uint16_t modbusCrc(uint8_t buffer[], int len){
       uint16_t crc = 0xFFFF;
       
@@ -203,19 +184,16 @@
       // Note, this number has low and high bytes swapped
       return crc;  
     };
-
-
-
-
+    
+//variables and buffers
 private:
 
     Serial      &Device;
-    DigitalOut  &VBB;
     DigitalOut  &VBB_EN;    
     DigitalIn   &RDY;
     Timer       &lp8Wait;
     
-    //msg containers (needs to be initialized at constructor level)
+    //msg containers 
     uint8_t  firstWrite[8];     
     uint8_t  stateWrite[31]; 
     uint8_t  stateRead[7];
@@ -225,14 +203,13 @@
     int         counter;                                                                   //simple counter 
     uint16_t    CRC;                                                                       //modbus crc value
     float       _timeMe;                                                                   //timer value
-//    uint8_t     gC;                                                                         //getCharacter...
 
 
 };
 #endif
 
 /* 
-LP8 Communication Protocol (With no external Pressure Sensor):
+LP8 Modbus Communication Protocol (With no external Pressure Sensor):
 --------------------------------------------------------------------------------
 Initial Measurement (first read after powerup):                                     COMMANDS:
 --------------------------------------------------------------------------------
@@ -272,6 +249,26 @@
 
 
 --------------------------------------------------------------------------------
+LP8 Background Calibration, Calculation Control Byte 
+--------------------------------------------------------------------------------
+To calibrate the lp8, commands needs to be sent with the calculation control byte
+Calculation:
+CC =
+0x10 Initial measurement (filters reset, ABC sample reset and other,
+0x20 Subsequent measurement,
+0x40 Zero calibration using unfiltered data,
+0x41 Zero calibration using filtered data,
+0x42 Zero calibration using unfiltered data + reset filters,
+0x43 Zero calibration using filtered data + reset filters,
+0x50 Background calibration using unfiltered data,
+0x51 Background calibration using filtered data,
+0x52 Background calibration using unfiltered data + reset filters,
+0x53 Background calibration using filtered data + reset filters,
+0x70 ABC (based on filtered data),
+0x72 ABC (based on filtered data) + reset filters
+
+
+--------------------------------------------------------------------------------
 --------------------------------------------------------------------------------
 CC = Calculation Control, 1 byte
 SS = Sensor State, Sensor State, 23 bytes
--- a/main.cpp	Fri Apr 21 13:26:06 2017 +0000
+++ b/main.cpp	Mon Jun 05 11:10:28 2017 +0000
@@ -7,18 +7,16 @@
 BLE             ble;                                                                    //BLE object
 
 // Pins and timers needed for lp8 communication
-DigitalIn       RDY(P0_8);                                                              //
-DigitalOut      VBB(P0_5);
-DigitalOut      VBB_EN(P0_4);                                                        //
+DigitalIn       RDY(P0_5);                                                              //
+DigitalOut      VBB_EN(P0_29, 0);                                                       //set to low at startup
 Serial          Device(P0_9, P0_11);                                                    //tx, rx
-DigitalOut      led1(P0_19, 1);                                                         //board led
 Timer           lp8Wait;                                                                //timer for sensor communication
 
 
 
 //Sensor and ble Configuration parameters
-#define     SENSOR_TIMER                        10.0                                    //lp8 polling interval (seconds)
-#define     BLE_ADV_INTERVAL                    500                                     //advertisment interval (milliseconds)
+#define     SENSOR_TIMER                        20.0                                    //lp8 polling interval (seconds)
+#define     BLE_ADV_INTERVAL                    1000                                    //advertisment interval (milliseconds)
 
 
 
@@ -28,23 +26,21 @@
 
 
 //check for sensor triggering and uppdating Gatt Server
-bool                    triggerSensor = false;                                          //check for sensor polling
+bool                    triggerSensor = false;                                          //check for sensor polling, used with interupt
 LP8_Service             *lp8ServicePtr;                                                 //pointer to lp8 service object
 
 
 
 //****************************   ble functions      *******************************
-//****************************                      *******************************
 // on Disconnect, Restart BroadCasting
 void disconnectionCallback(const Gap::DisconnectionCallbackParams_t *params)
 {
-    //reset I/O pin, necessary?
-//    VBB_EN.write ( 1 );
-    
+    //turn of sensor at ble disconnect
+    VBB_EN.write( 0 );
     //restart broadcast
     ble.gap().startAdvertising();
 }
-//timer function callback function
+//timer function callback
 void triggerSensorPollingInterupt()
 {
     triggerSensor = true;
@@ -55,7 +51,7 @@
 //main 
 int main(void)
 {
-    led1 = 1;      //turn off led                                                                
+    wait(1); 
     
     Ticker lp8Timer;                                                                    //timer object for sensor polling interupts
     lp8Timer.attach(&triggerSensorPollingInterupt, SENSOR_TIMER);                       //trigger sensor reading every X.Y sec
@@ -64,12 +60,17 @@
     ble.gap().onDisconnection(disconnectionCallback);                                   //do callback if disconnection occurs
 
 
-    int                     co2Value = 400;                                             //initial CO2 value
-    bool                    initCheck = true;                                           //check for init sensor state or lost state
-    bool                    successCheck = false;
+    int                     co2Value = 400;                                             //initial CO2 value to display
+    bool                    initCheck = true;                                           //check for init sensor state (or lost state)
+    bool                    successCheck = false;                                       //check for sensor communication
+    //calibration control bytes for the lp 8
+    uint8_t                 subsequentMeasurement       = 0x20;                         //lp8 calculation control byte for subs. measurements
+    uint8_t                 noResetABC                  = 0x70;                         //abc calibration byte with no reset on filters
+    uint8_t                 resetABC                    = 0x72;                         //abc calibration AND resets filters
+    uint8_t                 backgroundCalibration       = 0x52;                         //background calibration using unfilterd data + resets filters
     
-//setup LP8 peripheral communication 
-    LP8               lp8(Device, VBB, VBB_EN, RDY, lp8Wait);
+//setup LP8 object 
+    LP8               lp8(Device, VBB_EN, RDY, lp8Wait);                                //constructor needs 4 arguments
      
      
 //setup for GattService
@@ -78,45 +79,42 @@
     lp8ServicePtr     = &lp8Service;                                                    //set pointer to "real" lp8 service object
 
 
-/* setup advertising parameters */
+/* setup ble advertising parameters */
     ble.gap().accumulateAdvertisingPayload(GapAdvertisingData::BREDR_NOT_SUPPORTED | GapAdvertisingData::LE_GENERAL_DISCOVERABLE);            //general bluetooth information(only support for ble
     ble.gap().accumulateAdvertisingPayload(GapAdvertisingData::COMPLETE_LIST_16BIT_SERVICE_IDS, (uint8_t *)uuid16_list, sizeof(uuid16_list)); //service list
     ble.gap().accumulateAdvertisingPayload(GapAdvertisingData::COMPLETE_LOCAL_NAME, (uint8_t *)DEVICE_NAME, sizeof(DEVICE_NAME));
     ble.gap().setAdvertisingType(GapAdvertisingParams::ADV_CONNECTABLE_UNDIRECTED);
-    ble.gap().setAdvertisingInterval(BLE_ADV_INTERVAL);                 /* advertising interval in ms. */
-    ble.gap().startAdvertising();                                       //start broadcast
+    ble.gap().setAdvertisingInterval(BLE_ADV_INTERVAL);                                 /* advertising interval in ms. */
+    ble.gap().startAdvertising();                                                       //start broadcast
     
-        /* SpinWait for initialization to complete. This is necessary because the
-     * BLE object is used in the main loop below. */
+        /* SpinWait for initialization to complete. */
     while (ble.hasInitialized()  == false) { /* spin loop */ }
 
 
 
-//start the loop    
+//start the main loop    
     while ( true ) 
     {
-        if(triggerSensor && ble.gap().getState().connected )                            //trigger when timer interupts ticks and there is an established connection
+        if(triggerSensor && ble.gap().getState().connected )                            //trigger when timer interupts and there is an established ble connection
         {
             if ( initCheck ) {
-                successCheck = lp8.lp8Init();
+                successCheck = lp8.lp8Init();                                           //initialize talking with the lp8 (first call on startup)
                 
-//                if ( successCheck ) {
+                if ( successCheck ) {
                     initCheck = false;
-//                    led1 = 0;       //turn on led 
-//                }
+                }
             }
             else {
-                lp8.lp8Talk();
-                led1 = 0;   //on when talking
+                lp8.lp8Talk( subsequentMeasurement );                                   //Communication with the lp8, sends calculation control: 0x20 == subs. talks
             }
+            //reset polling check
+            triggerSensor = false;
             
-            //reset sensor status
-            triggerSensor = false;
-            //update gattServer with new CO2 value
+            //update the gattServer with new CO2 value
             lp8ServicePtr->updateCo2Value( lp8.getValue() );
         }
         
-        else { ble.waitForEvent(); }                //ble save energy
+        else { ble.waitForEvent(); }                                                    //ble save energy
     }
     
 };