diff --git a/src/configuration.h b/src/configuration.h index fd4a5b196..3a0a2ac6e 100644 --- a/src/configuration.h +++ b/src/configuration.h @@ -186,6 +186,15 @@ along with this program. If not, see . // ----------------------------------------------------------------------------- #define FT6336U_ADDR 0x48 +// ----------------------------------------------------------------------------- +// RAK12035VB Soil Monitor (using RAK12023 up to 3 RAK12035 monitors can be connected) +// - the default i2c address for this sensor is 0x20, and users are instructed to +// set 0x21 and 0x22 for the second and third sensor if present. +// ----------------------------------------------------------------------------- +#define RAK120351_ADDR 0x20 +#define RAK120352_ADDR 0x21 +#define RAK120353_ADDR 0x22 + // ----------------------------------------------------------------------------- // BIAS-T Generator // ----------------------------------------------------------------------------- diff --git a/src/detect/ScanI2C.h b/src/detect/ScanI2C.h index 5b6bbe629..8f6f5e7c2 100644 --- a/src/detect/ScanI2C.h +++ b/src/detect/ScanI2C.h @@ -69,6 +69,7 @@ class ScanI2C DFROBOT_RAIN, DPS310, LTR390UV, + RAK12035, } DeviceType; // typedef uint8_t DeviceAddress; diff --git a/src/detect/ScanI2CTwoWire.cpp b/src/detect/ScanI2CTwoWire.cpp index 8b779277d..d28d0f687 100644 --- a/src/detect/ScanI2CTwoWire.cpp +++ b/src/detect/ScanI2CTwoWire.cpp @@ -417,9 +417,21 @@ void ScanI2CTwoWire::scanPort(I2CPort port, uint8_t *address, uint8_t asize) logFoundDevice("BMA423", (uint8_t)addr.address); } break; + case TCA9535_ADDR: + case RAK120352_ADDR: + case RAK120353_ADDR: + registerValue = getRegisterValue(ScanI2CTwoWire::RegisterLocation(addr, 0x02), 1); + if (registerValue == addr.address) { // RAK12035 returns its I2C address at 0x02 (eg 0x20) + type = RAK12035; + logFoundDevice("RAK12035", (uint8_t)addr.address); + } else { + type = TCA9535; + logFoundDevice("TCA9535", (uint8_t)addr.address); + } + + break; SCAN_SIMPLE_CASE(LSM6DS3_ADDR, LSM6DS3, "LSM6DS3", (uint8_t)addr.address); - SCAN_SIMPLE_CASE(TCA9535_ADDR, TCA9535, "TCA9535", (uint8_t)addr.address); SCAN_SIMPLE_CASE(TCA9555_ADDR, TCA9555, "TCA9555", (uint8_t)addr.address); SCAN_SIMPLE_CASE(VEML7700_ADDR, VEML7700, "VEML7700", (uint8_t)addr.address); SCAN_SIMPLE_CASE(TSL25911_ADDR, TSL2591, "TSL2591", (uint8_t)addr.address); diff --git a/src/main.cpp b/src/main.cpp index 4634c7c14..59d76c4c7 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -643,6 +643,7 @@ void setup() scannerToSensorsMap(i2cScanner, ScanI2C::DeviceType::DFROBOT_RAIN, meshtastic_TelemetrySensorType_DFROBOT_RAIN); scannerToSensorsMap(i2cScanner, ScanI2C::DeviceType::LTR390UV, meshtastic_TelemetrySensorType_LTR390UV); scannerToSensorsMap(i2cScanner, ScanI2C::DeviceType::DPS310, meshtastic_TelemetrySensorType_DPS310); + scannerToSensorsMap(i2cScanner, ScanI2C::DeviceType::RAK12035, meshtastic_TelemetrySensorType_RAK12035); i2cScanner.reset(); #endif diff --git a/src/modules/Telemetry/EnvironmentTelemetry.cpp b/src/modules/Telemetry/EnvironmentTelemetry.cpp index 8835c985d..adbe65c67 100644 --- a/src/modules/Telemetry/EnvironmentTelemetry.cpp +++ b/src/modules/Telemetry/EnvironmentTelemetry.cpp @@ -41,6 +41,9 @@ #include "Sensor/SHTC3Sensor.h" #include "Sensor/TSL2591Sensor.h" #include "Sensor/VEML7700Sensor.h" +#ifdef RAK4630 +#include "Sensor/RAK12035Sensor.h" +#endif BMP085Sensor bmp085Sensor; BMP280Sensor bmp280Sensor; @@ -63,6 +66,9 @@ DFRobotGravitySensor dfRobotGravitySensor; NAU7802Sensor nau7802Sensor; BMP3XXSensor bmp3xxSensor; CGRadSensSensor cgRadSens; +#ifdef RAK4630 +RAK12035Sensor rak12035Sensor; +#endif #endif #ifdef T1000X_SENSOR_EN #include "Sensor/T1000xSensor.h" @@ -72,6 +78,7 @@ T1000xSensor t1000xSensor; #include "Sensor/IndicatorSensor.h" IndicatorSensor indicatorSensor; #endif + #define FAILED_STATE_SENSOR_READ_MULTIPLIER 10 #define DISPLAY_RECEIVEID_MEASUREMENTS_ON_SCREEN true @@ -171,6 +178,11 @@ int32_t EnvironmentTelemetryModule::runOnce() result = rak9154Sensor.runOnce(); #endif +#ifdef RAK4630 + if (rak12035Sensor.hasSensor()) { + result = rak12035Sensor.runOnce(); + } +#endif #endif } // 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 valid = valid && rak9154Sensor.getMetrics(m); hasSensor = true; #endif +#ifdef RAK4630 + if (rak12035Sensor.hasSensor()) { + valid = valid && rak12035Sensor.getMetrics(m); + hasSensor = true; + } +#endif #endif return valid && hasSensor; } @@ -552,6 +570,9 @@ bool EnvironmentTelemetryModule::sendTelemetry(NodeNum dest, bool phoneOnly) LOG_INFO("Send: radiation=%fµR/h", m.variant.environment_metrics.radiation); + LOG_INFO("Send: soil_temperature=%f, soil_moisture=%u", m.variant.environment_metrics.soil_temperature, + m.variant.environment_metrics.soil_moisture); + sensor_read_error_count = 0; meshtastic_MeshPacket *p = allocDataProtobuf(m); @@ -710,8 +731,15 @@ AdminMessageHandleResult EnvironmentTelemetryModule::handleAdminMessageForModule if (result != AdminMessageHandleResult::NOT_HANDLED) return result; } +#ifdef RAK4630 + if (rak12035Sensor.hasSensor()) { + result = rak12035Sensor.handleAdminMessage(mp, request, response); + if (result != AdminMessageHandleResult::NOT_HANDLED) + return result; + } +#endif #endif return result; } -#endif \ No newline at end of file +#endif diff --git a/src/modules/Telemetry/Sensor/RAK12035Sensor.cpp b/src/modules/Telemetry/Sensor/RAK12035Sensor.cpp new file mode 100644 index 000000000..b31e34ee5 --- /dev/null +++ b/src/modules/Telemetry/Sensor/RAK12035Sensor.cpp @@ -0,0 +1,118 @@ +#include "configuration.h" +#if !MESHTASTIC_EXCLUDE_ENVIRONMENTAL_SENSOR && defined(RAK4630) + +#include "../mesh/generated/meshtastic/telemetry.pb.h" +#include "RAK12035Sensor.h" + +RAK12035Sensor::RAK12035Sensor() : TelemetrySensor(meshtastic_TelemetrySensorType_RAK12035, "RAK12035") {} + +int32_t RAK12035Sensor::runOnce() +{ + LOG_INFO("Init sensor: %s", sensorName); + if (!hasSensor()) { + return DEFAULT_SENSOR_MINIMUM_WAIT_TIME_BETWEEN_READS; + } + + sensor.set_sensor_addr(RAK120351_ADDR); + + sensor.begin(nodeTelemetrySensorsMap[sensorType].first); + // Get sensor firmware version + uint8_t data = 0; + sensor.get_sensor_version(&data); + LOG_INFO("Sensor Firmware version: %i", data); + + if (data != 0) { + LOG_DEBUG("RAK12035Sensor Init Succeed"); + status = true; + } else { + LOG_ERROR("RAK12035Sensor Init Failed"); + status = false; + } + sensor.sensor_sleep(); + return initI2CSensor(); +} + +void RAK12035Sensor::setup() +{ + // Set the calibration values + // Reading the saved calibration values from the sensor. + uint16_t zero_val = 0; + uint16_t hundred_val = 0; + uint16_t default_zero_val = 550; + uint16_t default_hundred_val = 420; + sensor.sensor_on(); + delay(200); + sensor.get_dry_cal(&zero_val); + sensor.get_wet_cal(&hundred_val); + delay(200); + if (zero_val == 0 || zero_val <= hundred_val) { + LOG_ERROR("Dry calibration value is %d", zero_val); + LOG_ERROR("Wet calibration value is %d", hundred_val); + LOG_ERROR("This does not make sense. Youc can recalibrate this sensor using the calibration sketch included here: " + "https://github.com/RAKWireless/RAK12035_SoilMoisture."); + LOG_ERROR("For now, setting default calibration value for Dry Calibration: %d", default_zero_val); + sensor.set_dry_cal(default_zero_val); + sensor.get_dry_cal(&zero_val); + LOG_ERROR("Dry calibration reset complete. New value is %d", zero_val); + } + if (hundred_val == 0 || hundred_val >= zero_val) { + LOG_ERROR("Dry calibration value is %d", zero_val); + LOG_ERROR("Wet calibration value is %d", hundred_val); + LOG_ERROR("This does not make sense. Youc can recalibrate this sensor using the calibration sketch included here: " + "https://github.com/RAKWireless/RAK12035_SoilMoisture."); + LOG_ERROR("For now, setting default calibration value for Wet Calibration: %d", default_hundred_val); + sensor.set_wet_cal(default_hundred_val); + sensor.get_wet_cal(&hundred_val); + LOG_ERROR("Wet calibration reset complete. New value is %d", hundred_val); + } + sensor.sensor_sleep(); + delay(200); + LOG_INFO("Dry calibration value is %d", zero_val); + LOG_INFO("Wet calibration value is %d", hundred_val); +} + +bool RAK12035Sensor::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; + bool success = false; + + sensor.sensor_on(); + delay(200); + success = sensor.get_sensor_moisture(&moisture); + delay(200); + success = sensor.get_sensor_temperature(&temp); + delay(200); + sensor.sensor_sleep(); + + if (success == false) { + LOG_ERROR("Failed to read sensor data"); + return false; + } + LOG_INFO("Successful read from sensor Temperature: %.2f, Moisture: %ld%", (double)(temp / 10), moisture); + measurement->variant.environment_metrics.soil_temperature = (float)(temp / 10); + measurement->variant.environment_metrics.soil_moisture = moisture; + + LOG_INFO("Check if the original temperature and moisture (relative_humidity) are being used.. if not just use them for the " + "soil monitoring."); + + if (!measurement->variant.environment_metrics.has_temperature) { + LOG_INFO("Overwrite the temp metrics (not being set right now and this will allow the soil temp value to be used in the " + "client interface)."); + measurement->variant.environment_metrics.has_temperature = true; + measurement->variant.environment_metrics.temperature = (float)(temp / 10); + } + + if (!measurement->variant.environment_metrics.has_relative_humidity) { + LOG_INFO("Overwrite the moisture metrics (not being used for air humidity and this will allow the soil humidity to " + "appear in the client interfaces without adjustments)."); + measurement->variant.environment_metrics.has_relative_humidity = true; + measurement->variant.environment_metrics.relative_humidity = (float)moisture; + } + + return true; +} +#endif diff --git a/src/modules/Telemetry/Sensor/RAK12035Sensor.h b/src/modules/Telemetry/Sensor/RAK12035Sensor.h new file mode 100644 index 000000000..77ffe24fa --- /dev/null +++ b/src/modules/Telemetry/Sensor/RAK12035Sensor.h @@ -0,0 +1,29 @@ +#pragma once + +#include "configuration.h" + +#if !MESHTASTIC_EXCLUDE_ENVIRONMENTAL_SENSOR && defined(RAK4630) +#ifndef _MT_RAK12035VBSENSOR_H +#define _MT_RAK12035VBSENSOR_H +#endif + +#include "../mesh/generated/meshtastic/telemetry.pb.h" +#include "RAK12035_SoilMoisture.h" +#include "TelemetrySensor.h" +#include + +class RAK12035Sensor : public TelemetrySensor +{ + private: + RAK12035 sensor; + + protected: + virtual void setup() override; + + public: + RAK12035Sensor(); + virtual int32_t runOnce() override; + virtual bool getMetrics(meshtastic_Telemetry *measurement) override; +}; + +#endif diff --git a/variants/rak4631/platformio.ini b/variants/rak4631/platformio.ini index ced93df66..4823ccdfa 100644 --- a/variants/rak4631/platformio.ini +++ b/variants/rak4631/platformio.ini @@ -20,6 +20,7 @@ lib_deps = https://github.com/RAKWireless/RAK13800-W5100S.git#1.0.2 rakwireless/RAKwireless NCP5623 RGB LED library@^1.0.2 https://github.com/RAKWireless/RAK12034-BMX160.git#dcead07ffa267d3c906e9ca4a1330ab989e957e2 + beegee-tokyo/RAK12035_SoilMoisture@^1.0.3 ; If not set we will default to uploading over serial (first it forces bootloader entry by talking 1200bps to cdcacm) ; Note: as of 6/2013 the serial/bootloader based programming takes approximately 30 seconds @@ -52,4 +53,4 @@ lib_deps = upload_protocol = stlink ; eventually use platformio/tool-pyocd@^2.3600.0 instad ;upload_protocol = custom -;upload_command = pyocd flash -t nrf52840 $UPLOADERFLAGS $SOURCE \ No newline at end of file +;upload_command = pyocd flash -t nrf52840 $UPLOADERFLAGS $SOURCE diff --git a/variants/rak4631/variant.h b/variants/rak4631/variant.h index bc5541336..c8a2f83ae 100644 --- a/variants/rak4631/variant.h +++ b/variants/rak4631/variant.h @@ -90,6 +90,8 @@ static const uint8_t A7 = PIN_A7; // Other pins #define PIN_AREF (2) #define PIN_NFC1 (9) +#define WB_IO5 PIN_NFC1 +#define WB_IO4 (4) #define PIN_NFC2 (10) 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 // enables 3.3V periphery like GPS or IO Module // Do not toggle this for GPS power savings #define PIN_3V3_EN (34) +#define WB_IO2 PIN_3V3_EN // RAK1910 GPS module // 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 * Arduino objects - C++ only *----------------------------------------------------------------------------*/ -#endif \ No newline at end of file +#endif diff --git a/variants/rak4631_epaper/platformio.ini b/variants/rak4631_epaper/platformio.ini index b851691ed..9fe7ac1c7 100644 --- a/variants/rak4631_epaper/platformio.ini +++ b/variants/rak4631_epaper/platformio.ini @@ -17,6 +17,7 @@ lib_deps = melopero/Melopero RV3028@^1.1.0 rakwireless/RAKwireless NCP5623 RGB LED library@^1.0.2 beegee-tokyo/RAKwireless RAK12034@^1.0.0 + beegee-tokyo/RAK12035_SoilMoisture@^1.0.3 debug_tool = jlink ; If not set we will default to uploading over serial (first it forces bootloader entry by talking 1200bps to cdcacm) ;upload_protocol = jlink diff --git a/variants/rak4631_epaper/variant.h b/variants/rak4631_epaper/variant.h index 0bb97498c..c1e11bee5 100644 --- a/variants/rak4631_epaper/variant.h +++ b/variants/rak4631_epaper/variant.h @@ -90,6 +90,8 @@ static const uint8_t A7 = PIN_A7; // Other pins #define PIN_AREF (2) #define PIN_NFC1 (9) +#define WB_IO5 PIN_NFC1 +#define WB_IO4 (4) #define PIN_NFC2 (10) static const uint8_t AREF = PIN_AREF; @@ -188,6 +190,7 @@ static const uint8_t SCK = PIN_SPI_SCK; // enables 3.3V periphery like GPS or IO Module #define PIN_3V3_EN (34) +#define WB_IO2 PIN_3V3_EN // RAK1910 GPS module // 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; * Arduino objects - C++ only *----------------------------------------------------------------------------*/ -#endif \ No newline at end of file +#endif diff --git a/variants/rak4631_epaper_onrxtx/platformio.ini b/variants/rak4631_epaper_onrxtx/platformio.ini index 8612a3f3d..c5300243d 100644 --- a/variants/rak4631_epaper_onrxtx/platformio.ini +++ b/variants/rak4631_epaper_onrxtx/platformio.ini @@ -19,6 +19,7 @@ lib_deps = melopero/Melopero RV3028@^1.1.0 rakwireless/RAKwireless NCP5623 RGB LED library@^1.0.2 beegee-tokyo/RAKwireless RAK12034@^1.0.0 + beegee-tokyo/RAK12035_SoilMoisture@^1.0.3 debug_tool = jlink ; If not set we will default to uploading over serial (first it forces bootloader entry by talking 1200bps to cdcacm) ;upload_protocol = jlink diff --git a/variants/rak4631_epaper_onrxtx/variant.h b/variants/rak4631_epaper_onrxtx/variant.h index 5888cff33..1f8257e8e 100644 --- a/variants/rak4631_epaper_onrxtx/variant.h +++ b/variants/rak4631_epaper_onrxtx/variant.h @@ -69,7 +69,9 @@ static const uint8_t A7 = PIN_A7; // Other pins #define PIN_AREF (2) -// #define PIN_NFC1 (9) +#define PIN_NFC1 (9) +#define WB_IO5 PIN_NFC1 +#define WB_IO4 (4) // #define PIN_NFC2 (10) static const uint8_t AREF = PIN_AREF; @@ -160,6 +162,7 @@ static const uint8_t SCK = PIN_SPI_SCK; // enables 3.3V periphery like GPS or IO Module #define PIN_3V3_EN (34) +#define WB_IO2 PIN_3V3_EN // NO GPS #undef GPS_RX_PIN @@ -202,4 +205,4 @@ static const uint8_t SCK = PIN_SPI_SCK; * Arduino objects - C++ only *----------------------------------------------------------------------------*/ -#endif \ No newline at end of file +#endif diff --git a/variants/rak4631_eth_gw/variant.h b/variants/rak4631_eth_gw/variant.h index bc5541336..c8a2f83ae 100644 --- a/variants/rak4631_eth_gw/variant.h +++ b/variants/rak4631_eth_gw/variant.h @@ -90,6 +90,8 @@ static const uint8_t A7 = PIN_A7; // Other pins #define PIN_AREF (2) #define PIN_NFC1 (9) +#define WB_IO5 PIN_NFC1 +#define WB_IO4 (4) #define PIN_NFC2 (10) 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 // enables 3.3V periphery like GPS or IO Module // Do not toggle this for GPS power savings #define PIN_3V3_EN (34) +#define WB_IO2 PIN_3V3_EN // RAK1910 GPS module // 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 * Arduino objects - C++ only *----------------------------------------------------------------------------*/ -#endif \ No newline at end of file +#endif diff --git a/variants/rak_wismeshtap/platformio.ini b/variants/rak_wismeshtap/platformio.ini index bcf46b90d..a40a27ae4 100644 --- a/variants/rak_wismeshtap/platformio.ini +++ b/variants/rak_wismeshtap/platformio.ini @@ -23,6 +23,7 @@ lib_deps = bodmer/TFT_eSPI beegee-tokyo/RAKwireless RAK12034@^1.0.0 beegee-tokyo/RAK14014-FT6336U @ 1.0.1 + beegee-tokyo/RAK12035_SoilMoisture@^1.0.3 debug_tool = jlink ; If not set we will default to uploading over serial (first it forces bootloader entry by talking 1200bps to cdcacm) ;upload_protocol = jlink diff --git a/variants/rak_wismeshtap/variant.h b/variants/rak_wismeshtap/variant.h index c21a11ac1..3006189cf 100644 --- a/variants/rak_wismeshtap/variant.h +++ b/variants/rak_wismeshtap/variant.h @@ -90,6 +90,8 @@ static const uint8_t A7 = PIN_A7; // Other pins #define PIN_AREF (2) #define PIN_NFC1 (9) +#define WB_IO5 PIN_NFC1 +#define WB_IO4 (4) #define PIN_NFC2 (10) static const uint8_t AREF = PIN_AREF; @@ -311,4 +313,4 @@ SO GPIO 39/TXEN MAY NOT BE DEFINED FOR SUCCESSFUL OPERATION OF THE SX1262 - TG * Arduino objects - C++ only *----------------------------------------------------------------------------*/ -#endif \ No newline at end of file +#endif