library for AMS ENS210 temperature and humidity sensor
Dependents: rIoTwear-temp-humid
Diff: AMS_ENS210.cpp
- Revision:
- 8:1a7d241afbcb
- Parent:
- 7:d61772b5cd3b
- Child:
- 9:e121ac861a82
--- a/AMS_ENS210.cpp Tue Jan 24 14:08:26 2017 +0000 +++ b/AMS_ENS210.cpp Wed Mar 08 09:44:13 2017 +0000 @@ -1,268 +1,265 @@ #include "AMS_ENS210.h" -AMS_ENS210::AMS_ENS210(I2C * i2c) : - _temp_mode(CONFIG_TEMP_OP_MODE), - _humid_mode(CONFIG_HUMID_OP_MODE), +AMS_ENS210::AMS_ENS210(PinName sda, PinName scl) : + _temp_mode(CONFIG_TEMP_OP_MODE), + _humid_mode(CONFIG_HUMID_OP_MODE), _power_mode(CONFIG_POWER_MODE), _reset(0), temp_reading(0), humid_reading(0), - _i2c() -{ - _i2c = i2c; -} + _i2c(sda, scl) +{ } -AMS_ENS210::AMS_ENS210(I2C * i2c, bool temp_single_shot, bool humid_single_shot) : - _temp_mode(temp_single_shot), - _humid_mode(humid_single_shot), +AMS_ENS210::AMS_ENS210(PinName sda, PinName scl, bool temp_single_shot, bool humid_single_shot) : + _temp_mode(temp_single_shot), + _humid_mode(humid_single_shot), _power_mode(CONFIG_POWER_MODE), _reset(0), temp_reading(0), humid_reading(0), - _i2c() -{ - _i2c = i2c; -} + _i2c(sda, scl) +{ } -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), +AMS_ENS210::AMS_ENS210(PinName sda, PinName scl, 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), _reset(0), temp_reading(0), humid_reading(0), - _i2c() -{ - _i2c = i2c; -} + _i2c(sda, scl) +{ } AMS_ENS210::~AMS_ENS210() {} -bool AMS_ENS210::init() { - +bool AMS_ENS210::init() +{ + return write_config(); - + } -bool AMS_ENS210::reset() { - +bool AMS_ENS210::reset() +{ + _reset = true; bool success = write_config(true, false); _reset = false; - + return success; - + } -bool AMS_ENS210::low_power_mode(bool low_power) { +bool AMS_ENS210::low_power_mode(bool low_power) +{ _power_mode = low_power; return write_config(true, false); } -bool AMS_ENS210::low_power_mode() { +bool AMS_ENS210::low_power_mode() +{ return read_config(true, false)[0] & 1; // just mask bit 0 } -bool AMS_ENS210::is_active() { +bool AMS_ENS210::is_active() +{ char output[1]; i2c_read(SYS_STATUS, output, 1); - return output[0] & 1; + return output[0] & 1; } -bool AMS_ENS210::temp_continuous_mode(bool continuous) { +bool AMS_ENS210::temp_continuous_mode(bool continuous) +{ _temp_mode = continuous; return write_config(false, true); } -bool AMS_ENS210::temp_continuous_mode() { +bool AMS_ENS210::temp_continuous_mode() +{ return read_config(false, true)[0] & 1; // just mask bit 0 } -bool AMS_ENS210::humid_continuous_mode(bool continuous) { +bool AMS_ENS210::humid_continuous_mode(bool continuous) +{ _humid_mode = continuous; return write_config(false, true); } -bool AMS_ENS210::humid_continuous_mode() { +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) { - _i2c = i2c; -} - -I2C* AMS_ENS210::i2c_interface() { - return _i2c; +bool AMS_ENS210::start(bool temp, bool humid) +{ + char cmd[1] = {0 | temp | (humid << 1)}; + return i2c_write(SENS_START, cmd, 1) == 1; //_i2c.write(ENS210_SLAVE_ADDR, cmd, 2) == 2; } -bool AMS_ENS210::start(bool temp, bool humid) { +bool AMS_ENS210::stop(bool temp, bool humid) +{ char cmd[1] = {0 | temp | (humid << 1)}; - return i2c_write(SENS_START, cmd, 1) == 1; //_i2c->write(ENS210_SLAVE_ADDR, cmd, 2) == 2; + return i2c_write(SENS_STOP, cmd, 1) == 1; //_i2c.write(ENS210_SLAVE_ADDR, cmd, 2) == 2; } -bool AMS_ENS210::stop(bool temp, bool humid) { - char cmd[1] = {0 | temp | (humid << 1)}; - return i2c_write(SENS_STOP, cmd, 1) == 1; //_i2c->write(ENS210_SLAVE_ADDR, cmd, 2) == 2; -} - -bool AMS_ENS210::temp_is_measuring() { +bool AMS_ENS210::temp_is_measuring() +{ char output[1]; i2c_read(SENS_STATUS, output, 1); - return output[0] & 1; + return output[0] & 1; } - -bool AMS_ENS210::humid_is_measuring() { + +bool AMS_ENS210::humid_is_measuring() +{ char output[1]; i2c_read(SENS_STATUS, output, 1); - return output[0] >> 1 & 1; + return output[0] >> 1 & 1; } -bool AMS_ENS210::temp_has_data() { - +bool AMS_ENS210::temp_has_data() +{ + char output[3]; i2c_read(SENS_TEMP, output, 3); - + // do crc7 - // Store read data to avoid reading from I2C again + // 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 - + 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()) + if (!temp_is_measuring()) start(true, false); // set start bit if sensor is idle } } - + return valid; } -bool AMS_ENS210::humid_has_data() { - +bool AMS_ENS210::humid_has_data() +{ + char output[3]; i2c_read(SENS_HUMID, output, 3); - + // do crc7 - // Store read data to avoid reading from I2C again + // Store read data to avoid reading from I2C again 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 - + if (!valid) { - if (!humid_continuous_mode()) { // when in single shot mode make sure sensor has started first - if (!humid_is_measuring()) + 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 AMS_ENS210::temp_read() +{ + uint16_t reading = 0; - + 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]; i2c_read(SENS_TEMP, output, 3); - + // do crc7 if (output[2] & 1) // bit 0 of byte 3 is the valid flag reading = 0 | output[0] | (output[1] << 8); // bytes 1 and 2 make the 16 bit data } - + return reading; } -uint16_t AMS_ENS210::humid_read() { +uint16_t AMS_ENS210::humid_read() +{ uint16_t reading = 0; - + 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]; i2c_read(SENS_HUMID, output, 3); - + // do crc7 if (output[2] & 1) // bit 0 of byte 3 is the valid flag reading = 0 | output[0] | (output[1] << 8); // bytes 1 and 2 make the 16 bit data } - + return reading; } /*** Private ***/ -bool AMS_ENS210::write_config(bool system, bool sensor) { +bool AMS_ENS210::write_config(bool system, bool sensor) +{ int w_bytes = 0; char cmd[1]; - + if (system) { 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(ENS210_ENS210_ENS210_ENS210_ENS210_ENS210_ENS210_SLAVE_ADDR, cmd, 2); + w_bytes += i2c_write(SYS_CONFIG, cmd, 1); //_i2c.write(ENS210_SLAVE_ADDR, cmd, 2); } - + if (sensor) { 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(ENS210_ENS210_ENS210_ENS210_ENS210_ENS210_ENS210_SLAVE_ADDR, cmd, 2); + w_bytes += i2c_write(SENS_OP_MODE, cmd, 1); //_i2c.write(ENS210_SLAVE_ADDR, cmd, 2); } - + return w_bytes == (system + sensor); } -const char *AMS_ENS210::read_config(bool system, bool sensor) { // todo, maybe throw excpetion if i2c read fails? - +const char *AMS_ENS210::read_config(bool system, bool sensor) // todo, maybe throw excpetion if i2c read fails? +{ + static char output[2] = {0, 0}; - + if (system) i2c_read(SYS_CONFIG, output, 1); - - if (sensor) + + if (sensor) i2c_read(SENS_OP_MODE, output+system, 1); return output; - + } -int AMS_ENS210::i2c_read(char reg_addr, char* output, int len) { - +int AMS_ENS210::i2c_read(char reg_addr, char* output, int len) +{ + int read_count = 0; - - _i2c->start(); // send start condition for write - if(_i2c->write(ENS210_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(ENS210_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 - + + + char reg_cmd[1]; + reg_cmd[0] = reg_addr; + _i2c.write(ENS210_SLAVE_ADDR, reg_cmd, 1, true); + wait_ms(10); + int read_res = _i2c.read(ENS210_SLAVE_ADDR, output, len); + if (read_res == 0) read_count = len; + return read_count; } -int AMS_ENS210::i2c_write(char reg_addr, char* input, int len) { - +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(ENS210_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 - + + + char cmd[len+1]; + cmd[0] = reg_addr; + memcpy(cmd+1, input, len); + write_count = _i2c.write(ENS210_SLAVE_ADDR, cmd, len+1) + 1; + return write_count; } \ No newline at end of file