Skip to content

Commit 0c41f90

Browse files
committed
[WIP] Add RAK12035VB Soil Moisture Sensor support
Introduce the RAK12035 sensor as an environmental telemetry sensor, including necessary calibration checks and default values. Update relevant files to integrate the sensor into the existing telemetry system. This hardware is not just one module, but a couple.. RAK12023 and RAK12035 is the component stack, the RAK12023 does not seem to matter much and allows for multiple RAK12035 devices to be used. Co-Authored-By: @Justin-Mann
1 parent 7c3edde commit 0c41f90

File tree

16 files changed

+225
-9
lines changed

16 files changed

+225
-9
lines changed

src/configuration.h

+9
Original file line numberDiff line numberDiff line change
@@ -186,6 +186,15 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
186186
// -----------------------------------------------------------------------------
187187
#define FT6336U_ADDR 0x48
188188

189+
// -----------------------------------------------------------------------------
190+
// RAK12035VB Soil Monitor (using RAK12023 up to 3 RAK12035 monitors can be connected)
191+
// - the default i2c address for this sensor is 0x20, and users are instructed to
192+
// set 0x21 and 0x22 for the second and third sensor if present.
193+
// -----------------------------------------------------------------------------
194+
#define RAK120351_ADDR 0x20
195+
#define RAK120352_ADDR 0x21
196+
#define RAK120353_ADDR 0x22
197+
189198
// -----------------------------------------------------------------------------
190199
// BIAS-T Generator
191200
// -----------------------------------------------------------------------------

src/detect/ScanI2C.h

+1
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,7 @@ class ScanI2C
6969
DFROBOT_RAIN,
7070
DPS310,
7171
LTR390UV,
72+
RAK12035,
7273
} DeviceType;
7374

7475
// typedef uint8_t DeviceAddress;

src/detect/ScanI2CTwoWire.cpp

+13-1
Original file line numberDiff line numberDiff line change
@@ -417,9 +417,21 @@ void ScanI2CTwoWire::scanPort(I2CPort port, uint8_t *address, uint8_t asize)
417417
logFoundDevice("BMA423", (uint8_t)addr.address);
418418
}
419419
break;
420+
case TCA9535_ADDR:
421+
case RAK120352_ADDR:
422+
case RAK120353_ADDR:
423+
registerValue = getRegisterValue(ScanI2CTwoWire::RegisterLocation(addr, 0x02), 1);
424+
if (registerValue == addr.address) { // RAK12035 returns its I2C address at 0x02 (eg 0x20)
425+
type = RAK12035;
426+
logFoundDevice("RAK12035", (uint8_t)addr.address);
427+
} else {
428+
type = TCA9535;
429+
logFoundDevice("TCA9535", (uint8_t)addr.address);
430+
}
431+
432+
break;
420433

421434
SCAN_SIMPLE_CASE(LSM6DS3_ADDR, LSM6DS3, "LSM6DS3", (uint8_t)addr.address);
422-
SCAN_SIMPLE_CASE(TCA9535_ADDR, TCA9535, "TCA9535", (uint8_t)addr.address);
423435
SCAN_SIMPLE_CASE(TCA9555_ADDR, TCA9555, "TCA9555", (uint8_t)addr.address);
424436
SCAN_SIMPLE_CASE(VEML7700_ADDR, VEML7700, "VEML7700", (uint8_t)addr.address);
425437
SCAN_SIMPLE_CASE(TSL25911_ADDR, TSL2591, "TSL2591", (uint8_t)addr.address);

src/main.cpp

+1
Original file line numberDiff line numberDiff line change
@@ -643,6 +643,7 @@ void setup()
643643
scannerToSensorsMap(i2cScanner, ScanI2C::DeviceType::DFROBOT_RAIN, meshtastic_TelemetrySensorType_DFROBOT_RAIN);
644644
scannerToSensorsMap(i2cScanner, ScanI2C::DeviceType::LTR390UV, meshtastic_TelemetrySensorType_LTR390UV);
645645
scannerToSensorsMap(i2cScanner, ScanI2C::DeviceType::DPS310, meshtastic_TelemetrySensorType_DPS310);
646+
scannerToSensorsMap(i2cScanner, ScanI2C::DeviceType::RAK12035, meshtastic_TelemetrySensorType_RAK12035);
646647

