library for AMS ENS210 temperature and humidity sensor
Dependents: rIoTwear-temp-humid
AMS_ENS210.cpp@1:94a79c88c105, 2017-01-17 (annotated)
- Committer:
- UHSLMarcus
- Date:
- Tue Jan 17 14:26:34 2017 +0000
- Revision:
- 1:94a79c88c105
- Parent:
- 0:7088b1bdc2e5
- Child:
- 2:f5a7883ae9c2
initalised the data stores to 0
Who changed what in which revision?
User | Revision | Line number | New 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 | 0:7088b1bdc2e5 | 142 | if (output[3] & 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 | 0:7088b1bdc2e5 | 159 | if (output[3] & 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 | } |