diff --git a/platformio.ini b/platformio.ini
index 217e75631..ea4de4db1 100644
--- a/platformio.ini
+++ b/platformio.ini
@@ -126,6 +126,7 @@ lib_deps =
mprograms/QMC5883LCompass@1.2.3
dfrobot/DFRobot_RTU@1.0.3
https://github.com/meshtastic/DFRobot_LarkWeatherStation#4de3a9cadef0f6a5220a8a906cf9775b02b0040d
+ https://github.com/DFRobot/DFRobot_RainfallSensor#38fea5e02b40a5430be6dab39a99a6f6347d667e
robtillaart/INA226@0.6.0
; Health Sensor Libraries
diff --git a/src/configuration.h b/src/configuration.h
index 2c77b55e3..6f5255ec9 100644
--- a/src/configuration.h
+++ b/src/configuration.h
@@ -145,6 +145,7 @@ along with this program. If not, see .
#define OPT3001_ADDR_ALT 0x44
#define MLX90632_ADDR 0x3A
#define DFROBOT_LARK_ADDR 0x42
+#define DFROBOT_RAIN_ADDR 0x1d
#define NAU7802_ADDR 0x2A
#define MAX30102_ADDR 0x57
#define MLX90614_ADDR_DEF 0x5A
diff --git a/src/detect/ScanI2C.h b/src/detect/ScanI2C.h
index 2561a8e17..faa94c7d3 100644
--- a/src/detect/ScanI2C.h
+++ b/src/detect/ScanI2C.h
@@ -66,6 +66,7 @@ class ScanI2C
CGRADSENS,
INA226,
NXP_SE050,
+ DFROBOT_RAIN,
} DeviceType;
// typedef uint8_t DeviceAddress;
diff --git a/src/detect/ScanI2CTwoWire.cpp b/src/detect/ScanI2CTwoWire.cpp
index a786f874d..880e5c131 100644
--- a/src/detect/ScanI2CTwoWire.cpp
+++ b/src/detect/ScanI2CTwoWire.cpp
@@ -84,23 +84,33 @@ ScanI2C::DeviceType ScanI2CTwoWire::probeOLED(ScanI2C::DeviceAddress addr) const
return o_probe;
}
uint16_t ScanI2CTwoWire::getRegisterValue(const ScanI2CTwoWire::RegisterLocation ®isterLocation,
- ScanI2CTwoWire::ResponseWidth responseWidth) const
+ ScanI2CTwoWire::ResponseWidth responseWidth, bool zeropad = false) const
{
uint16_t value = 0x00;
TwoWire *i2cBus = fetchI2CBus(registerLocation.i2cAddress);
i2cBus->beginTransmission(registerLocation.i2cAddress.address);
i2cBus->write(registerLocation.registerAddress);
+ if (zeropad) {
+ // Lark Commands need the argument list length in 2 bytes.
+ i2cBus->write((int)0);
+ i2cBus->write((int)0);
+ }
i2cBus->endTransmission();
delay(20);
i2cBus->requestFrom(registerLocation.i2cAddress.address, responseWidth);
- if (i2cBus->available() == 2) {
+ if (i2cBus->available() > 1) {
// Read MSB, then LSB
value = (uint16_t)i2cBus->read() << 8;
value |= i2cBus->read();
} else if (i2cBus->available()) {
value = i2cBus->read();
}
+ // Drain excess bytes
+ for (uint8_t i = 0; i < responseWidth - 1; i++) {
+ if (i2cBus->available())
+ i2cBus->read();
+ }
return value;
}
@@ -286,7 +296,7 @@ void ScanI2CTwoWire::scanPort(I2CPort port, uint8_t *address, uint8_t asize)
RESPONSE_PAYLOAD 0x01
RESPONSE_PAYLOAD+1 0x00
*/
- registerValue = getRegisterValue(ScanI2CTwoWire::RegisterLocation(addr, 0x05), 2);
+ registerValue = getRegisterValue(ScanI2CTwoWire::RegisterLocation(addr, 0x05), 6, true);
LOG_DEBUG("Register MFG_UID 05: 0x%x", registerValue);
if (registerValue == 0x5305) {
logFoundDevice("DFRobot Lark", (uint8_t)addr.address);
@@ -402,6 +412,7 @@ void ScanI2CTwoWire::scanPort(I2CPort port, uint8_t *address, uint8_t asize)
SCAN_SIMPLE_CASE(MLX90632_ADDR, MLX90632, "MLX90632", (uint8_t)addr.address);
SCAN_SIMPLE_CASE(NAU7802_ADDR, NAU7802, "NAU7802", (uint8_t)addr.address);
SCAN_SIMPLE_CASE(MAX1704X_ADDR, MAX17048, "MAX17048", (uint8_t)addr.address);
+ SCAN_SIMPLE_CASE(DFROBOT_RAIN_ADDR, DFROBOT_RAIN, "DFRobot Rain Gauge", (uint8_t)addr.address);
#ifdef HAS_TPS65233
SCAN_SIMPLE_CASE(TPS65233_ADDR, TPS65233, "TPS65233", (uint8_t)addr.address);
#endif
diff --git a/src/detect/ScanI2CTwoWire.h b/src/detect/ScanI2CTwoWire.h
index d0af7cde6..6988091ad 100644
--- a/src/detect/ScanI2CTwoWire.h
+++ b/src/detect/ScanI2CTwoWire.h
@@ -53,7 +53,7 @@ class ScanI2CTwoWire : public ScanI2C
concurrency::Lock lock;
- uint16_t getRegisterValue(const RegisterLocation &, ResponseWidth) const;
+ uint16_t getRegisterValue(const RegisterLocation &, ResponseWidth, bool) const;
DeviceType probeOLED(ScanI2C::DeviceAddress) const;
diff --git a/src/main.cpp b/src/main.cpp
index fc9d24e37..24fc71749 100644
--- a/src/main.cpp
+++ b/src/main.cpp
@@ -610,6 +610,7 @@ void setup()
scannerToSensorsMap(i2cScanner, ScanI2C::DeviceType::ICM20948, meshtastic_TelemetrySensorType_ICM20948);
scannerToSensorsMap(i2cScanner, ScanI2C::DeviceType::MAX30102, meshtastic_TelemetrySensorType_MAX30102);
scannerToSensorsMap(i2cScanner, ScanI2C::DeviceType::CGRADSENS, meshtastic_TelemetrySensorType_RADSENS);
+ scannerToSensorsMap(i2cScanner, ScanI2C::DeviceType::DFROBOT_RAIN, meshtastic_TelemetrySensorType_DFROBOT_RAIN);
i2cScanner.reset();
#endif
diff --git a/src/modules/Telemetry/EnvironmentTelemetry.cpp b/src/modules/Telemetry/EnvironmentTelemetry.cpp
index fe1d0d2a9..1af6347f2 100644
--- a/src/modules/Telemetry/EnvironmentTelemetry.cpp
+++ b/src/modules/Telemetry/EnvironmentTelemetry.cpp
@@ -27,6 +27,7 @@
#include "Sensor/BMP280Sensor.h"
#include "Sensor/BMP3XXSensor.h"
#include "Sensor/CGRadSensSensor.h"
+#include "Sensor/DFRobotGravitySensor.h"
#include "Sensor/DFRobotLarkSensor.h"
#include "Sensor/LPS22HBSensor.h"
#include "Sensor/MCP9808Sensor.h"
@@ -56,6 +57,7 @@ RCWL9620Sensor rcwl9620Sensor;
AHT10Sensor aht10Sensor;
MLX90632Sensor mlx90632Sensor;
DFRobotLarkSensor dfRobotLarkSensor;
+DFRobotGravitySensor dfRobotGravitySensor;
NAU7802Sensor nau7802Sensor;
BMP3XXSensor bmp3xxSensor;
CGRadSensSensor cgRadSens;
@@ -115,6 +117,8 @@ int32_t EnvironmentTelemetryModule::runOnce()
#elif !MESHTASTIC_EXCLUDE_ENVIRONMENTAL_SENSOR_EXTERNAL
if (dfRobotLarkSensor.hasSensor())
result = dfRobotLarkSensor.runOnce();
+ if (dfRobotGravitySensor.hasSensor())
+ result = dfRobotGravitySensor.runOnce();
if (bmp085Sensor.hasSensor())
result = bmp085Sensor.runOnce();
if (bmp280Sensor.hasSensor())
@@ -368,6 +372,10 @@ bool EnvironmentTelemetryModule::getEnvironmentTelemetry(meshtastic_Telemetry *m
valid = valid && dfRobotLarkSensor.getMetrics(m);
hasSensor = true;
}
+ if (dfRobotGravitySensor.hasSensor()) {
+ valid = valid && dfRobotGravitySensor.getMetrics(m);
+ hasSensor = true;
+ }
if (sht31Sensor.hasSensor()) {
valid = valid && sht31Sensor.getMetrics(m);
hasSensor = true;
@@ -569,6 +577,11 @@ AdminMessageHandleResult EnvironmentTelemetryModule::handleAdminMessageForModule
if (result != AdminMessageHandleResult::NOT_HANDLED)
return result;
}
+ if (dfRobotGravitySensor.hasSensor()) {
+ result = dfRobotGravitySensor.handleAdminMessage(mp, request, response);
+ if (result != AdminMessageHandleResult::NOT_HANDLED)
+ return result;
+ }
if (sht31Sensor.hasSensor()) {
result = sht31Sensor.handleAdminMessage(mp, request, response);
if (result != AdminMessageHandleResult::NOT_HANDLED)
diff --git a/src/modules/Telemetry/Sensor/DFRobotGravitySensor.cpp b/src/modules/Telemetry/Sensor/DFRobotGravitySensor.cpp
new file mode 100644
index 000000000..c7fa29966
--- /dev/null
+++ b/src/modules/Telemetry/Sensor/DFRobotGravitySensor.cpp
@@ -0,0 +1,44 @@
+#include "configuration.h"
+
+#if !MESHTASTIC_EXCLUDE_ENVIRONMENTAL_SENSOR
+
+#include "../mesh/generated/meshtastic/telemetry.pb.h"
+#include "DFRobotGravitySensor.h"
+#include "TelemetrySensor.h"
+#include
+#include
+
+DFRobotGravitySensor::DFRobotGravitySensor() : TelemetrySensor(meshtastic_TelemetrySensorType_DFROBOT_RAIN, "DFROBOT_RAIN") {}
+
+int32_t DFRobotGravitySensor::runOnce()
+{
+ LOG_INFO("Init sensor: %s", sensorName);
+ if (!hasSensor()) {
+ return DEFAULT_SENSOR_MINIMUM_WAIT_TIME_BETWEEN_READS;
+ }
+
+ gravity = DFRobot_RainfallSensor_I2C(nodeTelemetrySensorsMap[sensorType].second);
+ status = gravity.begin();
+
+ return initI2CSensor();
+}
+
+void DFRobotGravitySensor::setup()
+{
+ LOG_DEBUG("%s VID: %x, PID: %x, Version: %s", sensorName, gravity.vid, gravity.pid, gravity.getFirmwareVersion().c_str());
+}
+
+bool DFRobotGravitySensor::getMetrics(meshtastic_Telemetry *measurement)
+{
+ measurement->variant.environment_metrics.has_rainfall_1h = true;
+ measurement->variant.environment_metrics.has_rainfall_24h = true;
+
+ measurement->variant.environment_metrics.rainfall_1h = gravity.getRainfall(1);
+ measurement->variant.environment_metrics.rainfall_24h = gravity.getRainfall(24);
+
+ LOG_INFO("Rain 1h: %f mm", measurement->variant.environment_metrics.rainfall_1h);
+ LOG_INFO("Rain 24h: %f mm", measurement->variant.environment_metrics.rainfall_24h);
+ return true;
+}
+
+#endif
\ No newline at end of file
diff --git a/src/modules/Telemetry/Sensor/DFRobotGravitySensor.h b/src/modules/Telemetry/Sensor/DFRobotGravitySensor.h
new file mode 100644
index 000000000..8bd7335b5
--- /dev/null
+++ b/src/modules/Telemetry/Sensor/DFRobotGravitySensor.h
@@ -0,0 +1,29 @@
+#pragma once
+
+#ifndef _MT_DFROBOTGRAVITYSENSOR_H
+#define _MT_DFROBOTGRAVITYSENSOR_H
+#include "configuration.h"
+
+#if !MESHTASTIC_EXCLUDE_ENVIRONMENTAL_SENSOR
+
+#include "../mesh/generated/meshtastic/telemetry.pb.h"
+#include "TelemetrySensor.h"
+#include
+#include
+
+class DFRobotGravitySensor : public TelemetrySensor
+{
+ private:
+ DFRobot_RainfallSensor_I2C gravity = DFRobot_RainfallSensor_I2C(nodeTelemetrySensorsMap[sensorType].second);
+
+ protected:
+ virtual void setup() override;
+
+ public:
+ DFRobotGravitySensor();
+ virtual int32_t runOnce() override;
+ virtual bool getMetrics(meshtastic_Telemetry *measurement) override;
+};
+
+#endif
+#endif
\ No newline at end of file