647648
i2cScanner.reset();
648649
#endif

src/modules/Telemetry/EnvironmentTelemetry.cpp

+29-1
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,9 @@
4141
#include "Sensor/SHTC3Sensor.h"
4242
#include "Sensor/TSL2591Sensor.h"
4343
#include "Sensor/VEML7700Sensor.h"
44+
#ifdef RAK4630
45+
#include "Sensor/RAK12035Sensor.h"
46+
#endif
4447

4548
BMP085Sensor bmp085Sensor;
4649
BMP280Sensor bmp280Sensor;
@@ -63,6 +66,9 @@ DFRobotGravitySensor dfRobotGravitySensor;
6366
NAU7802Sensor nau7802Sensor;
6467
BMP3XXSensor bmp3xxSensor;
6568
CGRadSensSensor cgRadSens;
69+
#ifdef RAK4630
70+
RAK12035Sensor rak12035Sensor;
71+
#endif
6672
#endif
6773
#ifdef T1000X_SENSOR_EN
6874
#include "Sensor/T1000xSensor.h"
@@ -72,6 +78,7 @@ T1000xSensor t1000xSensor;
7278
#include "Sensor/IndicatorSensor.h"
7379
IndicatorSensor indicatorSensor;
7480
#endif
81+
7582
#define FAILED_STATE_SENSOR_READ_MULTIPLIER 10
7683
#define DISPLAY_RECEIVEID_MEASUREMENTS_ON_SCREEN true
7784

@@ -171,6 +178,11 @@ int32_t EnvironmentTelemetryModule::runOnce()
171178

172179
result = rak9154Sensor.runOnce();
173180
#endif
181+
#ifdef RAK4630
182+
if (rak12035Sensor.hasSensor()) {
183+
result = rak12035Sensor.runOnce();
184+
}
185+
#endif
174186
#endif
175187
}
176188
// it's possible to have this module enabled, only for displaying values on the screen.
@@ -498,6 +510,12 @@ bool EnvironmentTelemetryModule::getEnvironmentTelemetry(meshtastic_Telemetry *m
498510
valid = valid && rak9154Sensor.getMetrics(m);
499511
hasSensor = true;
500512
#endif
513+
#ifdef RAK4630
514+
if (rak12035Sensor.hasSensor()) {
515+
valid = valid && rak12035Sensor.getMetrics(m);
516+
hasSensor = true;
517+
}
518+
#endif
501519
#endif
502520
return valid && hasSensor;
503521
}
@@ -552,6 +570,9 @@ bool EnvironmentTelemetryModule::sendTelemetry(NodeNum dest, bool phoneOnly)
552570

553571
LOG_INFO("Send: radiation=%fµR/h", m.variant.environment_metrics.radiation);
554572

573+
LOG_INFO("Send: soil_temperature=%f, soil_moisture=%u", m.variant.environment_metrics.soil_temperature,
574+
m.variant.environment_metrics.soil_moisture);
575+
555576
sensor_read_error_count = 0;
556577

557578
meshtastic_MeshPacket *p = allocDataProtobuf(m);
@@ -710,8 +731,15 @@ AdminMessageHandleResult EnvironmentTelemetryModule::handleAdminMessageForModule
710731
if (result != AdminMessageHandleResult::NOT_HANDLED)
711732
return result;
712733
}
734+
#ifdef RAK4630
735+
if (rak12035Sensor.hasSensor()) {
736+
result = rak12035Sensor.handleAdminMessage(mp, request, response);
737+
if (result != AdminMessageHandleResult::NOT_HANDLED)
738+
return result;
739+
}
740+
#endif
713741
#endif
714742
return result;
715743
}
716744

