From 008f917c589be6092f8750b807fb1b2816dbbde9 Mon Sep 17 00:00:00 2001 From: "Justin E. Mann" Date: Wed, 27 Nov 2024 14:20:01 -0700 Subject: [PATCH] add library, do initial work to add support as an environmental telemetry sensor --- platformio.ini | 1 + src/configuration.h | 1 + src/detect/ScanI2C.h | 3 +- src/detect/ScanI2CTwoWire.cpp | 32 +++++++++- src/mesh/generated/meshtastic/telemetry.pb.h | 10 +++- .../Telemetry/EnvironmentTelemetry.cpp | 17 ++++++ .../Telemetry/Sensor/RAK12035VBSensor.cpp | 59 +++++++++++++++++++ .../Telemetry/Sensor/RAK12035VBSensor.h | 28 +++++++++ variants/rak4631/variant.h | 21 +++++++ 9 files changed, 168 insertions(+), 4 deletions(-) create mode 100644 src/modules/Telemetry/Sensor/RAK12035VBSensor.cpp create mode 100644 src/modules/Telemetry/Sensor/RAK12035VBSensor.h diff --git a/platformio.ini b/platformio.ini index 982848f41..eeb46df01 100644 --- a/platformio.ini +++ b/platformio.ini @@ -162,3 +162,4 @@ lib_deps = mprograms/QMC5883LCompass@1.2.3 dfrobot/DFRobot_RTU@1.0.3 https://github.com/meshtastic/DFRobot_LarkWeatherStation#4de3a9cadef0f6a5220a8a906cf9775b02b0040d + beegee-tokyo/RAK12035_SoilMoisture@^1.0.3 diff --git a/src/configuration.h b/src/configuration.h index 2e81557b1..b721d34ac 100644 --- a/src/configuration.h +++ b/src/configuration.h @@ -149,6 +149,7 @@ along with this program. If not, see . #define MAX30102_ADDR 0x57 #define MLX90614_ADDR_DEF 0x5A #define CGRADSENS_ADDR 0x66 +#define RAK12035VB_ADDR 0x20 // ----------------------------------------------------------------------------- // ACCELEROMETER diff --git a/src/detect/ScanI2C.h b/src/detect/ScanI2C.h index f4516458b..8bffea634 100644 --- a/src/detect/ScanI2C.h +++ b/src/detect/ScanI2C.h @@ -64,7 +64,8 @@ class ScanI2C MAX30102, TPS65233, MPR121KB, - CGRADSENS + CGRADSENS, + RAK12035VB } DeviceType; // typedef uint8_t DeviceAddress; diff --git a/src/detect/ScanI2CTwoWire.cpp b/src/detect/ScanI2CTwoWire.cpp index 55f13c5a0..cfbb32c55 100644 --- a/src/detect/ScanI2CTwoWire.cpp +++ b/src/detect/ScanI2CTwoWire.cpp @@ -312,7 +312,13 @@ void ScanI2CTwoWire::scanPort(I2CPort port, uint8_t *address, uint8_t asize) type = INA219; } break; - case INA3221_ADDR: + + + + + + + case INA3221_ADDR: // (0x40) can be INA3221, RAK12500 or DFROBOT Lark weather station registerValue = getRegisterValue(ScanI2CTwoWire::RegisterLocation(addr, 0xFE), 2); LOG_DEBUG("Register MFG_UID FE: 0x%x", registerValue); if (registerValue == 0x5449) { @@ -337,6 +343,28 @@ void ScanI2CTwoWire::scanPort(I2CPort port, uint8_t *address, uint8_t asize) // else: probably a RAK12500/UBLOX GPS on I2C } break; + + case RAK12035VB_ADDR: // (0x20) can be RAK12023VB Soil Sensor or TCA9535 I2C expander + + // check if it is a RAK12035, if not can assume it is a TCA9535 I2C expander + registerValue = getRegisterValue(ScanI2CTwoWire::RegisterLocation(addr, 0x20), 1); // get ID + if (registerValue == 0xC0) { + type = RAK12035VB; + LOG_INFO("RAK12023VB Soil Sensor found\n"); + } else { + type = TCA9535; + LOG_INFO("TCA9535 I2C expander found\n"); + } + break; + + + + + + + + + case MCP9808_ADDR: // We need to check for STK8BAXX first, since register 0x07 is new data flag for the z-axis and can produce some // weird result. and register 0x00 doesn't seems to be colliding with MCP9808 and LIS3DH chips. @@ -437,7 +465,7 @@ void ScanI2CTwoWire::scanPort(I2CPort port, uint8_t *address, uint8_t asize) break; SCAN_SIMPLE_CASE(LSM6DS3_ADDR, LSM6DS3, "LSM6DS3 accelerometer found at address 0x%x", (uint8_t)addr.address); - SCAN_SIMPLE_CASE(TCA9535_ADDR, TCA9535, "TCA9535 I2C expander found"); + //SCAN_SIMPLE_CASE(TCA9535_ADDR, TCA9535, "TCA9535 I2C expander found"); SCAN_SIMPLE_CASE(TCA9555_ADDR, TCA9555, "TCA9555 I2C expander found"); SCAN_SIMPLE_CASE(VEML7700_ADDR, VEML7700, "VEML7700 light sensor found"); SCAN_SIMPLE_CASE(TSL25911_ADDR, TSL2591, "TSL2591 light sensor found"); diff --git a/src/mesh/generated/meshtastic/telemetry.pb.h b/src/mesh/generated/meshtastic/telemetry.pb.h index 874eef60f..eca192397 100644 --- a/src/mesh/generated/meshtastic/telemetry.pb.h +++ b/src/mesh/generated/meshtastic/telemetry.pb.h @@ -79,7 +79,9 @@ typedef enum _meshtastic_TelemetrySensorType { /* SCD40/SCD41 CO2, humidity, temperature sensor */ meshtastic_TelemetrySensorType_SCD4X = 32, /* ClimateGuard RadSens, radiation, Geiger-Muller Tube */ - meshtastic_TelemetrySensorType_RADSENS = 33 + meshtastic_TelemetrySensorType_RADSENS = 33, + /* RAK12023VB IO Extender and RAK12035VB Soil MoistureMonitor */ + meshtastic_TelemetrySensorType_RAK12035VB = 34 } meshtastic_TelemetrySensorType; /* Struct definitions */ @@ -104,6 +106,12 @@ typedef struct _meshtastic_DeviceMetrics { /* Weather station or other environmental metrics */ typedef struct _meshtastic_EnvironmentMetrics { + /* Soil moisture measured */ + bool has_soil_moisture; + uint16_t soil_moisture; + /* Soil temperature measured */ + bool has_soil_temperature; + double soil_temperature; /* Temperature measured */ bool has_temperature; float temperature; diff --git a/src/modules/Telemetry/EnvironmentTelemetry.cpp b/src/modules/Telemetry/EnvironmentTelemetry.cpp index 92d964f7d..d242f0904 100644 --- a/src/modules/Telemetry/EnvironmentTelemetry.cpp +++ b/src/modules/Telemetry/EnvironmentTelemetry.cpp @@ -39,6 +39,7 @@ #include "Sensor/T1000xSensor.h" #include "Sensor/TSL2591Sensor.h" #include "Sensor/VEML7700Sensor.h" +#include "Sensor/RAK12035VBSensor.h" BMP085Sensor bmp085Sensor; BMP280Sensor bmp280Sensor; @@ -58,6 +59,7 @@ MLX90632Sensor mlx90632Sensor; DFRobotLarkSensor dfRobotLarkSensor; NAU7802Sensor nau7802Sensor; BMP3XXSensor bmp3xxSensor; +RAK12035VBSensor rak12035vbSensor; #ifdef T1000X_SENSOR_EN T1000xSensor t1000xSensor; #endif @@ -151,6 +153,8 @@ int32_t EnvironmentTelemetryModule::runOnce() result = max17048Sensor.runOnce(); if (cgRadSens.hasSensor()) result = cgRadSens.runOnce(); + if (rak12035vbSensor.hasSensor()) + result = rak12035vbSensor.runOnce(); #endif } return result; @@ -407,6 +411,10 @@ bool EnvironmentTelemetryModule::getEnvironmentTelemetry(meshtastic_Telemetry *m valid = valid && cgRadSens.getMetrics(m); hasSensor = true; } + if (rak12035vbSensor.hasSensor()){ + valid = valid && rak12035vbSensor.getMetrics(m); + hasSensor = true; + } #endif return valid && hasSensor; @@ -454,6 +462,10 @@ bool EnvironmentTelemetryModule::sendTelemetry(NodeNum dest, bool phoneOnly) m.variant.environment_metrics.barometric_pressure, m.variant.environment_metrics.current, m.variant.environment_metrics.gas_resistance, m.variant.environment_metrics.relative_humidity, m.variant.environment_metrics.temperature); + + LOG_INFO("(Sending): soil_temperature=%u, soil_moisture=%u\n", + m.variant.environment_metrics.soil_temperature, m.variant.environment_metrics.soil_moisture); + LOG_INFO("Send: voltage=%f, IAQ=%d, distance=%f, lux=%f", m.variant.environment_metrics.voltage, m.variant.environment_metrics.iaq, m.variant.environment_metrics.distance, m.variant.environment_metrics.lux); @@ -609,6 +621,11 @@ AdminMessageHandleResult EnvironmentTelemetryModule::handleAdminMessageForModule if (result != AdminMessageHandleResult::NOT_HANDLED) return result; } + if (rak12035vbSensor.hasSensor()){ + result = rak12035vbSensor.handleAdminMessage(mp, request, response); + if (result != AdminMessageHandleResult::NOT_HANDLED) + return result; + } return result; } diff --git a/src/modules/Telemetry/Sensor/RAK12035VBSensor.cpp b/src/modules/Telemetry/Sensor/RAK12035VBSensor.cpp new file mode 100644 index 000000000..4d336b0c2 --- /dev/null +++ b/src/modules/Telemetry/Sensor/RAK12035VBSensor.cpp @@ -0,0 +1,59 @@ +#include "configuration.h" + +#if !MESHTASTIC_EXCLUDE_ENVIRONMENTAL_SENSOR + +#include "../mesh/generated/meshtastic/telemetry.pb.h" +#include "RAK12035VBSensor.h" + +RAK12035VBSensor::RAK12035VBSensor() : TelemetrySensor(meshtastic_TelemetrySensorType_RAK12035VB, "RAK12035VB_SOIL") {} + +int32_t RAK12035VBSensor::runOnce() +{ + LOG_INFO("Init sensor: %s\n", sensorName); + if (!hasSensor()) { + return DEFAULT_SENSOR_MINIMUM_WAIT_TIME_BETWEEN_READS; + } + + sensor.begin(); + // Get sensor firmware version + uint8_t data = 0; + sensor.get_sensor_version(&data); + LOG_INFO("Sensor Firmware version: %i\n", data); + + if ( data != 0) + { + LOG_DEBUG("RAK12035VBSensor Init Succeed\n"); + status = true; + } else { + LOG_ERROR("RAK12035VBSensor Init Failed\n"); + status = false; + } + return initI2CSensor(); +} + +void RAK12035VBSensor::setup() { + // Set the calibration values + // Reading the saved calibration values from the sensor. + uint16_t zero_val = 73; + uint16_t hundred_val = 250; + sensor.get_dry_cal(&zero_val); + sensor.get_wet_cal(&hundred_val); + LOG_INFO("Dry calibration value is %d\n", zero_val); + LOG_INFO("Wet calibration value is %d\n", hundred_val); +} + +bool RAK12035VBSensor::getMetrics(meshtastic_Telemetry *measurement) +{ + measurement->variant.environment_metrics.has_soil_temperature = true; + measurement->variant.environment_metrics.has_soil_moisture = true; + + uint8_t moisture = 0; + uint16_t temp = 0; + sensor.get_sensor_moisture(&moisture); + sensor.get_sensor_temperature(&temp); + measurement->variant.environment_metrics.soil_temperature = (double)temp/10.0; + measurement->variant.environment_metrics.soil_moisture = moisture; + return true; +} + +#endif \ No newline at end of file diff --git a/src/modules/Telemetry/Sensor/RAK12035VBSensor.h b/src/modules/Telemetry/Sensor/RAK12035VBSensor.h new file mode 100644 index 000000000..be5d0c04b --- /dev/null +++ b/src/modules/Telemetry/Sensor/RAK12035VBSensor.h @@ -0,0 +1,28 @@ +#pragma once + +#ifndef _MT_RAK12035VBSENSOR_H +#define _MT_RAK12035VBSENSOR_H +#include "configuration.h" + +#if !MESHTASTIC_EXCLUDE_ENVIRONMENTAL_SENSOR + +#include "../mesh/generated/meshtastic/telemetry.pb.h" +#include "TelemetrySensor.h" +#include + +class RAK12035VBSensor : public TelemetrySensor +{ + private: + RAK12035 sensor; + + protected: + virtual void setup() override; + + public: + RAK12035VBSensor(); + virtual int32_t runOnce() override; + virtual bool getMetrics(meshtastic_Telemetry *measurement) override; +}; + +#endif +#endif \ No newline at end of file diff --git a/variants/rak4631/variant.h b/variants/rak4631/variant.h index bc5541336..5e555905e 100644 --- a/variants/rak4631/variant.h +++ b/variants/rak4631/variant.h @@ -158,6 +158,27 @@ static const uint8_t SCK = PIN_SPI_SCK; #define EXTERNAL_FLASH_DEVICES IS25LP080D #define EXTERNAL_FLASH_USE_QSPI +/* + * WisBlock Base GPIO definitions + */ + #define WB_IO1 (17) // SLOT_A SLOT_B + #define WB_IO2 (34) // SLOT_A SLOT_B + #define WB_IO3 (21) // SLOT_C + #define WB_IO4 (4) // SLOT_C + #define WB_IO5 (9) // SLOT_D + #define WB_IO6 (10) // SLOT_D + #define WB_SW1 (33) // IO_SLOT + #define WB_A0 (5) // IO_SLOT + #define WB_A1 (31) // IO_SLOT + #define WB_I2C1_SDA (13) // SENSOR_SLOT IO_SLOT + #define WB_I2C1_SCL (14) // SENSOR_SLOT IO_SLOT + #define WB_I2C2_SDA (24) // IO_SLOT + #define WB_I2C2_SCL (25) // IO_SLOT + #define WB_SPI_CS (26) // IO_SLOT + #define WB_SPI_CLK (3) // IO_SLOT + #define WB_SPI_MISO (29) // IO_SLOT + #define WB_SPI_MOSI (30) // IO_SLOT + /* @note RAK5005-O GPIO mapping to RAK4631 GPIO ports RAK5005-O <-> nRF52840 IO1 <-> P0.17 (Arduino GPIO number 17)