A Library for the AMS ENS210 temperature and humidity sensor.

Dependents:   AMS_CCS811_gas_sensor AMS_CCS811_gas_sensor

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?

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 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 }