717-
#endif
745+
#endif
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,118 @@
1+
#include "configuration.h"
2+
#if !MESHTASTIC_EXCLUDE_ENVIRONMENTAL_SENSOR && defined(RAK4630)
3+
4+
#include "../mesh/generated/meshtastic/telemetry.pb.h"
5+
#include "RAK12035Sensor.h"
6+
7+
RAK12035Sensor::RAK12035Sensor() : TelemetrySensor(meshtastic_TelemetrySensorType_RAK12035, "RAK12035") {}
8+
9+
int32_t RAK12035Sensor::runOnce()
10+
{
11+
LOG_INFO("Init sensor: %s", sensorName);
12+
if (!hasSensor()) {
13+
return DEFAULT_SENSOR_MINIMUM_WAIT_TIME_BETWEEN_READS;
14+
}
15+
16+
sensor.set_sensor_addr(RAK120351_ADDR);
17+
18+
sensor.begin(nodeTelemetrySensorsMap[sensorType].first);
19+
// Get sensor firmware version
20+
uint8_t data = 0;
21+
sensor.get_sensor_version(&data);
22+
LOG_INFO("Sensor Firmware version: %i", data);
23+
24+
if (data != 0) {
25+
LOG_DEBUG("RAK12035Sensor Init Succeed");
26+
status = true;
27+
} else {
28+
LOG_ERROR("RAK12035Sensor Init Failed");
29+
status = false;
30+
}
31+
sensor.sensor_sleep();
32+
return initI2CSensor();
33+
}
34+
35+
void RAK12035Sensor::setup()
36+
{
37+
// Set the calibration values
38+
// Reading the saved calibration values from the sensor.
39+
uint16_t zero_val = 0;
40+
uint16_t hundred_val = 0;
41+
uint16_t default_zero_val = 550;
42+
uint16_t default_hundred_val = 420;
43+
sensor.sensor_on();
44+
delay(200);
45+
sensor.get_dry_cal(&zero_val);
46+
sensor.get_wet_cal(&hundred_val);
47+
delay(200);
48+
if (zero_val == 0 || zero_val <= hundred_val) {
49+
LOG_ERROR("Dry calibration value is %d", zero_val);
50+
LOG_ERROR("Wet calibration value is %d", hundred_val);
51+
LOG_ERROR("This does not make sense. Youc can recalibrate this sensor using the calibration sketch included here: "
52+
"https://github.com/RAKWireless/RAK12035_SoilMoisture.");
53+
LOG_ERROR("For now, setting default calibration value for Dry Calibration: %d", default_zero_val);
54+
sensor.set_dry_cal(default_zero_val);
55+
sensor.get_dry_cal(&zero_val);
56+
LOG_ERROR("Dry calibration reset complete. New value is %d", zero_val);
57+
}
58+
if (hundred_val == 0 || hundred_val >= zero_val) {
59+
LOG_ERROR("Dry calibration value is %d", zero_val);
60+
LOG_ERROR("Wet calibration value is %d", hundred_val);
61+
LOG_ERROR("This does not make sense. Youc can recalibrate this sensor using the calibration sketch included here: "
62+
"https://github.com/RAKWireless/RAK12035_SoilMoisture.");
63+
LOG_ERROR("For now, setting default calibration value for Wet Calibration: %d", default_hundred_val);
64+
sensor.set_wet_cal(default_hundred_val);
65+
sensor.get_wet_cal(&hundred_val);
66+
LOG_ERROR("Wet calibration reset complete. New value is %d", hundred_val);
67+
}
68+
sensor.sensor_sleep();
69+
delay(200);
70+
LOG_INFO("Dry calibration value is %d", zero_val);
71+
LOG_INFO("Wet calibration value is %d", hundred_val);
72+
}
73+
74+
bool RAK12035Sensor::getMetrics(meshtastic_Telemetry *measurement)
75+
{
76+
measurement->variant.environment_metrics.has_soil_temperature = true;
77+
measurement->variant.environment_metrics.has_soil_moisture = true;
78+
79+
uint8_t moisture = 0;
80+
uint16_t temp = 0;
81+
bool success = false;
82+
83+
sensor.sensor_on();
84+
delay(200);
85+
success = sensor.get_sensor_moisture(&moisture);
86+
delay(200);
87+
success = sensor.get_sensor_temperature(&temp);
88+
delay(200);
89+
sensor.sensor_sleep();
90+
91+
if (success == false) {
92+
LOG_ERROR("Failed to read sensor data");
93+
return false;
94+
}
95+
LOG_INFO("Successful read from sensor Temperature: %.2f, Moisture: %ld%", (double)(temp / 10), moisture);
96+
measurement->variant.environment_metrics.soil_temperature = (float)(temp / 10);
97+
measurement->variant.environment_metrics.soil_moisture = moisture;
98+
99+
LOG_INFO("Check if the original temperature and moisture (relative_humidity) are being used.. if not just use them for the "
100+
"soil monitoring.");
101+
102+
if (!measurement->variant.environment_metrics.has_temperature) {
103+
LOG_INFO("Overwrite the temp metrics (not being set right now and this will allow the soil temp value to be used in the "
104+
"client interface).");
105+
measurement->variant.environment_metrics.has_temperature = true;
106+
measurement->variant.environment_metrics.temperature = (float)(temp / 10);
107+
}
108+
109+
if (!measurement->variant.environment_metrics.has_relative_humidity) {
110+
LOG_INFO("Overwrite the moisture metrics (not being used for air humidity and this will allow the soil humidity to "
111+
"appear in the client interfaces without adjustments).");
112+
measurement->variant.environment_metrics.has_relative_humidity = true;
113+
measurement->variant.environment_metrics.relative_humidity = (float)moisture;
114+
}
115+
116+
return true;
117+
}
118+
#endif
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
#pragma once
2+
3+
#include "configuration.h"
4+
5+
#if !MESHTASTIC_EXCLUDE_ENVIRONMENTAL_SENSOR && defined(RAK4630)
6+
#ifndef _MT_RAK12035VBSENSOR_H
7+
#define _MT_RAK12035VBSENSOR_H
8+
#endif
9+
10+
#include "../mesh/generated/meshtastic/telemetry.pb.h"
11+
#include "RAK12035_SoilMoisture.h"
12+
#include "TelemetrySensor.h"
13+
#include <Arduino.h>
14+
15+
class RAK12035Sensor : public TelemetrySensor
16+
{
17+
private:
18+
RAK12035 sensor;
19+
20+
protected:
21+
virtual void setup() override;
22+
23+
public:
24+
RAK12035Sensor();
25+
virtual int32_t runOnce() override;
26+
virtual bool getMetrics(meshtastic_Telemetry *measurement) override;
27+
};
28+
29+
#endif

