SHT41 bug resolved. It now logs reading failures.
This commit is contained in:
parent
d3514f7d2b
commit
6c1941cc80
|
|
@ -28,6 +28,11 @@ public:
|
|||
bool writeRead(const std::vector<uint8_t>& tx, std::vector<uint8_t>& rx);
|
||||
bool write(const std::vector<uint8_t>& tx);
|
||||
|
||||
// For diagnostics: what this bus is actually pointed at. A silent sensor is
|
||||
// almost always the wrong bus or address, so error messages should name both.
|
||||
const std::string& device() const { return device_; }
|
||||
uint8_t address() const { return addr_; }
|
||||
|
||||
private:
|
||||
std::string device_;
|
||||
uint8_t addr_;
|
||||
|
|
|
|||
|
|
@ -5,6 +5,7 @@
|
|||
#include "fgc/sensors/Sht41Protocol.h"
|
||||
|
||||
#include <atomic>
|
||||
#include <ios>
|
||||
#include <chrono>
|
||||
#include <mutex>
|
||||
#include <thread>
|
||||
|
|
@ -36,11 +37,37 @@ struct Sht41EnvSensor::Impl {
|
|||
EnvSample latest;
|
||||
clock::time_point last_ok{};
|
||||
|
||||
// Consecutive failed reads. The transfers run every `period` forever, so the
|
||||
// failure is logged on the FIRST one only: a wrong bus would otherwise print
|
||||
// the same line every couple of seconds for the life of the process. Reset on
|
||||
// a good read, which also gives us a recovery message.
|
||||
long long fail_streak = 0;
|
||||
|
||||
// A silent sensor is nearly always the wrong bus or address, and neither
|
||||
// open() nor the I2C_SLAVE ioctl can tell you that - the ioctl only records
|
||||
// the target address, it never probes. This is the first point where the
|
||||
// absence of a device is actually observable, so it is where it gets said.
|
||||
void reportFailure(const char* what) {
|
||||
if (fail_streak++ > 0) return;
|
||||
LOG_ERROR << "SHT41: " << what << " at address 0x" << std::hex
|
||||
<< static_cast<int>(bus.address()) << std::dec << " on " << bus.device()
|
||||
<< " - check [Env] i2c_device/i2c_addr and the wiring"
|
||||
<< " (probe with: i2cdetect -l, then i2ctransfer -y <bus> w1@0x"
|
||||
<< std::hex << static_cast<int>(bus.address()) << std::dec << " 0x89)";
|
||||
LOG_ERROR << "SHT41: further read failures will not be logged until it responds";
|
||||
}
|
||||
|
||||
void readOnce() {
|
||||
if (!bus.write({kSht41CmdMeasureHighPrec})) return;
|
||||
if (!bus.write({kSht41CmdMeasureHighPrec})) {
|
||||
reportFailure("no response to the measure command");
|
||||
return;
|
||||
}
|
||||
std::this_thread::sleep_for(kConversionDelay);
|
||||
std::vector<uint8_t> rx(kSht41ResponseBytes);
|
||||
if (!bus.writeRead({}, rx)) return;
|
||||
if (!bus.writeRead({}, rx)) {
|
||||
reportFailure("command acknowledged but no measurement came back");
|
||||
return;
|
||||
}
|
||||
|
||||
auto reading = decodeSht41Measurement(rx);
|
||||
if (!reading) {
|
||||
|
|
@ -48,6 +75,11 @@ struct Sht41EnvSensor::Impl {
|
|||
return;
|
||||
}
|
||||
|
||||
if (fail_streak > 0) {
|
||||
LOG_INFO << "SHT41: responding again after " << fail_streak << " failed read(s)";
|
||||
fail_streak = 0;
|
||||
}
|
||||
|
||||
std::lock_guard<std::mutex> lock(mutex);
|
||||
latest.valid = true;
|
||||
latest.temp_c = reading->temp_c;
|
||||
|
|
@ -81,7 +113,11 @@ void Sht41EnvSensor::start() {
|
|||
std::this_thread::sleep_for(kSoftResetSettle);
|
||||
impl_->running = true;
|
||||
impl_->worker = std::thread([this] { impl_->run(); });
|
||||
LOG_INFO << "SHT41 env sensor started";
|
||||
// Deliberately not "started OK": opening the node proves nothing about the
|
||||
// sensor being there. The first read either succeeds quietly or logs why not.
|
||||
LOG_INFO << "SHT41 env sensor polling 0x" << std::hex << static_cast<int>(impl_->bus.address())
|
||||
<< std::dec << " on " << impl_->bus.device() << " every "
|
||||
<< impl_->period.count() << " ms";
|
||||
}
|
||||
|
||||
void Sht41EnvSensor::stop() {
|
||||
|
|
|
|||
Loading…
Reference in New Issue