library for AMS ENS210 temperature and humidity sensor

Dependents:   rIoTwear-temp-humid

Committer:
UHSLMarcus
Date:
Wed Jan 18 08:54:58 2017 +0000
Revision:
2:f5a7883ae9c2
Parent:
1:94a79c88c105
Child:
3:3b427231e5a7
fixed index out of bounds

Who changed what in which revision?

UserRevisionLine numberNew contents of line
UHSLMarcus 0:7088b1bdc2e5 1
UHSLMarcus 0:7088b1bdc2e5 2 #include "AMS_ENS201.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 1:94a79c88c105 7 _power_mode(CONFIG_POWER_MODE)
UHSLMarcus 0:7088b1bdc2e5 8 {
UHSLMarcus 0:7088b1bdc2e5 9 _i2c = i2c;
UHSLMarcus 0:7088b1bdc2e5 10 }
UHSLMarcus 0:7088b1bdc2e5 11
UHSLMarcus 0:7088b1bdc2e5 12 AMS_ENS210::AMS_ENS210(I2C * i2c, bool temp_single_shot, bool humid_single_shot) :
UHSLMarcus 0:7088b1bdc2e5 13 _temp_mode(temp_single_shot),
UHSLMarcus 0:7088b1bdc2e5 14 _humid_mode(humid_single_shot),
UHSLMarcus 1:94a79c88c105 15 _power_mode(CONFIG_POWER_MODE)
UHSLMarcus 0:7088b1bdc2e5 16 {
UHSLMarcus 0:7088b1bdc2e5 17 _i2c = i2c;
UHSLMarcus 0:7088b1bdc2e5 18 }
UHSLMarcus 0:7088b1bdc2e5 19
UHSLMarcus 0:7088b1bdc2e5 20 AMS_ENS210::AMS_ENS210(I2C * i2c, bool temp_single_shot, bool humid_single_shot, bool low_power) :
UHSLMarcus 0:7088b1bdc2e5 21 _temp_mode(temp_single_shot),
UHSLMarcus 0:7088b1bdc2e5 22 _humid_mode(humid_single_shot),
UHSLMarcus 1:94a79c88c105 23 _power_mode(low_power)
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() {}
UHSLMarcus 0:7088b1bdc2e5 29
UHSLMarcus 0:7088b1bdc2e5 30 bool AMS_ENS210::init() {
UHSLMarcus 0:7088b1bdc2e5 31
UHSLMarcus 0:7088b1bdc2e5 32 return write_config();
UHSLMarcus 0:7088b1bdc2e5 33
UHSLMarcus 0:7088b1bdc2e5 34 }
UHSLMarcus 0:7088b1bdc2e5 35
UHSLMarcus 0:7088b1bdc2e5 36 bool AMS_ENS210::reset() {
UHSLMarcus 0:7088b1bdc2e5 37
UHSLMarcus 0:7088b1bdc2e5 38 _reset = true;
UHSLMarcus 0:7088b1bdc2e5 39 bool success = write_config(true, false);
UHSLMarcus 0:7088b1bdc2e5 40 _reset = false;
UHSLMarcus 0:7088b1bdc2e5 41
UHSLMarcus 0:7088b1bdc2e5 42 return success;
UHSLMarcus 0:7088b1bdc2e5 43
UHSLMarcus 0:7088b1bdc2e5 44 }
UHSLMarcus 0:7088b1bdc2e5 45
UHSLMarcus 0:7088b1bdc2e5 46 bool AMS_ENS210::power_mode(bool low_power) {
UHSLMarcus 0:7088b1bdc2e5 47 _power_mode = low_power;
UHSLMarcus 0:7088b1bdc2e5 48 write_config(true, false);
UHSLMarcus 0:7088b1bdc2e5 49 }
UHSLMarcus 0:7088b1bdc2e5 50
UHSLMarcus 0:7088b1bdc2e5 51 bool AMS_ENS210::power_mode() {
UHSLMarcus 0:7088b1bdc2e5 52 return read_config(true, false)[0] & 1; // just mask bit 0
UHSLMarcus 0:7088b1bdc2e5 53 }
UHSLMarcus 0:7088b1bdc2e5 54
UHSLMarcus 0:7088b1bdc2e5 55 bool AMS_ENS210::temp_mode(bool single_shot) {
UHSLMarcus 0:7088b1bdc2e5 56 _temp_mode = single_shot;
UHSLMarcus 0:7088b1bdc2e5 57 write_config(false, true);
UHSLMarcus 0:7088b1bdc2e5 58 }
UHSLMarcus 0:7088b1bdc2e5 59
UHSLMarcus 0:7088b1bdc2e5 60 bool AMS_ENS210::temp_mode() {
UHSLMarcus 0:7088b1bdc2e5 61 return read_config(false, true)[0] & 1; // just mask bit 0
UHSLMarcus 0:7088b1bdc2e5 62 }
UHSLMarcus 0:7088b1bdc2e5 63
UHSLMarcus 0:7088b1bdc2e5 64 bool AMS_ENS210::humid_mode(bool single_shot) {
UHSLMarcus 0:7088b1bdc2e5 65 _humid_mode = single_shot;
UHSLMarcus 0:7088b1bdc2e5 66 write_config(false, true);
UHSLMarcus 0:7088b1bdc2e5 67 }
UHSLMarcus 0:7088b1bdc2e5 68
UHSLMarcus 0:7088b1bdc2e5 69 bool AMS_ENS210::humid_mode() {
UHSLMarcus 0:7088b1bdc2e5 70 return read_config(false, true)[0] & 0b10; // just mask bit 1
UHSLMarcus 0:7088b1bdc2e5 71 }
UHSLMarcus 0:7088b1bdc2e5 72
UHSLMarcus 0:7088b1bdc2e5 73 void AMS_ENS210::i2c_interface(I2C * i2c) {
UHSLMarcus 0:7088b1bdc2e5 74 _i2c = i2c;
UHSLMarcus 0:7088b1bdc2e5 75 }
UHSLMarcus 0:7088b1bdc2e5 76
UHSLMarcus 0:7088b1bdc2e5 77 bool AMS_ENS210::start(bool temp, bool humid) {
UHSLMarcus 0:7088b1bdc2e5 78 char cmd[2] = {SENS_START, 0 | temp | (humid << 1)}
UHSLMarcus 0:7088b1bdc2e5 79 return _i2c->write(SLAVE_ADDR, cmd, 2) == 2;
UHSLMarcus 0:7088b1bdc2e5 80 }
UHSLMarcus 0:7088b1bdc2e5 81
UHSLMarcus 0:7088b1bdc2e5 82 bool AMS_ENS210::stop(bool temp, bool humid) {
UHSLMarcus 0:7088b1bdc2e5 83 char cmd[2] = {SENS_STOP, 0 | temp | (humid << 1)}
UHSLMarcus 0:7088b1bdc2e5 84 return _i2c->write(SLAVE_ADDR, cmd, 2) == 2;
UHSLMarcus 0:7088b1bdc2e5 85 }
UHSLMarcus 0:7088b1bdc2e5 86
UHSLMarcus 0:7088b1bdc2e5 87 bool AMS_ENS210::temp_is_measuring() {
UHSLMarcus 0:7088b1bdc2e5 88 char[1] output;
UHSLMarcus 0:7088b1bdc2e5 89 i2c_read(SENS_STATUS, output, 1);
UHSLMarcus 0:7088b1bdc2e5 90 return output[0] & 1;
UHSLMarcus 0:7088b1bdc2e5 91 }
UHSLMarcus 0:7088b1bdc2e5 92
UHSLMarcus 0:7088b1bdc2e5 93 bool AMS_ENS210::humid_is _measuring() {
UHSLMarcus 0:7088b1bdc2e5 94 char[1] output;
UHSLMarcus 0:7088b1bdc2e5 95 i2c_read(SENS_STATUS, output, 1);
UHSLMarcus 0:7088b1bdc2e5 96 return output[0] >> 1 & 1;
UHSLMarcus 0:7088b1bdc2e5 97 }
UHSLMarcus 0:7088b1bdc2e5 98
UHSLMarcus 0:7088b1bdc2e5 99 bool AMS_ENS210::temp_has_data() {
UHSLMarcus 0:7088b1bdc2e5 100 if (temp_mode()) { // when in single shot mode make sure sensor has started first
UHSLMarcus 0:7088b1bdc2e5 101 if (!temp_is_measuring())
UHSLMarcus 0:7088b1bdc2e5 102 start(true, false); // set start bit if sensor is idle
UHSLMarcus 0:7088b1bdc2e5 103 }
UHSLMarcus 0:7088b1bdc2e5 104
UHSLMarcus 0:7088b1bdc2e5 105 char output[3];
UHSLMarcus 0:7088b1bdc2e5 106 i2c_read(SENS_TEMP, output, 3);
UHSLMarcus 0:7088b1bdc2e5 107
UHSLMarcus 0:7088b1bdc2e5 108 // do crc7
UHSLMarcus 0:7088b1bdc2e5 109 // Store read data to avoid reading from I2C again
UHSLMarcus 0:7088b1bdc2e5 110 temp_reading = 0 | output[0] | (output[1] << 8); // bytes 1 and 2 make the 16 bit data
UHSLMarcus 0:7088b1bdc2e5 111
UHSLMarcus 0:7088b1bdc2e5 112 return output[3] & 1; // bit 0 of byte 3 is the valid flag
UHSLMarcus 0:7088b1bdc2e5 113 }
UHSLMarcus 0:7088b1bdc2e5 114
UHSLMarcus 0:7088b1bdc2e5 115 bool AMS_ENS210::humid_has_data() {
UHSLMarcus 0:7088b1bdc2e5 116 if (humid_mode()) { // when in single shot mode make sure sensor has started first
UHSLMarcus 0:7088b1bdc2e5 117 if (!humid_is_measuring())
UHSLMarcus 0:7088b1bdc2e5 118 start(false, true); // set start bit if sensor is idle
UHSLMarcus 0:7088b1bdc2e5 119 }
UHSLMarcus 0:7088b1bdc2e5 120
UHSLMarcus 0:7088b1bdc2e5 121 char output[3];
UHSLMarcus 0:7088b1bdc2e5 122 i2c_read(SENS_HUMID, output, 3);
UHSLMarcus 0:7088b1bdc2e5 123
UHSLMarcus 0:7088b1bdc2e5 124 // do crc7
UHSLMarcus 0:7088b1bdc2e5 125 // Store read data to avoid reading from I2C again
UHSLMarcus 0:7088b1bdc2e5 126 temp_reading = 0 | output[0] | (output[1] << 8); // bytes 1 and 2 make the 16 bit data
UHSLMarcus 0:7088b1bdc2e5 127
UHSLMarcus 0:7088b1bdc2e5 128 return output[3] & 1; // bit 0 of byte 3 is the valid flag
UHSLMarcus 0:7088b1bdc2e5 129 }
UHSLMarcus 0:7088b1bdc2e5 130
UHSLMarcus 0:7088b1bdc2e5 131 uint16_t AMS_ENS210::temp_read() {
UHSLMarcus 0:7088b1bdc2e5 132
UHSLMarcus 0:7088b1bdc2e5 133 uint16_t reading = 0;
UHSLMarcus 0:7088b1bdc2e5 134
UHSLMarcus 0:7088b1bdc2e5 135 if (temp_mode()) { // when in single shot mode, data is read and saved in temp_has_data()
UHSLMarcus 0:7088b1bdc2e5 136 reading = temp_reading;
UHSLMarcus 0:7088b1bdc2e5 137 } else {
UHSLMarcus 0:7088b1bdc2e5 138 char output[3];
UHSLMarcus 0:7088b1bdc2e5 139 i2c_read(SENS_TEMP, output, 3);
UHSLMarcus 0:7088b1bdc2e5 140
UHSLMarcus 0:7088b1bdc2e5 141 // do crc7
UHSLMarcus 2:f5a7883ae9c2 142 if (output[2] & 1) // bit 0 of byte 3 is the valid flag
UHSLMarcus 0:7088b1bdc2e5 143 reading = 0 | output[0] | (output[1] << 8); // bytes 1 and 2 make the 16 bit data
UHSLMarcus 0:7088b1bdc2e5 144 }
UHSLMarcus 0:7088b1bdc2e5 145
UHSLMarcus 0:7088b1bdc2e5 146 return reading;
UHSLMarcus 0:7088b1bdc2e5 147 }
UHSLMarcus 0:7088b1bdc2e5 148
UHSLMarcus 0:7088b1bdc2e5 149 uint16_t AMS_ENS210::humid_read() {
UHSLMarcus 0:7088b1bdc2e5 150 uint16_t reading = 0;
UHSLMarcus 0:7088b1bdc2e5 151
UHSLMarcus 0:7088b1bdc2e5 152 if (humid_mode()) { // when in single shot mode, data is read and saved in humid_has_data()
UHSLMarcus 0:7088b1bdc2e5 153 reading = humid_reading;
UHSLMarcus 0:7088b1bdc2e5 154 } else {
UHSLMarcus 0:7088b1bdc2e5 155 char output[3];
UHSLMarcus 0:7088b1bdc2e5 156 i2c_read(SENS_HUMID, output, 3);
UHSLMarcus 0:7088b1bdc2e5 157
UHSLMarcus 0:7088b1bdc2e5 158 // do crc7
UHSLMarcus 2:f5a7883ae9c2 159 if (output[2] & 1) // bit 0 of byte 3 is the valid flag
UHSLMarcus 0:7088b1bdc2e5 160 reading = 0 | output[0] | (output[1] << 8); // bytes 1 and 2 make the 16 bit data
UHSLMarcus 0:7088b1bdc2e5 161 }
UHSLMarcus 0:7088b1bdc2e5 162
UHSLMarcus 0:7088b1bdc2e5 163 return reading;
UHSLMarcus 0:7088b1bdc2e5 164 }
UHSLMarcus 0:7088b1bdc2e5 165
UHSLMarcus 0:7088b1bdc2e5 166 /*** Private ***/
UHSLMarcus 0:7088b1bdc2e5 167
UHSLMarcus 0:7088b1bdc2e5 168 bool AMS_ENS210::write_config(bool system, bool sensor) {
UHSLMarcus 0:7088b1bdc2e5 169 int w_bytes = 0;
UHSLMarcus 0:7088b1bdc2e5 170 char cmd[2];
UHSLMarcus 0:7088b1bdc2e5 171
UHSLMarcus 0:7088b1bdc2e5 172 if (system) {
UHSLMarcus 0:7088b1bdc2e5 173 cmd[0] = SYS_CONFIG;
UHSLMarcus 0:7088b1bdc2e5 174 cmd[1] = 0 | _power_mode | _reset << 7; // bit 0 of SYS_CTRL is power mode, bit 7 is reset
UHSLMarcus 0:7088b1bdc2e5 175 w_bytes += _i2c->write(SLAVE_ADDR, cmd, 2);
UHSLMarcus 0:7088b1bdc2e5 176 }
UHSLMarcus 0:7088b1bdc2e5 177
UHSLMarcus 0:7088b1bdc2e5 178 if (sensor) {
UHSLMarcus 0:7088b1bdc2e5 179 cmd[0] = SENS_OP_MODE;
UHSLMarcus 0:7088b1bdc2e5 180 cmd[1] = 0 | _temp_mode | (_humid_mode << 1); // bit 0 is temp mode, bit 1 is humid mode
UHSLMarcus 0:7088b1bdc2e5 181 w_bytes += _i2c->write(SLAVE_ADDR, cmd, 2);
UHSLMarcus 0:7088b1bdc2e5 182 }
UHSLMarcus 0:7088b1bdc2e5 183
UHSLMarcus 0:7088b1bdc2e5 184 return w_bytes == (system + sensor)*2; // add error reporting/handling later...
UHSLMarcus 0:7088b1bdc2e5 185 }
UHSLMarcus 0:7088b1bdc2e5 186
UHSLMarcus 0:7088b1bdc2e5 187 const char *AMS_ENS210::read_config(bool system, bool sensor) {
UHSLMarcus 0:7088b1bdc2e5 188
UHSLMarcus 0:7088b1bdc2e5 189 static char output[2];
UHSLMarcus 0:7088b1bdc2e5 190
UHSLMarcus 0:7088b1bdc2e5 191 if (system)
UHSLMarcus 0:7088b1bdc2e5 192 i2c_read(SYS_CONFIG, output, 1);
UHSLMarcus 0:7088b1bdc2e5 193
UHSLMarcus 0:7088b1bdc2e5 194 if (sensor)
UHSLMarcus 0:7088b1bdc2e5 195 i2c_read(SYS_CONFIG, output+system, 1);
UHSLMarcus 0:7088b1bdc2e5 196
UHSLMarcus 0:7088b1bdc2e5 197 return output;
UHSLMarcus 0:7088b1bdc2e5 198
UHSLMarcus 0:7088b1bdc2e5 199 }
UHSLMarcus 0:7088b1bdc2e5 200
UHSLMarcus 0:7088b1bdc2e5 201 int AMS_ENS210::i2c_read(char reg_addr, char* output, int len) {
UHSLMarcus 0:7088b1bdc2e5 202
UHSLMarcus 0:7088b1bdc2e5 203 int read_count = 0;
UHSLMarcus 0:7088b1bdc2e5 204
UHSLMarcus 0:7088b1bdc2e5 205 _i2c->start(); // send start condition for write
UHSLMarcus 0:7088b1bdc2e5 206 if(_i2c->write(SLAVE_ADDR_W) == 1) { // write slave address
UHSLMarcus 0:7088b1bdc2e5 207 if(_i2c->write(reg_addr) == 1) { // write register address
UHSLMarcus 0:7088b1bdc2e5 208 _i2c->start(); // send another start condition for read
UHSLMarcus 0:7088b1bdc2e5 209 for (int i = 0; < len) { // read len bytes
UHSLMarcus 0:7088b1bdc2e5 210 output[i] = _i2c->read(i < len-1 ? 1 : 0); // ack all reads aside from the final one (i == len-1)
UHSLMarcus 0:7088b1bdc2e5 211 read_count++;
UHSLMarcus 0:7088b1bdc2e5 212 }
UHSLMarcus 0:7088b1bdc2e5 213 }
UHSLMarcus 0:7088b1bdc2e5 214 }
UHSLMarcus 0:7088b1bdc2e5 215 _i2c->stop(); // send stop condition
UHSLMarcus 0:7088b1bdc2e5 216
UHSLMarcus 0:7088b1bdc2e5 217 return read_count;
UHSLMarcus 0:7088b1bdc2e5 218 }