Compare commits
7 Commits
Author | SHA1 | Date | |
---|---|---|---|
5667279cf1 | |||
2941bb2d5d | |||
a0044ad0ac | |||
fc5c0a1d6e | |||
b28719b7a5 | |||
7a6cc8caef | |||
05594441b8 |
@ -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
|
||||
|
@ -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();
|
||||
@ -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();
|
||||
|
||||
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() {
|
||||
|
@ -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();
|
||||
|
||||
/** 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()) {
|
||||
|
||||
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");
|
||||
}
|
||||
}
|
||||
|
@ -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 \
|
||||
*/
|
||||
|
@ -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
|
||||
}
|
@ -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
|
||||
}
|
@ -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");
|
||||
} else {
|
||||
Serial.printf(" Get humidity: %f\r\n", hum);
|
||||
} else {
|
||||
Serial.println("Measure failed");
|
||||
}
|
||||
|
||||
delay(1000);
|
||||
}
|
||||
|
@ -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.
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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']
|
||||
...
|
70
src/library/SensirionSHT4x/.gitignore
vendored
@ -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
|
@ -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
|
@ -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
|
@ -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.
|
@ -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).
|
@ -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();
|
||||
}
|
Before Width: | Height: | Size: 405 KiB |
Before Width: | Height: | Size: 322 KiB |
Before Width: | Height: | Size: 296 KiB |
Before Width: | Height: | Size: 315 KiB |
Before Width: | Height: | Size: 128 KiB |
Before Width: | Height: | Size: 524 KiB |
Before Width: | Height: | Size: 238 KiB |
@ -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)
|
||||
#######################################
|
@ -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
|
@ -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'
|
@ -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;
|
||||
}
|
@ -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
|
@ -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']
|
||||
...
|
@ -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
|
@ -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
|
||||
|
@ -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).
|
@ -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();
|
||||
}
|
@ -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();
|
||||
}
|
Before Width: | Height: | Size: 405 KiB |
Before Width: | Height: | Size: 322 KiB |
Before Width: | Height: | Size: 296 KiB |
Before Width: | Height: | Size: 315 KiB |
Before Width: | Height: | Size: 63 KiB |
Before Width: | Height: | Size: 128 KiB |
Before Width: | Height: | Size: 524 KiB |
@ -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)
|
||||
#######################################
|
@ -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
|
@ -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'
|
@ -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;
|
||||
}
|
@ -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
|
@ -1,19 +1,17 @@
|
||||
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
|
||||
* 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,
|
||||
* 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
|
||||
* 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.
|
||||
|
72
src/library/arduino-sht/README.md
Normal 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)
|
442
src/library/arduino-sht/SHTSensor.cpp
Normal 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;
|
||||
}
|
||||
}
|
309
src/library/arduino-sht/SHTSensor.h
Normal 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 */
|
6
src/library/arduino-sht/arduino-sht.h
Normal file
@ -0,0 +1,6 @@
|
||||
#ifndef ARDUINO_SHT_H
|
||||
#define ARDUINO_SHT_H
|
||||
|
||||
#include "SHTSensor.h"
|
||||
|
||||
#endif
|
@ -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);
|
||||
}
|
@ -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);
|
||||
}
|
27
src/library/arduino-sht/examples/sht3xanalog/sht3xanalog.ino
Normal 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);
|
||||
}
|
29
src/library/arduino-sht/keywords.txt
Normal 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)
|
||||
#######################################
|
9
src/library/arduino-sht/library.properties
Normal 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
@ -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(); }
|
@ -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_ */
|
@ -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;
|
||||
}
|
@ -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_ */
|
@ -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;
|
||||
}
|
||||
|