simple CCS811 driver

Dependencies:   AMS_ENS210_temp_humid_sensor

Dependents:   TBSense2_Sensor_Demo

Fork of AMS_CCS811_gas_sensor by Marcus Lee

Revision:
7:5c95614a61ee
Parent:
6:22c0a7f2ece2
Child:
8:58a36d9218be
--- 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() {