A Library for the AMS ENS210 temperature and humidity sensor.

Dependents:   AMS_CCS811_gas_sensor AMS_CCS811_gas_sensor

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers AMS_ENS210.cpp Source File

AMS_ENS210.cpp

00001 
00002 #include "AMS_ENS210.h"
00003 
00004 AMS_ENS210::AMS_ENS210(PinName sda, PinName scl) :
00005     _temp_mode(CONFIG_TEMP_OP_MODE),
00006     _humid_mode(CONFIG_HUMID_OP_MODE),
00007     _power_mode(CONFIG_POWER_MODE),
00008     _reset(0),
00009     temp_reading(0),
00010     humid_reading(0),
00011     _i2c(sda, scl)
00012 { }
00013 
00014 AMS_ENS210::AMS_ENS210(PinName sda, PinName scl, bool temp_single_shot, bool humid_single_shot) :
00015     _temp_mode(temp_single_shot),
00016     _humid_mode(humid_single_shot),
00017     _power_mode(CONFIG_POWER_MODE),
00018     _reset(0),
00019     temp_reading(0),
00020     humid_reading(0),
00021     _i2c(sda, scl)
00022 { }
00023 
00024 AMS_ENS210::AMS_ENS210(PinName sda, PinName scl, bool temp_single_shot, bool humid_single_shot, bool low_power) :
00025     _temp_mode(temp_single_shot),
00026     _humid_mode(humid_single_shot),
00027     _power_mode(low_power),
00028     _reset(0),
00029     temp_reading(0),
00030     humid_reading(0),
00031     _i2c(sda, scl)
00032 { }
00033 
00034 AMS_ENS210::~AMS_ENS210() {}
00035 
00036 bool AMS_ENS210::init()
00037 {
00038 
00039     return write_config();
00040 
00041 }
00042 
00043 bool AMS_ENS210::reset()
00044 {
00045 
00046     _reset = true;
00047     bool success = write_config(true, false);
00048     _reset = false;
00049 
00050     return success;
00051 
00052 }
00053 
00054 bool AMS_ENS210::low_power_mode(bool low_power)
00055 {
00056     _power_mode = low_power;
00057     return write_config(true, false);
00058 }
00059 
00060 bool AMS_ENS210::low_power_mode()
00061 {
00062     return read_config(true, false)[0] & 1; // just mask bit 0
00063 }
00064 
00065 bool AMS_ENS210::is_active()
00066 {
00067     char output[1];
00068     i2c_read(SYS_STATUS, output, 1);
00069     return output[0] & 1;
00070 }
00071 
00072 bool AMS_ENS210::temp_continuous_mode(bool continuous)
00073 {
00074     _temp_mode = continuous;
00075     return write_config(false, true);
00076 }
00077 
00078 bool AMS_ENS210::temp_continuous_mode()
00079 {
00080     return read_config(false, true)[0] & 1; // just mask bit 0
00081 }
00082 
00083 bool AMS_ENS210::humid_continuous_mode(bool continuous)
00084 {
00085     _humid_mode = continuous;
00086     return write_config(false, true);
00087 }
00088 
00089 bool AMS_ENS210::humid_continuous_mode()
00090 {
00091     return (read_config(false, true)[0] >> 1) & 1; // shift bit 1 and mask
00092 }
00093 
00094 bool AMS_ENS210::start(bool temp, bool humid)
00095 {
00096     char cmd[1] = {0 | temp | (humid << 1)};
00097     return i2c_write(SENS_START, cmd, 1) == 1; //_i2c.write(ENS210_SLAVE_ADDR, cmd, 2) == 2;
00098 }
00099 
00100 bool AMS_ENS210::stop(bool temp, bool humid)
00101 {
00102     char cmd[1] = {0 | temp | (humid << 1)};
00103     return i2c_write(SENS_STOP, cmd, 1) == 1; //_i2c.write(ENS210_SLAVE_ADDR, cmd, 2) == 2;
00104 }
00105 
00106 bool AMS_ENS210::temp_is_measuring()
00107 {
00108     char output[1];
00109     i2c_read(SENS_STATUS, output, 1);
00110     return output[0] & 1;
00111 }
00112 
00113 bool AMS_ENS210::humid_is_measuring()
00114 {
00115     char output[1];
00116     i2c_read(SENS_STATUS, output, 1);
00117     return output[0] >> 1 & 1;
00118 }
00119 
00120 bool AMS_ENS210::temp_has_data()
00121 {
00122 
00123     char output[3];
00124     i2c_read(SENS_TEMP, output, 3);
00125 
00126     // do crc7
00127     // Store read data to avoid reading from I2C again
00128     temp_reading = 0 | output[0] | (output[1] << 8);    // bytes 1 and 2 make the 16 bit data
00129 
00130     bool valid = output[2] & 1;                         // bit 0 of byte 3 is the valid flag
00131 
00132 
00133     if (!valid) {
00134         if (!temp_continuous_mode()) {                  // when in single shot mode make sure sensor has started
00135             if (!temp_is_measuring())
00136                 start(true, false);                     // set start bit if sensor is idle
00137         }
00138     }
00139 
00140     return valid;
00141 }
00142 
00143 bool AMS_ENS210::humid_has_data()
00144 {
00145 
00146     char output[3];
00147     i2c_read(SENS_HUMID, output, 3);
00148 
00149     // do crc7
00150     // Store read data to avoid reading from I2C again
00151     humid_reading = 0 | output[0] | (output[1] << 8);   // bytes 1 and 2 make the 16 bit data
00152 
00153     bool valid = output[2] & 1;                         // bit 0 of byte 3 is the valid flag
00154 
00155     if (!valid) {
00156         if (!humid_continuous_mode()) {                 // when in single shot mode make sure sensor has started first
00157             if (!humid_is_measuring())
00158                 start(false, true);                     // set start bit if sensor is idle
00159         }
00160     }
00161 
00162     return valid;
00163 }
00164 
00165 uint16_t AMS_ENS210::temp_read()
00166 {
00167 
00168     uint16_t reading = 0;
00169 
00170     if (!temp_continuous_mode()) {                          // when in single shot mode, data is read and saved in temp_has_data()
00171         reading = temp_reading;
00172     } else {
00173         char output[3];
00174         i2c_read(SENS_TEMP, output, 3);
00175 
00176         // do crc7
00177         if (output[2] & 1)                                  // bit 0 of byte 3 is the valid flag
00178             reading = 0 | output[0] | (output[1] << 8);     // bytes 1 and 2 make the 16 bit data
00179     }
00180 
00181     return reading;
00182 }
00183 
00184 uint16_t AMS_ENS210::humid_read()
00185 {
00186     uint16_t reading = 0;
00187 
00188     if (!humid_continuous_mode()) {                         // when in single shot mode, data is read and saved in humid_has_data()
00189         reading = humid_reading;
00190     } else {
00191         char output[3];
00192         i2c_read(SENS_HUMID, output, 3);
00193 
00194         // do crc7
00195         if (output[2] & 1)                                  // bit 0 of byte 3 is the valid flag
00196             reading = 0 | output[0] | (output[1] << 8);     // bytes 1 and 2 make the 16 bit data
00197     }
00198 
00199     return reading;
00200 }
00201 
00202 /*** Private ***/
00203 
00204 bool AMS_ENS210::write_config(bool system, bool sensor)
00205 {
00206     int w_bytes = 0;
00207     char cmd[1];
00208 
00209     if (system) {
00210         cmd[0] = 0 | _power_mode | _reset << 7; // bit 0 of SYS_CTRL is power mode, bit 7 is reset
00211         w_bytes += i2c_write(SYS_CONFIG, cmd, 1); //_i2c.write(ENS210_SLAVE_ADDR, cmd, 2);
00212     }
00213 
00214     if (sensor) {
00215         cmd[0] = 0 | _temp_mode | (_humid_mode << 1); // bit 0 is temp mode, bit 1 is humid mode
00216         w_bytes += i2c_write(SENS_OP_MODE, cmd, 1); //_i2c.write(ENS210_SLAVE_ADDR, cmd, 2);
00217     }
00218 
00219     return w_bytes == (system + sensor);
00220 }
00221 
00222 const char *AMS_ENS210::read_config(bool system, bool sensor)   // todo, maybe throw excpetion if i2c read fails?
00223 {
00224 
00225     static char output[2] = {0, 0};
00226 
00227     if (system)
00228         i2c_read(SYS_CONFIG, output, 1);
00229 
00230     if (sensor)
00231         i2c_read(SENS_OP_MODE, output+system, 1);
00232 
00233     return output;
00234 
00235 }
00236 
00237 int AMS_ENS210::i2c_read(char reg_addr, char* output, int len)
00238 {
00239 
00240     int read_count = 0;
00241 
00242 
00243     char reg_cmd[1];
00244     reg_cmd[0] = reg_addr;
00245     _i2c.write(ENS210_SLAVE_ADDR, reg_cmd, 1, true);
00246     wait_ms(10);
00247     int read_res = _i2c.read(ENS210_SLAVE_ADDR, output, len);
00248     if (read_res == 0) read_count = len;
00249 
00250     return read_count;
00251 }
00252 
00253 int AMS_ENS210::i2c_write(char reg_addr, char* input, int len)
00254 {
00255 
00256     int write_count = 0;
00257 
00258 
00259     char cmd[len+1];
00260     cmd[0] = reg_addr;
00261     memcpy(cmd+1, input, len);
00262     write_count = _i2c.write(ENS210_SLAVE_ADDR, cmd, len+1) + 1;
00263 
00264     return write_count;
00265 }