From 7c17e489c207ab5464af5d5455e7c376cbfeaa1b Mon Sep 17 00:00:00 2001 From: oscgonfer Date: Sun, 14 Jun 2026 13:45:15 +0200 Subject: [PATCH] Fixes on 0x69 address detection * Change SEN5X detection method, using class itself * MPU6050 register check * BMX160 default removed --- src/detect/ScanI2CTwoWire.cpp | 94 +++++++++----------- src/modules/Telemetry/Sensor/SEN5XSensor.cpp | 26 ++++++ src/modules/Telemetry/Sensor/SEN5XSensor.h | 1 + 3 files changed, 70 insertions(+), 51 deletions(-) diff --git a/src/detect/ScanI2CTwoWire.cpp b/src/detect/ScanI2CTwoWire.cpp index 5a9ec9a65..af3ff44dc 100644 --- a/src/detect/ScanI2CTwoWire.cpp +++ b/src/detect/ScanI2CTwoWire.cpp @@ -137,45 +137,52 @@ bool ScanI2CTwoWire::i2cCommandResponseLength(ScanI2C::DeviceAddress addr, uint1 } #if HAS_TELEMETRY && !MESHTASTIC_EXCLUDE_AIR_QUALITY_SENSOR +#include "../modules/Telemetry/Sensor/SEN5XSensor.h" +bool probeSEN5X(TwoWire *i2cBus, uint8_t address, ScanI2C::I2CPort port) +{ + SEN5XSensor sen5xsensor = SEN5XSensor(); + return sen5xsensor.probe(i2cBus, address, port); +} + // FIXME Move to a separate file for detection of sensors that require more complex interactions? // For SEN5X detection // Note, this code needs to be called before setting the I2C bus speed // for the screen at high speed. The speed needs to be at 100kHz, otherwise // detection will not work -String readSEN5xProductName(TwoWire *i2cBus, uint8_t address) -{ - uint8_t cmd[] = {0xD0, 0x14}; - uint8_t response[48] = {0}; +// String readSEN5xProductName(TwoWire *i2cBus, uint8_t address) +// { +// uint8_t cmd[] = {0xD0, 0x14}; +// uint8_t response[48] = {0}; - i2cBus->beginTransmission(address); - i2cBus->write(cmd, 2); - if (i2cBus->endTransmission() != 0) - return ""; +// i2cBus->beginTransmission(address); +// i2cBus->write(cmd, 2); +// if (i2cBus->endTransmission() != 0) +// return ""; - delay(20); - if (i2cBus->requestFrom(address, (uint8_t)48) != 48) - return ""; +// delay(20); +// if (i2cBus->requestFrom(address, (uint8_t)48) != 48) +// return ""; - for (int i = 0; i < 48 && i2cBus->available(); ++i) { - response[i] = i2cBus->read(); - } +// for (int i = 0; i < 48 && i2cBus->available(); ++i) { +// response[i] = i2cBus->read(); +// } - char productName[33] = {0}; - int j = 0; - for (int i = 0; i < 48 && j < 32; i += 3) { - if (response[i] >= 32 && response[i] <= 126) - productName[j++] = response[i]; - else - break; +// char productName[33] = {0}; +// int j = 0; +// for (int i = 0; i < 48 && j < 32; i += 3) { +// if (response[i] >= 32 && response[i] <= 126) +// productName[j++] = response[i]; +// else +// break; - if (response[i + 1] >= 32 && response[i + 1] <= 126) - productName[j++] = response[i + 1]; - else - break; - } +// if (response[i + 1] >= 32 && response[i + 1] <= 126) +// productName[j++] = response[i + 1]; +// else +// break; +// } - return String(productName); -} +// return String(productName); +// } #endif #if HAS_TELEMETRY && !MESHTASTIC_EXCLUDE_ENVIRONMENTAL_SENSOR @@ -789,33 +796,18 @@ void ScanI2CTwoWire::scanPort(I2CPort port, uint8_t *address, uint8_t asize) type = ICM42607P; logFoundDevice("ICM-42607-P", (uint8_t)addr.address); break; - } -#if HAS_TELEMETRY && !MESHTASTIC_EXCLUDE_AIR_QUALITY_SENSOR - String prod = ""; - prod = readSEN5xProductName(i2cBus, addr.address); - if (prod.startsWith("SEN55")) { - type = SEN5X; - logFoundDevice("Sensirion SEN55", addr.address); - break; - } else if (prod.startsWith("SEN54")) { - type = SEN5X; - logFoundDevice("Sensirion SEN54", addr.address); - break; - } else if (prod.startsWith("SEN50")) { - type = SEN5X; - logFoundDevice("Sensirion SEN50", addr.address); - break; - } -#endif - if (addr.address == BMX160_ADDR) { - type = BMX160; - logFoundDevice("BMX160", (uint8_t)addr.address); - break; - } else { + } else if (registerValue == 0x68) { // WHO_AM_I from datasheet type = MPU6050; logFoundDevice("MPU6050", (uint8_t)addr.address); break; } +#if HAS_TELEMETRY && !MESHTASTIC_EXCLUDE_AIR_QUALITY_SENSOR + if (probeSEN5X(i2cBus, addr.address, port)) { + type = SEN5X; + logFoundDevice("SEN5X", addr.address); + break; + } +#endif } break; diff --git a/src/modules/Telemetry/Sensor/SEN5XSensor.cpp b/src/modules/Telemetry/Sensor/SEN5XSensor.cpp index 2feac6d5f..b638bf47f 100644 --- a/src/modules/Telemetry/Sensor/SEN5XSensor.cpp +++ b/src/modules/Telemetry/Sensor/SEN5XSensor.cpp @@ -76,6 +76,32 @@ bool SEN5XSensor::findModel() return true; } +bool SEN5XSensor::probe(TwoWire *bus, uint8_t address, ScanI2C::I2CPort port) +{ + LOG_INFO("SEN5X: probing sensor"); + + _bus = bus; + _address = address; +#ifdef SEN5X_I2C_CLOCK_SPEED + _port = port; + reClockI2C.setup(_bus, _port); +#endif /* SEN5X_I2C_CLOCK_SPEED */ + + delay(50); // without this there is an error on the deviceReset function + + if (!sendCommand(SEN5X_RESET)) { + LOG_ERROR("SEN5X: error resetting device"); + return false; + } + delay(200); // From Sensirion Datasheet + + if (!findModel()) { + LOG_ERROR("SEN5X: error finding sensor model"); + return false; + } + return true; +} + bool SEN5XSensor::sendCommand(uint16_t command) { uint8_t nothing; diff --git a/src/modules/Telemetry/Sensor/SEN5XSensor.h b/src/modules/Telemetry/Sensor/SEN5XSensor.h index ef5ad5c29..9fb25fdd6 100644 --- a/src/modules/Telemetry/Sensor/SEN5XSensor.h +++ b/src/modules/Telemetry/Sensor/SEN5XSensor.h @@ -153,6 +153,7 @@ See: https://sensirion.com/resource/application_note/low_power_mode/sen5x public: SEN5XSensor(); + bool probe(TwoWire *bus, uint8_t address, ScanI2C::I2CPort port); virtual bool initDevice(TwoWire *bus, ScanI2C::FoundDevice *dev) override; virtual bool getMetrics(meshtastic_Telemetry *measurement) override;