add library, do initial work to add support as an environmental telemetry sensor

This commit is contained in:
Justin E. Mann 2024-11-27 14:20:01 -07:00
parent ad9d7a4972
commit 008f917c58
9 changed files with 168 additions and 4 deletions

View File

@ -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

View File

@ -149,6 +149,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
#define MAX30102_ADDR 0x57
#define MLX90614_ADDR_DEF 0x5A
#define CGRADSENS_ADDR 0x66
#define RAK12035VB_ADDR 0x20
// -----------------------------------------------------------------------------
// ACCELEROMETER

View File

@ -64,7 +64,8 @@ class ScanI2C
MAX30102,
TPS65233,
MPR121KB,
CGRADSENS
CGRADSENS,
RAK12035VB
} DeviceType;
// typedef uint8_t DeviceAddress;

View File

@ -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");

View File

@ -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;

View File

@ -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;
}

View File

@ -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

View File

@ -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 <RAK12035_SoilMoisture.h>
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

View File

@ -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)