library for AMS ENS210 temperature and humidity sensor
Dependents: rIoTwear-temp-humid
Diff: AMS_ENS210.cpp
- Revision:
- 3:3b427231e5a7
- Parent:
- 2:f5a7883ae9c2
- Child:
- 4:31fbbf39d935
diff -r f5a7883ae9c2 -r 3b427231e5a7 AMS_ENS210.cpp --- a/AMS_ENS210.cpp Wed Jan 18 08:54:58 2017 +0000 +++ b/AMS_ENS210.cpp Wed Jan 18 12:04:25 2017 +0000 @@ -1,10 +1,13 @@ -#include "AMS_ENS201.h" +#include "AMS_ENS210.h" AMS_ENS210::AMS_ENS210(I2C * i2c) : _temp_mode(CONFIG_TEMP_OP_MODE), _humid_mode(CONFIG_HUMID_OP_MODE), - _power_mode(CONFIG_POWER_MODE) + _power_mode(CONFIG_POWER_MODE), + _reset(0), + temp_reading(0), + humid_reading(0) { _i2c = i2c; } @@ -12,7 +15,10 @@ AMS_ENS210::AMS_ENS210(I2C * i2c, bool temp_single_shot, bool humid_single_shot) : _temp_mode(temp_single_shot), _humid_mode(humid_single_shot), - _power_mode(CONFIG_POWER_MODE) + _power_mode(CONFIG_POWER_MODE), + _reset(0), + temp_reading(0), + humid_reading(0) { _i2c = i2c; } @@ -20,12 +26,15 @@ AMS_ENS210::AMS_ENS210(I2C * i2c, bool temp_single_shot, bool humid_single_shot, bool low_power) : _temp_mode(temp_single_shot), _humid_mode(humid_single_shot), - _power_mode(low_power) + _power_mode(low_power), + _reset(0), + temp_reading(0), + humid_reading(0) { _i2c = i2c; } -AMS_ENS210::AMS_ENS210() {} +AMS_ENS210::~AMS_ENS210() {} bool AMS_ENS210::init() { @@ -43,31 +52,37 @@ } -bool AMS_ENS210::power_mode(bool low_power) { +bool AMS_ENS210::low_power_mode(bool low_power) { _power_mode = low_power; - write_config(true, false); + return write_config(true, false); } -bool AMS_ENS210::power_mode() { +bool AMS_ENS210::low_power_mode() { return read_config(true, false)[0] & 1; // just mask bit 0 } -bool AMS_ENS210::temp_mode(bool single_shot) { - _temp_mode = single_shot; - write_config(false, true); +bool AMS_ENS210::is_active() { + char output[1]; + i2c_read(SYS_STATUS, output, 1); + return output[0] & 1; } -bool AMS_ENS210::temp_mode() { +bool AMS_ENS210::temp_continuous_mode(bool continuous) { + _temp_mode = continuous; + return write_config(false, true); +} + +bool AMS_ENS210::temp_continuous_mode() { return read_config(false, true)[0] & 1; // just mask bit 0 } -bool AMS_ENS210::humid_mode(bool single_shot) { - _humid_mode = single_shot; - write_config(false, true); +bool AMS_ENS210::humid_continuous_mode(bool continuous) { + _humid_mode = continuous; + return write_config(false, true); } -bool AMS_ENS210::humid_mode() { - return read_config(false, true)[0] & 0b10; // just mask bit 1 +bool AMS_ENS210::humid_continuous_mode() { + return (read_config(false, true)[0] >> 1) & 1; // shift bit 1 and mask } void AMS_ENS210::i2c_interface(I2C * i2c) { @@ -75,32 +90,28 @@ } bool AMS_ENS210::start(bool temp, bool humid) { - char cmd[2] = {SENS_START, 0 | temp | (humid << 1)} - return _i2c->write(SLAVE_ADDR, cmd, 2) == 2; + char cmd[1] = {0 | temp | (humid << 1)}; + return i2c_write(SENS_START, cmd, 1) == 1; //_i2c->write(SLAVE_ADDR, cmd, 2) == 2; } bool AMS_ENS210::stop(bool temp, bool humid) { - char cmd[2] = {SENS_STOP, 0 | temp | (humid << 1)} - return _i2c->write(SLAVE_ADDR, cmd, 2) == 2; + char cmd[1] = {0 | temp | (humid << 1)}; + return i2c_write(SENS_STOP, cmd, 1) == 1; //_i2c->write(SLAVE_ADDR, cmd, 2) == 2; } bool AMS_ENS210::temp_is_measuring() { - char[1] output; + char output[1]; i2c_read(SENS_STATUS, output, 1); return output[0] & 1; } -bool AMS_ENS210::humid_is _measuring() { - char[1] output; +bool AMS_ENS210::humid_is_measuring() { + char output[1]; i2c_read(SENS_STATUS, output, 1); return output[0] >> 1 & 1; } bool AMS_ENS210::temp_has_data() { - if (temp_mode()) { // when in single shot mode make sure sensor has started first - if (!temp_is_measuring()) - start(true, false); // set start bit if sensor is idle - } char output[3]; i2c_read(SENS_TEMP, output, 3); @@ -109,30 +120,45 @@ // Store read data to avoid reading from I2C again temp_reading = 0 | output[0] | (output[1] << 8); // bytes 1 and 2 make the 16 bit data - return output[3] & 1; // bit 0 of byte 3 is the valid flag + bool valid = output[2] & 1; // bit 0 of byte 3 is the valid flag + + + if (!valid) { + if (!temp_continuous_mode()) { // when in single shot mode make sure sensor has started + if (!temp_is_measuring()) + start(true, false); // set start bit if sensor is idle + } + } + + return valid; } bool AMS_ENS210::humid_has_data() { - if (humid_mode()) { // when in single shot mode make sure sensor has started first - if (!humid_is_measuring()) - start(false, true); // set start bit if sensor is idle - } char output[3]; i2c_read(SENS_HUMID, output, 3); // do crc7 // Store read data to avoid reading from I2C again - temp_reading = 0 | output[0] | (output[1] << 8); // bytes 1 and 2 make the 16 bit data + humid_reading = 0 | output[0] | (output[1] << 8); // bytes 1 and 2 make the 16 bit data + + bool valid = output[2] & 1; // bit 0 of byte 3 is the valid flag - return output[3] & 1; // bit 0 of byte 3 is the valid flag + if (!valid) { + if (!humid_continuous_mode()) { // when in single shot mode make sure sensor has started first + if (!humid_is_measuring()) + start(false, true); // set start bit if sensor is idle + } + } + + return valid; } uint16_t AMS_ENS210::temp_read() { uint16_t reading = 0; - if (temp_mode()) { // when in single shot mode, data is read and saved in temp_has_data() + if (!temp_continuous_mode()) { // when in single shot mode, data is read and saved in temp_has_data() reading = temp_reading; } else { char output[3]; @@ -149,7 +175,7 @@ uint16_t AMS_ENS210::humid_read() { uint16_t reading = 0; - if (humid_mode()) { // when in single shot mode, data is read and saved in humid_has_data() + if (!humid_continuous_mode()) { // when in single shot mode, data is read and saved in humid_has_data() reading = humid_reading; } else { char output[3]; @@ -167,33 +193,31 @@ bool AMS_ENS210::write_config(bool system, bool sensor) { int w_bytes = 0; - char cmd[2]; + char cmd[1]; if (system) { - cmd[0] = SYS_CONFIG; - cmd[1] = 0 | _power_mode | _reset << 7; // bit 0 of SYS_CTRL is power mode, bit 7 is reset - w_bytes += _i2c->write(SLAVE_ADDR, cmd, 2); + cmd[0] = 0 | _power_mode | _reset << 7; // bit 0 of SYS_CTRL is power mode, bit 7 is reset + w_bytes += i2c_write(SYS_CONFIG, cmd, 1); //_i2c->write(SLAVE_ADDR, cmd, 2); } if (sensor) { - cmd[0] = SENS_OP_MODE; - cmd[1] = 0 | _temp_mode | (_humid_mode << 1); // bit 0 is temp mode, bit 1 is humid mode - w_bytes += _i2c->write(SLAVE_ADDR, cmd, 2); + cmd[0] = 0 | _temp_mode | (_humid_mode << 1); // bit 0 is temp mode, bit 1 is humid mode + w_bytes += i2c_write(SENS_OP_MODE, cmd, 1); //_i2c->write(SLAVE_ADDR, cmd, 2); } - return w_bytes == (system + sensor)*2; // add error reporting/handling later... + return w_bytes == (system + sensor); } const char *AMS_ENS210::read_config(bool system, bool sensor) { - static char output[2]; + static char output[2] = {0, 0}; if (system) i2c_read(SYS_CONFIG, output, 1); - if (sensor) - i2c_read(SYS_CONFIG, output+system, 1); - + if (sensor) + i2c_read(SENS_OP_MODE, output+system, 1); + return output; } @@ -202,17 +226,36 @@ int read_count = 0; - _i2c->start(); // send start condition for write - if(_i2c->write(SLAVE_ADDR_W) == 1) { // write slave address - if(_i2c->write(reg_addr) == 1) { // write register address - _i2c->start(); // send another start condition for read - for (int i = 0; < len) { // read len bytes - output[i] = _i2c->read(i < len-1 ? 1 : 0); // ack all reads aside from the final one (i == len-1) - read_count++; + _i2c->start(); // send start condition for write + if(_i2c->write(SLAVE_ADDR_W) == 1) { // write slave address with write bit + if(_i2c->write(reg_addr) == 1) { // write register address + _i2c->start(); // send another start condition for read + if(_i2c->write(SLAVE_ADDR_R) == 1) { // write slave address with read bit + for (int i = 0; i < len; i++) { // read len bytes + output[i] = _i2c->read(i < len-1 ? 1 : 0); // ack all reads aside from the final one (i == len-1) + read_count++; + } } } } - _i2c->stop(); // send stop condition + _i2c->stop(); // send stop condition return read_count; +} + +int AMS_ENS210::i2c_write(char reg_addr, char* input, int len) { + + int write_count = 0; + + _i2c->start(); // send start condition for write + if(_i2c->write(SLAVE_ADDR_W) == 1) { // write slave address + if(_i2c->write(reg_addr) == 1) { // write register address + for (int i = 0; i < len; i++) { // write len bytes + if(_i2c->write(input[i]) == 1) write_count++; // write each byte, if successful increment count + } + } + } + _i2c->stop(); // send stop condition + + return write_count; } \ No newline at end of file