library for AMS ENS210 temperature and humidity sensor

Dependents:   rIoTwear-temp-humid

Committer:
UHSLMarcus
Date:
Tue Jan 24 14:08:26 2017 +0000
Revision:
7:d61772b5cd3b
Parent:
6:475b764b720d
Child:
8:1a7d241afbcb
made sure the i2c pointer is initialized to NULL

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