Marcus Lee / AMS_CCS811_gas_sensor

Dependencies:   AMS_ENS210_temp_humid_sensor

Files at this revision

API Documentation at this revision

Comitter:
UHSLMarcus
Date:
Tue Jan 24 10:47:38 2017 +0000
Parent:
6:22c0a7f2ece2
Child:
8:58a36d9218be
Commit message:
ENS210 auto poll and manual env_data functionality added

Changed in this revision

AMS_CCS811.cpp Show annotated file Show diff for this revision Revisions of this file
AMS_CCS811.h Show annotated file Show diff for this revision Revisions of this file
AMS_ENS210_temp_humid_sensor.lib Show annotated file Show diff for this revision Revisions of this file
--- a/AMS_CCS811.cpp	Mon Jan 23 14:27:57 2017 +0000
+++ b/AMS_CCS811.cpp	Tue Jan 24 10:47:38 2017 +0000
@@ -1,34 +1,6 @@
 
 #include "AMS_CCS811.h"
 
-const char *byte_to_binary(uint8_t in)
-{
-    static char b[9];
-    b[0] = '\0';
-
-    int z;
-    for (z = 128; z > 0; z >>= 1)
-    {
-        strcat(b, ((in & z) == z) ? "1" : "0");
-    }
-
-    return b;
-}
-
-const char *short_to_binary(uint16_t in)
-{
-    static char b[17];
-    b[0] = '\0';
-
-    uint16_t z;
-    for (z = 32768; z > 0; z >>= 1)
-    {
-        strcat(b, ((in & z) == z) ? "1" : "0");
-    }
-
-    return b;
-}
-
 AMS_CCS811::AMS_CCS811(I2C * i2c, PinName n_wake_pin) { 
     _n_wake_out = new (std::nothrow) DigitalOut(n_wake_pin, 1);
     _i2c = i2c; 
@@ -37,13 +9,14 @@
 AMS_CCS811::AMS_CCS811(I2C * i2c, PinName n_wake_pin, I2C * ens210_i2c) {
     _n_wake_out = new (std::nothrow) DigitalOut(n_wake_pin, 1);
     _i2c = i2c;
-    _ens210_i2c = ens210_i2c;
+    ens210_i2c_interface(ens210_i2c);
 }
               
 AMS_CCS811::~AMS_CCS811() {
     delete _n_wake_out;
     delete _addr_out;
     delete _int_data;
+    delete _ens210;
 }
 
 bool AMS_CCS811::init() {
@@ -51,6 +24,7 @@
     bool success = false;
     
     _init_errors();
+    _init_fractions();
     set_defaults();
     
     if (_n_wake_out) {
@@ -73,26 +47,43 @@
     _i2c = i2c;
 }
         
-void AMS_CCS811::ens210_i2c_interface(I2C * i2c) {
-    _ens210_i2c = i2c;
+bool AMS_CCS811::ens210_i2c_interface(I2C * i2c) {
+    bool success;
+    if (_ens210 == NULL) {
+        _ens210 = new (std::nothrow) AMS_ENS210(i2c, true, true);
+        if (_ens210 != NULL) {
+            if (_ens210->init()) {
+                success = _ens210->start();
+            }
+        } 
+    } else {
+        _ens210->i2c_interface(i2c);
+        success = true;
+    }
+    
+    if (!success) new_error(CCS811_LIB_ENS210_INIT_ID);
+    
+    return success;
 }
 
 bool AMS_CCS811::enable_ens210(bool enable) {
     
     _ens210_enabled = false;
-    if (_ens210_i2c != NULL) _ens210_enabled = enable;
+    if (_ens210 != NULL) {
+        if (_ens210->i2c_interface() != NULL) _ens210_enabled = enable;
+    }
     update_ens210_timer();
-
     return _ens210_enabled;
 }
 
 bool AMS_CCS811::ens210_is_enabled() {
+    enable_ens210(_ens210_enabled);     // Make sure the state is representive
     return _ens210_enabled;
 }
         
 void AMS_CCS811::ens210_poll_interval(int poll_ms) {
     _ens210_poll_split = poll_ms;
-    update_ens210_timer();
+    enable_ens210(_ens210_enabled);     // makes sure the state is representive, and will also update the timer
 }
 
 int AMS_CCS811::ens210_poll_interval() {
@@ -169,7 +160,23 @@
 }
 
 bool AMS_CCS811::env_data(float humid, float temp) {
-    return true;
+    char bytes[4];
+    if (humid > CCS811_MAX_HUMID) humid = CCS811_MAX_HUMID;
+    if (humid < 0) humid = 0;
+        
+    temp += 25;
+    if (temp > CCS811_MAX_TEMP) humid = CCS811_MAX_TEMP;
+    if (temp < 0) temp = 0;
+    
+    float_to_short(humid, bytes);
+    float_to_short(temp, bytes+2);
+    
+    USBserialComms.printf("humid byte0: %s ", byte_to_binary(bytes[0]));
+    USBserialComms.printf("humid byte1: %s\r", byte_to_binary(bytes[1]));
+    USBserialComms.printf("temp byte0: %s ", byte_to_binary(bytes[2]));
+    USBserialComms.printf("temp byte1: %s\r", byte_to_binary(bytes[3]));
+    
+    return i2c_write(ENV_DATA, bytes, 4) == 4;
 }
 
 
@@ -332,6 +339,7 @@
     strcpy(_error_strings[CCS811_LIB_I2CWRITE_ID+CCS811_ERR_NUM], CCS811_LIB_I2CWRITE);
     strcpy(_error_strings[CCS811_LIB_SLAVE_R_ID+CCS811_ERR_NUM], CCS811_LIB_SLAVE_R);
     strcpy(_error_strings[CCS811_LIB_INV_MODE_ID+CCS811_ERR_NUM], CCS811_LIB_INV_MODE);
+    strcpy(_error_strings[CCS811_LIB_ENS210_INIT_ID+CCS811_ERR_NUM], CCS811_LIB_ENS210_INIT);
 }
 
 void AMS_CCS811::clear_errors() {
@@ -355,6 +363,42 @@
 }
 
 void AMS_CCS811::ens210_isr() {
+    uint16_t temp_data = _ens210->temp_read(); uint16_t humind_data = _ens210->humid_read();
+    env_data((float)humind_data/512, ((float)temp_data / 64) - 273.15);
+}
+
+void AMS_CCS811::_init_fractions() {
+    
+    fractions[0] = 0.5;
+    fractions[1] = 0.25;
+    fractions[2] = 0.125;
+    fractions[3] = 0.0625;
+    fractions[4] = 0.03125;
+    fractions[5] = 0.015625;
+    fractions[6] = 0.0078125;
+    fractions[7] = 0.00390625;
+    fractions[8] = 0.001953125;
+    
+}
+
+void AMS_CCS811::float_to_short(float in, char * output) {
+
+    uint8_t int_part = (uint8_t)in;
+    float dec_part = in - int_part;
+
+    uint16_t _short = 0;
+    for (int i = 0; i < 9; i++) {
+        if (dec_part == 0) break;  
+        if (dec_part >= fractions[i]) {
+            dec_part -= fractions[i];
+            _short |= 256 >> i;
+        } else USBserialComms.printf("no\r");
+    }
+    
+    _short |= int_part << 9;
+    
+    output[0] = _short >> 8;
+    output[1] = _short;
 }
 
 void AMS_CCS811::update_slave_addr() {
--- a/AMS_CCS811.h	Mon Jan 23 14:27:57 2017 +0000
+++ b/AMS_CCS811.h	Tue Jan 24 10:47:38 2017 +0000
@@ -9,11 +9,7 @@
 #define AMS_CCS811_H
 
 #include "mbed.h"
-
-#include "serialBuffer.h"
-using utils::SerialBuffer;
-extern SerialBuffer USBserialComms;
-const char *short_to_binary(uint16_t in);
+#include "AMS_ENS210.h"
 
 /* Library defaults */
 #define CONFIG_OP_MODE              TEN_SECOND              // Every 10 seconds
@@ -42,6 +38,9 @@
 #define CCS811_T_AWAKE              55                      // us - time taken for sensor I2C to become active
 #define CCS811_T_DWAKE              25                      // us - time taken for sensor I2C to become inactive
 
+#define CCS811_MAX_HUMID            127.998046875           // maxmium value that can be represented in the register
+#define CCS811_MAX_TEMP             102.998046875           // maxmium value that can be represented in the register
+
 /* Error Codes */
 #define CCS811_NO_ERROR             "No Error";
 /* Sensor Errors */
@@ -54,7 +53,7 @@
 #define CCS811_HEATER_SUPPLY        "The Heater voltage is not being applied correctly"
 #define CCS811_RESERVED             "Reserved for Future Use"
 /* Library Errors */
-#define CCS811_LIB_ERR_NUM          7
+#define CCS811_LIB_ERR_NUM          9
 #define CCS811_LIB_N_WAKE_ID        0
 #define CCS811_LIB_N_WAKE           "nWAKE pin not set"
 #define CCS811_LIB_I2C_ID           1
@@ -69,6 +68,10 @@
 #define CCS811_LIB_SLAVE_R          "Failed to write slave read address"
 #define CCS811_LIB_INV_MODE_ID      6
 #define CCS811_LIB_INV_MODE         "Invalid operation mode"
+#define CCS811_LIB_ENS210_INIT_ID   7
+#define CCS811_LIB_ENS210_INIT      "Failed to create new AMS_ENS210 object"
+#define CCS811_LIB_ENS210_POLL_ID   7
+#define CCS811_LIB_ENS210_POLL      "AMS_ENS210 poll error"
 
 #define CCS811_TOTAL_ERR_NUM        CCS811_ERR_NUM+CCS811_LIB_ERR_NUM
 
@@ -136,8 +139,9 @@
          *
          * @param i2c  The I2C interface for an attached AMS_ENS210
          *
+         * @return Success
          */
-        void ens210_i2c_interface(I2C * i2c);
+        bool ens210_i2c_interface(I2C * i2c);
         
         /** Set whether the attached AMS_ENS210 is enabled.
          *  If an I2C interface is not set for the ENS210, calling this method will have no effect.
@@ -238,13 +242,15 @@
          */
         PinName n_wake_pin();
         
-        /** Set the relative humidity (%) and temperature (C)
-         *  Use when AMS ENS210 is not linked
+        /** Set the relative humidity (%) and temperature (C).\ \n
+         *  Use when AMS ENS210 is not linked.\ \n
+         *  Humidity values are clipped between 0 and CCS811_MAX_HUMID.\ \n
+         *  Temperature values are clipped between -25 and CCS811_MAX_TEMP.
          *
          * @return Write success
          */
         bool env_data(float humid, float temp);
-    
+        
         /** Get the sensor collection state
          *  Use when interrupts are disabled.
          *
@@ -360,18 +366,22 @@
     
     private:
         I2C* _i2c;
-        I2C* _ens210_i2c;
         
         bool _addr_dir;
         int _slave_addr;
         void update_slave_addr();
         
+        AMS_ENS210 *_ens210;
         bool _ens210_enabled;
         int _ens210_poll_split;
         void update_ens210_timer();
         Ticker _ens210_poll_t;
         void ens210_isr();
         
+        float fractions[9];
+        void _init_fractions();
+        void float_to_short(float in, char * output);
+        
         OP_MODES _mode;
         
         void set_defaults();
--- a/AMS_ENS210_temp_humid_sensor.lib	Mon Jan 23 14:27:57 2017 +0000
+++ b/AMS_ENS210_temp_humid_sensor.lib	Tue Jan 24 10:47:38 2017 +0000
@@ -1,1 +1,1 @@
-https://developer.mbed.org/users/UHSLMarcus/code/AMS_ENS210_temp_humid_sensor/#22b8ef3a65e1
+https://developer.mbed.org/users/UHSLMarcus/code/AMS_ENS210_temp_humid_sensor/#475b764b720d