variants/rak4631/platformio.ini

+2-1
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ lib_deps =
2020
https://github.com/RAKWireless/RAK13800-W5100S.git#1.0.2
2121
rakwireless/RAKwireless NCP5623 RGB LED library@^1.0.2
2222
https://github.com/RAKWireless/RAK12034-BMX160.git#dcead07ffa267d3c906e9ca4a1330ab989e957e2
23+
beegee-tokyo/RAK12035_SoilMoisture@^1.0.3
2324

2425
; If not set we will default to uploading over serial (first it forces bootloader entry by talking 1200bps to cdcacm)
2526
; Note: as of 6/2013 the serial/bootloader based programming takes approximately 30 seconds
@@ -52,4 +53,4 @@ lib_deps =
5253
upload_protocol = stlink
5354
; eventually use platformio/tool-pyocd@^2.3600.0 instad
5455
;upload_protocol = custom
55-
;upload_command = pyocd flash -t nrf52840 $UPLOADERFLAGS $SOURCE
56+
;upload_command = pyocd flash -t nrf52840 $UPLOADERFLAGS $SOURCE

variants/rak4631/variant.h

+4-1
Original file line numberDiff line numberDiff line change
@@ -90,6 +90,8 @@ static const uint8_t A7 = PIN_A7;
9090
// Other pins
9191
#define PIN_AREF (2)
9292
#define PIN_NFC1 (9)
93+
#define WB_IO5 PIN_NFC1
94+
#define WB_IO4 (4)
9395
#define PIN_NFC2 (10)
9496

