Compare commits

..

7 Commits
3.0.1 ... 3.0.3

62 changed files with 1282 additions and 4353 deletions

View File

@ -34,8 +34,7 @@ If you have any questions or problems, check out [our forum](https://forum.airgr
- [Sensirion Gas Index Algorithm](https://github.com/Sensirion/arduino-gas-index-algorithm)
- [Sensirion Core](https://github.com/Sensirion/arduino-core/)
- [Sensirion I2C SGP41](https://github.com/Sensirion/arduino-i2c-sgp41)
- [Sensirion I2C SHT4x](https://github.com/Sensirion/arduino-i2c-sht4x)
- [Sensirion I2C SHT3x](https://github.com/Sensirion/arduino-i2c-sht3x)
- [Sensirion I2C SHT](https://github.com/Sensirion/arduino-sht)
- [PMS](https://github.com/fu-hsi/pms)
## License

View File

@ -51,7 +51,7 @@ CC BY-SA 4.0 Attribution-ShareAlike 4.0 International License
#define SENSOR_CO2_UPDATE_INTERVAL 5000 /** ms */
#define SENSOR_PM_UPDATE_INTERVAL 5000 /** ms */
#define SENSOR_TEMP_HUM_UPDATE_INTERVAL 5000 /** ms */
#define DISPLAY_DELAY_SHOW_CONTENT_MS 6000 /** ms */
#define DISPLAY_DELAY_SHOW_CONTENT_MS 2000 /** ms */
#define WIFI_HOTSPOT_PASSWORD_DEFAULT \
"cleanair" /** default WiFi AP password \
*/
@ -389,6 +389,7 @@ void setup() {
/** Init I2C */
Wire.begin(ag.getI2cSdaPin(), ag.getI2cSclPin());
delay(1000);
/** Board init */
boardInit();
@ -423,7 +424,7 @@ void setup() {
Serial.println("Device id: " + id);
String id1 = id.substring(0, 9);
String id2 = id.substring(9, 12);
ag.display.setText("\'"+ id1);
ag.display.setText("\'" + id1);
ag.display.setCursor(1, 40);
ag.display.setText(id2 + "\'");
ag.display.show();
@ -505,7 +506,7 @@ void connectToWifi() {
static void boardInit(void) {
/** Init SHT sensor */
if (ag.sht4x.begin(Wire) == false) {
if (ag.sht.begin(Wire) == false) {
failedHandler("SHT init failed");
}
@ -584,11 +585,14 @@ void pmPoll() {
}
static void tempHumPoll() {
temp = ag.sht4x.getTemperature();
hum = ag.sht4x.getRelativeHumidity();
Serial.printf("Temperature: %0.2f\r\n", temp);
Serial.printf(" Humidity: %d\r\n", hum);
if (ag.sht.measure()) {
temp = ag.sht.getTemperature();
hum = ag.sht.getRelativeHumidity();
Serial.printf("Temperature: %0.2f\r\n", temp);
Serial.printf(" Humidity: %d\r\n", hum);
} else {
Serial.println("Meaure SHT failed");
}
}
static void sendDataToServer() {

View File

@ -94,7 +94,7 @@ enum {
#define SENSOR_CO2_UPDATE_INTERVAL 5000 /** ms */
#define SENSOR_PM_UPDATE_INTERVAL 5000 /** ms */
#define SENSOR_TEMP_HUM_UPDATE_INTERVAL 5000 /** ms */
#define DISPLAY_DELAY_SHOW_CONTENT_MS 6000 /** ms */
#define DISPLAY_DELAY_SHOW_CONTENT_MS 2000 /** ms */
#define WIFI_HOTSPOT_PASSWORD_DEFAULT \
"cleanair" /** default WiFi AP password \
*/
@ -204,7 +204,7 @@ public:
}
}
/** Get "pmStandard" */
/** Get "pmsStandard" */
if (JSON.typeof_(root["pmStandard"]) == "string") {
String standard = root["pmStandard"];
if (standard == "ugm3") {
@ -491,6 +491,7 @@ void setup() {
/** Init I2C */
Wire.begin(ag.getI2cSdaPin(), ag.getI2cSclPin());
delay(1000);
/** Display init */
u8g2.begin();
@ -505,8 +506,27 @@ void setup() {
/** Init AirGradient server */
agServer.begin();
/** WIFI connect */
connectToWifi();
/** Run LED test on start up */
displayShowText("Press now for", "LED test", "");
bool test = false;
uint32_t stime = millis();
while (1) {
if (ag.button.getState() == ag.button.BUTTON_PRESSED) {
test = true;
break;
}
delay(1);
uint32_t ms = (uint32_t)(millis() - stime);
if (ms >= 3000) {
break;
}
}
if (test) {
ledTest();
} else {
/** WIFI connect */
connectToWifi();
}
/**
* Send first data to ping server and get server configuration
@ -694,6 +714,7 @@ static void displayShowDashboard(String err) {
do {
u8g2.setFont(u8g2_font_t0_16_tf);
if ((err == NULL) || err.isEmpty()) {
/** Show temperature */
if (agServer.isTemperatureUnitF()) {
if (temp > -10001) {
@ -727,6 +748,38 @@ static void displayShowDashboard(String err) {
Serial.println("Disp show error: " + err);
int strWidth = u8g2.getStrWidth(err.c_str());
u8g2.drawStr((126 - strWidth) / 2, 10, err.c_str());
if (err == "WiFi N/A") {
u8g2.setFont(u8g2_font_t0_12_tf);
if (agServer.isTemperatureUnitF()) {
if (temp > -10001) {
float tempF = (temp * 9 / 5) + 32;
sprintf(strBuf, "%.1f", tempF);
} else {
sprintf(strBuf, "-");
}
u8g2.drawUTF8(1, 10, strBuf);
} else {
if (temp > -10001) {
sprintf(strBuf, "%.1f", temp);
} else {
sprintf(strBuf, "-");
}
u8g2.drawUTF8(1, 10, strBuf);
}
/** Show humidity */
if (hum >= 0) {
sprintf(strBuf, "%d%%", hum);
} else {
sprintf(strBuf, " -%%");
}
if (hum > 99) {
u8g2.drawStr(97, 10, strBuf);
} else {
u8g2.drawStr(105, 10, strBuf);
}
}
}
/** Draw horizontal line */
@ -995,7 +1048,7 @@ static void boardInit(void) {
}
/** INit SHT */
if (ag.sht4x.begin(Wire) == false) {
if (ag.sht.begin(Wire) == false) {
failedHandler("Init SHT failed");
}
@ -1011,25 +1064,6 @@ static void boardInit(void) {
if (ag.pms5003.begin(Serial0) == false) {
failedHandler("Init PMS5003 failed");
}
/** Run LED test on start up */
displayShowText("Press now for", "LED test", "");
bool test = false;
uint32_t stime = millis();
while (1) {
if (ag.button.getState() == ag.button.BUTTON_PRESSED) {
test = true;
break;
}
delay(1);
uint32_t ms = (uint32_t)(millis() - stime);
if (ms >= 3000) {
break;
}
}
if (test) {
ledTest();
}
}
/**
@ -1472,9 +1506,14 @@ static void sendDataToServer(void) {
* @brief Update temperature and humidity value
*/
static void tempHumPoll(void) {
temp = ag.sht4x.getTemperature();
hum = ag.sht4x.getRelativeHumidity();
if (ag.sht.measure()) {
Serial.printf("Temperature: %0.2f\r\n", temp);
Serial.printf(" Humidity: %d\r\n", hum);
temp = ag.sht.getTemperature();
hum = ag.sht.getRelativeHumidity();
Serial.printf("Temperature: %0.2f\r\n", temp);
Serial.printf(" Humidity: %d\r\n", hum);
} else {
Serial.println("Measure SHT failed");
}
}

View File

@ -93,7 +93,7 @@ enum {
#define SENSOR_CO2_UPDATE_INTERVAL 5000 /** ms */
#define SENSOR_PM_UPDATE_INTERVAL 5000 /** ms */
#define SENSOR_TEMP_HUM_UPDATE_INTERVAL 5000 /** ms */
#define DISPLAY_DELAY_SHOW_CONTENT_MS 6000 /** ms */
#define DISPLAY_DELAY_SHOW_CONTENT_MS 2000 /** ms */
#define WIFI_HOTSPOT_PASSWORD_DEFAULT \
"cleanair" /** default WiFi AP password \
*/

View File

@ -1,369 +0,0 @@
#include <AirGradient.h>
#include <HardwareSerial.h>
#include <Wire.h>
/**
* AirGradient use ESP32C3 has default Serial0 use for PMS5003, to print log
* should use esp-hal-log instead.
*/
#include <esp32-hal-log.h>
/**
* @brief Define test board
*/
#define TEST_OPEN_AIR_OUTDOOR 0
#define TEST_ONE_INDOOR 1
/**
* @brief Define test sensor
*/
#define TEST_SENSOR_SenseAirS8 0
#define TEST_SENSOR_SHT4x 0
#define TEST_SENSOR_SGP4x 0
#define TEST_SWITCH 0
#define TEST_OLED 0
#if TEST_OPEN_AIR_OUTDOOR
#define TEST_STATUS_LED 0
#define TEST_PMS5003T 1
#endif
#define TEST_WATCHDOG 1
#if TEST_ONE_INDOOR
#define TEST_LED_BAR 1
#define TEST_SENSOR_PMS5003 0
#endif
#if TEST_OPEN_AIR_OUTDOOR
AirGradient ag(OPEN_AIR_OUTDOOR);
#elif TEST_ONE_INDOOR
AirGradient ag(ONE_INDOOR);
#else
#error "Must enable board test
#endif
void setup() {
/** Print All AirGradient board define */
printBoardDef(NULL);
#if TEST_SENSOR_SenseAirS8
/** Cause Serial is use default for PMS, CO2S8 should be use Serial 1
* Serial 1 will be init by SenseAirS8 don't need to init any more on user
* code
*/
if (ag.s8.begin(Serial1)) {
log_i("CO2S8 sensor init success");
} else {
log_i("CO2S8 sensor init failure");
}
log_i("Start baseline calib");
if (ag.s8.setBaselineCalibration()) {
log_i("Calib success");
} else {
log_e("Calib failure");
}
delay(5000); // Wait for calib done
#endif
#if TEST_SENSOR_PMS5003
if (ag.pms5003.begin(Serial0)) {
log_i("PMS5003 sensor init success");
} else {
log_i("PMS5003 sensor init failure");
}
#endif
#if TEST_PMS5003T
/**
* @brief PMS5003T_1 alway connect to Serial (esp32c3 RXD0, RXD0)
*/
if (ag.pms5003t_1.begin(Serial)) {
log_i("PMS5003T_1 sensor init success");
} else {
log_i("PMS5003T_1 sensor init failure");
}
// TODO Only test without senseair s8 because it's share the UART bus
#if TEST_SENSOR_SenseAirS8 == 0
if (ag.pms5003t_2.begin(Serial1)) {
log_i("PMS5003T_2 sensor init success");
} else {
log_i("PMS5003T_2 sensor init failure");
}
#endif
#endif
#if TEST_SENSOR_SHT4x || TEST_SENSOR_SGP4x || TEST_OLED
Wire.begin(ag.getI2cSdaPin(), ag.getI2cSclPin());
#endif
#if TEST_SENSOR_SHT4x
if (ag.sht4x.begin(Wire)) {
log_i("SHT init success");
} else {
log_i("SHT init failed");
}
#endif
#if TEST_SENSOR_SGP4x
if (ag.sgp41.begin(Wire)) {
log_i("SGP init success");
} else {
log_e("SGP init failure");
}
#endif
#if TEST_LED
led.begin();
#endif
#if TEST_SWITCH
ag.button.begin();
#endif
#if TEST_OLED
ag.display.begin(Wire);
ag.display.setTextSize(1);
ag.display.setCursor(0, 0);
ag.display.setTextColor(1);
ag.display.setText("180s to connect to wifi hostpost AC-xxxxx");
ag.display.show();
#endif
#if TEST_STATUS_LED
ag.statusLed.begin();
#endif
#if TEST_LED_BAR
ag.ledBar.begin();
#endif
#if TEST_WATCHDOG
ag.watchdog.begin();
#endif
}
void loop() {
uint32_t ms;
#if TEST_SENSOR_SenseAirS8
static uint32_t lastTime = 0;
/** Wait for sensor ready */
ms = (uint32_t)(millis() - lastTime);
if (ms >= 1000) {
lastTime = millis();
log_i("CO2: %d (PPM)", ag.s8.getCo2());
}
#endif
#if TEST_SENSOR_PMS5003
static uint32_t pmsTime = 0;
ms = (uint32_t)(millis() - pmsTime);
if (ms >= 1000) {
pmsTime = millis();
if (ag.pms5003.readData()) {
log_i("Passive mode PM 1.0 (ug/m3): %d", ag.pms5003.getPm10Ae());
log_i("Passive mode PM 2.5 (ug/m3): %d", ag.pms5003.getPm25Ae());
log_i("Passive mode PM 10.0 (ug/m3): %d", ag.pms5003.getPm10Ae());
} else {
log_i("PMS sensor read failure");
}
}
#endif
#if TEST_PMS5003T
static uint32_t pmsTime = 0;
ms = (uint32_t)(millis() - pmsTime);
if (ms >= 1000) {
pmsTime = millis();
if (ag.pms5003t_1.readData()) {
log_i("PMS5003_1 PM 1.0 (ug/m3): %d", ag.pms5003t_1.getPm10Ae());
log_i("PMS5003_1 PM 2.5 (ug/m3): %d", ag.pms5003t_1.getPm25Ae());
log_i("PMS5003_1 PM 10.0 (ug/m3): %d", ag.pms5003t_1.getPm10Ae());
log_i("PMS5003_1 PM 3.0 (ug/m3): %d",
ag.pms5003t_1.getPm03ParticleCount());
log_i("Temperature : %02f °C",
ag.pms5003t_1.getTemperature());
log_i("Humidity : %02f %%",
ag.pms5003t_1.getRelativeHumidity());
} else {
log_i("PMS5003_1 sensor read failure");
}
if (ag.pms5003t_2.readData()) {
log_i("PMS5003_2 PM 1.0 (ug/m3): %d", ag.pms5003t_2.getPm10Ae());
log_i("PMS5003_2 PM 2.5 (ug/m3): %d", ag.pms5003t_2.getPm25Ae());
log_i("PMS5003_2 PM 10.0 (ug/m3): %d", ag.pms5003t_2.getPm10Ae());
log_i("PMS5003_2 PM 3.0 (ug/m3): %d",
ag.pms5003t_2.getPm03ParticleCount());
// log_i("Temperature : %02f °C",
// ag.pms5003t_1.getTemperature());
// log_i("Humidity : %02f %%",
// ag.pms5003t_1.getRelativeHumidity());
} else {
log_i("PMS5003_2 sensor read failure");
}
}
#endif
#if TEST_SENSOR_SHT4x
/**
* @brief Get SHT sensor data each 1sec
*
*/
static uint32_t shtTime = 0;
ms = (uint32_t)(millis() - shtTime);
if (ms >= 1000) {
shtTime = millis();
log_i("Get sht4x temperature: %0.2f (degree celsius)",
ag.sht4x.getTemperature());
log_i("Get sht4x temperature: %0.2f (%%)", ag.sht4x.getRelativeHumidity());
}
#endif
#if TEST_SENSOR_SGP4x
static uint32_t sgpTime;
ms = (uint32_t)(millis() - sgpTime);
if (ms >= 1000) {
sgpTime = millis();
uint16_t rawVOC;
log_i("Get TVOC: %d", ag.sgp41.getTvocIndex());
log_i("Get NOx: %d", ag.sgp41.getNoxIndex());
}
#endif
#if TEST_LED
static uint32_t ledTime;
#if TEST_OPEN_AIR_OUTDOOR
// ms = (uint32_t)(millis() - ledTime);
// if(ms >= 500)
// {
// ledTime = millis();
// led.ledToggle();
// }
#elif TEST_ONE_INDOOR
static int ledIndex;
static int ledIndexOld;
ms = (uint32_t)(millis() - ledTime);
if (ms >= 50) {
ledTime = millis();
if (ledIndex == ledIndexOld) {
led.ledOff();
} else {
// Turn last LED off
led.ledSetColor(0, 0, 0, ledIndexOld);
}
// Turn new led ON
led.ledSetColor(255, 0, 0, ledIndex);
ledIndexOld = ledIndex;
ledIndex++;
if (ledIndex >= led.getNumberOfLeds()) {
ledIndex = 0;
}
}
#else
#endif
#endif
#if TEST_SWITCH
static PushButton::State stateOld = PushButton::State::BUTTON_RELEASED;
PushButton::State state = ag.button.getState();
if (state != stateOld) {
stateOld = state;
log_i("Button state changed: %s", ag.button.toString(state).c_str());
if (state == PushButton::State::BUTTON_PRESSED) {
ag.statusLed.setOn();
} else {
ag.statusLed.setOff();
}
}
#endif
#if TEST_LED_BAR
static uint32_t ledTime;
static uint8_t ledNum = 0;
static uint8_t ledIndex = 0;
static uint8_t ledStep = 0;
static bool ledOn = false;
if (ledNum == 0) {
ledNum = ag.ledBar.getNumberOfLeds();
log_i("Get number of led: %d", ledNum);
if (ledNum) {
ag.ledBar.setBrighness(0xff);
for (int i = 0; i < ledNum; i++) {
// ag.ledBar.setColor(0xff, 0xff, 0xff, i);
// ag.ledBar.setColor(204, 136, 153, i);
// ag.ledBar.setColor(204, 0, 0, i);
// ag.ledBar.setColor(204, 100, 153, i);
ag.ledBar.setColor(0, 136, 255, i);
}
ag.ledBar.show();
}
} else {
ms = (uint32_t)(millis() - ledTime);
if (ms >= 500) {
ledTime = millis();
switch (ledStep) {
case 0: {
ag.ledBar.setColor(255, 0, 0, ledIndex);
ledIndex++;
if (ledIndex >= ledNum) {
ag.ledBar.setColor(0, 0, 0);
ledIndex = 0;
ledStep = 1;
}
ag.ledBar.show();
break;
}
case 1: {
ledIndex++;
if (ledIndex >= ledNum) {
ag.ledBar.setColor(255, 0, 0);
ag.ledBar.show();
ledIndex = ledNum - 1;
ledStep = 2;
}
break;
}
case 2: {
if (ledOn) {
ag.ledBar.setColor(255, 0, 0);
} else {
ag.ledBar.setColor(0, 0, 0);
}
ledOn = !ledOn;
ag.ledBar.show();
ledIndex--;
if (ledIndex == 0) {
ag.ledBar.setColor(0, 0, 0);
ag.ledBar.show();
ledStep = 0;
ledIndex = 0;
}
break;
}
default:
break;
}
}
}
#endif
#if TEST_WATCHDOG
static uint32_t wdgTime;
ms = (uint32_t)(millis() - wdgTime);
if (ms >= (1000 * 60)) {
wdgTime = millis();
/** Reset watchdog reach 1 minutes */
ag.watchdog.reset();
}
#endif
}

View File

@ -1,172 +0,0 @@
#include <AirGradient.h>
#include <Wire.h>
/**
* @brief Define test board
*/
#define TEST_DIY_BASIC 1
/**
* @brief Define test sensor
*/
#define TEST_SENSOR_SenseAirS8 1
// #define S8_BASELINE_CALIB
#define TEST_SENSOR_PMS5003 0
#define TEST_SENSOR_SHT4x 0
#define TEST_SENSOR_SGP4x 0
#define TEST_SWITCH 0
#define TEST_OLED 0
#if TEST_DIY_BASIC
AirGradient ag(DIY_BASIC);
#elif TEST_DIY_PRO_INDOOR_V4_2
AirGradient ag(DIY_PRO_INDOOR_V4_2);
#else
#error "Board test not defined"
#endif
void setup() {
Serial.begin(115200);
/** Print All AirGradient board define */
printBoardDef(&Serial);
#if TEST_SENSOR_SenseAirS8
if (ag.s8.begin(&Serial) == true) {
Serial.println("CO2S8 sensor init success");
} else {
Serial.println("CO2S8 sensor init failure");
}
#ifdef S8_BASELINE_CALIB
if (ag.s8.setBaselineCalibration()) {
Serial.println("Manual calib success");
} else {
Serial.println("Manual calib failure");
}
#else
if (ag.s8.setAutoCalib(8)) {
Serial.println("Set auto calib success");
} else {
Serial.println("Set auto calib failure");
}
#endif
delay(5000);
#endif
#if TEST_SENSOR_PMS5003
if (ag.pms5003.begin(&Serial) == true) {
Serial.println("PMS5003 sensor init success");
} else {
Serial.println("PMS5003 sensor init failure");
}
#endif
#if TEST_SENSOR_SHT4x || TEST_SENSOR_SGP4x || TEST_OLED
Wire.begin(ag.getI2cSdaPin(), ag.getI2cSclPin());
#endif
#if TEST_SENSOR_SHT4x
if (ag.sht4x.begin(Wire, Serial)) {
Serial.println("SHT init success");
} else {
Serial.println("SHT init failed");
}
#endif
#if TEST_SENSOR_SGP4x
if (ag.sgp41.begin(Wire, Serial)) {
Serial.println("SGP init succses");
} else {
Serial.println("SGP init failure");
}
#endif
#if TEST_SWITCH
ag.button.begin(Serial);
#endif
#if TEST_OLED
ag.display.begin(Wire, Serial);
ag.display.setTextSize(1);
ag.display.setCursor(0, 0);
ag.display.setTextColor(1);
ag.display.setText("Hello");
ag.display.show();
#endif
}
void loop() {
uint32_t ms;
#if TEST_SENSOR_SenseAirS8
static uint32_t lastTime = 0;
/** Wait for sensor ready */
// if(co2s8.isReady())
// {
// Get sensor data each 1sec
ms = (uint32_t)(millis() - lastTime);
if (ms >= 1000) {
lastTime = millis();
Serial.printf("CO2: %d (PMM)\r\n", ag.s8.getCo2());
}
// }
#endif
#if TEST_SENSOR_PMS5003
static uint32_t pmsTime = 0;
ms = (uint32_t)(millis() - pmsTime);
if (ms >= 1000) {
pmsTime = millis();
if (ag.pms5003.readData()) {
Serial.printf("Passive mode PM 1.0 (ug/m3): %d\r\n",
ag.pms5003.getPm01Ae());
Serial.printf("Passive mode PM 2.5 (ug/m3): %d\r\n",
ag.pms5003.getPm25Ae());
Serial.printf("Passive mode PM 10.5 (ug/m3): %d\r\n",
ag.pms5003.getPm10Ae());
}
}
#endif
#if TEST_SENSOR_SHT4x
/**
* @brief Get SHT sensor data each 1sec
*
*/
static uint32_t shtTime = 0;
ms = (uint32_t)(millis() - shtTime);
if (ms >= 1000) {
shtTime = millis();
float temperature, humidity;
Serial.printf("SHT Temperature: %f, Humidity: %f\r\n",
ag.sht4x.getTemperature(), ag.sht4x.getRelativeHumidity());
}
#endif
#if TEST_SENSOR_SGP4x
static uint32_t sgpTime;
ms = (uint32_t)(millis() - sgpTime);
/***
* Must call this task on loop and avoid delay on loop over 1000 ms
*/
ag.sgp41.handle();
if (ms >= 1000) {
sgpTime = millis();
Serial.printf("SGP TVOC: %d, NOx: %d\r\n", ag.sgp41.getTvocIndex(),
ag.sgp41.getNoxIndex());
}
#endif
#if TEST_SWITCH
static PushButton::State stateOld = PushButton::State::BUTTON_RELEASED;
PushButton::State state = ag.button.getState();
if (state != stateOld) {
stateOld = state;
Serial.printf("Button state changed: %s\r\n",
ag.button.toString(state).c_str());
}
#endif
}

View File

@ -1,33 +1,33 @@
#include <AirGradient.h>
#if defined(ESP8266)
AirGradient ag(DIY_BASIC);
#else
AirGradient ag(ONE_INDOOR);
#endif
void failedHandler(String msg);
void setup() {
Serial.begin(115200);
Serial.println("Hello");
Wire.begin(ag.getI2cSdaPin(), ag.getI2cSclPin());
delay(1000);
if (ag.sht3x.begin(Wire, Serial) == false) {
failedHandler("SHT3x init failed");
if (ag.sht.begin(Wire) == false) {
failedHandler("SHT init failed");
}
}
void loop() {
float temp = ag.sht3x.getTemperature();
if (temp <= -256.0f) {
Serial.println("Get temperature failed");
} else {
if (ag.sht.measure()) {
float hum = ag.sht.getRelativeHumidity();
float temp = ag.sht.getTemperature();
Serial.printf("Get temperature: %f\r\n", temp);
}
float hum = ag.sht3x.getRelativeHumidity();
if (hum < 0) {
Serial.println("Get humidity failed");
Serial.printf(" Get humidity: %f\r\n", hum);
} else {
Serial.printf("Get humidity: %f\r\n", hum);
Serial.println("Measure failed");
}
delay(1000);
}

View File

@ -1,5 +1,5 @@
name=AirGradient Air Quality Sensor
version=3.0.1
version=3.0.3
author=AirGradient <support@airgradient.com>
maintainer=AirGradient <support@airgradient.com>
sentence=ESP32-C3 / ESP8266 library for air quality monitor measuring PM, CO2, Temperature, TVOC and Humidity with OLED display.

View File

@ -1,11 +1,11 @@
#include "AirGradient.h"
#define AG_LIB_VER "3.0.1"
#define AG_LIB_VER "3.0.3"
AirGradient::AirGradient(BoardType type)
: pms5003(type), pms5003t_1(type), pms5003t_2(type), s8(type), sht4x(type),
sht3x(type), sgp41(type), display(type), boardType(type), button(type),
statusLed(type), ledBar(type), watchdog(type) {}
: pms5003(type), pms5003t_1(type), pms5003t_2(type), s8(type), sgp41(type),
display(type), boardType(type), button(type), statusLed(type),
ledBar(type), watchdog(type), sht(type) {}
/**
* @brief Get pin number for I2C SDA

View File

@ -11,8 +11,7 @@
#include "pms/pms5003t.h"
#include "s8/s8.h"
#include "sgp41/sgp41.h"
#include "sht/sht4x.h"
#include "sht/sht3x.h"
#include "sht/sht.h"
/**
* @brief Class with define all the sensor has supported by Airgradient. Each
@ -43,15 +42,10 @@ public:
S8 s8;
/**
* @brief SHT41 Temperature and humidity sensor
*/
Sht4x sht4x;
/**
* @brief SHT3x Temperature and humidity sensor
* @brief Temperature and humidity sensor supported SHT3x and SHT4x
*
*/
Sht3x sht3x;
Sht sht;
/**
* @brief SGP41 TVOC and NOx sensor

View File

@ -1,14 +0,0 @@
---
Language: Cpp
BasedOnStyle: LLVM
IndentWidth: 4
AlignAfterOpenBracket: Align
AllowShortBlocksOnASingleLine: false
AllowShortCaseLabelsOnASingleLine: false
AllowShortFunctionsOnASingleLine: false
IndentCaseLabels: true
SpacesBeforeTrailingComments: 2
PointerAlignment: Left
AlignEscapedNewlines: Left
ForEachMacros: ['TEST_GROUP', 'TEST']
...

View File

@ -1,70 +0,0 @@
app/bin/
app/pde.jar
build/macosx/work/
arduino-core/bin/
arduino-core/arduino-core.jar
hardware/arduino/bootloaders/caterina_LUFA/Descriptors.o
hardware/arduino/bootloaders/caterina_LUFA/Descriptors.lst
hardware/arduino/bootloaders/caterina_LUFA/Caterina.sym
hardware/arduino/bootloaders/caterina_LUFA/Caterina.o
hardware/arduino/bootloaders/caterina_LUFA/Caterina.map
hardware/arduino/bootloaders/caterina_LUFA/Caterina.lst
hardware/arduino/bootloaders/caterina_LUFA/Caterina.lss
hardware/arduino/bootloaders/caterina_LUFA/Caterina.elf
hardware/arduino/bootloaders/caterina_LUFA/Caterina.eep
hardware/arduino/bootloaders/caterina_LUFA/.dep/
build/*.zip
build/*.tar.bz2
build/windows/work/
build/windows/*.zip
build/windows/*.tgz
build/windows/*.tar.bz2
build/windows/libastylej*
build/windows/liblistSerials*
build/windows/arduino-*.zip
build/windows/dist/*.tar.gz
build/windows/dist/*.tar.bz2
build/windows/launch4j-*.tgz
build/windows/launch4j-*.zip
build/windows/launcher/launch4j
build/windows/WinAVR-*.zip
build/macosx/arduino-*.zip
build/macosx/dist/*.tar.gz
build/macosx/dist/*.tar.bz2
build/macosx/*.tar.bz2
build/macosx/libastylej*
build/macosx/appbundler*.jar
build/macosx/appbundler*.zip
build/macosx/appbundler
build/macosx/appbundler-1.0ea-arduino?
build/macosx/appbundler-1.0ea-arduino*.zip
build/macosx/appbundler-1.0ea-upstream*.zip
build/linux/work/
build/linux/dist/*.tar.gz
build/linux/dist/*.tar.bz2
build/linux/*.tgz
build/linux/*.tar.xz
build/linux/*.tar.bz2
build/linux/*.zip
build/linux/libastylej*
build/linux/liblistSerials*
build/shared/arduino-examples*
build/shared/reference*.zip
build/shared/Edison*.zip
build/shared/Galileo*.zip
build/shared/WiFi101-Updater-ArduinoIDE-Plugin*.zip
test-bin
*.iml
.idea
.DS_Store
.directory
hardware/arduino/avr/libraries/Bridge/examples/XivelyClient/passwords.h
avr-toolchain-*.zip
/app/nbproject/private/
/arduino-core/nbproject/private/
/app/build/
/arduino-core/build/
manifest.mf
nbbuild.xml
nbproject

View File

@ -1,103 +0,0 @@
stages:
- validate
- test
variables:
YQ_URL: https://github.com/mikefarah/yq/releases/download/v4.33.3/yq_linux_amd64
compile_test:
stage: test
image:
name: registry.gitlab.sensirion.lokal/sensirion/docker/docker-arduino:0.4.0
tags: [docker, linux]
before_script:
- rm -rf ../sensirion-core-arduino-library
script:
- git clone --depth 1 --branch 0.5.2 https://github.com/Sensirion/arduino-core.git ../sensirion-core-arduino-library
- arduino-cli compile --libraries=".." --warnings all --fqbn arduino:samd:mkrzero ./examples/exampleUsage/exampleUsage.ino
- arduino-cli compile --libraries=".." --warnings all --fqbn arduino:avr:mega ./examples/exampleUsage/exampleUsage.ino
- arduino-cli compile --libraries=".." --warnings all --fqbn arduino:avr:nano ./examples/exampleUsage/exampleUsage.ino
- arduino-cli compile --libraries=".." --warnings all --fqbn arduino:avr:uno ./examples/exampleUsage/exampleUsage.ino
- arduino-cli compile --libraries=".." --warnings all --fqbn esp32:esp32:esp32 ./examples/exampleUsage/exampleUsage.ino
- arduino-cli compile --libraries=".." --warnings all --fqbn esp8266:esp8266:generic ./examples/exampleUsage/exampleUsage.ino
arduino_lint:
stage: validate
image:
name: registry.gitlab.sensirion.lokal/mso-sw/drivers/docker-driver-generator:0.2.0
tags: [linux, docker]
script:
- mkdir ~/arlint
- PATH=~/arlint:$PATH
- curl -fsSL https://raw.githubusercontent.com/arduino/arduino-lint/main/etc/install.sh | BINDIR=~/arlint sh
- arduino-lint --library-manager false
syntax_check:
stage: validate
image:
name: registry.gitlab.sensirion.lokal/mso-sw/drivers/docker-driver-generator:0.2.0
tags: [linux, docker]
script:
- find . -type f -iregex ".*\.\(c\|h\|cpp\|ino\)" -exec clang-format-6.0 -i -style=file {} \; && git diff --exit-code
cppcheck:
stage: validate
image:
name: registry.gitlab.sensirion.lokal/mso-sw/drivers/docker-driver-generator:0.2.0
tags: [linux, docker]
script:
- cppcheck --std=c++11 --language=c++ --error-exitcode=1 --enable=warning,style,performance,portability --suppress=unreadVariable src/*
TODO_check:
stage: validate
image:
name: registry.gitlab.sensirion.lokal/mso-sw/drivers/docker-driver-generator:0.2.0
tags: [linux, docker]
script:
- '! grep -rnw --exclude=.gitlab-ci.yml --exclude-dir=.git . -e "TODO"'
metadata_check:
stage: validate
image:
name: registry.gitlab.sensirion.lokal/mso-sw/drivers/docker-driver-generator:0.2.0
tags: [linux, docker]
before_script:
- apt-get -qq update && apt-get -qq install -y wget
- if ! [ -d downloads/ ]; then mkdir downloads; fi
- if ! [ -e downloads/yq ]; then wget --no-verbose $YQ_URL -O downloads/yq; fi
- cp downloads/yq /usr/local/bin/yq && chmod +x /usr/local/bin/yq
script:
# check if metadata.yml exists
- >
if ! [ -f "metadata.yml" ]; then
echo "metadata.yml file not found"
exit 1
fi
# check that dg_status is 'released'
- export DG_STATUS=$(yq ".dg_status.[]" ./metadata.yml)
- >
if [ $DG_STATUS != "released" ]; then
echo "dg_status in metadata.yml has to be 'released', not '$DG_STATUS'"
exit 1
fi
# check that last_generated is not older than timestamp of last non-merge commit (+ 3 minutes)
- export IS_MANUALLY_MODIFIED=$(yq ".is_manually_modified" ./metadata.yml)
- >
if [ $IS_MANUALLY_MODIFIED = false ]; then
export LAST_GENERATED_TS=$(yq ".last_generated" ./metadata.yml)
export LAST_GENERATED_TS_EPOCH=$(date -d "$LAST_GENERATED_TS" +%s)
export LAST_NON_MERGE_COMMIT_TS=$(git log --format=%ad --date=iso-strict --no-merges -1)
export COMMIT_TS_EPOCH=$(date -d "$LAST_NON_MERGE_COMMIT_TS" +%s)
if [ $(($LAST_GENERATED_TS_EPOCH + 180)) -lt $COMMIT_TS_EPOCH ]; then
echo "'last_generated' timestamp in metadata.yml is older than commit timestamp ($LAST_GENERATED_TS vs $LAST_NON_MERGE_COMMIT_TS)"
exit 1
fi
fi
# check that 'is_manually_modified' is set to true if commit is not from driver generator
- export LAST_NON_MERGE_COMMIT_AUTHOR=$(git log --format=%an --no-merges -1)
- >
if ! [ "$LAST_NON_MERGE_COMMIT_AUTHOR" = "Driver Generator 2" ] && [ "$IS_MANUALLY_MODIFIED" = false ]; then
echo "Last commit is not from Driver Generator. Please update 'is_manually_modified' in metadata.yml"
exit 1
fi

View File

@ -1,19 +0,0 @@
# Changelog
All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
## [Unreleased]
Defined I2C addresses for different sensor models.
You must now pass the I2C address to use in the begin() method of SensirionI2cSht4x
Improved README
## [0.1.0] - 2021-07-27
Initial release
[0.1.0]: https://github.com/Sensirion/arduino-i2c-sht4x/releases/tag/0.1.0

View File

@ -1,29 +0,0 @@
BSD 3-Clause License
Copyright (c) 2023, Sensirion AG
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice, this
list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution.
3. Neither the name of the copyright holder nor the names of its
contributors may be used to endorse or promote products derived from
this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

View File

@ -1,206 +0,0 @@
# Sensirion I²C SHT4X Arduino Library
This is the Sensirion SHT4X library for Arduino allowing you to
communicate with a sensor of the SHT4X family over I²C.
<img src="images/SHT4x.png" width="300px">
Click [here](https://sensirion.com/products/catalog/SEK-SHT40/) to learn more about the Sensirion SHT4X sensor family.
## Supported sensor types
| Sensor name | I²C Addresses |
| ------------- | -------------- |
|[SHT40](https://sensirion.com/products/catalog/SHT40/)| **0x44**, 0x45|
|[SHT41](https://sensirion.com/products/catalog/SHT41/)| **0x44**, 0x45|
|[SHT45](https://sensirion.com/products/catalog/SHT45/)| **0x44**, 0x45|
The following instructions and examples use a *SHT40*.
## Installation of the library
This library can be installed using the Arduino Library manager:
Start the [Arduino IDE](http://www.arduino.cc/en/main/software) and open
the Library Manager via
`Sketch``Include Library``Manage Libraries...`
Search for the `Sensirion I2C SHT4X` library in the `Filter
your search...` field and install it by clicking the `install` button.
If you cannot find it in the library manager, download the latest release as .zip file
and add it to your [Arduino IDE](http://www.arduino.cc/en/main/software) via
`Sketch``Include Library``Add .ZIP Library...`
Don't forget to **install the dependencies** listed below the same way via library
manager or `Add .ZIP Library`
#### Dependencies
* [Sensirion Core](https://github.com/Sensirion/arduino-core)
## Sensor wiring
Use the following pin description to connect your SHT4X to the standard I²C bus of your Arduino board:
<img src="images/SHT40_pinout.png" width="300px">
| *Pin* | *Cable Color* | *Name* | *Description* | *Comments* |
|-------|---------------|:------:|----------------|------------|
| 1 | green | SDA | I2C: Serial data input / output |
| 2 | black | GND | Ground |
| 3 | yellow | SCL | I2C: Serial clock input |
| 4 | red | VDD | Supply Voltage | 1.1V to 3.6V
The recommended voltage is 3.3V.
Please refer to the datasheet for proper circuit setup. There are 3rd party boards for easy connection of the SHT4x sensor to your Arduino Board.
### Board specific wiring
You will find pinout schematics for recommended board models below:
<details><summary>Arduino Uno</summary>
<p>
| *SHT4X* | *SHT4X Pin* | *Cable Color* | *Board Pin* |
| :---: | --- | --- | --- |
| SDA | 1 | green | D18/SDA |
| GND | 2 | black | GND |
| SCL | 3 | yellow | D19/SCL |
| VDD | 4 | red | 3.3V |
<img src="images/Arduino-Uno-Rev3-i2c-pinout-3.3V.png" width="600px">
</p>
</details>
<details><summary>Arduino Nano</summary>
<p>
| *SHT4X* | *SHT4X Pin* | *Cable Color* | *Board Pin* |
| :---: | --- | --- | --- |
| SDA | 1 | green | A4 |
| GND | 2 | black | GND |
| SCL | 3 | yellow | A5 |
| VDD | 4 | red | 3.3V |
<img src="images/Arduino-Nano-i2c-pinout-3.3V.png" width="600px">
</p>
</details>
<details><summary>Arduino Micro</summary>
<p>
| *SHT4X* | *SHT4X Pin* | *Cable Color* | *Board Pin* |
| :---: | --- | --- | --- |
| SDA | 1 | green | D2/SDA |
| GND | 2 | black | GND |
| SCL | 3 | yellow | ~D3/SCL |
| VDD | 4 | red | 3.3V |
<img src="images/Arduino-Micro-i2c-pinout-3.3V.png" width="600px">
</p>
</details>
<details><summary>Arduino Mega 2560</summary>
<p>
| *SHT4X* | *SHT4X Pin* | *Cable Color* | *Board Pin* |
| :---: | --- | --- | --- |
| SDA | 1 | green | D20/SDA |
| GND | 2 | black | GND |
| SCL | 3 | yellow | D21/SCL |
| VDD | 4 | red | 3.3V |
<img src="images/Arduino-Mega-2560-Rev3-i2c-pinout-3.3V.png" width="600px">
</p>
</details>
<details><summary>ESP32 DevKitC</summary>
<p>
| *SHT4X* | *SHT4X Pin* | *Cable Color* | *Board Pin* |
| :---: | --- | --- | --- |
| SDA | 1 | green | GPIO 21 |
| GND | 2 | black | GND |
| SCL | 3 | yellow | GPIO 22 |
| VDD | 4 | red | 3V3 |
<img src="images/esp32-devkitc-i2c-pinout-3.3V.png" width="600px">
</p>
</details>
## Quick Start
1. Install the libraries and dependencies according to [Installation of the library](#installation-of-the-library)
2. Connect the SHT4X sensor to your Arduino as explained in [Sensor wiring](#sensor-wiring)
3. Open the `exampleUsage` sample project within the Arduino IDE:
`File``Examples``Sensirion I2C SHT4X``exampleUsage`
The provided example is working with a SHT40, I²C address 0x44.
In order to use the code with another product or I²C address you need to change it in the code of `exampleUsage`.
You find the list with pre-defined addresses in `src/SensirionI2CSht4x.h`.
5. Click the `Upload` button in the Arduino IDE or `Sketch``Upload`
4. When the upload process has finished, open the `Serial Monitor` or `Serial
Plotter` via the `Tools` menu to observe the measurement values. Note that
the `Baud Rate` in the used tool has to be set to `115200 baud`.
## Contributing
**Contributions are welcome!**
We develop and test this driver using our company internal tools (version
control, continuous integration, code review etc.) and automatically
synchronize the master branch with GitHub. But this doesn't mean that we don't
respond to issues or don't accept pull requests on GitHub. In fact, you're very
welcome to open issues or create pull requests :)
This Sensirion library uses
[`clang-format`](https://releases.llvm.org/download.html) to standardize the
formatting of all our `.cpp` and `.h` files. Make sure your contributions are
formatted accordingly:
The `-i` flag will apply the format changes to the files listed.
```bash
clang-format -i src/*.cpp src/*.h
```
Note that differences from this formatting will result in a failed build until
they are fixed.
## License
See [LICENSE](LICENSE).

View File

@ -1,89 +0,0 @@
/*
* THIS FILE IS AUTOMATICALLY GENERATED
*
* Generator: sensirion-driver-generator 0.32.0
* Product: sht4x
* Model-Version: 2.0.0
*/
/*
* Copyright (c) 2023, Sensirion AG
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* * Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* * Neither the name of Sensirion AG nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
#include <Arduino.h>
#include <SensirionI2CSht4x.h>
#include <Wire.h>
SensirionI2CSht4x sensor;
static char errorMessage[64];
static int16_t error;
void setup() {
Serial.begin(115200);
while (!Serial) {
delay(100);
}
Wire.begin();
sensor.begin(Wire, SHT40_I2C_ADDR_44);
sensor.softReset();
delay(10);
uint32_t serialNumber = 0;
error = sensor.serialNumber(serialNumber);
if (error != NO_ERROR) {
Serial.print("Error trying to execute serialNumber(): ");
errorToString(error, errorMessage, sizeof errorMessage);
Serial.println(errorMessage);
return;
}
Serial.print("serialNumber: ");
Serial.print(serialNumber);
Serial.println();
}
void loop() {
float aTemperature = 0.0;
float aHumidity = 0.0;
delay(20);
error = sensor.measureLowestPrecision(aTemperature, aHumidity);
if (error != NO_ERROR) {
Serial.print("Error trying to execute measureLowestPrecision(): ");
errorToString(error, errorMessage, sizeof errorMessage);
Serial.println(errorMessage);
return;
}
Serial.print("aTemperature: ");
Serial.print(aTemperature);
Serial.print("\t");
Serial.print("aHumidity: ");
Serial.print(aHumidity);
Serial.println();
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 405 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 322 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 296 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 315 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 128 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 524 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 238 KiB

View File

@ -1,46 +0,0 @@
#######################################
# Syntax Coloring Map
#######################################
#######################################
# Datatypes (KEYWORD1)
#######################################
SensirionI2CSht4x KEYWORD1
#######################################
# Methods and Functions (KEYWORD2)
#######################################
measureHighPrecision KEYWORD2
measureMediumPrecision KEYWORD2
measureLowestPrecision KEYWORD2
activateHighestHeaterPowerLong KEYWORD2
activateHighestHeaterPowerShort KEYWORD2
activateMediumHeaterPowerLong KEYWORD2
activateMediumHeaterPowerShort KEYWORD2
activateLowestHeaterPowerLong KEYWORD2
activateLowestHeaterPowerShort KEYWORD2
measureHighPrecisionTicks KEYWORD2
measureMediumPrecisionTicks KEYWORD2
measureLowestPrecisionTicks KEYWORD2
activateHighestHeaterPowerLongTicks KEYWORD2
activateHighestHeaterPowerShortTicks KEYWORD2
activateMediumHeaterPowerLongTicks KEYWORD2
activateMediumHeaterPowerShortTicks KEYWORD2
activateLowestHeaterPowerLongTicks KEYWORD2
activateLowestHeaterPowerShortTicks KEYWORD2
serialNumber KEYWORD2
softReset KEYWORD2
signalTemperature KEYWORD2
signalHumidity KEYWORD2
#######################################
# Instances (KEYWORD2)
#######################################
sensor KEYWORD2
#######################################
# Constants (LITERAL1)
#######################################

View File

@ -1,11 +0,0 @@
name=Sensirion I2C SHT4x
version=1.0.0
author=Sensirion
maintainer=Sensirion
sentence=Library for the SHT4X sensor family by Sensirion
paragraph=Enables you to use the SHT4X sensor family via I2C.
url=https://github.com/Sensirion/arduino-i2c-sht4x
category=Sensors
architectures=*
depends=Sensirion Core
includes=SensirionI2CSht4x.h

View File

@ -1,7 +0,0 @@
generator_version: 0.32.0
model_version: 2.0.0
dg_status:
- released
is_manually_modified: true
first_generated: '2021-07-06 15:05'
last_generated: '2023-10-18 07:36'

View File

@ -1,436 +0,0 @@
/*
* THIS FILE IS AUTOMATICALLY GENERATED
*
* Generator: sensirion-driver-generator 0.32.0
* Product: sht4x
* Model-Version: 2.0.0
*/
/*
* Copyright (c) 2023, Sensirion AG
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* * Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* * Neither the name of Sensirion AG nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
#include "SensirionI2CSht4x.h"
#include "../../SensirionCore/src/SensirionCore.h"
#include <Arduino.h>
static uint8_t communication_buffer[6] = {0};
SensirionI2CSht4x::SensirionI2CSht4x() {
}
float SensirionI2CSht4x::signalTemperature(uint16_t temperatureTicks) {
float temperature = 0.0;
temperature = (float)(temperatureTicks);
temperature = (float)((temperature * 175.0) / 65535.0) - 45.0;
return temperature;
}
float SensirionI2CSht4x::signalHumidity(uint16_t humidityTicks) {
float humidity = 0.0;
humidity = (float)(humidityTicks);
humidity = (float)((humidity * 125.0) / 65535.0) - 6.0;
return humidity;
}
int16_t SensirionI2CSht4x::measureHighPrecision(float& aTemperature,
float& aHumidity) {
uint16_t tempTicks = 0;
uint16_t humiTicks = 0;
int16_t localError = 0;
localError = measureHighPrecisionTicks(tempTicks, humiTicks);
if (localError != NO_ERROR) {
return localError;
}
aTemperature = signalTemperature(tempTicks);
aHumidity = signalHumidity(humiTicks);
return localError;
}
int16_t SensirionI2CSht4x::measureMediumPrecision(float& aTemperature,
float& aHumidity) {
uint16_t tempTicks = 0;
uint16_t humiTicks = 0;
int16_t localError = 0;
localError = measureMediumPrecisionTicks(tempTicks, humiTicks);
if (localError != NO_ERROR) {
return localError;
}
aTemperature = signalTemperature(tempTicks);
aHumidity = signalHumidity(humiTicks);
return localError;
}
int16_t SensirionI2CSht4x::measureLowestPrecision(float& aTemperature,
float& aHumidity) {
uint16_t tempTicks = 0;
uint16_t humiTicks = 0;
int16_t localError = 0;
localError = measureLowestPrecisionTicks(tempTicks, humiTicks);
if (localError != NO_ERROR) {
return localError;
}
aTemperature = signalTemperature(tempTicks);
aHumidity = signalHumidity(humiTicks);
return localError;
}
int16_t SensirionI2CSht4x::activateHighestHeaterPowerLong(float& aTemperature,
float& aHumidity) {
uint16_t tempTicks = 0;
uint16_t humiTicks = 0;
int16_t localError = 0;
localError = activateHighestHeaterPowerLongTicks(tempTicks, humiTicks);
if (localError != NO_ERROR) {
return localError;
}
aTemperature = signalTemperature(tempTicks);
aHumidity = signalHumidity(humiTicks);
return localError;
}
int16_t SensirionI2CSht4x::activateHighestHeaterPowerShort(float& aTemperature,
float& aHumidity) {
uint16_t tempTicks = 0;
uint16_t humiTicks = 0;
int16_t localError = 0;
localError = activateHighestHeaterPowerShortTicks(tempTicks, humiTicks);
if (localError != NO_ERROR) {
return localError;
}
aTemperature = signalTemperature(tempTicks);
aHumidity = signalHumidity(humiTicks);
return localError;
}
int16_t SensirionI2CSht4x::activateMediumHeaterPowerLong(float& aTemperature,
float& aHumidity) {
uint16_t tempTicks = 0;
uint16_t humiTicks = 0;
int16_t localError = 0;
localError = activateMediumHeaterPowerLongTicks(tempTicks, humiTicks);
if (localError != NO_ERROR) {
return localError;
}
aTemperature = signalTemperature(tempTicks);
aHumidity = signalHumidity(humiTicks);
return localError;
}
int16_t SensirionI2CSht4x::activateMediumHeaterPowerShort(float& aTemperature,
float& aHumidity) {
uint16_t tempTicks = 0;
uint16_t humiTicks = 0;
int16_t localError = 0;
localError = activateMediumHeaterPowerShortTicks(tempTicks, humiTicks);
if (localError != NO_ERROR) {
return localError;
}
aTemperature = signalTemperature(tempTicks);
aHumidity = signalHumidity(humiTicks);
return localError;
}
int16_t SensirionI2CSht4x::activateLowestHeaterPowerLong(float& aTemperature,
float& aHumidity) {
uint16_t tempTicks = 0;
uint16_t humiTicks = 0;
int16_t localError = 0;
localError = activateLowestHeaterPowerLongTicks(tempTicks, humiTicks);
if (localError != NO_ERROR) {
return localError;
}
aTemperature = signalTemperature(tempTicks);
aHumidity = signalHumidity(humiTicks);
return localError;
}
int16_t SensirionI2CSht4x::activateLowestHeaterPowerShort(float& aTemperature,
float& aHumidity) {
uint16_t tempTicks = 0;
uint16_t humiTicks = 0;
int16_t localError = 0;
localError = activateLowestHeaterPowerShortTicks(tempTicks, humiTicks);
if (localError != NO_ERROR) {
return localError;
}
aTemperature = signalTemperature(tempTicks);
aHumidity = signalHumidity(humiTicks);
return localError;
}
int16_t SensirionI2CSht4x::measureHighPrecisionTicks(uint16_t& temperatureTicks,
uint16_t& humidityTicks) {
int16_t localError = NO_ERROR;
uint8_t* buffer_ptr = communication_buffer;
SensirionI2CTxFrame txFrame =
SensirionI2CTxFrame::createWithUInt8Command(0xfd, buffer_ptr, 6);
localError =
SensirionI2CCommunication::sendFrame(_i2cAddress, txFrame, *_i2cBus);
if (localError != NO_ERROR) {
return localError;
}
delay(10);
SensirionI2CRxFrame rxFrame(buffer_ptr, 6);
localError = SensirionI2CCommunication::receiveFrame(_i2cAddress, 6,
rxFrame, *_i2cBus);
if (localError != NO_ERROR) {
return localError;
}
localError |= rxFrame.getUInt16(temperatureTicks);
localError |= rxFrame.getUInt16(humidityTicks);
return localError;
}
int16_t
SensirionI2CSht4x::measureMediumPrecisionTicks(uint16_t& temperatureTicks,
uint16_t& humidityTicks) {
int16_t localError = NO_ERROR;
uint8_t* buffer_ptr = communication_buffer;
SensirionI2CTxFrame txFrame =
SensirionI2CTxFrame::createWithUInt8Command(0xf6, buffer_ptr, 6);
localError =
SensirionI2CCommunication::sendFrame(_i2cAddress, txFrame, *_i2cBus);
if (localError != NO_ERROR) {
return localError;
}
delay(5);
SensirionI2CRxFrame rxFrame(buffer_ptr, 6);
localError = SensirionI2CCommunication::receiveFrame(_i2cAddress, 6,
rxFrame, *_i2cBus);
if (localError != NO_ERROR) {
return localError;
}
localError |= rxFrame.getUInt16(temperatureTicks);
localError |= rxFrame.getUInt16(humidityTicks);
return localError;
}
int16_t
SensirionI2CSht4x::measureLowestPrecisionTicks(uint16_t& temperatureTicks,
uint16_t& humidityTicks) {
int16_t localError = NO_ERROR;
uint8_t* buffer_ptr = communication_buffer;
SensirionI2CTxFrame txFrame =
SensirionI2CTxFrame::createWithUInt8Command(0xe0, buffer_ptr, 6);
localError =
SensirionI2CCommunication::sendFrame(_i2cAddress, txFrame, *_i2cBus);
if (localError != NO_ERROR) {
return localError;
}
delay(2);
SensirionI2CRxFrame rxFrame(buffer_ptr, 6);
localError = SensirionI2CCommunication::receiveFrame(_i2cAddress, 6,
rxFrame, *_i2cBus);
if (localError != NO_ERROR) {
return localError;
}
localError |= rxFrame.getUInt16(temperatureTicks);
localError |= rxFrame.getUInt16(humidityTicks);
return localError;
}
int16_t SensirionI2CSht4x::activateHighestHeaterPowerLongTicks(
uint16_t& temperatureTicks, uint16_t& humidityTicks) {
int16_t localError = NO_ERROR;
uint8_t* buffer_ptr = communication_buffer;
SensirionI2CTxFrame txFrame =
SensirionI2CTxFrame::createWithUInt8Command(0x39, buffer_ptr, 6);
localError =
SensirionI2CCommunication::sendFrame(_i2cAddress, txFrame, *_i2cBus);
if (localError != NO_ERROR) {
return localError;
}
delay(1100);
SensirionI2CRxFrame rxFrame(buffer_ptr, 6);
localError = SensirionI2CCommunication::receiveFrame(_i2cAddress, 6,
rxFrame, *_i2cBus);
if (localError != NO_ERROR) {
return localError;
}
localError |= rxFrame.getUInt16(temperatureTicks);
localError |= rxFrame.getUInt16(humidityTicks);
return localError;
}
int16_t SensirionI2CSht4x::activateHighestHeaterPowerShortTicks(
uint16_t& temperatureTicks, uint16_t& humidityTicks) {
int16_t localError = NO_ERROR;
uint8_t* buffer_ptr = communication_buffer;
SensirionI2CTxFrame txFrame =
SensirionI2CTxFrame::createWithUInt8Command(0x32, buffer_ptr, 6);
localError =
SensirionI2CCommunication::sendFrame(_i2cAddress, txFrame, *_i2cBus);
if (localError != NO_ERROR) {
return localError;
}
delay(110);
SensirionI2CRxFrame rxFrame(buffer_ptr, 6);
localError = SensirionI2CCommunication::receiveFrame(_i2cAddress, 6,
rxFrame, *_i2cBus);
if (localError != NO_ERROR) {
return localError;
}
localError |= rxFrame.getUInt16(temperatureTicks);
localError |= rxFrame.getUInt16(humidityTicks);
return localError;
}
int16_t SensirionI2CSht4x::activateMediumHeaterPowerLongTicks(
uint16_t& temperatureTicks, uint16_t& humidityTicks) {
int16_t localError = NO_ERROR;
uint8_t* buffer_ptr = communication_buffer;
SensirionI2CTxFrame txFrame =
SensirionI2CTxFrame::createWithUInt8Command(0x2f, buffer_ptr, 6);
localError =
SensirionI2CCommunication::sendFrame(_i2cAddress, txFrame, *_i2cBus);
if (localError != NO_ERROR) {
return localError;
}
delay(1100);
SensirionI2CRxFrame rxFrame(buffer_ptr, 6);
localError = SensirionI2CCommunication::receiveFrame(_i2cAddress, 6,
rxFrame, *_i2cBus);
if (localError != NO_ERROR) {
return localError;
}
localError |= rxFrame.getUInt16(temperatureTicks);
localError |= rxFrame.getUInt16(humidityTicks);
return localError;
}
int16_t SensirionI2CSht4x::activateMediumHeaterPowerShortTicks(
uint16_t& temperatureTicks, uint16_t& humidityTicks) {
int16_t localError = NO_ERROR;
uint8_t* buffer_ptr = communication_buffer;
SensirionI2CTxFrame txFrame =
SensirionI2CTxFrame::createWithUInt8Command(0x24, buffer_ptr, 6);
localError =
SensirionI2CCommunication::sendFrame(_i2cAddress, txFrame, *_i2cBus);
if (localError != NO_ERROR) {
return localError;
}
delay(110);
SensirionI2CRxFrame rxFrame(buffer_ptr, 6);
localError = SensirionI2CCommunication::receiveFrame(_i2cAddress, 6,
rxFrame, *_i2cBus);
if (localError != NO_ERROR) {
return localError;
}
localError |= rxFrame.getUInt16(temperatureTicks);
localError |= rxFrame.getUInt16(humidityTicks);
return localError;
}
int16_t SensirionI2CSht4x::activateLowestHeaterPowerLongTicks(
uint16_t& temperatureTicks, uint16_t& humidityTicks) {
int16_t localError = NO_ERROR;
uint8_t* buffer_ptr = communication_buffer;
SensirionI2CTxFrame txFrame =
SensirionI2CTxFrame::createWithUInt8Command(0x1e, buffer_ptr, 6);
localError =
SensirionI2CCommunication::sendFrame(_i2cAddress, txFrame, *_i2cBus);
if (localError != NO_ERROR) {
return localError;
}
delay(1100);
SensirionI2CRxFrame rxFrame(buffer_ptr, 6);
localError = SensirionI2CCommunication::receiveFrame(_i2cAddress, 6,
rxFrame, *_i2cBus);
if (localError != NO_ERROR) {
return localError;
}
localError |= rxFrame.getUInt16(temperatureTicks);
localError |= rxFrame.getUInt16(humidityTicks);
return localError;
}
int16_t SensirionI2CSht4x::activateLowestHeaterPowerShortTicks(
uint16_t& temperatureTicks, uint16_t& humidityTicks) {
int16_t localError = NO_ERROR;
uint8_t* buffer_ptr = communication_buffer;
SensirionI2CTxFrame txFrame =
SensirionI2CTxFrame::createWithUInt8Command(0x15, buffer_ptr, 6);
localError =
SensirionI2CCommunication::sendFrame(_i2cAddress, txFrame, *_i2cBus);
if (localError != NO_ERROR) {
return localError;
}
delay(110);
SensirionI2CRxFrame rxFrame(buffer_ptr, 6);
localError = SensirionI2CCommunication::receiveFrame(_i2cAddress, 6,
rxFrame, *_i2cBus);
if (localError != NO_ERROR) {
return localError;
}
localError |= rxFrame.getUInt16(temperatureTicks);
localError |= rxFrame.getUInt16(humidityTicks);
return localError;
}
int16_t SensirionI2CSht4x::serialNumber(uint32_t& serialNumber) {
int16_t localError = NO_ERROR;
uint8_t* buffer_ptr = communication_buffer;
SensirionI2CTxFrame txFrame =
SensirionI2CTxFrame::createWithUInt8Command(0x89, buffer_ptr, 6);
localError =
SensirionI2CCommunication::sendFrame(_i2cAddress, txFrame, *_i2cBus);
if (localError != NO_ERROR) {
return localError;
}
delay(10);
SensirionI2CRxFrame rxFrame(buffer_ptr, 6);
localError = SensirionI2CCommunication::receiveFrame(_i2cAddress, 6,
rxFrame, *_i2cBus);
if (localError != NO_ERROR) {
return localError;
}
localError |= rxFrame.getUInt32(serialNumber);
return localError;
}
int16_t SensirionI2CSht4x::softReset() {
int16_t localError = NO_ERROR;
uint8_t* buffer_ptr = communication_buffer;
SensirionI2CTxFrame txFrame =
SensirionI2CTxFrame::createWithUInt8Command(0x94, buffer_ptr, 2);
localError =
SensirionI2CCommunication::sendFrame(_i2cAddress, txFrame, *_i2cBus);
if (localError != NO_ERROR) {
return localError;
}
delay(10);
return localError;
}
void SensirionI2CSht4x::begin(TwoWire& i2cBus, uint8_t i2cAddress) {
_i2cBus = &i2cBus;
_i2cAddress = i2cAddress;
}

View File

@ -1,424 +0,0 @@
/*
* THIS FILE IS AUTOMATICALLY GENERATED
*
* Generator: sensirion-driver-generator 0.32.0
* Product: sht4x
* Model-Version: 2.0.0
*/
/*
* Copyright (c) 2023, Sensirion AG
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* * Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* * Neither the name of Sensirion AG nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef SENSIRIONI2CSHT4X_H
#define SENSIRIONI2CSHT4X_H
#include <Wire.h>
#define NO_ERROR 0
#define SHT40_I2C_ADDR_44 0x44
#define SHT40_I2C_ADDR_45 0x45
#define SHT41_I2C_ADDR_44 0x44
#define SHT41_I2C_ADDR_45 0x45
#define SHT45_I2C_ADDR_44 0x44
#define SHT45_I2C_ADDR_45 0x45
typedef enum {
MEASURE_HIGH_PRECISION_TICKS_CMD_ID = 0xfd,
MEASURE_MEDIUM_PRECISION_TICKS_CMD_ID = 0xf6,
MEASURE_LOWEST_PRECISION_TICKS_CMD_ID = 0xe0,
ACTIVATE_HIGHEST_HEATER_POWER_LONG_TICKS_CMD_ID = 0x39,
ACTIVATE_HIGHEST_HEATER_POWER_SHORT_TICKS_CMD_ID = 0x32,
ACTIVATE_MEDIUM_HEATER_POWER_LONG_TICKS_CMD_ID = 0x2f,
ACTIVATE_MEDIUM_HEATER_POWER_SHORT_TICKS_CMD_ID = 0x24,
ACTIVATE_LOWEST_HEATER_POWER_LONG_TICKS_CMD_ID = 0x1e,
ACTIVATE_LOWEST_HEATER_POWER_SHORT_TICKS_CMD_ID = 0x15,
SERIAL_NUMBER_CMD_ID = 0x89,
SOFT_RESET_CMD_ID = 0x94,
} CmdId;
class SensirionI2CSht4x {
public:
SensirionI2CSht4x();
/**
* @brief Initializes the SHT4x class.
*
* @param i2cBus Arduino stream object to be used for communication.
*/
void begin(TwoWire& i2cBus, uint8_t i2cAddress);
/**
* @brief Run measurement with high precision
*
* SHT4x command for a single shot measurement with high repeatability.
*
* @param[out] aTemperature Converted from ticks to degrees celsius by (175
* * ticks_value / 65535) - 45
* @param[out] aHumidity Converted from ticks to percent relative humdity by
* (125 * ticks_value / 65535) - 6
*
* @return error_code 0 on success, an error code otherwise.
*/
int16_t measureHighPrecision(float& aTemperature, float& aHumidity);
/**
* @brief Run measurement with medium precision
*
* SHT4x command for a single shot measurement with medium repeatability.
*
* @param[out] aTemperature Converted from ticks to degrees celsius by (175
* * ticks_value / 65535) - 45
* @param[out] aHumidity Converted from ticks to percent relative humdity by
* (125 * ticks_value / 65535) - 6
*
* @return error_code 0 on success, an error code otherwise.
*/
int16_t measureMediumPrecision(float& aTemperature, float& aHumidity);
/**
* @brief Run measurement with low precision
*
* SHT4x command for a single shot measurement with low repeatability.
*
* @param[out] aTemperature Converted from ticks to degrees celsius by (175
* * ticks_value / 65535) - 45
* @param[out] aHumidity Converted from ticks to percent relative humdity by
* (125 * ticks_value / 65535) - 6
*
* @return error_code 0 on success, an error code otherwise.
*/
int16_t measureLowestPrecision(float& aTemperature, float& aHumidity);
/**
* @brief Run measurement with high precision and the highest power heater
* for 1s
*
* SHT4x command to activate highest heater power and perform a single shot
* high precision measurement for 1s.
*
* @param[out] aTemperature Converted from ticks to degrees celsius by (175
* * ticks_value / 65535) - 45
* @param[out] aHumidity Converted from ticks to percent relative humdity by
* (125 * ticks_value / 65535) - 6
*
* @return error_code 0 on success, an error code otherwise.
*/
int16_t activateHighestHeaterPowerLong(float& aTemperature,
float& aHumidity);
/**
* @brief Run measurement with high precision and the highest power heater
* for 0.1s
*
* SHT4x command to activate highest heater power and perform a single shot
* high precision measurement for 0.1s.
*
* @param[out] aTemperature Converted from ticks to degrees celsius by (175
* * ticks_value / 65535) - 45
* @param[out] aHumidity Converted from ticks to percent relative humdity by
* (125 * ticks_value / 65535) - 6
*
* @return error_code 0 on success, an error code otherwise.
*/
int16_t activateHighestHeaterPowerShort(float& aTemperature,
float& aHumidity);
/**
* @brief Run measurement with high precision and the medium power heater
* for 1s
*
* SHT4x command to activate medium heater power and perform a single shot
* high precision measurement for 1s.
*
* @param[out] aTemperature Converted from ticks to degrees celsius by (175
* * ticks_value / 65535) - 45
* @param[out] aHumidity Converted from ticks to percent relative humdity by
* (125 * ticks_value / 65535) - 6
*
* @return error_code 0 on success, an error code otherwise.
*/
int16_t activateMediumHeaterPowerLong(float& aTemperature,
float& aHumidity);
/**
* @brief Run measurement with high precision and the medium power heater
* for 0.1s
*
* SHT4x command to activate medium heater power and perform a single shot
* high precision measurement for 0.1s.
*
* @param[out] aTemperature Converted from ticks to degrees celsius by (175
* * ticks_value / 65535) - 45
* @param[out] aHumidity Converted from ticks to percent relative humdity by
* (125 * ticks_value / 65535) - 6
*
* @return error_code 0 on success, an error code otherwise.
*/
int16_t activateMediumHeaterPowerShort(float& aTemperature,
float& aHumidity);
/**
* @brief Run measurement with high precision and the lowest power heater
* for 1s
*
* SHT4x command to activate lowest heater power and perform a single shot
* high precision measurement for 1s.
*
* @param[out] aTemperature Converted from ticks to degrees celsius by (175
* * ticks_value / 65535) - 45
* @param[out] aHumidity Converted from ticks to percent relative humdity by
* (125 * ticks_value / 65535) - 6
*
* @return error_code 0 on success, an error code otherwise.
*/
int16_t activateLowestHeaterPowerLong(float& aTemperature,
float& aHumidity);
/**
* @brief Run measurement with high precision and the lowest power heater
* for 0.1s
*
* SHT4x command to activate lowest heater power and perform a single shot
* high precision measurement for 0.1s.
*
* @param[out] aTemperature Converted from ticks to degrees celsius by (175
* * ticks_value / 65535) - 45
* @param[out] aHumidity Converted from ticks to percent relative humdity by
* (125 * ticks_value / 65535) - 6
*
* @return error_code 0 on success, an error code otherwise.
*/
int16_t activateLowestHeaterPowerShort(float& aTemperature,
float& aHumidity);
/**
* @brief measureHighPrecisionTicks
*
* SHT4x command for a single shot measurement with high repeatability.
*
* @param[out] temperatureTicks Temperature ticks. Convert to degrees
* celsius by (175 * value / 65535) - 45
* @param[out] humidityTicks Humidity ticks. Convert to degrees celsius by
* (125
* * value / 65535) - 6
*
* @return error_code 0 on success, an error code otherwise.
*/
int16_t measureHighPrecisionTicks(uint16_t& temperatureTicks,
uint16_t& humidityTicks);
/**
* @brief measureMediumPrecisionTicks
*
* SHT4x command for a single shot measurement with medium repeatability.
*
* @param[out] temperatureTicks Temperature ticks. Convert to degrees
* celsius by (175 * value / 65535) - 45
* @param[out] humidityTicks Humidity ticks. Convert to degrees celsius by
* (125
* * value / 65535) - 6
*
* @return error_code 0 on success, an error code otherwise.
*/
int16_t measureMediumPrecisionTicks(uint16_t& temperatureTicks,
uint16_t& humidityTicks);
/**
* @brief measureLowestPrecisionTicks
*
* SHT4x command for a single shot measurement with lowest repeatability.
*
* @param[out] temperatureTicks Temperature ticks. Convert to degrees
* celsius by (175 * value / 65535) - 45
* @param[out] humidityTicks Humidity ticks. Convert to degrees celsius by
* (125
* * value / 65535) - 6
*
* @return error_code 0 on success, an error code otherwise.
*/
int16_t measureLowestPrecisionTicks(uint16_t& temperatureTicks,
uint16_t& humidityTicks);
/**
* @brief activateHighestHeaterPowerLongTicks
*
* SHT4x command to activate highest heater power and perform a single shot
* high precision measurement for 1s.
*
* @param[out] temperatureTicks Temperature ticks. Convert to degrees
* celsius by (175 * value / 65535) - 45
* @param[out] humidityTicks Humidity ticks. Convert to degrees celsius by
* (125
* * value / 65535) - 6
*
* @return error_code 0 on success, an error code otherwise.
*/
int16_t activateHighestHeaterPowerLongTicks(uint16_t& temperatureTicks,
uint16_t& humidityTicks);
/**
* @brief activateHighestHeaterPowerShortTicks
*
* SHT4x command to activate highest heater power and perform a single shot
* high precision measurement for 0.1s.
*
* @param[out] temperatureTicks Temperature ticks. Convert to degrees
* celsius by (175 * value / 65535) - 45
* @param[out] humidityTicks Humidity ticks. Convert to degrees celsius by
* (125
* * value / 65535) - 6
*
* @return error_code 0 on success, an error code otherwise.
*/
int16_t activateHighestHeaterPowerShortTicks(uint16_t& temperatureTicks,
uint16_t& humidityTicks);
/**
* @brief activateMediumHeaterPowerLongTicks
*
* SHT4x command to activate medium heater power and perform a single shot
* high precision measurement for 1s.
*
* @param[out] temperatureTicks Temperature ticks. Convert to degrees
* celsius by (175 * value / 65535) - 45
* @param[out] humidityTicks Humidity ticks. Convert to degrees celsius by
* (125
* * value / 65535) - 6
*
* @return error_code 0 on success, an error code otherwise.
*/
int16_t activateMediumHeaterPowerLongTicks(uint16_t& temperatureTicks,
uint16_t& humidityTicks);
/**
* @brief activateMediumHeaterPowerShortTicks
*
* SHT4x command to activate medium heater power and perform a single shot
* high precision measurement for 0.1s.
*
* @param[out] temperatureTicks Temperature ticks. Convert to degrees
* celsius by (175 * value / 65535) - 45
* @param[out] humidityTicks Humidity ticks. Convert to degrees celsius by
* (125
* * value / 65535) - 6
*
* @return error_code 0 on success, an error code otherwise.
*/
int16_t activateMediumHeaterPowerShortTicks(uint16_t& temperatureTicks,
uint16_t& humidityTicks);
/**
* @brief activateLowestHeaterPowerLongTicks
*
* SHT4x command to activate lowest heater power and perform a single shot
* high precision measurement for 1s.
*
* @param[out] temperatureTicks Temperature ticks. Convert to degrees
* celsius by (175 * value / 65535) - 45
* @param[out] humidityTicks Humidity ticks. Convert to degrees celsius by
* (125
* * value / 65535) - 6
*
* @return error_code 0 on success, an error code otherwise.
*/
int16_t activateLowestHeaterPowerLongTicks(uint16_t& temperatureTicks,
uint16_t& humidityTicks);
/**
* @brief activateLowestHeaterPowerShortTicks
*
* SHT4x command to activate lowest heater power and perform a single shot
* high precision measurement for 0.1s.
*
* @param[out] temperatureTicks Temperature ticks. Convert to degrees
* celsius by (175 * value / 65535) - 45
* @param[out] humidityTicks Humidity ticks. Convert to degrees celsius by
* (125
* * value / 65535) - 6
*
* @return error_code 0 on success, an error code otherwise.
*/
int16_t activateLowestHeaterPowerShortTicks(uint16_t& temperatureTicks,
uint16_t& humidityTicks);
/**
* @brief serialNumber
*
* Read out the serial number
*
* @param[out] serialNumber Unique serial number
*
* @note Each sensor has a unique serial number that is assigned by
* Sensirion during production.It is stored in the one-time-programmable
* memory and cannot be manipulated after production.
*
* @return error_code 0 on success, an error code otherwise.
*/
int16_t serialNumber(uint32_t& serialNumber);
/**
* @brief softReset
*
* Perform a soft reset.
*
* @note A reset of the sensor can be achieved in three ways: • Soft reset:
* use this function • I2C general call: all devices on the I2C bus are
* reset by sending the command 0x06 to the I2C address 0x00. • Power down
* (incl.pulling SCL and SDA low)
*
* @return error_code 0 on success, an error code otherwise.
*/
int16_t softReset();
private:
TwoWire* _i2cBus = nullptr;
uint8_t _i2cAddress = 0;
/**
* @brief signalTemperature
*
* @param[in] temperatureTicks
*
* @return Converted from ticks to degrees celsius by (175 * ticks_value /
* 65535) - 45
*/
float signalTemperature(uint16_t temperatureTicks);
/**
* @brief signalHumidity
*
* @param[in] humidityTicks
*
* @return Converted from ticks to percent relative humdity by (125 *
* ticks_value / 65535) - 6
*/
float signalHumidity(uint16_t humidityTicks);
};
#endif // SENSIRIONI2CSHT4X_H

View File

@ -1,14 +0,0 @@
---
Language: Cpp
BasedOnStyle: LLVM
IndentWidth: 4
AlignAfterOpenBracket: Align
AllowShortBlocksOnASingleLine: false
AllowShortCaseLabelsOnASingleLine: false
AllowShortFunctionsOnASingleLine: false
IndentCaseLabels: true
SpacesBeforeTrailingComments: 2
PointerAlignment: Left
AlignEscapedNewlines: Left
ForEachMacros: ['TEST_GROUP', 'TEST']
...

View File

@ -1,110 +0,0 @@
stages:
- validate
- test
variables:
YQ_URL: https://github.com/mikefarah/yq/releases/download/v4.33.3/yq_linux_amd64
compile_test:
stage: test
image:
name: registry.gitlab.sensirion.lokal/sensirion/docker/docker-arduino:0.4.0
tags: [docker, linux]
before_script:
- rm -rf ../sensirion-core-arduino-library
script:
- git clone --depth 1 --branch 0.5.2 https://github.com/Sensirion/arduino-core.git ../sensirion-core-arduino-library
- arduino-cli compile --libraries=".." --warnings all --fqbn arduino:samd:mkrzero ./examples/exampleUsageSingleShot/exampleUsageSingleShot.ino
- arduino-cli compile --libraries=".." --warnings all --fqbn arduino:avr:mega ./examples/exampleUsageSingleShot/exampleUsageSingleShot.ino
- arduino-cli compile --libraries=".." --warnings all --fqbn arduino:avr:nano ./examples/exampleUsageSingleShot/exampleUsageSingleShot.ino
- arduino-cli compile --libraries=".." --warnings all --fqbn arduino:avr:uno ./examples/exampleUsageSingleShot/exampleUsageSingleShot.ino
- arduino-cli compile --libraries=".." --warnings all --fqbn esp32:esp32:esp32 ./examples/exampleUsageSingleShot/exampleUsageSingleShot.ino
- arduino-cli compile --libraries=".." --warnings all --fqbn esp8266:esp8266:generic ./examples/exampleUsageSingleShot/exampleUsageSingleShot.ino
- arduino-cli compile --libraries=".." --warnings all --fqbn arduino:samd:mkrzero ./examples/exampleUsage/exampleUsage.ino
- arduino-cli compile --libraries=".." --warnings all --fqbn arduino:avr:mega ./examples/exampleUsage/exampleUsage.ino
- arduino-cli compile --libraries=".." --warnings all --fqbn arduino:avr:nano ./examples/exampleUsage/exampleUsage.ino
- arduino-cli compile --libraries=".." --warnings all --fqbn arduino:avr:uno ./examples/exampleUsage/exampleUsage.ino
- arduino-cli compile --libraries=".." --warnings all --fqbn esp32:esp32:esp32 ./examples/exampleUsage/exampleUsage.ino
- arduino-cli compile --libraries=".." --warnings all --fqbn esp8266:esp8266:generic ./examples/exampleUsage/exampleUsage.ino
arduino_lint:
stage: validate
image:
name: registry.gitlab.sensirion.lokal/mso-sw/drivers/docker-driver-generator:0.2.0
tags: [linux, docker]
script:
- mkdir ~/arlint
- PATH=~/arlint:$PATH
- curl -fsSL https://raw.githubusercontent.com/arduino/arduino-lint/main/etc/install.sh | BINDIR=~/arlint sh
- arduino-lint --library-manager false
syntax_check:
stage: validate
image:
name: registry.gitlab.sensirion.lokal/mso-sw/drivers/docker-driver-generator:0.2.0
tags: [linux, docker]
script:
- find . -type f -iregex ".*\.\(c\|h\|cpp\|ino\)" -exec clang-format-6.0 -i -style=file {} \; && git diff --exit-code
cppcheck:
stage: validate
image:
name: registry.gitlab.sensirion.lokal/mso-sw/drivers/docker-driver-generator:0.2.0
tags: [linux, docker]
script:
- cppcheck --std=c++11 --language=c++ --error-exitcode=1 --enable=warning,style,performance,portability --suppress=unreadVariable src/*
TODO_check:
stage: validate
image:
name: registry.gitlab.sensirion.lokal/mso-sw/drivers/docker-driver-generator:0.2.0
tags: [linux, docker]
script:
- '! grep -rnw --exclude=.gitlab-ci.yml --exclude-dir=.git . -e "TODO"'
metadata_check:
stage: validate
image:
name: registry.gitlab.sensirion.lokal/mso-sw/drivers/docker-driver-generator:0.2.0
tags: [linux, docker]
before_script:
- apt-get -qq update && apt-get -qq install -y wget
- if ! [ -d downloads/ ]; then mkdir downloads; fi
- if ! [ -e downloads/yq ]; then wget --no-verbose $YQ_URL -O downloads/yq; fi
- cp downloads/yq /usr/local/bin/yq && chmod +x /usr/local/bin/yq
script:
# check if metadata.yml exists
- >
if ! [ -f "metadata.yml" ]; then
echo "metadata.yml file not found"
exit 1
fi
# check that dg_status is 'released'
- export DG_STATUS=$(yq ".dg_status.[]" ./metadata.yml)
- >
if [ $DG_STATUS != "released" ]; then
echo "dg_status in metadata.yml has to be 'released', not '$DG_STATUS'"
exit 1
fi
# check that last_generated is not older than timestamp of last non-merge commit (+ 3 minutes)
- export IS_MANUALLY_MODIFIED=$(yq ".is_manually_modified" ./metadata.yml)
- >
if [ $IS_MANUALLY_MODIFIED = false ]; then
export LAST_GENERATED_TS=$(yq ".last_generated" ./metadata.yml)
export LAST_GENERATED_TS_EPOCH=$(date -d "$LAST_GENERATED_TS" +%s)
export LAST_NON_MERGE_COMMIT_TS=$(git log --format=%ad --date=iso-strict --no-merges -1)
export COMMIT_TS_EPOCH=$(date -d "$LAST_NON_MERGE_COMMIT_TS" +%s)
if [ $(($LAST_GENERATED_TS_EPOCH + 180)) -lt $COMMIT_TS_EPOCH ]; then
echo "'last_generated' timestamp in metadata.yml is older than commit timestamp ($LAST_GENERATED_TS vs $LAST_NON_MERGE_COMMIT_TS)"
exit 1
fi
fi
# check that 'is_manually_modified' is set to true if commit is not from driver generator
- export LAST_NON_MERGE_COMMIT_AUTHOR=$(git log --format=%an --no-merges -1)
- >
if ! [ "$LAST_NON_MERGE_COMMIT_AUTHOR" = "Driver Generator 2" ] && [ "$IS_MANUALLY_MODIFIED" = false ]; then
echo "Last commit is not from Driver Generator. Please update 'is_manually_modified' in metadata.yml"
exit 1
fi

View File

@ -1,13 +0,0 @@
# Changelog
All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
## [Unreleased]
## [1.0.0] - 2023-10-27
Initial release

View File

@ -1,217 +0,0 @@
# Sensirion I²C SHT3X Arduino Library
This is the Sensirion SHT3X library for Arduino allowing you to
communicate with a sensor of the SHT3X family over I²C.
<img src="images/SHT3x.png" width="300px">
Click [here](https://sensirion.com/products/catalog/SHT30-DIS-B) to learn more about the Sensirion SHT3X sensor family.
Not all sensors of this driver family support all measurements.
In case a measurement is not supported by all sensors, the products that
support it are listed in the API description.
## Supported sensor types
| Sensor name | I²C Addresses |
| ------------- | -------------- |
|[SHT30A](https://sensirion.com/products/catalog/SHT30A-DIS-B)| **0x44**, 0x45|
|[SHT30](https://sensirion.com/products/catalog/SHT30-DIS-B)| **0x44**, 0x45|
|[SHT31A](https://sensirion.com/products/catalog/SHT31A-DIS-B)| **0x44**, 0x45|
|[SHT31](https://sensirion.com/products/catalog/SHT31-DIS-B)| **0x44**, 0x45|
|[SHT33](https://sensirion.com/products/catalog/SHT33-DIS)| **0x44**, 0x45|
|[SHT35A](https://sensirion.com/products/catalog/SHT35A-DIS-B)| **0x44**, 0x45|
|[SHT35](https://sensirion.com/products/catalog/SHT35-DIS-B)| **0x44**, 0x45|
|[SHT85](https://sensirion.com/sht85)| **0x44** |
The following instructions and examples use a *SHT30*.
## Installation of the library
This library can be installed using the Arduino Library manager:
Start the [Arduino IDE](http://www.arduino.cc/en/main/software) and open
the Library Manager via
`Sketch``Include Library``Manage Libraries...`
Search for the `Sensirion I2C SHT3X` library in the `Filter
your search...` field and install it by clicking the `install` button.
If you cannot find it in the library manager, download the latest release as .zip file
and add it to your [Arduino IDE](http://www.arduino.cc/en/main/software) via
`Sketch``Include Library``Add .ZIP Library...`
Don't forget to **install the dependencies** listed below the same way via library
manager or `Add .ZIP Library`
#### Dependencies
* [Sensirion Core](https://github.com/Sensirion/arduino-core)
## Sensor wiring
Use the following pin description to connect your SHT3X to the standard I²C bus of your Arduino board:
<img src="images/SHT3x_pinout.png" width="300px">
| *Pin* | *Cable Color* | *Name* | *Description* | *Comments* |
|-------|---------------|:------:|----------------|------------|
| 1 | green | SDA | I2C: Serial data input / output |
| 2 | black | GND | Ground |
| 3 | yellow | SCL | I2C: Serial clock input |
| 4 | red | VDD | Supply Voltage | 2.15V to 5.5V
The recommended voltage is 3.3V.
### Board specific wiring
You will find pinout schematics for recommended board models below:
<details><summary>Arduino Uno</summary>
<p>
| *SHT3X* | *SHT3X Pin* | *Cable Color* | *Board Pin* |
| :---: | --- | --- | --- |
| SDA | 1 | green | D18/SDA |
| GND | 2 | black | GND |
| SCL | 3 | yellow | D19/SCL |
| VDD | 4 | red | 3.3V |
<img src="images/Arduino-Uno-Rev3-i2c-pinout-3.3V.png" width="600px">
</p>
</details>
<details><summary>Arduino Nano</summary>
<p>
| *SHT3X* | *SHT3X Pin* | *Cable Color* | *Board Pin* |
| :---: | --- | --- | --- |
| SDA | 1 | green | A4 |
| GND | 2 | black | GND |
| SCL | 3 | yellow | A5 |
| VDD | 4 | red | 3.3V |
<img src="images/Arduino-Nano-i2c-pinout-3.3V.png" width="600px">
</p>
</details>
<details><summary>Arduino Micro</summary>
<p>
| *SHT3X* | *SHT3X Pin* | *Cable Color* | *Board Pin* |
| :---: | --- | --- | --- |
| SDA | 1 | green | D2/SDA |
| GND | 2 | black | GND |
| SCL | 3 | yellow | ~D3/SCL |
| VDD | 4 | red | 3.3V |
<img src="images/Arduino-Micro-i2c-pinout-3.3V.png" width="600px">
</p>
</details>
<details><summary>Arduino Mega 2560</summary>
<p>
| *SHT3X* | *SHT3X Pin* | *Cable Color* | *Board Pin* |
| :---: | --- | --- | --- |
| SDA | 1 | green | D20/SDA |
| GND | 2 | black | GND |
| SCL | 3 | yellow | D21/SCL |
| VDD | 4 | red | 3.3V |
<img src="images/Arduino-Mega-2560-Rev3-i2c-pinout-3.3V.png" width="600px">
</p>
</details>
<details><summary>ESP32 DevKitC</summary>
<p>
| *SHT3X* | *SHT3X Pin* | *Cable Color* | *Board Pin* |
| :---: | --- | --- | --- |
| SDA | 1 | green | GPIO 21 |
| GND | 2 | black | GND |
| SCL | 3 | yellow | GPIO 22 |
| VDD | 4 | red | 3V3 |
<img src="images/esp32-devkitc-i2c-pinout-3.3V.png" width="600px">
</p>
</details>
## Quick Start
1. Install the libraries and dependencies according to [Installation of the library](#installation-of-the-library)
2. Connect the SHT3X sensor to your Arduino as explained in [Sensor wiring](#sensor-wiring)
3. Open the `exampleUsage` sample project within the Arduino IDE:
`File``Examples``Sensirion I2C SHT3X``exampleUsage`
The provided example is working with a SHT30, I²C address 0x44.
In order to use the code with another product or I²C address you need to change it in the code of `exampleUsage`.
You find the list with pre-defined addresses in `src/SensirionI2CSht3x.h`.
5. Click the `Upload` button in the Arduino IDE or `Sketch``Upload`
4. When the upload process has finished, open the `Serial Monitor` or `Serial
Plotter` via the `Tools` menu to observe the measurement values. Note that
the `Baud Rate` in the used tool has to be set to `115200 baud`.
## Contributing
**Contributions are welcome!**
We develop and test this driver using our company internal tools (version
control, continuous integration, code review etc.) and automatically
synchronize the master branch with GitHub. But this doesn't mean that we don't
respond to issues or don't accept pull requests on GitHub. In fact, you're very
welcome to open issues or create pull requests :)
This Sensirion library uses
[`clang-format`](https://releases.llvm.org/download.html) to standardize the
formatting of all our `.cpp` and `.h` files. Make sure your contributions are
formatted accordingly:
The `-i` flag will apply the format changes to the files listed.
```bash
clang-format -i src/*.cpp src/*.h
```
Note that differences from this formatting will result in a failed build until
they are fixed.
## License
See [LICENSE](LICENSE).

View File

@ -1,98 +0,0 @@
/*
* THIS FILE IS AUTOMATICALLY GENERATED
*
* Generator: sensirion-driver-generator 0.33.0
* Product: sht3x
* Model-Version: 1.0.0
*/
/*
* Copyright (c) 2023, Sensirion AG
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* * Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* * Neither the name of Sensirion AG nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
#include <Arduino.h>
#include <SensirionI2cSht3x.h>
#include <Wire.h>
SensirionI2cSht3x sensor;
static char errorMessage[64];
static int16_t error;
void setup() {
Serial.begin(115200);
while (!Serial) {
delay(100);
}
Wire.begin();
sensor.begin(Wire, SHT30_I2C_ADDR_44);
sensor.stopMeasurement();
delay(1);
sensor.softReset();
delay(100);
uint16_t aStatusRegister = 0u;
error = sensor.readStatusRegister(aStatusRegister);
if (error != NO_ERROR) {
Serial.print("Error trying to execute readStatusRegister(): ");
errorToString(error, errorMessage, sizeof errorMessage);
Serial.println(errorMessage);
return;
}
Serial.print("aStatusRegister: ");
Serial.print(aStatusRegister);
Serial.println();
error = sensor.startPeriodicMeasurement(REPEATABILITY_MEDIUM,
MPS_ONE_PER_SECOND);
if (error != NO_ERROR) {
Serial.print("Error trying to execute startPeriodicMeasurement(): ");
errorToString(error, errorMessage, sizeof errorMessage);
Serial.println(errorMessage);
return;
}
}
void loop() {
float aTemperature = 0.0;
float aHumidity = 0.0;
error = sensor.blockingReadMeasurement(aTemperature, aHumidity);
if (error != NO_ERROR) {
Serial.print("Error trying to execute blockingReadMeasurement(): ");
errorToString(error, errorMessage, sizeof errorMessage);
Serial.println(errorMessage);
return;
}
Serial.print("aTemperature: ");
Serial.print(aTemperature);
Serial.print("\t");
Serial.print("aHumidity: ");
Serial.print(aHumidity);
Serial.println();
}

View File

@ -1,91 +0,0 @@
/*
* THIS FILE IS AUTOMATICALLY GENERATED
*
* Generator: sensirion-driver-generator 0.33.0
* Product: sht3x
* Model-Version: 1.0.0
*/
/*
* Copyright (c) 2023, Sensirion AG
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* * Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* * Neither the name of Sensirion AG nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
#include <Arduino.h>
#include <SensirionI2cSht3x.h>
#include <Wire.h>
SensirionI2cSht3x sensor;
static char errorMessage[64];
static int16_t error;
void setup() {
Serial.begin(115200);
while (!Serial) {
delay(100);
}
Wire.begin();
sensor.begin(Wire, SHT30_I2C_ADDR_44);
sensor.stopMeasurement();
delay(1);
sensor.softReset();
delay(100);
uint16_t aStatusRegister = 0u;
error = sensor.readStatusRegister(aStatusRegister);
if (error != NO_ERROR) {
Serial.print("Error trying to execute readStatusRegister(): ");
errorToString(error, errorMessage, sizeof errorMessage);
Serial.println(errorMessage);
return;
}
Serial.print("aStatusRegister: ");
Serial.print(aStatusRegister);
Serial.println();
}
void loop() {
float aTemperature = 0.0;
float aHumidity = 0.0;
error = sensor.measureSingleShot(REPEATABILITY_MEDIUM, false, aTemperature,
aHumidity);
if (error != NO_ERROR) {
Serial.print("Error trying to execute measureSingleShot(): ");
errorToString(error, errorMessage, sizeof errorMessage);
Serial.println(errorMessage);
return;
}
Serial.print("aTemperature: ");
Serial.print(aTemperature);
Serial.print("\t");
Serial.print("aHumidity: ");
Serial.print(aHumidity);
Serial.println();
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 405 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 322 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 296 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 315 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 63 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 128 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 524 KiB

View File

@ -1,59 +0,0 @@
#######################################
# Syntax Coloring Map
#######################################
#######################################
# Datatypes (KEYWORD1)
#######################################
SensirionI2cSht3x KEYWORD1
#######################################
# Methods and Functions (KEYWORD2)
#######################################
measureSingleShot KEYWORD2
startPeriodicMeasurement KEYWORD2
blockingReadMeasurement KEYWORD2
readStatusRegister KEYWORD2
measureSingleShotHighRepeatability KEYWORD2
measureSingleShotHighRepeatabilityClockStretching KEYWORD2
measureSingleShotMediumRepeatability KEYWORD2
measureSingleShotMediumRepeatabilityClockStretching KEYWORD2
measureSingleShotLowRepeatability KEYWORD2
measureSingleShotLowRepeatabilityClockStretching KEYWORD2
startMeasurement05MpsHighRepeatability KEYWORD2
startMeasurement05MpsMediumRepeatability KEYWORD2
startMeasurement05MpsLowRepeatability KEYWORD2
startMeasurement1MpsHighRepeatability KEYWORD2
startMeasurement1MpsMediumRepeatability KEYWORD2
startMeasurement1MpsLowRepeatability KEYWORD2
startMeasurement2MpsHighRepeatability KEYWORD2
startMeasurement2MpsMediumRepeatability KEYWORD2
startMeasurement2MpsLowRepeatability KEYWORD2
startMeasurement4MpsHighRepeatability KEYWORD2
startMeasurement4MpsMediumRepeatability KEYWORD2
startMeasurement4MpsLowRepeatability KEYWORD2
startMeasurement10MpsHighRepeatability KEYWORD2
startMeasurement10MpsMediumRepeatability KEYWORD2
startMeasurement10MpsLowRepeatability KEYWORD2
startArtMeasurement KEYWORD2
readMeasurement KEYWORD2
stopMeasurement KEYWORD2
enableHeater KEYWORD2
disableHeater KEYWORD2
llreadStatusRegister KEYWORD2
clearStatusRegister KEYWORD2
softReset KEYWORD2
signalTemperature KEYWORD2
signalHumidity KEYWORD2
#######################################
# Instances (KEYWORD2)
#######################################
sensor KEYWORD2
#######################################
# Constants (LITERAL1)
#######################################

View File

@ -1,11 +0,0 @@
name=SensirionI2cSht3x
version=1.0.0
author=Sensirion
maintainer=Sensirion
sentence=Library for the SHT3X sensor family by Sensirion
paragraph=Enables you to use the SHT3X sensor family via I2C.
url=https://github.com/Sensirion/arduino-i2c-sht3x
category=Sensors
architectures=*
depends=Sensirion Core
includes=SensirionI2cSht3x.h

View File

@ -1,7 +0,0 @@
generator_version: 0.33.0
model_version: 1.0.0
dg_status:
- released
is_manually_modified: true
first_generated: '2023-10-27 14:38'
last_generated: '2023-10-27 14:38'

View File

@ -1,720 +0,0 @@
/*
* THIS FILE IS AUTOMATICALLY GENERATED
*
* Generator: sensirion-driver-generator 0.33.0
* Product: sht3x
* Model-Version: 1.0.0
*/
/*
* Copyright (c) 2023, Sensirion AG
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* * Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* * Neither the name of Sensirion AG nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
#include "SensirionI2cSht3x.h"
#include <Arduino.h>
static uint8_t communication_buffer[6] = {0};
SensirionI2cSht3x::SensirionI2cSht3x() {
}
float SensirionI2cSht3x::signalTemperature(uint16_t temperatureTicks) {
float temperature = 0.0;
temperature = (float)(temperatureTicks);
temperature = -45 + ((temperature * 175.0) / 65535.0);
return temperature;
}
float SensirionI2cSht3x::signalHumidity(uint16_t humidityTicks) {
float humidity = 0.0;
humidity = (float)(humidityTicks);
humidity = (100 * humidity) / 65535.0;
return humidity;
}
int16_t
SensirionI2cSht3x::measureSingleShot(Repeatability measurementRepeatability,
bool isClockStretching,
float& aTemperature, float& aHumidity) {
uint16_t rawTemp = 0;
uint16_t rawHumi = 0;
int16_t localError = 0;
if (isClockStretching) {
if (measurementRepeatability == REPEATABILITY_HIGH) {
localError = measureSingleShotHighRepeatabilityClockStretching(
rawTemp, rawHumi);
if (localError != NO_ERROR) {
return localError;
}
} else if (measurementRepeatability == REPEATABILITY_MEDIUM) {
localError = measureSingleShotMediumRepeatabilityClockStretching(
rawTemp, rawHumi);
if (localError != NO_ERROR) {
return localError;
}
} else if (measurementRepeatability == REPEATABILITY_LOW) {
localError = measureSingleShotLowRepeatabilityClockStretching(
rawTemp, rawHumi);
if (localError != NO_ERROR) {
return localError;
}
}
} else if (measurementRepeatability == REPEATABILITY_HIGH) {
localError = measureSingleShotHighRepeatability(rawTemp, rawHumi);
if (localError != NO_ERROR) {
return localError;
}
} else if (measurementRepeatability == REPEATABILITY_MEDIUM) {
localError = measureSingleShotMediumRepeatability(rawTemp, rawHumi);
if (localError != NO_ERROR) {
return localError;
}
} else if (measurementRepeatability == REPEATABILITY_LOW) {
localError = measureSingleShotLowRepeatability(rawTemp, rawHumi);
if (localError != NO_ERROR) {
return localError;
}
}
aTemperature = signalTemperature(rawTemp);
aHumidity = signalHumidity(rawHumi);
return localError;
}
int16_t SensirionI2cSht3x::startPeriodicMeasurement(
Repeatability measurementRepeatability, Mps messagesPerSecond) {
int16_t localError = 0;
if (messagesPerSecond == MPS_EVERY_TWO_SECONDS) {
if (measurementRepeatability == REPEATABILITY_HIGH) {
localError = startMeasurement05MpsHighRepeatability();
if (localError != NO_ERROR) {
return localError;
}
} else if (measurementRepeatability == REPEATABILITY_MEDIUM) {
localError = startMeasurement05MpsMediumRepeatability();
if (localError != NO_ERROR) {
return localError;
}
} else if (measurementRepeatability == REPEATABILITY_LOW) {
localError = startMeasurement05MpsLowRepeatability();
if (localError != NO_ERROR) {
return localError;
}
}
} else if (messagesPerSecond == MPS_ONE_PER_SECOND) {
if (measurementRepeatability == REPEATABILITY_HIGH) {
localError = startMeasurement1MpsHighRepeatability();
if (localError != NO_ERROR) {
return localError;
}
} else if (measurementRepeatability == REPEATABILITY_MEDIUM) {
localError = startMeasurement1MpsMediumRepeatability();
if (localError != NO_ERROR) {
return localError;
}
} else if (measurementRepeatability == REPEATABILITY_LOW) {
localError = startMeasurement1MpsLowRepeatability();
if (localError != NO_ERROR) {
return localError;
}
}
} else if (messagesPerSecond == MPS_TWO_PER_SECOND) {
if (measurementRepeatability == REPEATABILITY_HIGH) {
localError = startMeasurement2MpsHighRepeatability();
if (localError != NO_ERROR) {
return localError;
}
} else if (measurementRepeatability == REPEATABILITY_MEDIUM) {
localError = startMeasurement2MpsMediumRepeatability();
if (localError != NO_ERROR) {
return localError;
}
} else if (measurementRepeatability == REPEATABILITY_LOW) {
localError = startMeasurement2MpsLowRepeatability();
if (localError != NO_ERROR) {
return localError;
}
}
} else if (messagesPerSecond == MPS_FOUR_PER_SECOND) {
if (measurementRepeatability == REPEATABILITY_HIGH) {
localError = startMeasurement4MpsHighRepeatability();
if (localError != NO_ERROR) {
return localError;
}
} else if (measurementRepeatability == REPEATABILITY_MEDIUM) {
localError = startMeasurement4MpsMediumRepeatability();
if (localError != NO_ERROR) {
return localError;
}
} else if (measurementRepeatability == REPEATABILITY_LOW) {
localError = startMeasurement4MpsLowRepeatability();
if (localError != NO_ERROR) {
return localError;
}
}
} else if (messagesPerSecond == MPS_TEN_PER_SECOND) {
if (measurementRepeatability == REPEATABILITY_HIGH) {
localError = startMeasurement10MpsHighRepeatability();
if (localError != NO_ERROR) {
return localError;
}
} else if (measurementRepeatability == REPEATABILITY_MEDIUM) {
localError = startMeasurement10MpsMediumRepeatability();
if (localError != NO_ERROR) {
return localError;
}
} else if (measurementRepeatability == REPEATABILITY_LOW) {
localError = startMeasurement10MpsLowRepeatability();
if (localError != NO_ERROR) {
return localError;
}
}
}
return localError;
}
int16_t SensirionI2cSht3x::blockingReadMeasurement(float& aTemperature,
float& aHumidity) {
uint16_t status = 0u;
uint16_t dataReadyFlag = 0u;
uint16_t rawTemp = 0;
uint16_t rawHumi = 0;
int16_t localError = 0;
localError = llreadStatusRegister(status);
if (localError != NO_ERROR) {
return localError;
}
dataReadyFlag = (status >> 6) & 15;
while (dataReadyFlag == 0) {
delay(100);
localError = llreadStatusRegister(status);
if (localError != NO_ERROR) {
return localError;
}
dataReadyFlag = (status >> 6) & 15;
}
localError = readMeasurement(rawTemp, rawHumi);
if (localError != NO_ERROR) {
return localError;
}
aTemperature = signalTemperature(rawTemp);
aHumidity = signalHumidity(rawHumi);
return localError;
}
int16_t SensirionI2cSht3x::readStatusRegister(uint16_t& aStatusRegister) {
uint16_t status = 0u;
int16_t localError = 0;
localError = llreadStatusRegister(status);
if (localError != NO_ERROR) {
return localError;
}
aStatusRegister = static_cast<uint16_t>(status);
return localError;
}
int16_t SensirionI2cSht3x::measureSingleShotHighRepeatability(
uint16_t& temperatureTicks, uint16_t& humidityTicks) {
int16_t localError = NO_ERROR;
uint8_t* buffer_ptr = communication_buffer;
SensirionI2CTxFrame txFrame =
SensirionI2CTxFrame::createWithUInt16Command(0x2400, buffer_ptr, 6);
localError =
SensirionI2CCommunication::sendFrame(_i2cAddress, txFrame, *_i2cBus);
if (localError != NO_ERROR) {
return localError;
}
delay(16);
SensirionI2CRxFrame rxFrame(buffer_ptr, 6);
localError = SensirionI2CCommunication::receiveFrame(_i2cAddress, 6,
rxFrame, *_i2cBus);
if (localError != NO_ERROR) {
return localError;
}
localError |= rxFrame.getUInt16(temperatureTicks);
localError |= rxFrame.getUInt16(humidityTicks);
return localError;
}
int16_t SensirionI2cSht3x::measureSingleShotHighRepeatabilityClockStretching(
uint16_t& temperatureTicks, uint16_t& humidityTicks) {
int16_t localError = NO_ERROR;
uint8_t* buffer_ptr = communication_buffer;
SensirionI2CTxFrame txFrame =
SensirionI2CTxFrame::createWithUInt16Command(0x2c06, buffer_ptr, 6);
localError =
SensirionI2CCommunication::sendFrame(_i2cAddress, txFrame, *_i2cBus);
if (localError != NO_ERROR) {
return localError;
}
delay(16);
SensirionI2CRxFrame rxFrame(buffer_ptr, 6);
localError = SensirionI2CCommunication::receiveFrame(_i2cAddress, 6,
rxFrame, *_i2cBus);
if (localError != NO_ERROR) {
return localError;
}
localError |= rxFrame.getUInt16(temperatureTicks);
localError |= rxFrame.getUInt16(humidityTicks);
return localError;
}
int16_t SensirionI2cSht3x::measureSingleShotMediumRepeatability(
uint16_t& temperatureTicks, uint16_t& humidityTicks) {
int16_t localError = NO_ERROR;
uint8_t* buffer_ptr = communication_buffer;
SensirionI2CTxFrame txFrame =
SensirionI2CTxFrame::createWithUInt16Command(0x240b, buffer_ptr, 6);
localError =
SensirionI2CCommunication::sendFrame(_i2cAddress, txFrame, *_i2cBus);
if (localError != NO_ERROR) {
return localError;
}
delay(7);
SensirionI2CRxFrame rxFrame(buffer_ptr, 6);
localError = SensirionI2CCommunication::receiveFrame(_i2cAddress, 6,
rxFrame, *_i2cBus);
if (localError != NO_ERROR) {
return localError;
}
localError |= rxFrame.getUInt16(temperatureTicks);
localError |= rxFrame.getUInt16(humidityTicks);
return localError;
}
int16_t SensirionI2cSht3x::measureSingleShotMediumRepeatabilityClockStretching(
uint16_t& temperatureTicks, uint16_t& humidityTicks) {
int16_t localError = NO_ERROR;
uint8_t* buffer_ptr = communication_buffer;
SensirionI2CTxFrame txFrame =
SensirionI2CTxFrame::createWithUInt16Command(0x2c0d, buffer_ptr, 6);
localError =
SensirionI2CCommunication::sendFrame(_i2cAddress, txFrame, *_i2cBus);
if (localError != NO_ERROR) {
return localError;
}
delay(7);
SensirionI2CRxFrame rxFrame(buffer_ptr, 6);
localError = SensirionI2CCommunication::receiveFrame(_i2cAddress, 6,
rxFrame, *_i2cBus);
if (localError != NO_ERROR) {
return localError;
}
localError |= rxFrame.getUInt16(temperatureTicks);
localError |= rxFrame.getUInt16(humidityTicks);
return localError;
}
int16_t
SensirionI2cSht3x::measureSingleShotLowRepeatability(uint16_t& temperatureTicks,
uint16_t& humidityTicks) {
int16_t localError = NO_ERROR;
uint8_t* buffer_ptr = communication_buffer;
SensirionI2CTxFrame txFrame =
SensirionI2CTxFrame::createWithUInt16Command(0x2416, buffer_ptr, 6);
localError =
SensirionI2CCommunication::sendFrame(_i2cAddress, txFrame, *_i2cBus);
if (localError != NO_ERROR) {
return localError;
}
delay(5);
SensirionI2CRxFrame rxFrame(buffer_ptr, 6);
localError = SensirionI2CCommunication::receiveFrame(_i2cAddress, 6,
rxFrame, *_i2cBus);
if (localError != NO_ERROR) {
return localError;
}
localError |= rxFrame.getUInt16(temperatureTicks);
localError |= rxFrame.getUInt16(humidityTicks);
return localError;
}
int16_t SensirionI2cSht3x::measureSingleShotLowRepeatabilityClockStretching(
uint16_t& temperatureTicks, uint16_t& humidityTicks) {
int16_t localError = NO_ERROR;
uint8_t* buffer_ptr = communication_buffer;
SensirionI2CTxFrame txFrame =
SensirionI2CTxFrame::createWithUInt16Command(0x2c10, buffer_ptr, 6);
localError =
SensirionI2CCommunication::sendFrame(_i2cAddress, txFrame, *_i2cBus);
if (localError != NO_ERROR) {
return localError;
}
delay(5);
SensirionI2CRxFrame rxFrame(buffer_ptr, 6);
localError = SensirionI2CCommunication::receiveFrame(_i2cAddress, 6,
rxFrame, *_i2cBus);
if (localError != NO_ERROR) {
return localError;
}
localError |= rxFrame.getUInt16(temperatureTicks);
localError |= rxFrame.getUInt16(humidityTicks);
return localError;
}
int16_t SensirionI2cSht3x::startMeasurement05MpsHighRepeatability() {
int16_t localError = NO_ERROR;
uint8_t* buffer_ptr = communication_buffer;
SensirionI2CTxFrame txFrame =
SensirionI2CTxFrame::createWithUInt16Command(0x2032, buffer_ptr, 2);
localError =
SensirionI2CCommunication::sendFrame(_i2cAddress, txFrame, *_i2cBus);
if (localError != NO_ERROR) {
return localError;
}
delay(16);
return localError;
}
int16_t SensirionI2cSht3x::startMeasurement05MpsMediumRepeatability() {
int16_t localError = NO_ERROR;
uint8_t* buffer_ptr = communication_buffer;
SensirionI2CTxFrame txFrame =
SensirionI2CTxFrame::createWithUInt16Command(0x2024, buffer_ptr, 2);
localError =
SensirionI2CCommunication::sendFrame(_i2cAddress, txFrame, *_i2cBus);
if (localError != NO_ERROR) {
return localError;
}
delay(7);
return localError;
}
int16_t SensirionI2cSht3x::startMeasurement05MpsLowRepeatability() {
int16_t localError = NO_ERROR;
uint8_t* buffer_ptr = communication_buffer;
SensirionI2CTxFrame txFrame =
SensirionI2CTxFrame::createWithUInt16Command(0x202f, buffer_ptr, 2);
localError =
SensirionI2CCommunication::sendFrame(_i2cAddress, txFrame, *_i2cBus);
if (localError != NO_ERROR) {
return localError;
}
delay(5);
return localError;
}
int16_t SensirionI2cSht3x::startMeasurement1MpsHighRepeatability() {
int16_t localError = NO_ERROR;
uint8_t* buffer_ptr = communication_buffer;
SensirionI2CTxFrame txFrame =
SensirionI2CTxFrame::createWithUInt16Command(0x2130, buffer_ptr, 2);
localError =
SensirionI2CCommunication::sendFrame(_i2cAddress, txFrame, *_i2cBus);
if (localError != NO_ERROR) {
return localError;
}
delay(16);
return localError;
}
int16_t SensirionI2cSht3x::startMeasurement1MpsMediumRepeatability() {
int16_t localError = NO_ERROR;
uint8_t* buffer_ptr = communication_buffer;
SensirionI2CTxFrame txFrame =
SensirionI2CTxFrame::createWithUInt16Command(0x2126, buffer_ptr, 2);
localError =
SensirionI2CCommunication::sendFrame(_i2cAddress, txFrame, *_i2cBus);
if (localError != NO_ERROR) {
return localError;
}
delay(7);
return localError;
}
int16_t SensirionI2cSht3x::startMeasurement1MpsLowRepeatability() {
int16_t localError = NO_ERROR;
uint8_t* buffer_ptr = communication_buffer;
SensirionI2CTxFrame txFrame =
SensirionI2CTxFrame::createWithUInt16Command(0x212d, buffer_ptr, 2);
localError =
SensirionI2CCommunication::sendFrame(_i2cAddress, txFrame, *_i2cBus);
if (localError != NO_ERROR) {
return localError;
}
delay(5);
return localError;
}
int16_t SensirionI2cSht3x::startMeasurement2MpsHighRepeatability() {
int16_t localError = NO_ERROR;
uint8_t* buffer_ptr = communication_buffer;
SensirionI2CTxFrame txFrame =
SensirionI2CTxFrame::createWithUInt16Command(0x2236, buffer_ptr, 2);
localError =
SensirionI2CCommunication::sendFrame(_i2cAddress, txFrame, *_i2cBus);
if (localError != NO_ERROR) {
return localError;
}
delay(16);
return localError;
}
int16_t SensirionI2cSht3x::startMeasurement2MpsMediumRepeatability() {
int16_t localError = NO_ERROR;
uint8_t* buffer_ptr = communication_buffer;
SensirionI2CTxFrame txFrame =
SensirionI2CTxFrame::createWithUInt16Command(0x2220, buffer_ptr, 2);
localError =
SensirionI2CCommunication::sendFrame(_i2cAddress, txFrame, *_i2cBus);
if (localError != NO_ERROR) {
return localError;
}
delay(7);
return localError;
}
int16_t SensirionI2cSht3x::startMeasurement2MpsLowRepeatability() {
int16_t localError = NO_ERROR;
uint8_t* buffer_ptr = communication_buffer;
SensirionI2CTxFrame txFrame =
SensirionI2CTxFrame::createWithUInt16Command(0x222b, buffer_ptr, 2);
localError =
SensirionI2CCommunication::sendFrame(_i2cAddress, txFrame, *_i2cBus);
if (localError != NO_ERROR) {
return localError;
}
delay(5);
return localError;
}
int16_t SensirionI2cSht3x::startMeasurement4MpsHighRepeatability() {
int16_t localError = NO_ERROR;
uint8_t* buffer_ptr = communication_buffer;
SensirionI2CTxFrame txFrame =
SensirionI2CTxFrame::createWithUInt16Command(0x2334, buffer_ptr, 2);
localError =
SensirionI2CCommunication::sendFrame(_i2cAddress, txFrame, *_i2cBus);
if (localError != NO_ERROR) {
return localError;
}
delay(16);
return localError;
}
int16_t SensirionI2cSht3x::startMeasurement4MpsMediumRepeatability() {
int16_t localError = NO_ERROR;
uint8_t* buffer_ptr = communication_buffer;
SensirionI2CTxFrame txFrame =
SensirionI2CTxFrame::createWithUInt16Command(0x2322, buffer_ptr, 2);
localError =
SensirionI2CCommunication::sendFrame(_i2cAddress, txFrame, *_i2cBus);
if (localError != NO_ERROR) {
return localError;
}
delay(7);
return localError;
}
int16_t SensirionI2cSht3x::startMeasurement4MpsLowRepeatability() {
int16_t localError = NO_ERROR;
uint8_t* buffer_ptr = communication_buffer;
SensirionI2CTxFrame txFrame =
SensirionI2CTxFrame::createWithUInt16Command(0x2329, buffer_ptr, 2);
localError =
SensirionI2CCommunication::sendFrame(_i2cAddress, txFrame, *_i2cBus);
if (localError != NO_ERROR) {
return localError;
}
delay(5);
return localError;
}
int16_t SensirionI2cSht3x::startMeasurement10MpsHighRepeatability() {
int16_t localError = NO_ERROR;
uint8_t* buffer_ptr = communication_buffer;
SensirionI2CTxFrame txFrame =
SensirionI2CTxFrame::createWithUInt16Command(0x2737, buffer_ptr, 2);
localError =
SensirionI2CCommunication::sendFrame(_i2cAddress, txFrame, *_i2cBus);
if (localError != NO_ERROR) {
return localError;
}
delay(16);
return localError;
}
int16_t SensirionI2cSht3x::startMeasurement10MpsMediumRepeatability() {
int16_t localError = NO_ERROR;
uint8_t* buffer_ptr = communication_buffer;
SensirionI2CTxFrame txFrame =
SensirionI2CTxFrame::createWithUInt16Command(0x2721, buffer_ptr, 2);
localError =
SensirionI2CCommunication::sendFrame(_i2cAddress, txFrame, *_i2cBus);
if (localError != NO_ERROR) {
return localError;
}
delay(7);
return localError;
}
int16_t SensirionI2cSht3x::startMeasurement10MpsLowRepeatability() {
int16_t localError = NO_ERROR;
uint8_t* buffer_ptr = communication_buffer;
SensirionI2CTxFrame txFrame =
SensirionI2CTxFrame::createWithUInt16Command(0x273a, buffer_ptr, 2);
localError =
SensirionI2CCommunication::sendFrame(_i2cAddress, txFrame, *_i2cBus);
if (localError != NO_ERROR) {
return localError;
}
delay(5);
return localError;
}
int16_t SensirionI2cSht3x::startArtMeasurement() {
int16_t localError = NO_ERROR;
uint8_t* buffer_ptr = communication_buffer;
SensirionI2CTxFrame txFrame =
SensirionI2CTxFrame::createWithUInt16Command(0x2b32, buffer_ptr, 2);
localError =
SensirionI2CCommunication::sendFrame(_i2cAddress, txFrame, *_i2cBus);
if (localError != NO_ERROR) {
return localError;
}
return localError;
}
int16_t SensirionI2cSht3x::readMeasurement(uint16_t& temperatureTicks,
uint16_t& humidityTicks) {
int16_t localError = NO_ERROR;
uint8_t* buffer_ptr = communication_buffer;
SensirionI2CTxFrame txFrame =
SensirionI2CTxFrame::createWithUInt16Command(0xe000, buffer_ptr, 6);
localError =
SensirionI2CCommunication::sendFrame(_i2cAddress, txFrame, *_i2cBus);
if (localError != NO_ERROR) {
return localError;
}
SensirionI2CRxFrame rxFrame(buffer_ptr, 6);
localError = SensirionI2CCommunication::receiveFrame(_i2cAddress, 6,
rxFrame, *_i2cBus);
if (localError != NO_ERROR) {
return localError;
}
localError |= rxFrame.getUInt16(temperatureTicks);
localError |= rxFrame.getUInt16(humidityTicks);
return localError;
}
int16_t SensirionI2cSht3x::stopMeasurement() {
int16_t localError = NO_ERROR;
uint8_t* buffer_ptr = communication_buffer;
SensirionI2CTxFrame txFrame =
SensirionI2CTxFrame::createWithUInt16Command(0x3093, buffer_ptr, 2);
localError =
SensirionI2CCommunication::sendFrame(_i2cAddress, txFrame, *_i2cBus);
if (localError != NO_ERROR) {
return localError;
}
delay(1);
return localError;
}
int16_t SensirionI2cSht3x::enableHeater() {
int16_t localError = NO_ERROR;
uint8_t* buffer_ptr = communication_buffer;
SensirionI2CTxFrame txFrame =
SensirionI2CTxFrame::createWithUInt16Command(0x306d, buffer_ptr, 2);
localError =
SensirionI2CCommunication::sendFrame(_i2cAddress, txFrame, *_i2cBus);
if (localError != NO_ERROR) {
return localError;
}
delay(10);
return localError;
}
int16_t SensirionI2cSht3x::disableHeater() {
int16_t localError = NO_ERROR;
uint8_t* buffer_ptr = communication_buffer;
SensirionI2CTxFrame txFrame =
SensirionI2CTxFrame::createWithUInt16Command(0x3066, buffer_ptr, 2);
localError =
SensirionI2CCommunication::sendFrame(_i2cAddress, txFrame, *_i2cBus);
if (localError != NO_ERROR) {
return localError;
}
delay(10);
return localError;
}
int16_t SensirionI2cSht3x::llreadStatusRegister(uint16_t& statusRegister) {
int16_t localError = NO_ERROR;
uint8_t* buffer_ptr = communication_buffer;
SensirionI2CTxFrame txFrame =
SensirionI2CTxFrame::createWithUInt16Command(0xf32d, buffer_ptr, 3);
localError =
SensirionI2CCommunication::sendFrame(_i2cAddress, txFrame, *_i2cBus);
if (localError != NO_ERROR) {
return localError;
}
delay(10);
SensirionI2CRxFrame rxFrame(buffer_ptr, 3);
localError = SensirionI2CCommunication::receiveFrame(_i2cAddress, 3,
rxFrame, *_i2cBus);
if (localError != NO_ERROR) {
return localError;
}
localError |= rxFrame.getUInt16(statusRegister);
return localError;
}
int16_t SensirionI2cSht3x::clearStatusRegister() {
int16_t localError = NO_ERROR;
uint8_t* buffer_ptr = communication_buffer;
SensirionI2CTxFrame txFrame =
SensirionI2CTxFrame::createWithUInt16Command(0x3041, buffer_ptr, 2);
localError =
SensirionI2CCommunication::sendFrame(_i2cAddress, txFrame, *_i2cBus);
if (localError != NO_ERROR) {
return localError;
}
delay(10);
return localError;
}
int16_t SensirionI2cSht3x::softReset() {
int16_t localError = NO_ERROR;
uint8_t* buffer_ptr = communication_buffer;
SensirionI2CTxFrame txFrame =
SensirionI2CTxFrame::createWithUInt16Command(0x30a2, buffer_ptr, 2);
localError =
SensirionI2CCommunication::sendFrame(_i2cAddress, txFrame, *_i2cBus);
if (localError != NO_ERROR) {
return localError;
}
delay(2);
return localError;
}
void SensirionI2cSht3x::begin(TwoWire& i2cBus, uint8_t i2cAddress) {
_i2cBus = &i2cBus;
_i2cAddress = i2cAddress;
}

View File

@ -1,548 +0,0 @@
/*
* THIS FILE IS AUTOMATICALLY GENERATED
*
* Generator: sensirion-driver-generator 0.33.0
* Product: sht3x
* Model-Version: 1.0.0
*/
/*
* Copyright (c) 2023, Sensirion AG
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* * Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* * Neither the name of Sensirion AG nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef SENSIRIONI2CSHT3X_H
#define SENSIRIONI2CSHT3X_H
#include "../../SensirionCore/src/SensirionCore.h"
#include <Wire.h>
#define NO_ERROR 0
#define SHT30A_I2C_ADDR_44 0x44
#define SHT30A_I2C_ADDR_45 0x45
#define SHT30_I2C_ADDR_44 0x44
#define SHT30_I2C_ADDR_45 0x45
#define SHT31A_I2C_ADDR_44 0x44
#define SHT31A_I2C_ADDR_45 0x45
#define SHT31_I2C_ADDR_44 0x44
#define SHT31_I2C_ADDR_45 0x45
#define SHT33_I2C_ADDR_44 0x44
#define SHT33_I2C_ADDR_45 0x45
#define SHT35A_I2C_ADDR_44 0x44
#define SHT35A_I2C_ADDR_45 0x45
#define SHT35_I2C_ADDR_44 0x44
#define SHT35_I2C_ADDR_45 0x45
typedef enum {
MEASURE_SINGLE_SHOT_HIGH_REPEATABILITY_CMD_ID = 0x2400,
MEASURE_SINGLE_SHOT_HIGH_REPEATABILITY_CLOCK_STRETCHING_CMD_ID = 0x2c06,
MEASURE_SINGLE_SHOT_MEDIUM_REPEATABILITY_CMD_ID = 0x240b,
MEASURE_SINGLE_SHOT_MEDIUM_REPEATABILITY_CLOCK_STRETCHING_CMD_ID = 0x2c0d,
MEASURE_SINGLE_SHOT_LOW_REPEATABILITY_CMD_ID = 0x2416,
MEASURE_SINGLE_SHOT_LOW_REPEATABILITY_CLOCK_STRETCHING_CMD_ID = 0x2c10,
START_MEASUREMENT_0_5_MPS_HIGH_REPEATABILITY_CMD_ID = 0x2032,
START_MEASUREMENT_0_5_MPS_MEDIUM_REPEATABILITY_CMD_ID = 0x2024,
START_MEASUREMENT_0_5_MPS_LOW_REPEATABILITY_CMD_ID = 0x202f,
START_MEASUREMENT_1_MPS_HIGH_REPEATABILITY_CMD_ID = 0x2130,
START_MEASUREMENT_1_MPS_MEDIUM_REPEATABILITY_CMD_ID = 0x2126,
START_MEASUREMENT_1_MPS_LOW_REPEATABILITY_CMD_ID = 0x212d,
START_MEASUREMENT_2_MPS_HIGH_REPEATABILITY_CMD_ID = 0x2236,
START_MEASUREMENT_2_MPS_MEDIUM_REPEATABILITY_CMD_ID = 0x2220,
START_MEASUREMENT_2_MPS_LOW_REPEATABILITY_CMD_ID = 0x222b,
START_MEASUREMENT_4_MPS_HIGH_REPEATABILITY_CMD_ID = 0x2334,
START_MEASUREMENT_4_MPS_MEDIUM_REPEATABILITY_CMD_ID = 0x2322,
START_MEASUREMENT_4_MPS_LOW_REPEATABILITY_CMD_ID = 0x2329,
START_MEASUREMENT_10_MPS_HIGH_REPEATABILITY_CMD_ID = 0x2737,
START_MEASUREMENT_10_MPS_MEDIUM_REPEATABILITY_CMD_ID = 0x2721,
START_MEASUREMENT_10_MPS_LOW_REPEATABILITY_CMD_ID = 0x273a,
START_ART_MEASUREMENT_CMD_ID = 0x2b32,
READ_MEASUREMENT_CMD_ID = 0xe000,
STOP_MEASUREMENT_CMD_ID = 0x3093,
ENABLE_HEATER_CMD_ID = 0x306d,
DISABLE_HEATER_CMD_ID = 0x3066,
READ_STATUS_REGISTER_CMD_ID = 0xf32d,
CLEAR_STATUS_REGISTER_CMD_ID = 0x3041,
SOFT_RESET_CMD_ID = 0x30a2,
} CmdId;
typedef enum {
REPEATABILITY_LOW = 0,
REPEATABILITY_MEDIUM = 1,
REPEATABILITY_HIGH = 2,
} Repeatability;
typedef enum {
MPS_EVERY_TWO_SECONDS = 0,
MPS_ONE_PER_SECOND = 1,
MPS_TWO_PER_SECOND = 2,
MPS_FOUR_PER_SECOND = 4,
MPS_TEN_PER_SECOND = 10,
} Mps;
class SensirionI2cSht3x {
public:
SensirionI2cSht3x();
/**
* @brief Initializes the SHT3x class.
*
* @param i2cBus Arduino stream object to be used for communication.
*/
void begin(TwoWire& i2cBus, uint8_t i2cAddress);
/**
* @brief Single shot measurement with the specified properties
*
* @param[in] measurementRepeatability The repeatability of the periodic
* measurement
* @param[in] isClockStretching Toggle clock stretching
* @param[out] aTemperature Converted from ticks to degrees celsius by -45 +
* (175 * value / 65535)
* @param[out] aHumidity Converted from ticks to relative humidity by 100 *
* value / 65535
*
* @return error_code 0 on success, an error code otherwise.
*/
int16_t measureSingleShot(Repeatability measurementRepeatability,
bool isClockStretching, float& aTemperature,
float& aHumidity);
/**
* @brief startPeriodicMeasurement
*
* Start the periodic measurement measurement mode.
*
* This is a convenience method that selects the correct measurement command
* based on the provided arguments.
*
* @param[in] measurementRepeatability The repeatability of the periodic
* measurement
* @param[in] messagesPerSecond The messages per second of the periodic
* measurement
*
* @return error_code 0 on success, an error code otherwise.
*/
int16_t startPeriodicMeasurement(Repeatability measurementRepeatability,
Mps messagesPerSecond);
/**
* @brief blockingReadMeasurement
*
* This is a convenience method that combines polling the data ready flag
* and reading out the data. As the minimal measurement interval is 2s and
* we sleep for 100ms we iterate at most 200 times. Note that this is
* blocking the system for a considerable amount of time!
*
* @param[out] aTemperature Converted from ticks to degrees celsius by -45 +
* (175 * value / 65535)
* @param[out] aHumidity Converted from ticks to relative humidity by 100 *
* value / 65535
*
* @return error_code 0 on success, an error code otherwise.
*/
int16_t blockingReadMeasurement(float& aTemperature, float& aHumidity);
/**
* @brief Read the contents of the status register
*
* @param[out] aStatusRegister
*
* @return error_code 0 on success, an error code otherwise.
*/
int16_t readStatusRegister(uint16_t& aStatusRegister);
/**
* @brief measureSingleShotHighRepeatability
*
* Single shot measurement with high repeatability
*
* @param[out] temperatureTicks Temperature ticks. Convert to degrees
* celsius by -45 + 175 * value / 65535
* @param[out] humidityTicks Humidity ticks. Convert to relative humidity by
* 100
* * value / 65535
*
* @return error_code 0 on success, an error code otherwise.
*/
int16_t measureSingleShotHighRepeatability(uint16_t& temperatureTicks,
uint16_t& humidityTicks);
/**
* @brief measureSingleShotHighRepeatabilityClockStretching
*
* Single shot measurement with high repeatability and clock stretching
* enabled
*
* @param[out] temperatureTicks Temperature ticks. Convert to degrees
* celsius by -45 + 175 * value / 65535
* @param[out] humidityTicks Humidity ticks. Convert to relative humidity by
* 100
* * value / 65535
*
* @return error_code 0 on success, an error code otherwise.
*/
int16_t measureSingleShotHighRepeatabilityClockStretching(
uint16_t& temperatureTicks, uint16_t& humidityTicks);
/**
* @brief measureSingleShotMediumRepeatability
*
* Single shot measurement with medium repeatability
*
* @param[out] temperatureTicks Temperature ticks. Convert to degrees
* celsius by -45 + 175 * value / 65535
* @param[out] humidityTicks Humidity ticks. Convert to relative humidity by
* 100
* * value / 65535
*
* @return error_code 0 on success, an error code otherwise.
*/
int16_t measureSingleShotMediumRepeatability(uint16_t& temperatureTicks,
uint16_t& humidityTicks);
/**
* @brief measureSingleShotMediumRepeatabilityClockStretching
*
* Single shot measurement with medium repeatability and clock stretching
* enabled
*
* @param[out] temperatureTicks Temperature ticks. Convert to degrees
* celsius by -45 + 175 * value / 65535
* @param[out] humidityTicks Humidity ticks. Convert to relative humidity by
* 100
* * value / 65535
*
* @return error_code 0 on success, an error code otherwise.
*/
int16_t measureSingleShotMediumRepeatabilityClockStretching(
uint16_t& temperatureTicks, uint16_t& humidityTicks);
/**
* @brief measureSingleShotLowRepeatability
*
* Single shot measurement with low repeatability
*
* @param[out] temperatureTicks Temperature ticks. Convert to degrees
* celsius by -45 + 175 * value / 65535
* @param[out] humidityTicks Humidity ticks. Convert to relative humidity by
* 100
* * value / 65535
*
* @return error_code 0 on success, an error code otherwise.
*/
int16_t measureSingleShotLowRepeatability(uint16_t& temperatureTicks,
uint16_t& humidityTicks);
/**
* @brief measureSingleShotLowRepeatabilityClockStretching
*
* Single shot measurement with low repeatability and clock stretching
* enabled
*
* @param[out] temperatureTicks Temperature ticks. Convert to degrees
* celsius by -45 + 175 * value / 65535
* @param[out] humidityTicks Humidity ticks. Convert to relative humidity by
* 100
* * value / 65535
*
* @return error_code 0 on success, an error code otherwise.
*/
int16_t
measureSingleShotLowRepeatabilityClockStretching(uint16_t& temperatureTicks,
uint16_t& humidityTicks);
/**
* @brief startMeasurement05MpsHighRepeatability
*
* Start periodic measurement mode with 0.5 mps and high repeatability.
*
* @return error_code 0 on success, an error code otherwise.
*/
int16_t startMeasurement05MpsHighRepeatability();
/**
* @brief startMeasurement05MpsMediumRepeatability
*
* Start periodic measurement mode with 0.5 mps and medium repeatability.
*
* @return error_code 0 on success, an error code otherwise.
*/
int16_t startMeasurement05MpsMediumRepeatability();
/**
* @brief startMeasurement05MpsLowRepeatability
*
* Start periodic measurement mode with 0.5 mps and low repeatability.
*
* @return error_code 0 on success, an error code otherwise.
*/
int16_t startMeasurement05MpsLowRepeatability();
/**
* @brief startMeasurement1MpsHighRepeatability
*
* Start periodic measurement mode with 1 mps and high repeatability.
*
* @return error_code 0 on success, an error code otherwise.
*/
int16_t startMeasurement1MpsHighRepeatability();
/**
* @brief startMeasurement1MpsMediumRepeatability
*
* Start periodic measurement mode with 1 mps and medium repeatability.
*
* @return error_code 0 on success, an error code otherwise.
*/
int16_t startMeasurement1MpsMediumRepeatability();
/**
* @brief startMeasurement1MpsLowRepeatability
*
* Start periodic measurement mode with 1 mps and low repeatability.
*
* @return error_code 0 on success, an error code otherwise.
*/
int16_t startMeasurement1MpsLowRepeatability();
/**
* @brief startMeasurement2MpsHighRepeatability
*
* Start periodic measurement mode with 2 mps and high repeatability.
*
* @return error_code 0 on success, an error code otherwise.
*/
int16_t startMeasurement2MpsHighRepeatability();
/**
* @brief startMeasurement2MpsMediumRepeatability
*
* Start periodic measurement mode with 2 mps and medium repeatability.
*
* @return error_code 0 on success, an error code otherwise.
*/
int16_t startMeasurement2MpsMediumRepeatability();
/**
* @brief startMeasurement2MpsLowRepeatability
*
* Start periodic measurement mode with 2 mps and low repeatability.
*
* @return error_code 0 on success, an error code otherwise.
*/
int16_t startMeasurement2MpsLowRepeatability();
/**
* @brief startMeasurement4MpsHighRepeatability
*
* Start periodic measurement mode with 4 mps and high repeatability.
*
* @return error_code 0 on success, an error code otherwise.
*/
int16_t startMeasurement4MpsHighRepeatability();
/**
* @brief startMeasurement4MpsMediumRepeatability
*
* Start periodic measurement mode with 4 mps and medium repeatability.
*
* @return error_code 0 on success, an error code otherwise.
*/
int16_t startMeasurement4MpsMediumRepeatability();
/**
* @brief startMeasurement4MpsLowRepeatability
*
* Start periodic measurement mode with 4 mps and low repeatability.
*
* @return error_code 0 on success, an error code otherwise.
*/
int16_t startMeasurement4MpsLowRepeatability();
/**
* @brief startMeasurement10MpsHighRepeatability
*
* Start periodic measurement mode with 10 mps and high repeatability.
*
* @return error_code 0 on success, an error code otherwise.
*/
int16_t startMeasurement10MpsHighRepeatability();
/**
* @brief startMeasurement10MpsMediumRepeatability
*
* Start periodic measurement mode with 10 mps and medium repeatability.
*
* @return error_code 0 on success, an error code otherwise.
*/
int16_t startMeasurement10MpsMediumRepeatability();
/**
* @brief startMeasurement10MpsLowRepeatability
*
* Start periodic measurement mode with 10 mps and low repeatability.
*
* @return error_code 0 on success, an error code otherwise.
*/
int16_t startMeasurement10MpsLowRepeatability();
/**
* @brief startArtMeasurement
*
* Start ART (accelerated response time) measurement
*
* @note After issuing the ART command the sensor will start acquiring data
* with a frequency of 4Hz.
*
* @return error_code 0 on success, an error code otherwise.
*/
int16_t startArtMeasurement();
/**
* @brief readMeasurement
*
* Read out data after a "start measurement" or "start art measurement"
* command has been issued.
*
* @param[out] temperatureTicks Temperature ticks. Convert to degrees
* celsius by -45 + 175 * value / 65535
* @param[out] humidityTicks Humidity ticks. Convert to relative humidity by
* 100
* * value / 65535
*
* @note After the read out command fetch data has been issued, the data
* memory is cleared, i.e. no measurement data is present.
*
* @return error_code 0 on success, an error code otherwise.
*/
int16_t readMeasurement(uint16_t& temperatureTicks,
uint16_t& humidityTicks);
/**
* @brief stopMeasurement
*
* Stop the periodic measurement mode.
*
* @note Upon reception of this command the sensor will abort the ongoing
* measurement and enter the single shot mode.
*
* @return error_code 0 on success, an error code otherwise.
*/
int16_t stopMeasurement();
/**
* @brief enableHeater
*
* Enable the heater
*
* @note The SHT3x is equipped with an internal heater, which is meant for
* plausibility checking only. The temperature increase achieved by the
* heater depends on various parameters and lies in the range of a few
* degrees centigrade.
*
* After a reset the heater is disabled (default condition).
*
* @return error_code 0 on success, an error code otherwise.
*/
int16_t enableHeater();
/**
* @brief disableHeater
*
* Disable the heater
*
* @return error_code 0 on success, an error code otherwise.
*/
int16_t disableHeater();
/**
* @brief llreadStatusRegister
*
* Read out the status register
*
* @param[out] statusRegister The contents of the status register
*
* @note The status register contains information on the operational status
* of the heater, the alert mode and on the execution status of the last
* command and the last write sequence.
*
* @return error_code 0 on success, an error code otherwise.
*/
int16_t llreadStatusRegister(uint16_t& statusRegister);
/**
* @brief clearStatusRegister
*
* Clear (set to zero) all flags (Bit 4) in the status register.
*
* @return error_code 0 on success, an error code otherwise.
*/
int16_t clearStatusRegister();
/**
* @brief softReset
*
* Perform a soft reset.
*
* @note A system reset of the SHT3x can be achieved in multiple ways: -
* Soft reset: use this command - I2C general call: all devices on the I2C
* bus are reset by sending the command 0x06 to the I2C address 0x00 - Reset
* pin: send a pulse to the dedicated nReset pin. The nReset pin has to be
* pulled low for a minimum of 1 µs to generate a reset of the sensor. -
* Hard reset: Power down (incl. pulling SDA, SCL and ADDR low)
*
* During the reset procedure the sensor will not process commands.
*
* @return error_code 0 on success, an error code otherwise.
*/
int16_t softReset();
private:
TwoWire* _i2cBus = nullptr;
uint8_t _i2cAddress = 0;
/**
* @brief signalTemperature
*
* @param[in] temperatureTicks
*
* @return Converted from ticks to degrees celsius by -45 + (175 * value /
* 65535)
*/
float signalTemperature(uint16_t temperatureTicks);
/**
* @brief signalHumidity
*
* @param[in] humidityTicks
*
* @return Converted from ticks to relative humidity by 100 * value / 65535
*/
float signalHumidity(uint16_t humidityTicks);
};
#endif // SENSIRIONI2CSHT3X_H

View File

@ -1,21 +1,19 @@
BSD 3-Clause License
Copyright (c) 2023, Sensirion AG
Copyright (c) 2018, Sensirion AG
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice, this
list of conditions and the following disclaimer.
* Redistributions of source code must retain the above copyright notice, this
list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution.
* Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution.
3. Neither the name of the copyright holder nor the names of its
contributors may be used to endorse or promote products derived from
this software without specific prior written permission.
* Neither the name of Sensirion AG nor the names of its
contributors may be used to endorse or promote products derived from
this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE

View File

@ -0,0 +1,72 @@
# arduino-sht
Repository for Sensirion humidity and temperature sensor support on Arduino
## Supported sensors:
- SHTC1
- SHTC3
- SHTW1
- SHTW2
- SHT2x (SHT20, SHT21, SHT25)
- SHT3x-DIS (I2C)
- SHT3x-ARP (ratiometric analog voltage output)
- SHT85
- SHT4x
For <code><a href="https://github.com/Sensirion/arduino-i2c-sht3x">sht3x</a></code> and <code><a href="https://github.com/Sensirion/arduino-i2c-sht4x">sht4x</a></code> there are specific drivers available in separate repositories.
## Installation
The recommended way to install ```arduino-sht``` is through the Library
Manager of the Arduino IDE. To access it, go to the ```Tools``` menu and
select ```Manage Libraries...```, and search for the library name there.
If you prefer to install it manually, you can download either via git or from
the releases page and place it in your Arduino/libraries directory. After
restarting the Arduino IDE, you will see the new SHTSensor menu items under
libraries and examples.
## Integrating it into your sketch
Assuming you installed the library as described above, the following steps are
necessary:
1. Import the Wire library like this: From the menu bar, select Sketch > Import
Library > Wire
1. Import the arduino-sht library: From the menu bar, select Sketch >
Import Library > arduino-sht
1. Create an instance of the `SHTSensor` class (`SHTSensor sht;`)
2. In `setup()`, make sure to init the Wire library with `Wire.begin()`
3. Also in `setup()`, call `sht.init()`
5. If you want to use the serial console, remember to initialize the Serial
library with `Serial.begin(9600)`
1. Call `sht.readSample()` in the `loop()` function, which reads a temperature
and humidity sample from the sensor
2. Use `sht.getHumidity()` and `sht.getTemperature()` to get the values from
the last sample
*Important:* `getHumidity()` and `getTemperature()` do *not* read a new sample
from the sensor, but return the values read last. To read a new sample, make
sure to call `readSample()`
### Using an custom or alternative I2C port/Wire instance
Some Arduino boards have multiple predefined I2C ports; generally, the second port will be called `Wire1`.
The `arduino-sht` library allows to use an alternative interface; to do so, pass the port you want to use as an argument to `sht.init()`, like this:
```
if (sht.init(Wire1)) {
Serial.print("init(): success\n");
} else {
Serial.print("init(): failed\n");
}
```
## Example projects
See example project
[sht-autodetect](examples/sht-autodetect/sht-autodetect.ino)
### Usage with multiple SHT31 sensors
See example project
[multiple-sht-sensors](examples/multiple-sht-sensors/multiple-sht-sensors.ino)

View File

@ -0,0 +1,442 @@
/*
* Copyright (c) 2018, Sensirion AG <andreas.brauchli@sensirion.com>
* Copyright (c) 2015-2016, Johannes Winkelmann <jw@smts.ch>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* * Neither the name of the Sensirion AG nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include <inttypes.h>
#include <Arduino.h>
#include "SHTSensor.h"
//
// class SHTSensorDriver
//
SHTSensorDriver::~SHTSensorDriver()
{
}
bool SHTSensorDriver::readSample()
{
return false;
}
//
// class SHTI2cSensor
//
const uint8_t SHTI2cSensor::EXPECTED_DATA_SIZE = 6;
bool SHTI2cSensor::readFromI2c(TwoWire & wire,
uint8_t i2cAddress,
const uint8_t *i2cCommand,
uint8_t commandLength, uint8_t *data,
uint8_t dataLength,
uint8_t duration)
{
wire.beginTransmission(i2cAddress);
for (int i = 0; i < commandLength; ++i) {
if (wire.write(i2cCommand[i]) != 1) {
return false;
}
}
if (wire.endTransmission() != 0) {
return false;
}
delay(duration);
wire.requestFrom(i2cAddress, dataLength);
// check if the same number of bytes are received that are requested.
if (wire.available() != dataLength) {
return false;
}
for (int i = 0; i < dataLength; ++i) {
data[i] = wire.read();
}
return true;
}
uint8_t SHTI2cSensor::crc8(const uint8_t *data, uint8_t len, uint8_t crcInit)
{
// adapted from SHT21 sample code from
// http://www.sensirion.com/en/products/humidity-temperature/download-center/
uint8_t crc = crcInit;
uint8_t byteCtr;
for (byteCtr = 0; byteCtr < len; ++byteCtr) {
crc ^= data[byteCtr];
for (uint8_t bit = 8; bit > 0; --bit) {
if (crc & 0x80) {
crc = (crc << 1) ^ 0x31;
} else {
crc = (crc << 1);
}
}
}
return crc;
}
bool SHTI2cSensor::readSample()
{
uint8_t data[EXPECTED_DATA_SIZE];
uint8_t cmd[mCmd_Size];
cmd[0] = mI2cCommand >> 8;
//is omitted for SHT4x Sensors
cmd[1] = mI2cCommand & 0xff;
if (!readFromI2c(mWire, mI2cAddress, cmd, mCmd_Size, data,
EXPECTED_DATA_SIZE, mDuration)) {
return false;
}
// -- Important: assuming each 2 byte of data is followed by 1 byte of CRC
// check CRC for both RH and T
if (crc8(&data[0], 2) != data[2] || crc8(&data[3], 2) != data[5]) {
return false;
}
// convert to Temperature/Humidity
uint16_t val;
val = (data[0] << 8) + data[1];
mTemperature = mA + mB * (val / mC);
val = (data[3] << 8) + data[4];
mHumidity = mX + mY * (val / mZ);
return true;
}
//
// class SHTC1Sensor
//
class SHTC1Sensor : public SHTI2cSensor
{
public:
SHTC1Sensor(TwoWire & wire)
// clock stretching disabled, high precision, T first
: SHTI2cSensor(0x70, 0x7866, 15, -45, 175, 65535, 0, 100, 65535, 2, wire)
{
}
};
//
// class SHT2xSensor (SHT20, SHT21, SHT25)
//
class SHT2xSensor : public SHTI2cSensor
{
public:
SHT2xSensor(TwoWire &wire)
// clock stretching disabled
: SHTI2cSensor(0x40, // i2cAddress
0xF3F5, // i2cCommand Hi: T, Lo: RH
85, // duration
-46.85, // a (sht_t_poly1)
175.72, // b (sht_t_poly2)
65536.0, // c (sht_t_poly3)
-6.0, // x (sht_h_poly1)
125.0, // y (sht_h_poly2)
65536.0, // z (sht_h_poly3)
1, // cmd_Size
wire)
{
}
bool readSample() override
{
uint8_t data[EXPECTED_DATA_SIZE];
uint8_t cmd[mCmd_Size];
// SHT2x sends T and RH in two separate commands (different to other sensors)
// so we have to spit the command into two bytes and
// have to read from I2C two times with EXPECTED_DATA_SIZE / 2
// Upper byte is T for SHT2x Sensors
cmd[0] = mI2cCommand >> 8;
// Lower byte is RH for SHT2x Sensors
cmd[1] = mI2cCommand & 0xff;
// read T from SHT2x Sensor
if (!readFromI2c(mWire, mI2cAddress, cmd, mCmd_Size, data,
EXPECTED_DATA_SIZE / 2, mDuration)) {
DEBUG_SHT("SHT2x readFromI2c(T) false\n");
return false;
}
// read RH from SHT2x Sensor
if (!readFromI2c(mWire, mI2cAddress, &cmd[1], mCmd_Size, &data[3],
EXPECTED_DATA_SIZE / 2, mDuration)) {
DEBUG_SHT("SHT2x readFromI2c(RH) false\n");
return false;
}
// -- Important: assuming each 2 byte of data is followed by 1 byte of CRC
// check CRC for both RH and T with a crc init value of 0
if (crc8(&data[0], 2, 0) != data[2] || crc8(&data[3], 2, 0) != data[5]) {
DEBUG_SHT("SHT2x crc8 false\n");
return false;
}
// check status bits [1..0] (see datasheet)
// bit 0: not used, bit 1: measurement type (0: temperature, 1 humidity)
if (((data[1] & 0x02) != 0x00) || ((data[4] & 0x02) != 0x02)) {
DEBUG_SHT("SHT2x status bits false\n");
return false;
}
// convert to Temperature/Humidity
uint16_t val;
val = (data[0] << 8) + (data[1] & ~0x03); // get value and clear status bits [1..0]
mTemperature = mA + mB * (val / mC);
val = (data[3] << 8) + (data[4] & ~0x03); // get value and clear status bits [1..0]
mHumidity = mX + mY * (val / mZ);
return true;
}
};
//
// class SHT3xSensor
//
class SHT3xSensor : public SHTI2cSensor
{
private:
static const uint16_t SHT3X_ACCURACY_HIGH = 0x2400;
static const uint16_t SHT3X_ACCURACY_MEDIUM = 0x240b;
static const uint16_t SHT3X_ACCURACY_LOW = 0x2416;
static const uint8_t SHT3X_ACCURACY_HIGH_DURATION = 15;
static const uint8_t SHT3X_ACCURACY_MEDIUM_DURATION = 6;
static const uint8_t SHT3X_ACCURACY_LOW_DURATION = 4;
public:
static const uint8_t SHT3X_I2C_ADDRESS_44 = 0x44;
static const uint8_t SHT3X_I2C_ADDRESS_45 = 0x45;
SHT3xSensor(TwoWire & wire, uint8_t i2cAddress = SHT3X_I2C_ADDRESS_44)
: SHTI2cSensor(i2cAddress, SHT3X_ACCURACY_HIGH,
SHT3X_ACCURACY_HIGH_DURATION,
-45, 175, 65535, 0, 100, 65535, 2, wire)
{
}
virtual bool setAccuracy(SHTSensor::SHTAccuracy newAccuracy)
{
switch (newAccuracy) {
case SHTSensor::SHT_ACCURACY_HIGH:
mI2cCommand = SHT3X_ACCURACY_HIGH;
mDuration = SHT3X_ACCURACY_HIGH_DURATION;
break;
case SHTSensor::SHT_ACCURACY_MEDIUM:
mI2cCommand = SHT3X_ACCURACY_MEDIUM;
mDuration = SHT3X_ACCURACY_MEDIUM_DURATION;
break;
case SHTSensor::SHT_ACCURACY_LOW:
mI2cCommand = SHT3X_ACCURACY_LOW;
mDuration = SHT3X_ACCURACY_LOW_DURATION;
break;
default:
return false;
}
return true;
}
};
//
// class SHT4xSensor
//
class SHT4xSensor : public SHTI2cSensor
{
private:
static const uint16_t SHT4X_ACCURACY_HIGH = 0xFD00;
static const uint16_t SHT4X_ACCURACY_MEDIUM = 0xF600;
static const uint16_t SHT4X_ACCURACY_LOW = 0xE000;
static const uint8_t SHT4X_ACCURACY_HIGH_DURATION = 10;
static const uint8_t SHT4X_ACCURACY_MEDIUM_DURATION = 4;
static const uint8_t SHT4X_ACCURACY_LOW_DURATION = 2;
public:
static const uint8_t SHT4X_I2C_ADDRESS_44 = 0x44;
static const uint8_t SHT4X_I2C_ADDRESS_45 = 0x45;
SHT4xSensor(TwoWire & wire, uint8_t i2cAddress = SHT4X_I2C_ADDRESS_44)
: SHTI2cSensor(i2cAddress, SHT4X_ACCURACY_HIGH,
SHT4X_ACCURACY_HIGH_DURATION,
-45, 175, 65535, -6, 125, 65535, 1, wire)
{
}
virtual bool setAccuracy(SHTSensor::SHTAccuracy newAccuracy)
{
switch (newAccuracy) {
case SHTSensor::SHT_ACCURACY_HIGH:
mI2cCommand = SHT4X_ACCURACY_HIGH;
mDuration = SHT4X_ACCURACY_HIGH_DURATION;
break;
case SHTSensor::SHT_ACCURACY_MEDIUM:
mI2cCommand = SHT4X_ACCURACY_MEDIUM;
mDuration = SHT4X_ACCURACY_MEDIUM_DURATION;
break;
case SHTSensor::SHT_ACCURACY_LOW:
mI2cCommand = SHT4X_ACCURACY_LOW;
mDuration = SHT4X_ACCURACY_LOW_DURATION;
break;
default:
return false;
}
return true;
}
};
//
// class SHT3xAnalogSensor
//
float SHT3xAnalogSensor::readHumidity()
{
float max_adc = (float)((1 << mReadResolutionBits) - 1);
return -12.5f + 125 * (analogRead(mHumidityAdcPin) / max_adc);
}
float SHT3xAnalogSensor::readTemperature()
{
float max_adc = (float)((1 << mReadResolutionBits) - 1);
return -66.875f + 218.75f * (analogRead(mTemperatureAdcPin) / max_adc);
}
//
// class SHTSensor
//
const SHTSensor::SHTSensorType SHTSensor::AUTO_DETECT_SENSORS[] = {
SHT4X, // IMPORTANT: SHT4x needs to be probed before the SHT3x, since they
// share their I2C address, and probing for an SHT3x can cause the
// first reading of and SHT4x to be off.
// see https://github.com/Sensirion/arduino-sht/issues/27
SHT2X,
SHT3X,
SHT3X_ALT,
SHTC1
};
const float SHTSensor::TEMPERATURE_INVALID = NAN;
const float SHTSensor::HUMIDITY_INVALID = NAN;
bool SHTSensor::init(TwoWire & wire)
{
if (mSensor != NULL) {
cleanup();
}
switch(mSensorType) {
case SHT2X:
mSensor = new SHT2xSensor(wire);
break;
case SHT3X:
case SHT85:
mSensor = new SHT3xSensor(wire);
break;
case SHT3X_ALT:
mSensor = new SHT3xSensor(wire, SHT3xSensor::SHT3X_I2C_ADDRESS_45);
break;
case SHTW1:
case SHTW2:
case SHTC1:
case SHTC3:
mSensor = new SHTC1Sensor(wire);
break;
case SHT4X:
mSensor = new SHT4xSensor(wire);
break;
case AUTO_DETECT:
{
bool detected = false;
for (unsigned int i = 0;
i < sizeof(AUTO_DETECT_SENSORS) / sizeof(AUTO_DETECT_SENSORS[0]);
++i) {
mSensorType = AUTO_DETECT_SENSORS[i];
delay(40); // TODO: this was necessary to make SHT4x autodetect work; revisit to find root cause
if (init(wire)) {
detected = true;
break;
}
}
if (!detected) {
cleanup();
}
break;
}
}
// to finish the initialization, attempt to read to make sure the communication works
// Note: readSample() will check for a NULL mSensor in case auto detect failed
return readSample();
}
bool SHTSensor::readSample()
{
if (!mSensor || !mSensor->readSample())
return false;
mTemperature = mSensor->mTemperature;
mHumidity = mSensor->mHumidity;
return true;
}
bool SHTSensor::setAccuracy(SHTAccuracy newAccuracy)
{
if (!mSensor)
return false;
return mSensor->setAccuracy(newAccuracy);
}
void SHTSensor::cleanup()
{
if (mSensor) {
delete mSensor;
mSensor = NULL;
}
}

View File

@ -0,0 +1,309 @@
/*
* Copyright (c) 2018, Sensirion AG <andreas.brauchli@sensirion.com>
* Copyright (c) 2015-2016, Johannes Winkelmann <jw@smts.ch>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* * Neither the name of the Sensirion AG nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef SHTSENSOR_H
#define SHTSENSOR_H
#include <inttypes.h>
#include <Wire.h>
//#define DEBUG_SHT_SENSOR
#ifdef DEBUG_SHT_SENSOR
#ifdef DEBUG_ESP_PORT
#define DEBUG_SHT(f) do { DEBUG_ESP_PORT.print(PSTR(f)); } while (0)
#else
#define DEBUG_SHT(f) do { Serial.print(PSTR(f)); } while (0)
#endif
#else
#define DEBUG_SHT(x...) do { (void)0; } while (0)
#endif
// Forward declaration
class SHTSensorDriver;
/**
* Official interface for Sensirion SHT Sensors
*/
class SHTSensor
{
public:
/**
* Enum of the supported Digital Sensirion SHT Sensors.
* For analog sensors, see SHT3xAnalogSensor.
* Using the special AUTO_DETECT sensor causes all i2c sensors to be
* probed. The first matching sensor will then be used.
*/
enum SHTSensorType {
/** Automatically detect the sensor type (only i2c sensors listed above) */
AUTO_DETECT,
// i2c Sensors:
/** SHT3x-DIS with ADDR (sensor pin 2) connected to VSS (default) */
SHT3X,
SHT85,
/** SHT3x-DIS with ADDR (sensor pin 2) connected to VDD */
SHT3X_ALT,
SHTC1,
SHTC3,
SHTW1,
SHTW2,
SHT4X,
SHT2X
};
/**
* Accuracy setting of measurement.
* Not all sensors support changing the sampling accuracy.
*/
enum SHTAccuracy {
/** Highest repeatability at the cost of slower measurement */
SHT_ACCURACY_HIGH,
/** Balanced repeatability and speed of measurement */
SHT_ACCURACY_MEDIUM,
/** Fastest measurement but lowest repeatability */
SHT_ACCURACY_LOW
};
/** Value reported by getHumidity() when the sensor is not initialized */
static const float HUMIDITY_INVALID;
/** Value reported by getTemperature() when the sensor is not initialized */
static const float TEMPERATURE_INVALID;
/**
* Auto-detectable sensor types.
* Note that the SHTC3, SHTW1 and SHTW2 share exactly the same driver as the SHTC1
* and are thus not listed individually.
*/
static const SHTSensorType AUTO_DETECT_SENSORS[];
/**
* Instantiate a new SHTSensor
* By default, the i2c bus is queried for known SHT Sensors. To address
* a specific sensor, set the `sensorType'.
*/
SHTSensor(SHTSensorType sensorType = AUTO_DETECT)
: mSensorType(sensorType),
mSensor(NULL),
mTemperature(SHTSensor::TEMPERATURE_INVALID),
mHumidity(SHTSensor::HUMIDITY_INVALID)
{
}
virtual ~SHTSensor() {
cleanup();
}
/**
* Initialize the sensor driver, and probe for the sensor on the bus
*
* If SHTSensor() was created with an empty constructor or with 'sensorType'
* AUTO_DETECT, init() will also try to automatically detect a sensor.
* Auto detection will stop as soon as the first sensor was found; if you have
* multiple sensor types on the bus, use the 'sensorType' argument of the
* constructor to control which sensor type will be instantiated.
*
* To read out the sensor use readSample(), followed by getTemperature() and
* getHumidity() to retrieve the values from the sample
*
* Returns true if communication with a sensor on the bus was successful, false otherwise
*/
bool init(TwoWire & wire = Wire);
/**
* Read new values from the sensor
* After the call, use getTemperature() and getHumidity() to retrieve the
* values
* Returns true if the sample was read and the values are cached
*/
bool readSample();
/**
* Get the relative humidity in percent read from the last sample
* Use readSample() to trigger a new sensor reading
*/
float getHumidity() const {
return mHumidity;
}
/**
* Get the temperature in Celsius read from the last sample
* Use readSample() to trigger a new sensor reading
*/
float getTemperature() const {
return mTemperature;
}
/**
* Change the sensor accurancy, if supported by the sensor
* Returns true if the accuracy was changed
*/
bool setAccuracy(SHTAccuracy newAccuracy);
SHTSensorType mSensorType;
private:
void cleanup();
SHTSensorDriver *mSensor;
float mTemperature;
float mHumidity;
};
/** Abstract class for a digital SHT Sensor driver */
class SHTSensorDriver
{
public:
virtual ~SHTSensorDriver() = 0;
/**
* Set the sensor accuracy.
* Returns false if the sensor does not support changing the accuracy
*/
virtual bool setAccuracy(SHTSensor::SHTAccuracy /* newAccuracy */) {
return false;
}
/** Returns true if the next sample was read and the values are cached */
virtual bool readSample();
/**
* Get the relative humidity in percent read from the last sample
* Use readSample() to trigger a new sensor reading
*/
float getHumidity() const {
return mHumidity;
}
/**
* Get the humidity in percent read from the last sample
* Use readSample() to trigger a new sensor reading
*/
float getTemperature() const {
return mTemperature;
}
float mTemperature;
float mHumidity;
};
/** Base class for i2c SHT Sensor drivers */
class SHTI2cSensor : public SHTSensorDriver {
public:
/** Size of i2c commands to send */
/** Size of i2c replies to expect */
static const uint8_t EXPECTED_DATA_SIZE;
/**
* Constructor for i2c SHT Sensors
* Takes the `i2cAddress' to read, the `i2cCommand' issues when sampling
* the sensor and the values `a', `b', `c' to convert the fixed-point
* temperature value received by the sensor to a floating point value using
* the formula: temperature = a + b * (rawTemperature / c)
* and the values `x' and `y' to convert the fixed-point humidity value
* received by the sensor to a floating point value using the formula:
* humidity = x + y * (rawHumidity / z)
* duration is the duration in milliseconds of one measurement
*/
SHTI2cSensor(uint8_t i2cAddress, uint16_t i2cCommand, uint8_t duration,
float a, float b, float c,
float x, float y, float z, uint8_t cmd_Size,
TwoWire & wire = Wire)
: mI2cAddress(i2cAddress), mI2cCommand(i2cCommand), mDuration(duration),
mA(a), mB(b), mC(c), mX(x), mY(y), mZ(z), mCmd_Size(cmd_Size),
mWire(wire)
{
}
virtual ~SHTI2cSensor()
{
}
virtual bool readSample();
uint8_t mI2cAddress;
uint16_t mI2cCommand;
uint8_t mDuration;
float mA;
float mB;
float mC;
float mX;
float mY;
float mZ;
uint8_t mCmd_Size;
TwoWire & mWire;
private:
protected:
static uint8_t crc8(const uint8_t *data, uint8_t len, uint8_t crcInit = 0xff);
static bool readFromI2c(TwoWire & wire,
uint8_t i2cAddress,
const uint8_t *i2cCommand,
uint8_t commandLength, uint8_t *data,
uint8_t dataLength, uint8_t duration);
};
class SHT3xAnalogSensor
{
public:
/**
* Instantiate a new Sensirion SHT3x Analog sensor driver instance.
* The required paramters are `humidityPin` and `temperaturePin`
* An optional `readResolutionBits' can be set since the Arduino/Genuino Zero
* support 12bit precision analog readings. By default, 10 bit precision is
* used.
*
* Example usage:
* SHT3xAnalogSensor sht3xAnalog(HUMIDITY_PIN, TEMPERATURE_PIN);
* float humidity = sht.readHumidity();
* float temperature = sht.readTemperature();
*/
SHT3xAnalogSensor(uint8_t humidityPin, uint8_t temperaturePin,
uint8_t readResolutionBits = 10)
: mHumidityAdcPin(humidityPin), mTemperatureAdcPin(temperaturePin),
mReadResolutionBits(readResolutionBits)
{
}
virtual ~SHT3xAnalogSensor()
{
}
float readHumidity();
float readTemperature();
uint8_t mHumidityAdcPin;
uint8_t mTemperatureAdcPin;
uint8_t mReadResolutionBits;
};
#endif /* SHTSENSOR_H */

View File

@ -0,0 +1,6 @@
#ifndef ARDUINO_SHT_H
#define ARDUINO_SHT_H
#include "SHTSensor.h"
#endif

View File

@ -0,0 +1,62 @@
#include <Wire.h>
#include "SHTSensor.h"
// Note that all i2c devices sharing one bus must have distinct addresses. Thus
// this example only works with sensors that have distinct i2c addresses (e.g.
// SHT3x and SHT3x_alt, or SHT3x and SHTC3).
// Make sure not to use auto-detection as it will only pick up one sensor.
// Sensor with normal i2c address
// Sensor 1 with address pin pulled to GND
SHTSensor sht1(SHTSensor::SHT3X);
// Sensor with alternative i2c address
// Sensor 2 with address pin pulled to Vdd
SHTSensor sht2(SHTSensor::SHT3X_ALT);
void setup() {
// put your setup code here, to run once:
Wire.begin();
Serial.begin(9600);
delay(1000); // let serial console settle
// init on a specific sensor type (i.e. without auto detecting),
// does not check if the sensor is responding and will thus always succeed.
// initialize sensor with normal i2c-address
sht1.init();
// initialize sensor with alternative i2c-address
sht2.init();
}
void loop() {
// put your main code here, to run repeatedly:
// read from first sensor
if (sht1.readSample()) {
Serial.print("SHT1 :\n");
Serial.print(" RH: ");
Serial.print(sht1.getHumidity(), 2);
Serial.print("\n");
Serial.print(" T: ");
Serial.print(sht1.getTemperature(), 2);
Serial.print("\n");
} else {
Serial.print("Sensor 1: Error in readSample()\n");
}
// read from second sensor
if (sht2.readSample()) {
Serial.print("SHT2:\n");
Serial.print(" RH: ");
Serial.print(sht2.getHumidity(), 2);
Serial.print("\n");
Serial.print(" T: ");
Serial.print(sht2.getTemperature(), 2);
Serial.print("\n");
} else {
Serial.print("Sensor 2: Error in readSample()\n");
}
delay(1000);
}

View File

@ -0,0 +1,41 @@
#include <Wire.h>
#include "SHTSensor.h"
SHTSensor sht;
// To use a specific sensor instead of probing the bus use this command:
// SHTSensor sht(SHTSensor::SHT3X);
void setup() {
// put your setup code here, to run once:
Wire.begin();
Serial.begin(9600);
delay(1000); // let serial console settle
if (sht.init()) {
Serial.print("init(): success\n");
} else {
Serial.print("init(): failed\n");
}
sht.setAccuracy(SHTSensor::SHT_ACCURACY_MEDIUM); // only supported by SHT3x
}
void loop() {
// put your main code here, to run repeatedly:
if (sht.readSample()) {
Serial.print("SHT:\n");
Serial.print(" RH: ");
Serial.print(sht.getHumidity(), 2);
Serial.print("\n");
Serial.print(" T: ");
Serial.print(sht.getTemperature(), 2);
Serial.print("\n");
} else {
Serial.print("Error in readSample()\n");
}
delay(1000);
}

View File

@ -0,0 +1,27 @@
#include <Arduino.h>
#include <Wire.h>
#include "SHTSensor.h"
SHT3xAnalogSensor sht3xAnalog(A0, A1);
void setup() {
// put your setup code here, to run once:
Wire.begin();
Serial.begin(9600);
delay(1000); // let serial console settle
}
void loop() {
Serial.print("SHT3x Analog:\n");
Serial.print(" RH: ");
Serial.print(sht3xAnalog.readHumidity(), 2);
Serial.print("\n");
Serial.print(" T: ");
Serial.print(sht3xAnalog.readTemperature(), 2);
Serial.print("\n");
delay(1000);
}

View File

@ -0,0 +1,29 @@
#######################################
# Syntax Coloring Map For arduino-sht
#######################################
#######################################
# Datatypes (KEYWORD1)
#######################################
SHTSensorType KEYWORD1
SHTAccuracy KEYWORD1
SHTSensor KEYWORD1
#######################################
# Methods and Functions (KEYWORD2)
#######################################
init KEYWORD2
readSample KEYWORD2
getHumidity KEYWORD2
getTemperature KEYWORD2
setAccuracy KEYWORD2
#######################################
# Instances (KEYWORD2)
#######################################
#######################################
# Constants (LITERAL1)
#######################################

View File

@ -0,0 +1,9 @@
name=arduino-sht
version=1.2.3
author=Johannes Winkelmann, Andreas Brauchli
maintainer=Johannes Winkelmann <jwi@sensirion.com>
sentence=Support for Sensirion's humidity and temperature sensors.
paragraph=Supported sensors: SHTC1, SHTC3, SHTW1, SHTW2, SHT3x-DIS (I2C), SHT2x, SHT85, SHT3x-ARP, SHT4x
category=Sensors
url=https://developer.sensirion.com
architectures=*

149
src/sht/sht.cpp Normal file
View File

@ -0,0 +1,149 @@
#include "sht.h"
#include "../library/arduino-sht/SHTSensor.h"
/** Cast _sensor to SHTSensor */
#define shtSensor() ((SHTSensor *)(this->_sensor))
/**
* @brief Check that is sensor initialized
*
* @return true Initialized
* @return false Not-initialized
*/
bool Sht::isBegin(void) {
if (this->_isBegin) {
return true;
}
AgLog("Sensor not-initialized");
return false;
}
/**
* @brief Check board is support I2C to work with this sensor
*
* @return true Supported
* @return false Not supported
*/
bool Sht::boardSupported(void) {
if (this->_bsp == NULL) {
this->_bsp = getBoardDef(this->_boardType);
}
if ((this->_bsp == NULL) || (this->_bsp->I2C.supported == false)) {
AgLog("Board not supported");
return false;
}
return true;
}
/**
* @brief Construct a new Sht:: Sht object
*
* @param type
*/
Sht::Sht(BoardType type) : _boardType(type) {}
/**
* @brief Destroy the Sht:: Sht object
*
*/
Sht::~Sht() {}
#if defined(ESP8266)
/**
* @brief Init sensor, Ifthis funciton not call the other funtion call will
* always return false or value invalid
*
* @param wire wire TwoWire instance, Must be initialized
* @param debugStream Point to debug Serial to print debug log
* @return true Sucecss
* @return false Failure
*/
bool Sht::begin(TwoWire &wire, Stream &debugStream) {
_debugStream = &debugStream;
return begin(wire);
}
#else
#endif
/**
* @brief Initialize sensor, should be init sensor before use other API, if not
* return result always failed
*
* @param wire TwoWire instance, Must be initialized
* @return true Success
* @return false Failure
*/
bool Sht::begin(TwoWire &wire) {
if (_isBegin) {
AgLog("Initialized, call end() then try again");
return true;
}
if (boardSupported() == false) {
return false;
}
/** Create new sensor */
_sensor = new SHTSensor();
if (_sensor == nullptr) {
AgLog("Create SHTSensor failed");
return false;
}
/** Initialize sensor */
if (shtSensor()->init(wire) == false) {
AgLog("Initialize SHTSensor failed");
return false;
}
// Only supported by SHT3x
if (shtSensor()->setAccuracy(SHTSensor::SHT_ACCURACY_MEDIUM) == false) {
AgLog("Configure sensor failed");
return false;
}
AgLog("Initialize");
_isBegin = true;
return true;
}
/**
* @brief De-initialize sht sensor
*
*/
void Sht::end(void) {
if (_isBegin == false) {
return;
}
delete shtSensor();
_isBegin = false;
#if defined(ESP8266)
_debugStream = nullptr;
#else
#endif
_isBegin = false;
AgLog("De-Initialize");
}
/**
* @brief Get temprature degree celcius
*
* @return float
*/
float Sht::getTemperature(void) { return shtSensor()->getTemperature(); }
/**
* @brief Get humidity
*
* @return float
*/
float Sht::getRelativeHumidity(void) { return shtSensor()->getHumidity(); }
/**
* @brief Measure temperature and humidity
*
* @return true Success
* @return false Failure
*/
bool Sht::measure(void) { return shtSensor()->readSample(); }

View File

@ -1,40 +1,42 @@
#ifndef _AIR_GRADIENT_SHT_H_
#define _AIR_GRADIENT_SHT_H_
#ifndef _SHT_H_
#define _SHT_H_
#include "../main/BoardDef.h"
#include <Arduino.h>
#include <Wire.h>
#include "../main/BoardDef.h"
/**
* @brief The class with define how to handle the Sensirion sensor SHT41
* (temperature and humidity sensor).
* @brief This class with define how to handlet sensirion sensor sht4x and
* sht3x(Temperature and humidity sensor)
*
*/
class Sht4x {
public:
#if defined(ESP8266)
bool begin(TwoWire &wire, Stream &debugStream);
#else
#endif
Sht4x(BoardType type);
bool begin(TwoWire &wire);
void end(void);
float getTemperature(void);
float getRelativeHumidity(void);
class Sht {
private:
BoardType _boardType;
bool _isBegin = false; /** Flag indicate that sensor initialized or not */
bool _isBegin = false;
void *_sensor;
const BoardDef *_bsp = NULL;
#if defined(ESP8266)
Stream *_debugStream = nullptr;
const char *TAG = "SHT4x";
const char *TAG = "SHT";
#else
#endif
bool isBegin(void);
bool boardSupported(void);
bool measureMediumPrecision(float &temperature, float &humidity);
public:
Sht(BoardType type);
~Sht();
#if defined(ESP8266)
bool begin(TwoWire &wire, Stream &debugStream);
#else
#endif
bool begin(TwoWire &wire);
void end(void);
bool measure(void);
float getTemperature(void);
float getRelativeHumidity(void);
};
#endif /** _AIR_GRADIENT_SHT_H_ */
#endif /** _SHT_H_ */

View File

@ -1,163 +0,0 @@
#include "sht3x.h"
#include "../library/arduino-i2c-sht3x/src/SensirionI2cSht3x.h"
#define sht3x() ((SensirionI2cSht3x *)(this->_sensor))
/**
* @brief Check that sensor has initialized
*
* @return true Initialized
* @return false Not-initialized
*/
bool Sht3x::isBegin(void) {
if (_isBegin) {
return true;
}
AgLog("Sensor not-initialized");
return false;
}
/**
* @brief Check sensor has supported by board
*
* @return true Supported
* @return false Not-supported
*/
bool Sht3x::boardSupported(void) {
if (_bsp == NULL) {
_bsp = getBoardDef(_boarType);
}
if ((_bsp == NULL) || (_bsp->I2C.supported == false)) {
AgLog("Board not supported");
return false;
}
return true;
}
/**
* @brief Get temperature and humidity data
*
* @param temp Tempreature read out
* @param hum Humidity read out
* @return true Success
* @return false Failure
*/
bool Sht3x::measure(float &temp, float &hum) {
if (isBegin() == false) {
return false;
}
if (sht3x()->measureSingleShot(REPEATABILITY_MEDIUM, false, temp, hum) ==
NO_ERROR) {
return true;
}
return false;
}
/**
* @brief Construct a new Sht 3x:: Sht 3x object
*
* @param type
*/
Sht3x::Sht3x(BoardType type) : _boarType(type) {}
/**
* @brief Destroy the Sht 3x:: Sht 3x object
*
*/
Sht3x::~Sht3x() { end(); }
#ifdef ESP8266
/**
* @brief Initialized sensor
*
* @param wire TwoWire instance, must be initialized
* @param debugStream Point to debug Serial to print debug log
* @return true Success
* @return false Failure
*/
bool Sht3x::begin(TwoWire &wire, Stream &debugStream) {
_debugStream = &debugStream;
return begin(wire);
}
#else
#endif
/**
* @brief Init sensor, should init before use sensor, if not call other method
* always return invalid
*
* @param wire TwoWire instance, must be initialized
* @return true Success
* @return false Failure
*/
bool Sht3x::begin(TwoWire &wire) {
if (_isBegin) {
AgLog("Initialized, call end() then try again");
return true;
}
/** Check sensor has supported on board */
if (boardSupported() == false) {
return false;
}
/** Create sensor and init */
_sensor = new SensirionI2cSht3x();
sht3x()->begin(wire, SHT30_I2C_ADDR_44);
if (sht3x()->softReset() != NO_ERROR) {
AgLog("Reset sensor fail, look like sensor is not on I2C bus");
return false;
}
_isBegin = true;
AgLog("Initialize");
return true;
}
/**
* @brief De-initialize sensor
*
*/
void Sht3x::end(void) {
if (_isBegin == false) {
return;
}
_isBegin = false;
_bsp = NULL;
delete sht3x();
#ifdef ESP8266
_debugStream = nullptr;
#endif
AgLog("De-initialize");
}
/**
* @brief Get temperature degree celsius
*
* @return float value <= 256.0f is invalid, that mean sensor has issue or
* communication to sensor not worked as well
*/
float Sht3x::getTemperature(void) {
float temp;
float hum;
if (measure(temp, hum)) {
return temp;
}
return -256.0f;
}
/**
* @brief Get humidity
*
* @return float Percent(0 - 100), value < 0 is invalid.
*/
float Sht3x::getRelativeHumidity(void) {
float temp;
float hum;
if (measure(temp, hum)) {
return hum;
}
return -1.0f;
}

View File

@ -1,42 +0,0 @@
#ifndef _AIR_GRADIENT_SHT3X_H_
#define _AIR_GRADIENT_SHT3X_H_
#include "../main/BoardDef.h"
#include <Arduino.h>
#include <Wire.h>
/**
* @brief The class with define how to handle the Sensirion sensor SHT3x
* (temperature and humidity sensor).
*/
class Sht3x {
private:
BoardType _boarType;
bool _isBegin = false;
const BoardDef *_bsp = NULL;
void *_sensor;
#ifdef ESP8266
Stream *_debugStream = nullptr;
const char *TAG = "SHT3x";
#else
#endif
bool isBegin(void);
bool boardSupported(void);
bool measure(float &temp, float &hum);
public:
Sht3x(BoardType type);
~Sht3x();
#ifdef ESP8266
bool begin(TwoWire &wire, Stream &debugStream);
#else
#endif
bool begin(TwoWire &wire);
void end(void);
float getTemperature(void);
float getRelativeHumidity(void);
};
#endif /** _AIR_GRADIENT_SHT3X_H_ */

View File

@ -1,165 +0,0 @@
#include "sht4x.h"
#include "../library/SensirionSHT4x/src/SensirionI2CSht4x.h"
/** Cast _sensor to SensirionI2CSht4x */
#define shtSensor() ((SensirionI2CSht4x *)(this->_sensor))
#if defined(ESP8266)
/**
* @brief Init sensor, Ifthis funciton not call the other funtion call will
* always return false or value invalid
*
* @param wire wire TwoWire instance, Must be initialized
* @param debugStream Point to debug Serial to print debug log
* @return true Sucecss
* @return false Failure
*/
bool Sht4x::begin(TwoWire &wire, Stream &debugStream) {
this->_debugStream = &debugStream;
return this->begin(wire);
}
#else
#endif
/**
* @brief Construct a new Sht4x:: Sht4x object
*
* @param type Board type @ref BoardType
*/
Sht4x::Sht4x(BoardType type) : _boardType(type) {}
/**
* @brief Init sensor, Ifthis funciton not call the other funtion call will
* always return false or value invalid
*
* @param wire TwoWire instance, Must be initialized
* @return true Success
* @return false Failure
*/
bool Sht4x::begin(TwoWire &wire) {
/** Ignore next step if sensor has intiialized */
if (this->_isBegin) {
AgLog("Initialized, call end() then try again");
return true;
}
/** Check sensor has supported on board */
if (this->boardSupported() == false) {
return false;
}
/** Create new SensirionI2CSht4x and init */
this->_sensor = new SensirionI2CSht4x();
shtSensor()->begin(wire, SHT40_I2C_ADDR_44);
if (shtSensor()->softReset() != 0) {
AgLog("Reset sensor fail, look like sensor is not on I2C bus");
return false;
}
delay(10);
this->_isBegin = true;
AgLog("Initialize");
return true;
}
/**
* @brief De-initialize SHT41 sensor
*
*/
void Sht4x::end(void) {
if (this->_isBegin == false) {
return;
}
this->_isBegin = false;
_bsp = NULL;
delete shtSensor();
#if defined(ESP8266)
_debugStream = nullptr;
#endif
AgLog("De-initialize");
}
/**
* @brief Get temperature degrees celsius
*
* @return float value <= 256.0f is invalid, That mean sensor has issue or
* communication to sensor not worked as well.
*/
float Sht4x::getTemperature(void) {
float temperature;
float humidity;
if (this->measureMediumPrecision(temperature, humidity)) {
return temperature;
}
return -256.0f;
}
/**
* @brief Get humidity
*
* @return float Percent(0 - 100), value < 0 is invalid.
*/
float Sht4x::getRelativeHumidity(void) {
float temperature;
float humidity;
if (this->measureMediumPrecision(temperature, humidity)) {
return humidity;
}
return -1.0f;
}
/**
* @brief Check sensor has supported by board
*
* @return true Supported
* @return false Not supported
*/
bool Sht4x::boardSupported(void) {
if (this->_bsp == NULL) {
this->_bsp = getBoardDef(this->_boardType);
}
if ((this->_bsp == NULL) || (this->_bsp->I2C.supported == false)) {
AgLog("Board not supported");
return false;
}
return true;
}
/**
* @brief Check that sensor has initialized
*
* @return true Initialized
* @return false Not-initialized
*/
bool Sht4x::isBegin(void) {
if (this->_isBegin) {
return true;
}
AgLog("Sensor not-initialized");
return false;
}
/**
* @brief Ge SHT41 temperature and humidity value with medium meaure precision
*
* @param temperature Read out temperarure
* @param humidity Read humidity
* @return true Success
* @return false Failure
*/
bool Sht4x::measureMediumPrecision(float &temperature, float &humidity) {
if (this->isBegin() == false) {
return false;
}
if (shtSensor()->measureMediumPrecision(temperature, humidity) == 0) {
return true;
}
return false;
}