Skip to content

Commit

Permalink
Added support for continuous mode.
Browse files Browse the repository at this point in the history
Added example for continuous mode.
Added example for single shot without wait.
  • Loading branch information
maarten-pennings committed Oct 23, 2018
1 parent bde37bb commit 37c50d3
Show file tree
Hide file tree
Showing 8 changed files with 192 additions and 29 deletions.
10 changes: 10 additions & 0 deletions examples/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,11 +11,21 @@ It tries to not use any other libraries (it only uses `Serial` to print results,
The ENS210 library is used without error error handling.


## ens210cont
A sketch that demonstrates the continuous mode of the ENS210.
No error handling.


## ens210full
A sketch, that is basic like ens210basic in that it uses no other libraries.
But it does employ full error handling and it demos all conversions (Kelvin, Celsius, Fahrenheit).


## ens210single
A sketch that demonstrates single shot mode, doing other work during the conversion.
No error handling.


## ens210thingspeak
A real application, not just a basic demo.
Reads temperature and humidity from the ENS210, and uploads that to a ThingSpeak channel.
Expand Down
3 changes: 1 addition & 2 deletions examples/ens210basic/ens210basic.ino
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,7 @@ void setup() {
Serial.println("Starting ENS210 basic demo");

// Enable I2C
// Wire.begin(D2,D1); // For ESP8266 NodeMCU boards [VDD to 3V3, GND to GND, SDA to D2, SCL to D1]
Wire.begin(); // Arduino pro mini or Nano [VDD to VCC/3V3, GND to GND, SDA to A4, SCL to A5]
Wire.begin(); // For ESP8266 NodeMCU boards: VDD to 3V3, GND to GND, SDA to D2, SCL to D1

// Enable ENS210
ens210.begin();
Expand Down
52 changes: 52 additions & 0 deletions examples/ens210cont/ens210cont.ino
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
/*
ens210cont.ino - Demo sketch for continuous mode of the ENS210 relative humidity and temperature sensor with I2C interface from ams (no error handling)
Created by Maarten Pennings 2018 oct 23
*/


#include <Wire.h> // I2C library
#include "ens210.h" // ENS210 library


ENS210 ens210;


void setup() {
// Enable serial
Serial.begin(115200);
Serial.println("");
Serial.println("Starting ENS210 continuous mode demo");

// Enable I2C
Wire.begin(); // For ESP8266 NodeMCU boards: VDD to 3V3, GND to GND, SDA to D2, SCL to D1

// Enable ENS210
ens210.begin();

// Start continuous mode
ens210.startcont();

// Wait till first measurement is ready (comment out, and see status INVALID)
delay(ENS210_THCONV_CONT_MS);
}


void loop() {
// Get the measurement data
int t_data, t_status, h_data, h_status;
ens210.read(&t_data, &t_status, &h_data, &h_status );

// Print the results
Serial.print(ens210.status_str(t_status)); Serial.print(" ");
Serial.print(ens210.toCelsius(t_data,10)/10.0,1); Serial.print(" C, ");
Serial.print(ens210.status_str(h_status)); Serial.print(" ");
Serial.print(ens210.toPercentageH(h_data,1)); Serial.print(" %RH");
Serial.println();

// Uncomment for a test: stop measuring after 15 measurements
// static int count; if( count++==15 ) { Serial.println("stopped"); ens210.stopcont(); }

// Arbitrary delay
delay(2000);
}

3 changes: 1 addition & 2 deletions examples/ens210full/ens210full.ino
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,7 @@ void setup() {
Serial.println("Starting ENS210 full demo");

// Enable I2C
Wire.begin(D2,D1); // For ESP8266 NodeMCU boards [VDD to 3V3, GND to GND, SDA to D2, SCL to D1]
// Wire.begin(); // Arduino pro mini or Nano [VDD to VCC/3V3, GND to GND, SDA to A4, SCL to A5]
Wire.begin(); // For ESP8266 NodeMCU boards: VDD to 3V3, GND to GND, SDA to D2, SCL to D1

// Enable ENS210
bool ok= ens210.begin();
Expand Down
54 changes: 54 additions & 0 deletions examples/ens210single/ens210single.ino
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
/*
ens210single.ino - Demo sketch for single shot mode, doing something else during the conversion (no error handling)
Created by Maarten Pennings 2018 oct 23
*/


#include <Wire.h> // I2C library
#include "ens210.h" // ENS210 library


ENS210 ens210;


void setup() {
// Enable serial
Serial.begin(115200);
Serial.println("");
Serial.println("Starting ENS210 continuous mode demo");

// Enable I2C
Wire.begin(); // For ESP8266 NodeMCU boards: VDD to 3V3, GND to GND, SDA to D2, SCL to D1

// Enable ENS210
ens210.begin();
}


void loop() {
// Start one single shot conversion
ens210.startsingle();

// Start other work during ENS210 conversion
Serial.print("Working ");
for( int i=0; i<10; i++ ) {
Serial.print(".");
delay(20); // Try delay of 10; read comes too soon and gives INVALID
}
Serial.println(" done");

// Get the measurement data
int t_data, t_status, h_data, h_status;
ens210.read(&t_data, &t_status, &h_data, &h_status );

// Print the results
Serial.print(ens210.status_str(t_status)); Serial.print(" ");
Serial.print(ens210.toCelsius(t_data,10)/10.0,1); Serial.print(" C, ");
Serial.print(ens210.status_str(h_status)); Serial.print(" ");
Serial.print(ens210.toPercentageH(h_data,1)); Serial.print(" %RH");
Serial.println();

// Arbitrary delay
delay(2000);
}

2 changes: 2 additions & 0 deletions keywords.txt
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,8 @@ reset KEYWORD2
lowpower KEYWORD2
getversion KEYWORD2
startsingle KEYWORD2
startcont KEYWORD2
stopcont KEYWORD2
read KEYWORD2
extract KEYWORD2
status_str KEYWORD2
Expand Down
44 changes: 42 additions & 2 deletions src/ens210.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,6 @@

// Chip constants
#define ENS210_PARTID 0x0210 // The expected part id of the ENS210
#define ENS210_THCONVERSION_MS 130 // Conversion time in ms for one T/H measurement
#define ENS210_BOOTING_MS 2 // Booting time in ms (also after reset, or going to high power)

// Addresses of the ENS210 registers
Expand Down Expand Up @@ -107,7 +106,7 @@ void ENS210::measure(int * t_data, int * t_status, int * h_data, int * h_status
// Start a single shot measurement
ok= startsingle(); if(!ok) return; // Both statuses have value ENS210_STATUS_I2CERROR
// Wait for measurement to complete
delay(ENS210_THCONVERSION_MS);
delay(ENS210_THCONV_SINGLE_MS);
// Get the measurement data
ok= read(&t_val,&h_val); if(!ok) return; // Both statuses have value ENS210_STATUS_I2CERROR
// Extract the data and update the statuses
Expand Down Expand Up @@ -202,6 +201,29 @@ bool ENS210::startsingle(void) {
}


// Configures ENS210 to switch to continuous measurement. Returns false on I2C problems.
bool ENS210::startcont(void) {
Wire.beginTransmission(_slaveaddress); // START, SLAVEADDR
Wire.write(ENS210_REG_SENS_RUN); // Register address (SENS_RUN); using auto increment
Wire.write(0x03); // SENS_RUN : T_RUN=1/cont , H_RUN=1/cont
Wire.write(0x03); // SENS_START: T_START=1/start, H_START=1/start
int result= Wire.endTransmission(); // STOP
//PRINTF("ens210: debug: startcont %d\n",result);
return result==0;
}


// Configures ENS210 to stop continuous measurement. Returns false on I2C problems.
bool ENS210::stopcont(void) {
Wire.beginTransmission(_slaveaddress); // START, SLAVEADDR
Wire.write(ENS210_REG_SENS_STOP); // Register address (SENS_STOP)
Wire.write(0x03); // SENS_START: T_STOP=1/start, H_STOP=1/start
int result= Wire.endTransmission(); // STOP
//PRINTF("ens210: debug: stopcont %d\n",result);
return result==0;
}


// Reads measurement data from the ENS210. Returns false on I2C problems.
bool ENS210::read(uint32_t *t_val, uint32_t *h_val) {
uint8_t i2cbuf[6];
Expand All @@ -225,6 +247,24 @@ bool ENS210::read(uint32_t *t_val, uint32_t *h_val) {
}


// Reads measurement data from the ENS210 and extracts data and status.
void ENS210::read(int*t_data,int*t_status,int*h_data,int*h_status) {
uint32_t t_val;
uint32_t h_val;
// Get the measurement data
bool ok=read(&t_val,&h_val);
if( !ok ) {
// Signal I2C error
*t_status= ENS210_STATUS_I2CERROR;
*h_status= ENS210_STATUS_I2CERROR;
} else {
// Extract the data and update the statuses
extract(t_val, t_data, t_status);
extract(h_val, h_data, h_status);
}
}


// Extracts measurement `data` and `status` from a `val` obtained from `read`.
// Upon entry, 'val' is the 24 bits read from T_VAL or H_VAL.
// Upon exit, 'data' is the T_DATA or H_DATA, and 'status' one of ENS210_STATUS_XXX.
Expand Down
53 changes: 30 additions & 23 deletions src/ens210.h
Original file line number Diff line number Diff line change
Expand Up @@ -13,11 +13,14 @@
// Note that the ENS210 provides a "value" (`t_val` or `h_val` each 24 bit).
// A "value" consists of a payload (17 bit) and a CRC (7 bit) over that payload.
// The payload consists of a valid flag (1 bit) and the actual measurement "data" (`t_data` or `h_data`, 16 bit)
#define ENS210_STATUS_I2CERROR 4 // There was an I2C communication error, `read`ing the value.
#define ENS210_STATUS_CRCERROR 3 // The value was read, but the CRC over the payload (valid and data) does not match.
#define ENS210_STATUS_INVALID 2 // The value was read, the CRC matches, but the data is invalid (e.g. the measurement was not yet finished).
#define ENS210_STATUS_OK 1 // The value was read, the CRC matches, and data is valid.
#define ENS210_STATUS_I2CERROR 4 // There was an I2C communication error, `read`ing the value.
#define ENS210_STATUS_CRCERROR 3 // The value was read, but the CRC over the payload (valid and data) does not match.
#define ENS210_STATUS_INVALID 2 // The value was read, the CRC matches, but the data is invalid (e.g. the measurement was not yet finished).
#define ENS210_STATUS_OK 1 // The value was read, the CRC matches, and data is valid.

// Chip constants
#define ENS210_THCONV_SINGLE_MS 130 // Conversion time in ms for single shot T/H measurement
#define ENS210_THCONV_CONT_MS 238 // Conversion time in ms for continuous T/H measurement

class ENS210 {
public: // Main API functions
Expand All @@ -28,34 +31,38 @@ class ENS210 {
// Sets `h_data` (relative humidity in 1/512 %RH), and `h_status` (from ENS210STATUS_XXX).
// Use the conversion functions below to convert `t_data` to K, C, F; or `h_data` to %RH.
// Note that this function contains a delay of 130ms to wait for the measurement to complete.
// If you don't want that, use startsingle() ... wait ENS210_THCONVERSION_MS ... read().
void measure(int * t_data, int * t_status, int * h_data, int * h_status );

public: // Conversion functions - the temperature conversions also subtract the solder correction (see correction_set() method).
int32_t toKelvin (int t_data, int multiplier); // Converts t_data (from `measure`) to 1/multiplier Kelvin
int32_t toCelsius (int t_data, int multiplier); // Converts t_data (from `measure`) to 1/multiplier Celsius
int32_t toFahrenheit (int t_data, int multiplier); // Converts t_data (from `measure`) to 1/multiplier Fahrenheit
int32_t toPercentageH(int h_data, int multiplier); // Converts h_data (from `measure`) to 1/multiplier %RH
int32_t toKelvin (int t_data, int multiplier); // Converts t_data (from `measure`) to 1/multiplier Kelvin
int32_t toCelsius (int t_data, int multiplier); // Converts t_data (from `measure`) to 1/multiplier Celsius
int32_t toFahrenheit (int t_data, int multiplier); // Converts t_data (from `measure`) to 1/multiplier Fahrenheit
int32_t toPercentageH(int h_data, int multiplier); // Converts h_data (from `measure`) to 1/multiplier %RH

// Optionally set a solder `correction` (units: 1/64K, default from `begin` is 0).
// See "Effect of Soldering on Temperature Readout" in "Design-Guidelines" from
// https://download.ams.com/ENVIRONMENTAL-SENSORS/ENS210/Documentation
void correction_set(int correction=50*64/1000); // Sets the solder correction (default is 50mK) - only used by the `toXxx()` functions.
int correction_get(void); // Gets the solder correction.

public: // Helper functions (communicating with ENS210)
bool reset(void); // Sends a reset to the ENS210. Returns false on I2C problems.
bool lowpower(bool enable); // Sets ENS210 to low (true) or high (false) power. Returns false on I2C problems.
bool getversion(uint16_t*partid,uint64_t*uid); // Reads PART_ID and UID of ENS210. Returns false on I2C problems.
bool startsingle(void); // Configures ENS210 to perform one single shot measurement. Returns false on I2C problems.
bool read(uint32_t*t_val,uint32_t*h_val); // Reads measurement data from the ENS210. Returns false on I2C problems.
void correction_set(int correction=50*64/1000); // Sets the solder correction (default is 50mK) - only used by the `toXxx()` functions.
int correction_get(void); // Gets the solder correction.

public: // Helper functions (communicating with ENS210)
bool reset(void); // Sends a reset to the ENS210. Returns false on I2C problems.
bool lowpower(bool enable); // Sets ENS210 to low (true) or high (false) power. Returns false on I2C problems.
bool getversion(uint16_t*partid,uint64_t*uid); // Reads PART_ID and UID of ENS210. Returns false on I2C problems.
bool startsingle(void); // Configures ENS210 to perform one single shot measurement. Returns false on I2C problems.
bool startcont(void); // Configures ENS210 to switch to continuous measurement. Returns false on I2C problems.
bool stopcont(void); // Configures ENS210 to stop continuous measurement. Returns false on I2C problems.
bool read(uint32_t*t_val,uint32_t*h_val); // Reads measurement data from the ENS210. Returns false on I2C problems.
void read(int*t_data,int*t_status,int*h_data,int*h_status); // Reads measurement data from the ENS210 and extracts data and status.

public: // Helper functions (data conversion)
static void extract(uint32_t val,int*data,int*status); // Extracts measurement `data` and `status` from a `val` obtained from `read()`.
static const char * status_str( int status ); // Converts a status (ENS210_STATUS_XXX) to a human readable string.

protected: // Data members
int _slaveaddress= 0x43; // Slave address of ENS210
int _soldercorrection; // Correction due to soldering (in 1/64K); subtracted from `t_data` by conversion functions.
static void extract(uint32_t val,int*data,int*status); // Extracts measurement `data` and `status` from a `val` obtained from `read()`.
static const char * status_str( int status ); // Converts a status (ENS210_STATUS_XXX) to a human readable string.
protected: // Data members
int _slaveaddress= 0x43; // Slave address of ENS210
int _soldercorrection; // Correction due to soldering (in 1/64K); subtracted from `t_data` by conversion functions.
};


Expand Down

0 comments on commit 37c50d3

Please sign in to comment.