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)