library for AMS ENS210 temperature and humidity sensor

Dependents:   rIoTwear-temp-humid

Committer:
UHSLMarcus
Date:
Fri Jan 20 14:33:17 2017 +0000
Revision:
5:22b8ef3a65e1
Parent:
4:31fbbf39d935
Child:
6:475b764b720d
Little changes

Who changed what in which revision?

UserRevisionLine numberNew contents of line
UHSLMarcus 0:7088b1bdc2e5 1
UHSLMarcus 3:3b427231e5a7 2 #include "AMS_ENS210.h"
UHSLMarcus 0:7088b1bdc2e5 3
UHSLMarcus 0:7088b1bdc2e5 4 AMS_ENS210::AMS_ENS210(I2C * i2c) :
UHSLMarcus 0:7088b1bdc2e5 5 _temp_mode(CONFIG_TEMP_OP_MODE),
UHSLMarcus 0:7088b1bdc2e5 6 _humid_mode(CONFIG_HUMID_OP_MODE),
UHSLMarcus 3:3b427231e5a7 7 _power_mode(CONFIG_POWER_MODE),
UHSLMarcus 3:3b427231e5a7 8 _reset(0),
UHSLMarcus 3:3b427231e5a7 9 temp_reading(0),
UHSLMarcus 3:3b427231e5a7 10 humid_reading(0)
UHSLMarcus 0:7088b1bdc2e5 11 {
UHSLMarcus 0:7088b1bdc2e5 12 _i2c = i2c;
UHSLMarcus 0:7088b1bdc2e5 13 }
UHSLMarcus 0:7088b1bdc2e5 14
UHSLMarcus 0:7088b1bdc2e5 15 AMS_ENS210::AMS_ENS210(I2C * i2c, bool temp_single_shot, bool humid_single_shot) :
UHSLMarcus 0:7088b1bdc2e5 16 _temp_mode(temp_single_shot),
UHSLMarcus 0:7088b1bdc2e5 17 _humid_mode(humid_single_shot),
UHSLMarcus 3:3b427231e5a7 18 _power_mode(CONFIG_POWER_MODE),
UHSLMarcus 3:3b427231e5a7 19 _reset(0),
UHSLMarcus 3:3b427231e5a7 20 temp_reading(0),
UHSLMarcus 3:3b427231e5a7 21 humid_reading(0)
UHSLMarcus 0:7088b1bdc2e5 22 {
UHSLMarcus 0:7088b1bdc2e5 23 _i2c = i2c;
UHSLMarcus 0:7088b1bdc2e5 24 }
UHSLMarcus 0:7088b1bdc2e5 25
UHSLMarcus 0:7088b1bdc2e5 26 AMS_ENS210::AMS_ENS210(I2C * i2c, bool temp_single_shot, bool humid_single_shot, bool low_power) :
UHSLMarcus 0:7088b1bdc2e5 27 _temp_mode(temp_single_shot),
UHSLMarcus 0:7088b1bdc2e5 28 _humid_mode(humid_single_shot),
UHSLMarcus 3:3b427231e5a7 29 _power_mode(low_power),
UHSLMarcus 3:3b427231e5a7 30 _reset(0),
UHSLMarcus 3:3b427231e5a7 31 temp_reading(0),
UHSLMarcus 3:3b427231e5a7 32 humid_reading(0)
UHSLMarcus 0:7088b1bdc2e5 33 {
UHSLMarcus 0:7088b1bdc2e5 34 _i2c = i2c;
UHSLMarcus 0:7088b1bdc2e5 35 }
UHSLMarcus 0:7088b1bdc2e5 36
UHSLMarcus 3:3b427231e5a7 37 AMS_ENS210::~AMS_ENS210() {}
UHSLMarcus 0:7088b1bdc2e5 38
UHSLMarcus 0:7088b1bdc2e5 39 bool AMS_ENS210::init() {
UHSLMarcus 0:7088b1bdc2e5 40
UHSLMarcus 0:7088b1bdc2e5 41 return write_config();
UHSLMarcus 0:7088b1bdc2e5 42
UHSLMarcus 0:7088b1bdc2e5 43 }
UHSLMarcus 0:7088b1bdc2e5 44
UHSLMarcus 0:7088b1bdc2e5 45 bool AMS_ENS210::reset() {
UHSLMarcus 0:7088b1bdc2e5 46
UHSLMarcus 0:7088b1bdc2e5 47 _reset = true;
UHSLMarcus 0:7088b1bdc2e5 48 bool success = write_config(true, false);
UHSLMarcus 0:7088b1bdc2e5 49 _reset = false;
UHSLMarcus 0:7088b1bdc2e5 50
UHSLMarcus 0:7088b1bdc2e5 51 return success;
UHSLMarcus 0:7088b1bdc2e5 52
UHSLMarcus 0:7088b1bdc2e5 53 }
UHSLMarcus 0:7088b1bdc2e5 54
UHSLMarcus 3:3b427231e5a7 55 bool AMS_ENS210::low_power_mode(bool low_power) {
UHSLMarcus 0:7088b1bdc2e5 56 _power_mode = low_power;
UHSLMarcus 3:3b427231e5a7 57 return write_config(true, false);
UHSLMarcus 0:7088b1bdc2e5 58 }
UHSLMarcus 0:7088b1bdc2e5 59
UHSLMarcus 3:3b427231e5a7 60 bool AMS_ENS210::low_power_mode() {
UHSLMarcus 0:7088b1bdc2e5 61 return read_config(true, false)[0] & 1; // just mask bit 0
UHSLMarcus 0:7088b1bdc2e5 62 }
UHSLMarcus 0:7088b1bdc2e5 63
UHSLMarcus 3:3b427231e5a7 64 bool AMS_ENS210::is_active() {
UHSLMarcus 3:3b427231e5a7 65 char output[1];
UHSLMarcus 3:3b427231e5a7 66 i2c_read(SYS_STATUS, output, 1);
UHSLMarcus 3:3b427231e5a7 67 return output[0] & 1;
UHSLMarcus 0:7088b1bdc2e5 68 }
UHSLMarcus 0:7088b1bdc2e5 69
UHSLMarcus 3:3b427231e5a7 70 bool AMS_ENS210::temp_continuous_mode(bool continuous) {
UHSLMarcus 3:3b427231e5a7 71 _temp_mode = continuous;
UHSLMarcus 3:3b427231e5a7 72 return write_config(false, true);
UHSLMarcus 3:3b427231e5a7 73 }
UHSLMarcus 3:3b427231e5a7 74
UHSLMarcus 3:3b427231e5a7 75 bool AMS_ENS210::temp_continuous_mode() {
UHSLMarcus 0:7088b1bdc2e5 76 return read_config(false, true)[0] & 1; // just mask bit 0
UHSLMarcus 0:7088b1bdc2e5 77 }
UHSLMarcus 0:7088b1bdc2e5 78
UHSLMarcus 3:3b427231e5a7 79 bool AMS_ENS210::humid_continuous_mode(bool continuous) {
UHSLMarcus 3:3b427231e5a7 80 _humid_mode = continuous;
UHSLMarcus 3:3b427231e5a7 81 return write_config(false, true);
UHSLMarcus 0:7088b1bdc2e5 82 }
UHSLMarcus 0:7088b1bdc2e5 83
UHSLMarcus 3:3b427231e5a7 84 bool AMS_ENS210::humid_continuous_mode() {
UHSLMarcus 3:3b427231e5a7 85 return (read_config(false, true)[0] >> 1) & 1; // shift bit 1 and mask
UHSLMarcus 0:7088b1bdc2e5 86 }
UHSLMarcus 0:7088b1bdc2e5 87
UHSLMarcus 0:7088b1bdc2e5 88 void AMS_ENS210::i2c_interface(I2C * i2c) {
UHSLMarcus 0:7088b1bdc2e5 89 _i2c = i2c;
UHSLMarcus 0:7088b1bdc2e5 90 }
UHSLMarcus 0:7088b1bdc2e5 91
UHSLMarcus 0:7088b1bdc2e5 92 bool AMS_ENS210::start(bool temp, bool humid) {
UHSLMarcus 3:3b427231e5a7 93 char cmd[1] = {0 | temp | (humid << 1)};
UHSLMarcus 5:22b8ef3a65e1 94 return i2c_write(SENS_START, cmd, 1) == 1; //_i2c->write(ENS210_ENS210_ENS210_ENS210_ENS210_ENS210_ENS210_SLAVE_ADDR, cmd, 2) == 2;
UHSLMarcus 0:7088b1bdc2e5 95 }
UHSLMarcus 0:7088b1bdc2e5 96
UHSLMarcus 0:7088b1bdc2e5 97 bool AMS_ENS210::stop(bool temp, bool humid) {
UHSLMarcus 3:3b427231e5a7 98 char cmd[1] = {0 | temp | (humid << 1)};
UHSLMarcus 5:22b8ef3a65e1 99 return i2c_write(SENS_STOP, cmd, 1) == 1; //_i2c->write(ENS210_ENS210_ENS210_ENS210_ENS210_ENS210_ENS210_SLAVE_ADDR, cmd, 2) == 2;
UHSLMarcus 0:7088b1bdc2e5 100 }
UHSLMarcus 0:7088b1bdc2e5 101
UHSLMarcus 0:7088b1bdc2e5 102 bool AMS_ENS210::temp_is_measuring() {
UHSLMarcus 3:3b427231e5a7 103 char output[1];
UHSLMarcus 0:7088b1bdc2e5 104 i2c_read(SENS_STATUS, output, 1);
UHSLMarcus 0:7088b1bdc2e5 105 return output[0] & 1;
UHSLMarcus 0:7088b1bdc2e5 106 }
UHSLMarcus 0:7088b1bdc2e5 107
UHSLMarcus 3:3b427231e5a7 108 bool AMS_ENS210::humid_is_measuring() {
UHSLMarcus 3:3b427231e5a7 109 char output[1];
UHSLMarcus 0:7088b1bdc2e5 110 i2c_read(SENS_STATUS, output, 1);
UHSLMarcus 0:7088b1bdc2e5 111 return output[0] >> 1 & 1;
UHSLMarcus 0:7088b1bdc2e5 112 }
UHSLMarcus 0:7088b1bdc2e5 113
UHSLMarcus 0:7088b1bdc2e5 114 bool AMS_ENS210::temp_has_data() {
UHSLMarcus 0:7088b1bdc2e5 115
UHSLMarcus 0:7088b1bdc2e5 116 char output[3];
UHSLMarcus 0:7088b1bdc2e5 117 i2c_read(SENS_TEMP, output, 3);
UHSLMarcus 0:7088b1bdc2e5 118
UHSLMarcus 0:7088b1bdc2e5 119 // do crc7
UHSLMarcus 0:7088b1bdc2e5 120 // Store read data to avoid reading from I2C again
UHSLMarcus 0:7088b1bdc2e5 121 temp_reading = 0 | output[0] | (output[1] << 8); // bytes 1 and 2 make the 16 bit data
UHSLMarcus 0:7088b1bdc2e5 122
UHSLMarcus 3:3b427231e5a7 123 bool valid = output[2] & 1; // bit 0 of byte 3 is the valid flag
UHSLMarcus 3:3b427231e5a7 124
UHSLMarcus 3:3b427231e5a7 125
UHSLMarcus 3:3b427231e5a7 126 if (!valid) {
UHSLMarcus 3:3b427231e5a7 127 if (!temp_continuous_mode()) { // when in single shot mode make sure sensor has started
UHSLMarcus 3:3b427231e5a7 128 if (!temp_is_measuring())
UHSLMarcus 3:3b427231e5a7 129 start(true, false); // set start bit if sensor is idle
UHSLMarcus 3:3b427231e5a7 130 }
UHSLMarcus 3:3b427231e5a7 131 }
UHSLMarcus 3:3b427231e5a7 132
UHSLMarcus 3:3b427231e5a7 133 return valid;
UHSLMarcus 0:7088b1bdc2e5 134 }
UHSLMarcus 0:7088b1bdc2e5 135
UHSLMarcus 0:7088b1bdc2e5 136 bool AMS_ENS210::humid_has_data() {
UHSLMarcus 0:7088b1bdc2e5 137
UHSLMarcus 0:7088b1bdc2e5 138 char output[3];
UHSLMarcus 0:7088b1bdc2e5 139 i2c_read(SENS_HUMID, output, 3);
UHSLMarcus 0:7088b1bdc2e5 140
UHSLMarcus 0:7088b1bdc2e5 141 // do crc7
UHSLMarcus 0:7088b1bdc2e5 142 // Store read data to avoid reading from I2C again
UHSLMarcus 3:3b427231e5a7 143 humid_reading = 0 | output[0] | (output[1] << 8); // bytes 1 and 2 make the 16 bit data
UHSLMarcus 3:3b427231e5a7 144
UHSLMarcus 3:3b427231e5a7 145 bool valid = output[2] & 1; // bit 0 of byte 3 is the valid flag
UHSLMarcus 0:7088b1bdc2e5 146
UHSLMarcus 3:3b427231e5a7 147 if (!valid) {
UHSLMarcus 3:3b427231e5a7 148 if (!humid_continuous_mode()) { // when in single shot mode make sure sensor has started first
UHSLMarcus 3:3b427231e5a7 149 if (!humid_is_measuring())
UHSLMarcus 3:3b427231e5a7 150 start(false, true); // set start bit if sensor is idle
UHSLMarcus 3:3b427231e5a7 151 }
UHSLMarcus 3:3b427231e5a7 152 }
UHSLMarcus 3:3b427231e5a7 153
UHSLMarcus 3:3b427231e5a7 154 return valid;
UHSLMarcus 0:7088b1bdc2e5 155 }
UHSLMarcus 0:7088b1bdc2e5 156
UHSLMarcus 0:7088b1bdc2e5 157 uint16_t AMS_ENS210::temp_read() {
UHSLMarcus 0:7088b1bdc2e5 158
UHSLMarcus 0:7088b1bdc2e5 159 uint16_t reading = 0;
UHSLMarcus 0:7088b1bdc2e5 160
UHSLMarcus 3:3b427231e5a7 161 if (!temp_continuous_mode()) { // when in single shot mode, data is read and saved in temp_has_data()
UHSLMarcus 0:7088b1bdc2e5 162 reading = temp_reading;
UHSLMarcus 0:7088b1bdc2e5 163 } else {
UHSLMarcus 0:7088b1bdc2e5 164 char output[3];
UHSLMarcus 0:7088b1bdc2e5 165 i2c_read(SENS_TEMP, output, 3);
UHSLMarcus 0:7088b1bdc2e5 166
UHSLMarcus 0:7088b1bdc2e5 167 // do crc7
UHSLMarcus 2:f5a7883ae9c2 168 if (output[2] & 1) // bit 0 of byte 3 is the valid flag
UHSLMarcus 0:7088b1bdc2e5 169 reading = 0 | output[0] | (output[1] << 8); // bytes 1 and 2 make the 16 bit data
UHSLMarcus 0:7088b1bdc2e5 170 }
UHSLMarcus 0:7088b1bdc2e5 171
UHSLMarcus 0:7088b1bdc2e5 172 return reading;
UHSLMarcus 0:7088b1bdc2e5 173 }
UHSLMarcus 0:7088b1bdc2e5 174
UHSLMarcus 0:7088b1bdc2e5 175 uint16_t AMS_ENS210::humid_read() {
UHSLMarcus 0:7088b1bdc2e5 176 uint16_t reading = 0;
UHSLMarcus 0:7088b1bdc2e5 177
UHSLMarcus 3:3b427231e5a7 178 if (!humid_continuous_mode()) { // when in single shot mode, data is read and saved in humid_has_data()
UHSLMarcus 0:7088b1bdc2e5 179 reading = humid_reading;
UHSLMarcus 0:7088b1bdc2e5 180 } else {
UHSLMarcus 0:7088b1bdc2e5 181 char output[3];
UHSLMarcus 0:7088b1bdc2e5 182 i2c_read(SENS_HUMID, output, 3);
UHSLMarcus 0:7088b1bdc2e5 183
UHSLMarcus 0:7088b1bdc2e5 184 // do crc7
UHSLMarcus 2:f5a7883ae9c2 185 if (output[2] & 1) // bit 0 of byte 3 is the valid flag
UHSLMarcus 0:7088b1bdc2e5 186 reading = 0 | output[0] | (output[1] << 8); // bytes 1 and 2 make the 16 bit data
UHSLMarcus 0:7088b1bdc2e5 187 }
UHSLMarcus 0:7088b1bdc2e5 188
UHSLMarcus 0:7088b1bdc2e5 189 return reading;
UHSLMarcus 0:7088b1bdc2e5 190 }
UHSLMarcus 0:7088b1bdc2e5 191
UHSLMarcus 0:7088b1bdc2e5 192 /*** Private ***/
UHSLMarcus 0:7088b1bdc2e5 193
UHSLMarcus 0:7088b1bdc2e5 194 bool AMS_ENS210::write_config(bool system, bool sensor) {
UHSLMarcus 0:7088b1bdc2e5 195 int w_bytes = 0;
UHSLMarcus 3:3b427231e5a7 196 char cmd[1];
UHSLMarcus 0:7088b1bdc2e5 197
UHSLMarcus 0:7088b1bdc2e5 198 if (system) {
UHSLMarcus 3:3b427231e5a7 199 cmd[0] = 0 | _power_mode | _reset << 7; // bit 0 of SYS_CTRL is power mode, bit 7 is reset
UHSLMarcus 5:22b8ef3a65e1 200 w_bytes += i2c_write(SYS_CONFIG, cmd, 1); //_i2c->write(ENS210_ENS210_ENS210_ENS210_ENS210_ENS210_ENS210_SLAVE_ADDR, cmd, 2);
UHSLMarcus 0:7088b1bdc2e5 201 }
UHSLMarcus 0:7088b1bdc2e5 202
UHSLMarcus 0:7088b1bdc2e5 203 if (sensor) {
UHSLMarcus 3:3b427231e5a7 204 cmd[0] = 0 | _temp_mode | (_humid_mode << 1); // bit 0 is temp mode, bit 1 is humid mode
UHSLMarcus 5:22b8ef3a65e1 205 w_bytes += i2c_write(SENS_OP_MODE, cmd, 1); //_i2c->write(ENS210_ENS210_ENS210_ENS210_ENS210_ENS210_ENS210_SLAVE_ADDR, cmd, 2);
UHSLMarcus 0:7088b1bdc2e5 206 }
UHSLMarcus 0:7088b1bdc2e5 207
UHSLMarcus 3:3b427231e5a7 208 return w_bytes == (system + sensor);
UHSLMarcus 0:7088b1bdc2e5 209 }
UHSLMarcus 0:7088b1bdc2e5 210
UHSLMarcus 4:31fbbf39d935 211 const char *AMS_ENS210::read_config(bool system, bool sensor) { // todo, maybe throw excpetion if i2c read fails?
UHSLMarcus 0:7088b1bdc2e5 212
UHSLMarcus 3:3b427231e5a7 213 static char output[2] = {0, 0};
UHSLMarcus 0:7088b1bdc2e5 214
UHSLMarcus 0:7088b1bdc2e5 215 if (system)
UHSLMarcus 0:7088b1bdc2e5 216 i2c_read(SYS_CONFIG, output, 1);
UHSLMarcus 0:7088b1bdc2e5 217
UHSLMarcus 3:3b427231e5a7 218 if (sensor)
UHSLMarcus 3:3b427231e5a7 219 i2c_read(SENS_OP_MODE, output+system, 1);
UHSLMarcus 3:3b427231e5a7 220
UHSLMarcus 0:7088b1bdc2e5 221 return output;
UHSLMarcus 0:7088b1bdc2e5 222
UHSLMarcus 0:7088b1bdc2e5 223 }
UHSLMarcus 0:7088b1bdc2e5 224
UHSLMarcus 0:7088b1bdc2e5 225 int AMS_ENS210::i2c_read(char reg_addr, char* output, int len) {
UHSLMarcus 0:7088b1bdc2e5 226
UHSLMarcus 0:7088b1bdc2e5 227 int read_count = 0;
UHSLMarcus 0:7088b1bdc2e5 228
UHSLMarcus 3:3b427231e5a7 229 _i2c->start(); // send start condition for write
UHSLMarcus 5:22b8ef3a65e1 230 if(_i2c->write(ENS210_SLAVE_ADDR_W) == 1) { // write slave address with write bit
UHSLMarcus 3:3b427231e5a7 231 if(_i2c->write(reg_addr) == 1) { // write register address
UHSLMarcus 3:3b427231e5a7 232 _i2c->start(); // send another start condition for read
UHSLMarcus 5:22b8ef3a65e1 233 if(_i2c->write(ENS210_SLAVE_ADDR_R) == 1) { // write slave address with read bit
UHSLMarcus 3:3b427231e5a7 234 for (int i = 0; i < len; i++) { // read len bytes
UHSLMarcus 3:3b427231e5a7 235 output[i] = _i2c->read(i < len-1 ? 1 : 0); // ack all reads aside from the final one (i == len-1)
UHSLMarcus 3:3b427231e5a7 236 read_count++;
UHSLMarcus 3:3b427231e5a7 237 }
UHSLMarcus 0:7088b1bdc2e5 238 }
UHSLMarcus 0:7088b1bdc2e5 239 }
UHSLMarcus 0:7088b1bdc2e5 240 }
UHSLMarcus 3:3b427231e5a7 241 _i2c->stop(); // send stop condition
UHSLMarcus 0:7088b1bdc2e5 242
UHSLMarcus 0:7088b1bdc2e5 243 return read_count;
UHSLMarcus 3:3b427231e5a7 244 }
UHSLMarcus 3:3b427231e5a7 245
UHSLMarcus 3:3b427231e5a7 246 int AMS_ENS210::i2c_write(char reg_addr, char* input, int len) {
UHSLMarcus 3:3b427231e5a7 247
UHSLMarcus 3:3b427231e5a7 248 int write_count = 0;
UHSLMarcus 3:3b427231e5a7 249
UHSLMarcus 3:3b427231e5a7 250 _i2c->start(); // send start condition for write
UHSLMarcus 5:22b8ef3a65e1 251 if(_i2c->write(ENS210_SLAVE_ADDR_W) == 1) { // write slave address
UHSLMarcus 3:3b427231e5a7 252 if(_i2c->write(reg_addr) == 1) { // write register address
UHSLMarcus 3:3b427231e5a7 253 for (int i = 0; i < len; i++) { // write len bytes
UHSLMarcus 3:3b427231e5a7 254 if(_i2c->write(input[i]) == 1) write_count++; // write each byte, if successful increment count
UHSLMarcus 3:3b427231e5a7 255 }
UHSLMarcus 3:3b427231e5a7 256 }
UHSLMarcus 3:3b427231e5a7 257 }
UHSLMarcus 3:3b427231e5a7 258 _i2c->stop(); // send stop condition
UHSLMarcus 3:3b427231e5a7 259
UHSLMarcus 3:3b427231e5a7 260 return write_count;
UHSLMarcus 0:7088b1bdc2e5 261 }