diff --git a/platformio.ini b/platformio.ini index 7c63ad7ad..fe2f5e28a 100644 --- a/platformio.ini +++ b/platformio.ini @@ -181,6 +181,8 @@ lib_deps = dfrobot/DFRobot_BMM150@1.0.0 # renovate: datasource=custom.pio depName=Adafruit_TSL2561 packageName=adafruit/library/Adafruit TSL2561 adafruit/Adafruit TSL2561@1.1.2 + # renovate: datasource=custom.pio depName=BH1750_WE packageName=wollewald/BH1750_WE@^1.1.10 + wollewald/BH1750_WE@^1.1.10 ; (not included in native / portduino) [environmental_extra] diff --git a/src/detect/ScanI2C.h b/src/detect/ScanI2C.h index 2e602338c..e7bdf58c5 100644 --- a/src/detect/ScanI2C.h +++ b/src/detect/ScanI2C.h @@ -82,7 +82,8 @@ class ScanI2C BHI260AP, BMM150, TSL2561, - DRV2605 + DRV2605, + BH1750 } DeviceType; // typedef uint8_t DeviceAddress; diff --git a/src/detect/ScanI2CTwoWire.cpp b/src/detect/ScanI2CTwoWire.cpp index da2a57fee..59d93d74f 100644 --- a/src/detect/ScanI2CTwoWire.cpp +++ b/src/detect/ScanI2CTwoWire.cpp @@ -485,7 +485,25 @@ void ScanI2CTwoWire::scanPort(I2CPort port, uint8_t *address, uint8_t asize) SCAN_SIMPLE_CASE(LTR390UV_ADDR, LTR390UV, "LTR390UV", (uint8_t)addr.address); SCAN_SIMPLE_CASE(PCT2075_ADDR, PCT2075, "PCT2075", (uint8_t)addr.address); SCAN_SIMPLE_CASE(CST328_ADDR, CST328, "CST328", (uint8_t)addr.address); - SCAN_SIMPLE_CASE(LTR553ALS_ADDR, LTR553ALS, "LTR553ALS", (uint8_t)addr.address); + case LTR553ALS_ADDR: + registerValue = getRegisterValue(ScanI2CTwoWire::RegisterLocation(addr, 0x86), 1); // Part ID register + if (registerValue == 0x92) { // LTR553ALS Part ID + type = LTR553ALS; + logFoundDevice("LTR553ALS", (uint8_t)addr.address); + } else { + // Test BH1750 - send power on command + i2cBus->beginTransmission(addr.address); + i2cBus->write(0x01); // Power On command + uint8_t bh1750_error = i2cBus->endTransmission(); + if (bh1750_error == 0) { + type = BH1750; + logFoundDevice("BH1750", (uint8_t)addr.address); + } else { + LOG_INFO("Device found at address 0x%x was not able to be enumerated", (uint8_t)addr.address); + } + } + break; + SCAN_SIMPLE_CASE(BHI260AP_ADDR, BHI260AP, "BHI260AP", (uint8_t)addr.address); SCAN_SIMPLE_CASE(SCD4X_ADDR, SCD4X, "SCD4X", (uint8_t)addr.address); SCAN_SIMPLE_CASE(BMM150_ADDR, BMM150, "BMM150", (uint8_t)addr.address); diff --git a/src/modules/Telemetry/EnvironmentTelemetry.cpp b/src/modules/Telemetry/EnvironmentTelemetry.cpp index 2337af808..a923ab457 100644 --- a/src/modules/Telemetry/EnvironmentTelemetry.cpp +++ b/src/modules/Telemetry/EnvironmentTelemetry.cpp @@ -134,6 +134,10 @@ extern void drawCommonHeader(OLEDDisplay *display, int16_t x, int16_t y, const c #include "Sensor/TSL2561Sensor.h" #endif +#if __has_include() +#include "Sensor/BH1750Sensor.h" +#endif + #define FAILED_STATE_SENSOR_READ_MULTIPLIER 10 #define DISPLAY_RECEIVEID_MEASUREMENTS_ON_SCREEN true @@ -262,6 +266,9 @@ void EnvironmentTelemetryModule::i2cScanFinished(ScanI2C *i2cScanner) #if __has_include() addSensor(i2cScanner, ScanI2C::DeviceType::NAU7802); #endif +#if __has_include() + addSensor(i2cScanner, ScanI2C::DeviceType::BH1750); +#endif #endif } diff --git a/src/modules/Telemetry/Sensor/BH1750Sensor.cpp b/src/modules/Telemetry/Sensor/BH1750Sensor.cpp new file mode 100644 index 000000000..b8790dcd5 --- /dev/null +++ b/src/modules/Telemetry/Sensor/BH1750Sensor.cpp @@ -0,0 +1,54 @@ +#include "configuration.h" + +#if !MESHTASTIC_EXCLUDE_ENVIRONMENTAL_SENSOR && __has_include() + +#include "../mesh/generated/meshtastic/telemetry.pb.h" +#include "BH1750Sensor.h" +#include "TelemetrySensor.h" +#include + +#ifndef BH1750_SENSOR_MODE +#define BH1750_SENSOR_MODE BH1750Mode::CHM +#endif + +BH1750Sensor::BH1750Sensor() : TelemetrySensor(meshtastic_TelemetrySensorType_BH1750, "BH1750") {} + +bool BH1750Sensor::initDevice(TwoWire *bus, ScanI2C::FoundDevice *dev) +{ + LOG_INFO("Init sensor: %s with mode %d", sensorName, BH1750_SENSOR_MODE); + + bh1750 = BH1750_WE(bus, dev->address.address); + status = bh1750.init(); + if (!status) { + return status; + } + + bh1750.setMode(BH1750_SENSOR_MODE); + + initI2CSensor(); + return status; +} + +bool BH1750Sensor::getMetrics(meshtastic_Telemetry *measurement) +{ + + /* An OTH and OTH_2 measurement takes ~120 ms. I suggest to wait + 140 ms to be on the safe side. + An OTL measurement takes about 16 ms. I suggest to wait 20 ms + to be on the safe side. */ + if (BH1750_SENSOR_MODE == BH1750Mode::OTH || BH1750_SENSOR_MODE == BH1750Mode::OTH_2) { + bh1750.setMode(BH1750_SENSOR_MODE); + delay(140); // wait for measurement to be completed + } else if (BH1750_SENSOR_MODE == BH1750Mode::OTL) { + bh1750.setMode(BH1750_SENSOR_MODE); + delay(20); + } + + measurement->variant.environment_metrics.has_lux = true; + float lightIntensity = bh1750.getLux(); + + measurement->variant.environment_metrics.lux = lightIntensity; + return true; +} + +#endif diff --git a/src/modules/Telemetry/Sensor/BH1750Sensor.h b/src/modules/Telemetry/Sensor/BH1750Sensor.h new file mode 100644 index 000000000..d9a4ded95 --- /dev/null +++ b/src/modules/Telemetry/Sensor/BH1750Sensor.h @@ -0,0 +1,21 @@ +#pragma once +#include "configuration.h" + +#if !MESHTASTIC_EXCLUDE_ENVIRONMENTAL_SENSOR && __has_include() + +#include "../mesh/generated/meshtastic/telemetry.pb.h" +#include "TelemetrySensor.h" +#include + +class BH1750Sensor : public TelemetrySensor +{ + private: + BH1750_WE bh1750; + + public: + BH1750Sensor(); + virtual bool getMetrics(meshtastic_Telemetry *measurement) override; + virtual bool initDevice(TwoWire *bus, ScanI2C::FoundDevice *dev) override; +}; + +#endif