DeterministicESPAsyncWebServer v6.27.1
Zero-allocation, bounded-execution async HTTP server for ESP32
Loading...
Searching...
No Matches
sht3x.cpp
Go to the documentation of this file.
1// Copyright (C) 2026 Douglas Quigg (dstroy0) <dquigg123@gmail.com>
2// SPDX-License-Identifier: AGPL-3.0-or-later
3
4/**
5 * @file sht3x.cpp
6 * @brief Sensirion SHT3x temperature / humidity codec - implementation. See sht3x.h.
7 */
8
10#include "ServerConfig.h"
11
12#if DETWS_ENABLE_SHT3X
13
14uint8_t sht3x_crc8(const uint8_t *data, size_t len)
15{
16 uint8_t crc = 0xFF; // Sensirion CRC-8: poly 0x31, init 0xFF, MSB-first, no final XOR
17 for (size_t i = 0; i < len; i++)
18 {
19 crc ^= data[i];
20 for (int b = 0; b < 8; b++)
21 crc = (crc & 0x80) ? (uint8_t)((crc << 1) ^ 0x31) : (uint8_t)(crc << 1);
22 }
23 return crc;
24}
25
26int32_t sht3x_temp_mc(uint16_t raw)
27{
28 // T[C] = -45 + 175 * raw / 65535, in milli-degrees (64-bit to avoid overflow).
29 return (int32_t)(-45000 + (int64_t)175000 * raw / 65535);
30}
31
32int32_t sht3x_rh_mpct(uint16_t raw)
33{
34 int32_t v = (int32_t)((int64_t)100000 * raw / 65535); // RH[%] = 100 * raw / 65535
35 return v > 100000 ? 100000 : v;
36}
37
38bool sht3x_parse(const uint8_t resp[6], int32_t *temp_mc, int32_t *rh_mpct)
39{
40 if (!resp || sht3x_crc8(resp, 2) != resp[2] || sht3x_crc8(resp + 3, 2) != resp[5])
41 return false;
42 uint16_t traw = (uint16_t)(((uint16_t)resp[0] << 8) | resp[1]);
43 uint16_t hraw = (uint16_t)(((uint16_t)resp[3] << 8) | resp[4]);
44 if (temp_mc)
45 *temp_mc = sht3x_temp_mc(traw);
46 if (rh_mpct)
47 *rh_mpct = sht3x_rh_mpct(hraw);
48 return true;
49}
50
51// ---------------------------------------------------------------------------
52// I2C binding
53// ---------------------------------------------------------------------------
54
55#if defined(ARDUINO)
56
57#include "services/i2c.h"
58#include <Arduino.h>
59#include <Wire.h>
60
61namespace
62{
63// All SHT3x I2C-binding state, owned by one instance (internal linkage): the device address,
64// so it is one named owner, unreachable from any other translation unit.
65struct Sht3xCtx
66{
67 uint8_t addr = DETWS_SHT3X_I2C_ADDR;
68};
69Sht3xCtx s_sht;
70
71bool send_cmd(uint16_t cmd)
72{
73 Wire.beginTransmission(s_sht.addr);
74 Wire.write((uint8_t)(cmd >> 8));
75 Wire.write((uint8_t)(cmd & 0xFF));
76 return Wire.endTransmission() == 0;
77}
78} // namespace
79
80bool sht3x_begin(uint8_t addr)
81{
82 s_sht.addr = addr ? addr : (uint8_t)DETWS_SHT3X_I2C_ADDR;
84 bool ok = send_cmd(SHT3X_CMD_SOFT_RESET);
85 delay(2); // soft reset completes in < 1.5 ms
86 return ok;
87}
88
89bool sht3x_read(int32_t *temp_mc, int32_t *rh_mpct)
90{
91 if (!send_cmd(SHT3X_CMD_SINGLE_HIGH))
92 return false;
93 delay(20); // a high-repeatability measurement completes in < 15 ms
94 if (Wire.requestFrom((int)s_sht.addr, 6) != 6)
95 return false;
96 uint8_t r[6];
97 for (int i = 0; i < 6; i++)
98 r[i] = (uint8_t)Wire.read();
99 return sht3x_parse(r, temp_mc, rh_mpct);
100}
101
102#else // host build: no I2C. The CRC + conversion above are host-tested.
103
104bool sht3x_begin(uint8_t)
105{
106 return false;
107}
108bool sht3x_read(int32_t *, int32_t *)
109{
110 return false;
111}
112
113#endif // ARDUINO
114
115#endif // DETWS_ENABLE_SHT3X
User-facing configuration for DeterministicESPAsyncWebServer.
#define DETWS_SHT3X_I2C_ADDR
I2C address of the SHT3x (0x44 with ADDR low; 0x45 with ADDR high).
The one owner of the shared I2C bus bring-up for the peripheral drivers.
void detws_i2c_begin()
Bring up the shared I2C bus on DETWS_I2C_SDA_PIN / DETWS_I2C_SCL_PIN (-1 = default).
Definition i2c.h:33
Sensirion SHT3x temperature / humidity sensor codec (DETWS_ENABLE_SHT3X).
int32_t sht3x_rh_mpct(uint16_t raw)
Convert a raw 16-bit humidity tick to milli-percent relative humidity (0..100000).
bool sht3x_parse(const uint8_t resp[6], int32_t *temp_mc, int32_t *rh_mpct)
Decode a six-byte single-shot response (T msb/lsb/crc, RH msb/lsb/crc). Verifies both CRC-8 words,...
#define SHT3X_CMD_SOFT_RESET
soft reset
Definition sht3x.h:36
int32_t sht3x_temp_mc(uint16_t raw)
Convert a raw 16-bit temperature tick to milli-degrees Celsius.
bool sht3x_begin(uint8_t addr)
Soft-reset the SHT3x at addr over I2C.
bool sht3x_read(int32_t *temp_mc, int32_t *rh_mpct)
Trigger a single-shot high-repeatability measurement, read + verify the six bytes,...
#define SHT3X_CMD_SINGLE_HIGH
high repeatability, no clock stretching
Definition sht3x.h:33
uint8_t sht3x_crc8(const uint8_t *data, size_t len)
Sensirion CRC-8 (poly 0x31, init 0xFF) over len bytes.