library for AMS ENS210 temperature and humidity sensor

Dependents:   rIoTwear-temp-humid

Committer:
UHSLMarcus
Date:
Tue Jan 24 10:46:20 2017 +0000
Revision:
6:475b764b720d
Parent:
5:22b8ef3a65e1
Child:
7:d61772b5cd3b
Added get method for i2c interface

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 6:475b764b720d 92 I2C* AMS_ENS210::i2c_interface() {
UHSLMarcus 6:475b764b720d 93 return _i2c;
UHSLMarcus 6:475b764b720d 94 }
UHSLMarcus 6:475b764b720d 95
UHSLMarcus 0:7088b1bdc2e5 96 bool AMS_ENS210::start(bool temp, bool humid) {
UHSLMarcus 3:3b427231e5a7 97 char cmd[1] = {0 | temp | (humid << 1)};
UHSLMarcus 6:475b764b720d 98 return i2c_write(SENS_START, cmd, 1) == 1; //_i2c->write(ENS210_SLAVE_ADDR, cmd, 2) == 2;
UHSLMarcus 0:7088b1bdc2e5 99 }
UHSLMarcus 0:7088b1bdc2e5 100
UHSLMarcus 0:7088b1bdc2e5 101 bool AMS_ENS210::stop(bool temp, bool humid) {
UHSLMarcus 3:3b427231e5a7 102 char cmd[1] = {0 | temp | (humid << 1)};
UHSLMarcus 6:475b764b720d 103 return i2c_write(SENS_STOP, cmd, 1) == 1; //_i2c->write(ENS210_SLAVE_ADDR, cmd, 2) == 2;
UHSLMarcus 0:7088b1bdc2e5 104 }
UHSLMarcus 0:7088b1bdc2e5 105
UHSLMarcus 0:7088b1bdc2e5 106 bool AMS_ENS210::temp_is_measuring() {
UHSLMarcus 3:3b427231e5a7 107 char output[1];
UHSLMarcus 0:7088b1bdc2e5 108 i2c_read(SENS_STATUS, output, 1);
UHSLMarcus 0:7088b1bdc2e5 109 return output[0] & 1;
UHSLMarcus 0:7088b1bdc2e5 110 }
UHSLMarcus 0:7088b1bdc2e5 111
UHSLMarcus 3:3b427231e5a7 112 bool AMS_ENS210::humid_is_measuring() {
UHSLMarcus 3:3b427231e5a7 113 char output[1];
UHSLMarcus 0:7088b1bdc2e5 114 i2c_read(SENS_STATUS, output, 1);
UHSLMarcus 0:7088b1bdc2e5 115 return output[0] >> 1 & 1;
UHSLMarcus 0:7088b1bdc2e5 116 }
UHSLMarcus 0:7088b1bdc2e5 117
UHSLMarcus 0:7088b1bdc2e5 118 bool AMS_ENS210::temp_has_data() {
UHSLMarcus 0:7088b1bdc2e5 119
UHSLMarcus 0:7088b1bdc2e5 120 char output[3];
UHSLMarcus 0:7088b1bdc2e5 121 i2c_read(SENS_TEMP, output, 3);
UHSLMarcus 0:7088b1bdc2e5 122
UHSLMarcus 0:7088b1bdc2e5 123 // do crc7
UHSLMarcus 0:7088b1bdc2e5 124 // Store read data to avoid reading from I2C again
UHSLMarcus 0:7088b1bdc2e5 125 temp_reading = 0 | output[0] | (output[1] << 8); // bytes 1 and 2 make the 16 bit data
UHSLMarcus 0:7088b1bdc2e5 126
UHSLMarcus 3:3b427231e5a7 127 bool valid = output[2] & 1; // bit 0 of byte 3 is the valid flag
UHSLMarcus 3:3b427231e5a7 128
UHSLMarcus 3:3b427231e5a7 129
UHSLMarcus 3:3b427231e5a7 130 if (!valid) {
UHSLMarcus 3:3b427231e5a7 131 if (!temp_continuous_mode()) { // when in single shot mode make sure sensor has started
UHSLMarcus 3:3b427231e5a7 132 if (!temp_is_measuring())
UHSLMarcus 3:3b427231e5a7 133 start(true, false); // set start bit if sensor is idle
UHSLMarcus 3:3b427231e5a7 134 }
UHSLMarcus 3:3b427231e5a7 135 }
UHSLMarcus 3:3b427231e5a7 136
UHSLMarcus 3:3b427231e5a7 137 return valid;
UHSLMarcus 0:7088b1bdc2e5 138 }
UHSLMarcus 0:7088b1bdc2e5 139
UHSLMarcus 0:7088b1bdc2e5 140 bool AMS_ENS210::humid_has_data() {
UHSLMarcus 0:7088b1bdc2e5 141
UHSLMarcus 0:7088b1bdc2e5 142 char output[3];
UHSLMarcus 0:7088b1bdc2e5 143 i2c_read(SENS_HUMID, output, 3);
UHSLMarcus 0:7088b1bdc2e5 144
UHSLMarcus 0:7088b1bdc2e5 145 // do crc7
UHSLMarcus 0:7088b1bdc2e5 146 // Store read data to avoid reading from I2C again
UHSLMarcus 3:3b427231e5a7 147 humid_reading = 0 | output[0] | (output[1] << 8); // bytes 1 and 2 make the 16 bit data
UHSLMarcus 3:3b427231e5a7 148
UHSLMarcus 3:3b427231e5a7 149 bool valid = output[2] & 1; // bit 0 of byte 3 is the valid flag
UHSLMarcus 0:7088b1bdc2e5 150
UHSLMarcus 3:3b427231e5a7 151 if (!valid) {
UHSLMarcus 3:3b427231e5a7 152 if (!humid_continuous_mode()) { // when in single shot mode make sure sensor has started first
UHSLMarcus 3:3b427231e5a7 153 if (!humid_is_measuring())
UHSLMarcus 3:3b427231e5a7 154 start(false, true); // set start bit if sensor is idle
UHSLMarcus 3:3b427231e5a7 155 }
UHSLMarcus 3:3b427231e5a7 156 }
UHSLMarcus 3:3b427231e5a7 157
UHSLMarcus 3:3b427231e5a7 158 return valid;
UHSLMarcus 0:7088b1bdc2e5 159 }
UHSLMarcus 0:7088b1bdc2e5 160
UHSLMarcus 0:7088b1bdc2e5 161 uint16_t AMS_ENS210::temp_read() {
UHSLMarcus 0:7088b1bdc2e5 162
UHSLMarcus 0:7088b1bdc2e5 163 uint16_t reading = 0;
UHSLMarcus 0:7088b1bdc2e5 164
UHSLMarcus 3:3b427231e5a7 165 if (!temp_continuous_mode()) { // when in single shot mode, data is read and saved in temp_has_data()
UHSLMarcus 0:7088b1bdc2e5 166 reading = temp_reading;
UHSLMarcus 0:7088b1bdc2e5 167 } else {
UHSLMarcus 0:7088b1bdc2e5 168 char output[3];
UHSLMarcus 0:7088b1bdc2e5 169 i2c_read(SENS_TEMP, output, 3);
UHSLMarcus 0:7088b1bdc2e5 170
UHSLMarcus 0:7088b1bdc2e5 171 // do crc7
UHSLMarcus 2:f5a7883ae9c2 172 if (output[2] & 1) // bit 0 of byte 3 is the valid flag
UHSLMarcus 0:7088b1bdc2e5 173 reading = 0 | output[0] | (output[1] << 8); // bytes 1 and 2 make the 16 bit data
UHSLMarcus 0:7088b1bdc2e5 174 }
UHSLMarcus 0:7088b1bdc2e5 175
UHSLMarcus 0:7088b1bdc2e5 176 return reading;
UHSLMarcus 0:7088b1bdc2e5 177 }
UHSLMarcus 0:7088b1bdc2e5 178
UHSLMarcus 0:7088b1bdc2e5 179 uint16_t AMS_ENS210::humid_read() {
UHSLMarcus 0:7088b1bdc2e5 180 uint16_t reading = 0;
UHSLMarcus 0:7088b1bdc2e5 181
UHSLMarcus 3:3b427231e5a7 182 if (!humid_continuous_mode()) { // when in single shot mode, data is read and saved in humid_has_data()
UHSLMarcus 0:7088b1bdc2e5 183 reading = humid_reading;
UHSLMarcus 0:7088b1bdc2e5 184 } else {
UHSLMarcus 0:7088b1bdc2e5 185 char output[3];
UHSLMarcus 0:7088b1bdc2e5 186 i2c_read(SENS_HUMID, output, 3);
UHSLMarcus 0:7088b1bdc2e5 187
UHSLMarcus 0:7088b1bdc2e5 188 // do crc7
UHSLMarcus 2:f5a7883ae9c2 189 if (output[2] & 1) // bit 0 of byte 3 is the valid flag
UHSLMarcus 0:7088b1bdc2e5 190 reading = 0 | output[0] | (output[1] << 8); // bytes 1 and 2 make the 16 bit data
UHSLMarcus 0:7088b1bdc2e5 191 }
UHSLMarcus 0:7088b1bdc2e5 192
UHSLMarcus 0:7088b1bdc2e5 193 return reading;
UHSLMarcus 0:7088b1bdc2e5 194 }
UHSLMarcus 0:7088b1bdc2e5 195
UHSLMarcus 0:7088b1bdc2e5 196 /*** Private ***/
UHSLMarcus 0:7088b1bdc2e5 197
UHSLMarcus 0:7088b1bdc2e5 198 bool AMS_ENS210::write_config(bool system, bool sensor) {
UHSLMarcus 0:7088b1bdc2e5 199 int w_bytes = 0;
UHSLMarcus 3:3b427231e5a7 200 char cmd[1];
UHSLMarcus 0:7088b1bdc2e5 201
UHSLMarcus 0:7088b1bdc2e5 202 if (system) {
UHSLMarcus 3:3b427231e5a7 203 cmd[0] = 0 | _power_mode | _reset << 7; // bit 0 of SYS_CTRL is power mode, bit 7 is reset
UHSLMarcus 5:22b8ef3a65e1 204 w_bytes += i2c_write(SYS_CONFIG, cmd, 1); //_i2c->write(ENS210_ENS210_ENS210_ENS210_ENS210_ENS210_ENS210_SLAVE_ADDR, cmd, 2);
UHSLMarcus 0:7088b1bdc2e5 205 }
UHSLMarcus 0:7088b1bdc2e5 206
UHSLMarcus 0:7088b1bdc2e5 207 if (sensor) {
UHSLMarcus 3:3b427231e5a7 208 cmd[0] = 0 | _temp_mode | (_humid_mode << 1); // bit 0 is temp mode, bit 1 is humid mode
UHSLMarcus 5:22b8ef3a65e1 209 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 210 }
UHSLMarcus 0:7088b1bdc2e5 211
UHSLMarcus 3:3b427231e5a7 212 return w_bytes == (system + sensor);
UHSLMarcus 0:7088b1bdc2e5 213 }
UHSLMarcus 0:7088b1bdc2e5 214
UHSLMarcus 4:31fbbf39d935 215 const char *AMS_ENS210::read_config(bool system, bool sensor) { // todo, maybe throw excpetion if i2c read fails?
UHSLMarcus 0:7088b1bdc2e5 216
UHSLMarcus 3:3b427231e5a7 217 static char output[2] = {0, 0};
UHSLMarcus 0:7088b1bdc2e5 218
UHSLMarcus 0:7088b1bdc2e5 219 if (system)
UHSLMarcus 0:7088b1bdc2e5 220 i2c_read(SYS_CONFIG, output, 1);
UHSLMarcus 0:7088b1bdc2e5 221
UHSLMarcus 3:3b427231e5a7 222 if (sensor)
UHSLMarcus 3:3b427231e5a7 223 i2c_read(SENS_OP_MODE, output+system, 1);
UHSLMarcus 3:3b427231e5a7 224
UHSLMarcus 0:7088b1bdc2e5 225 return output;
UHSLMarcus 0:7088b1bdc2e5 226
UHSLMarcus 0:7088b1bdc2e5 227 }
UHSLMarcus 0:7088b1bdc2e5 228
UHSLMarcus 0:7088b1bdc2e5 229 int AMS_ENS210::i2c_read(char reg_addr, char* output, int len) {
UHSLMarcus 0:7088b1bdc2e5 230
UHSLMarcus 0:7088b1bdc2e5 231 int read_count = 0;
UHSLMarcus 0:7088b1bdc2e5 232
UHSLMarcus 3:3b427231e5a7 233 _i2c->start(); // send start condition for write
UHSLMarcus 5:22b8ef3a65e1 234 if(_i2c->write(ENS210_SLAVE_ADDR_W) == 1) { // write slave address with write bit
UHSLMarcus 3:3b427231e5a7 235 if(_i2c->write(reg_addr) == 1) { // write register address
UHSLMarcus 3:3b427231e5a7 236 _i2c->start(); // send another start condition for read
UHSLMarcus 5:22b8ef3a65e1 237 if(_i2c->write(ENS210_SLAVE_ADDR_R) == 1) { // write slave address with read bit
UHSLMarcus 3:3b427231e5a7 238 for (int i = 0; i < len; i++) { // read len bytes
UHSLMarcus 3:3b427231e5a7 239 output[i] = _i2c->read(i < len-1 ? 1 : 0); // ack all reads aside from the final one (i == len-1)
UHSLMarcus 3:3b427231e5a7 240 read_count++;
UHSLMarcus 3:3b427231e5a7 241 }
UHSLMarcus 0:7088b1bdc2e5 242 }
UHSLMarcus 0:7088b1bdc2e5 243 }
UHSLMarcus 0:7088b1bdc2e5 244 }
UHSLMarcus 3:3b427231e5a7 245 _i2c->stop(); // send stop condition
UHSLMarcus 0:7088b1bdc2e5 246
UHSLMarcus 0:7088b1bdc2e5 247 return read_count;
UHSLMarcus 3:3b427231e5a7 248 }
UHSLMarcus 3:3b427231e5a7 249
UHSLMarcus 3:3b427231e5a7 250 int AMS_ENS210::i2c_write(char reg_addr, char* input, int len) {
UHSLMarcus 3:3b427231e5a7 251
UHSLMarcus 3:3b427231e5a7 252 int write_count = 0;
UHSLMarcus 3:3b427231e5a7 253
UHSLMarcus 3:3b427231e5a7 254 _i2c->start(); // send start condition for write
UHSLMarcus 5:22b8ef3a65e1 255 if(_i2c->write(ENS210_SLAVE_ADDR_W) == 1) { // write slave address
UHSLMarcus 3:3b427231e5a7 256 if(_i2c->write(reg_addr) == 1) { // write register address
UHSLMarcus 3:3b427231e5a7 257 for (int i = 0; i < len; i++) { // write len bytes
UHSLMarcus 3:3b427231e5a7 258 if(_i2c->write(input[i]) == 1) write_count++; // write each byte, if successful increment count
UHSLMarcus 3:3b427231e5a7 259 }
UHSLMarcus 3:3b427231e5a7 260 }
UHSLMarcus 3:3b427231e5a7 261 }
UHSLMarcus 3:3b427231e5a7 262 _i2c->stop(); // send stop condition
UHSLMarcus 3:3b427231e5a7 263
UHSLMarcus 3:3b427231e5a7 264 return write_count;
UHSLMarcus 0:7088b1bdc2e5 265 }