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