9597
static const uint8_t AREF = PIN_AREF;
@@ -217,6 +219,7 @@ SO GPIO 39/TXEN MAY NOT BE DEFINED FOR SUCCESSFUL OPERATION OF THE SX1262 - TG
217219
// enables 3.3V periphery like GPS or IO Module
218220
// Do not toggle this for GPS power savings
219221
#define PIN_3V3_EN (34)
222+
#define WB_IO2 PIN_3V3_EN
220223

221224
// RAK1910 GPS module
222225
// If using the wisblock GPS module and pluged into Port A on WisBlock base
@@ -270,4 +273,4 @@ SO GPIO 39/TXEN MAY NOT BE DEFINED FOR SUCCESSFUL OPERATION OF THE SX1262 - TG
270273
* Arduino objects - C++ only
271274
*----------------------------------------------------------------------------*/
272275

273-
#endif
276+
#endif

variants/rak4631_epaper/platformio.ini

+1
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ lib_deps =
1717
melopero/Melopero RV3028@^1.1.0
1818
rakwireless/RAKwireless NCP5623 RGB LED library@^1.0.2
1919
beegee-tokyo/RAKwireless RAK12034@^1.0.0
20+
beegee-tokyo/RAK12035_SoilMoisture@^1.0.3
2021
debug_tool = jlink
2122
; If not set we will default to uploading over serial (first it forces bootloader entry by talking 1200bps to cdcacm)
2223
;upload_protocol = jlink

variants/rak4631_epaper/variant.h

+4-1
Original file line numberDiff line numberDiff line change
@@ -90,6 +90,8 @@ static const uint8_t A7 = PIN_A7;
9090
// Other pins
9191
#define PIN_AREF (2)
9292
#define PIN_NFC1 (9)
93+
#define WB_IO5 PIN_NFC1
94+
#define WB_IO4 (4)
9395
#define PIN_NFC2 (10)
9496

9597
static const uint8_t AREF = PIN_AREF;
@@ -188,6 +190,7 @@ static const uint8_t SCK = PIN_SPI_SCK;
188190

189191
// enables 3.3V periphery like GPS or IO Module
190192
#define PIN_3V3_EN (34)
193+
#define WB_IO2 PIN_3V3_EN
191194

192195
// RAK1910 GPS module
193196
// If using the wisblock GPS module and pluged into Port A on WisBlock base
@@ -231,4 +234,4 @@ static const uint8_t SCK = PIN_SPI_SCK;
231234
* Arduino objects - C++ only
232235
*----------------------------------------------------------------------------*/
233236

234-
#endif
237+
#endif

variants/rak4631_epaper_onrxtx/platformio.ini

+1
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ lib_deps =
1919
melopero/Melopero RV3028@^1.1.0
2020
rakwireless/RAKwireless NCP5623 RGB LED library@^1.0.2
2121
beegee-tokyo/RAKwireless RAK12034@^1.0.0
22+
beegee-tokyo/RAK12035_SoilMoisture@^1.0.3
2223
debug_tool = jlink
2324
; If not set we will default to uploading over serial (first it forces bootloader entry by talking 1200bps to cdcacm)
2425
;upload_protocol = jlink

variants/rak4631_epaper_onrxtx/variant.h

+5-2
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,9 @@ static const uint8_t A7 = PIN_A7;
6969

7070
// Other pins
7171
#define PIN_AREF (2)
72-
// #define PIN_NFC1 (9)
72+
#define PIN_NFC1 (9)
73+
#define WB_IO5 PIN_NFC1
74+
#define WB_IO4 (4)
7375
// #define PIN_NFC2 (10)
7476

7577
static const uint8_t AREF = PIN_AREF;
@@ -160,6 +162,7 @@ static const uint8_t SCK = PIN_SPI_SCK;
160162

161163
// enables 3.3V periphery like GPS or IO Module
162164
#define PIN_3V3_EN (34)
165+
#define WB_IO2 PIN_3V3_EN
163166

164167
// NO GPS
165168
#undef GPS_RX_PIN
@@ -202,4 +205,4 @@ static const uint8_t SCK = PIN_SPI_SCK;
202205
* Arduino objects - C++ only
203206
*----------------------------------------------------------------------------*/
204207

205-
#endif
208+
#endif

0 commit comments

Comments
 (0)