Skip to content

Commit

Permalink
Support for the ClimateGuard RadSens Geiger-Muller tube
Browse files Browse the repository at this point in the history
  • Loading branch information
jake-b authored and fifieldt committed Nov 23, 2024
1 parent 14b9a1a commit 8310a2c
Show file tree
Hide file tree
Showing 11 changed files with 145 additions and 12 deletions.
2 changes: 1 addition & 1 deletion .gitmodules
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[submodule "protobufs"]
path = protobufs
url = https://github.com/meshtastic/protobufs.git
url = https://github.com/jake-b/meshtastic-protobufs.git
[submodule "meshtestic"]
path = meshtestic
url = https://github.com/meshtastic/meshTestic
2 changes: 1 addition & 1 deletion bin/regen-protos.sh
Original file line number Diff line number Diff line change
Expand Up @@ -8,4 +8,4 @@ echo "prebuilt binaries for your computer into nanopb-0.4.9"

# the nanopb tool seems to require that the .options file be in the current directory!
cd protobufs
../nanopb-0.4.9/generator-bin/protoc --experimental_allow_proto3_optional "--nanopb_out=-S.cpp -v:../src/mesh/generated/" -I=../protobufs meshtastic/*.proto
protoc --experimental_allow_proto3_optional "--nanopb_out=-S.cpp -v:../src/mesh/generated/" -I=../protobufs meshtastic/*.proto
2 changes: 1 addition & 1 deletion protobufs
1 change: 1 addition & 0 deletions src/configuration.h
Original file line number Diff line number Diff line change
Expand Up @@ -148,6 +148,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
#define NAU7802_ADDR 0x2A
#define MAX30102_ADDR 0x57
#define MLX90614_ADDR_DEF 0x5A
#define CGRADSENS_ADDR 0x66

// -----------------------------------------------------------------------------
// ACCELEROMETER
Expand Down
3 changes: 2 additions & 1 deletion src/detect/ScanI2C.h
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,8 @@ class ScanI2C
ICM20948,
MAX30102,
TPS65233,
MPR121KB
MPR121KB,
CGRADSENS
} DeviceType;

// typedef uint8_t DeviceAddress;
Expand Down
10 changes: 10 additions & 0 deletions src/detect/ScanI2CTwoWire.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -463,6 +463,16 @@ void ScanI2CTwoWire::scanPort(I2CPort port, uint8_t *address, uint8_t asize)
}
break;

case CGRADSENS_ADDR:
LOG_INFO("Looking for ClimateGuard RadSense Geiger-Muller Sensor");
registerValue = getRegisterValue(ScanI2CTwoWire::RegisterLocation(addr, 0x00), 1);
if (registerValue == 0x7D) {
type = CGRADSENS;
LOG_INFO("ClimateGuard RadSense Geiger-Muller Sensor found");
break;
}
break;

default:
LOG_INFO("Device found at address 0x%x was not able to be enumerated", addr.address);
}
Expand Down
1 change: 1 addition & 0 deletions src/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -614,6 +614,7 @@ void setup()
SCANNER_TO_SENSORS_MAP(ScanI2C::DeviceType::DFROBOT_LARK, meshtastic_TelemetrySensorType_DFROBOT_LARK)
SCANNER_TO_SENSORS_MAP(ScanI2C::DeviceType::ICM20948, meshtastic_TelemetrySensorType_ICM20948)
SCANNER_TO_SENSORS_MAP(ScanI2C::DeviceType::MAX30102, meshtastic_TelemetrySensorType_MAX30102)
SCANNER_TO_SENSORS_MAP(ScanI2C::DeviceType::CGRADSENS, meshtastic_TelemetrySensorType_RADSENS)

i2cScanner.reset();
#endif
Expand Down
23 changes: 15 additions & 8 deletions src/mesh/generated/meshtastic/telemetry.pb.h
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,9 @@ typedef enum _meshtastic_TelemetrySensorType {
/* MLX90614 non-contact IR temperature sensor */
meshtastic_TelemetrySensorType_MLX90614 = 31,
/* SCD40/SCD41 CO2, humidity, temperature sensor */
meshtastic_TelemetrySensorType_SCD4X = 32
meshtastic_TelemetrySensorType_SCD4X = 32,
/* RADSENS, radiation, geiger-muller tube */
meshtastic_TelemetrySensorType_RADSENS = 33
} meshtastic_TelemetrySensorType;

/* Struct definitions */
Expand Down Expand Up @@ -155,6 +157,9 @@ typedef struct _meshtastic_EnvironmentMetrics {
/* Wind lull in m/s */
bool has_wind_lull;
float wind_lull;
/* Radiation in micro roentgen/hr */
bool has_radiation;
float radiation;
} meshtastic_EnvironmentMetrics;

/* Power Metrics (voltage / current / etc) */
Expand Down Expand Up @@ -299,8 +304,8 @@ extern "C" {

/* Helper constants for enums */
#define _meshtastic_TelemetrySensorType_MIN meshtastic_TelemetrySensorType_SENSOR_UNSET
#define _meshtastic_TelemetrySensorType_MAX meshtastic_TelemetrySensorType_SCD4X
#define _meshtastic_TelemetrySensorType_ARRAYSIZE ((meshtastic_TelemetrySensorType)(meshtastic_TelemetrySensorType_SCD4X+1))
#define _meshtastic_TelemetrySensorType_MAX meshtastic_TelemetrySensorType_RADSENS
#define _meshtastic_TelemetrySensorType_ARRAYSIZE ((meshtastic_TelemetrySensorType)(meshtastic_TelemetrySensorType_RADSENS+1))



Expand All @@ -313,15 +318,15 @@ extern "C" {

/* Initializer values for message structs */
#define meshtastic_DeviceMetrics_init_default {false, 0, false, 0, false, 0, false, 0, false, 0}
#define meshtastic_EnvironmentMetrics_init_default {false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0}
#define meshtastic_EnvironmentMetrics_init_default {false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0}
#define meshtastic_PowerMetrics_init_default {false, 0, false, 0, false, 0, false, 0, false, 0, false, 0}
#define meshtastic_AirQualityMetrics_init_default {false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0}
#define meshtastic_LocalStats_init_default {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
#define meshtastic_HealthMetrics_init_default {false, 0, false, 0, false, 0}
#define meshtastic_Telemetry_init_default {0, 0, {meshtastic_DeviceMetrics_init_default}}
#define meshtastic_Nau7802Config_init_default {0, 0}
#define meshtastic_DeviceMetrics_init_zero {false, 0, false, 0, false, 0, false, 0, false, 0}
#define meshtastic_EnvironmentMetrics_init_zero {false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0}
#define meshtastic_EnvironmentMetrics_init_zero {false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0}
#define meshtastic_PowerMetrics_init_zero {false, 0, false, 0, false, 0, false, 0, false, 0, false, 0}
#define meshtastic_AirQualityMetrics_init_zero {false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0}
#define meshtastic_LocalStats_init_zero {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
Expand Down Expand Up @@ -352,6 +357,7 @@ extern "C" {
#define meshtastic_EnvironmentMetrics_weight_tag 15
#define meshtastic_EnvironmentMetrics_wind_gust_tag 16
#define meshtastic_EnvironmentMetrics_wind_lull_tag 17
#define meshtastic_EnvironmentMetrics_radiation_tag 18
#define meshtastic_PowerMetrics_ch1_voltage_tag 1
#define meshtastic_PowerMetrics_ch1_current_tag 2
#define meshtastic_PowerMetrics_ch2_voltage_tag 3
Expand Down Expand Up @@ -422,7 +428,8 @@ X(a, STATIC, OPTIONAL, UINT32, wind_direction, 13) \
X(a, STATIC, OPTIONAL, FLOAT, wind_speed, 14) \
X(a, STATIC, OPTIONAL, FLOAT, weight, 15) \
X(a, STATIC, OPTIONAL, FLOAT, wind_gust, 16) \
X(a, STATIC, OPTIONAL, FLOAT, wind_lull, 17)
X(a, STATIC, OPTIONAL, FLOAT, wind_lull, 17) \
X(a, STATIC, OPTIONAL, FLOAT, radiation, 18)
#define meshtastic_EnvironmentMetrics_CALLBACK NULL
#define meshtastic_EnvironmentMetrics_DEFAULT NULL

Expand Down Expand Up @@ -521,12 +528,12 @@ extern const pb_msgdesc_t meshtastic_Nau7802Config_msg;
#define MESHTASTIC_MESHTASTIC_TELEMETRY_PB_H_MAX_SIZE meshtastic_Telemetry_size
#define meshtastic_AirQualityMetrics_size 78
#define meshtastic_DeviceMetrics_size 27
#define meshtastic_EnvironmentMetrics_size 85
#define meshtastic_EnvironmentMetrics_size 91
#define meshtastic_HealthMetrics_size 11
#define meshtastic_LocalStats_size 60
#define meshtastic_Nau7802Config_size 16
#define meshtastic_PowerMetrics_size 30
#define meshtastic_Telemetry_size 92
#define meshtastic_Telemetry_size 98

#ifdef __cplusplus
} /* extern "C" */
Expand Down
22 changes: 22 additions & 0 deletions src/modules/Telemetry/EnvironmentTelemetry.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@
#include "Sensor/T1000xSensor.h"
#include "Sensor/TSL2591Sensor.h"
#include "Sensor/VEML7700Sensor.h"
#include "Sensor/CGRadSensSensor.h"

BMP085Sensor bmp085Sensor;
BMP280Sensor bmp280Sensor;
Expand All @@ -60,6 +61,7 @@ BMP3XXSensor bmp3xxSensor;
#ifdef T1000X_SENSOR_EN
T1000xSensor t1000xSensor;
#endif
CGRadSensSensor cgRadSens;

#define FAILED_STATE_SENSOR_READ_MULTIPLIER 10
#define DISPLAY_RECEIVEID_MEASUREMENTS_ON_SCREEN true
Expand Down Expand Up @@ -147,6 +149,8 @@ int32_t EnvironmentTelemetryModule::runOnce()
result = nau7802Sensor.runOnce();
if (max17048Sensor.hasSensor())
result = max17048Sensor.runOnce();
if (cgRadSens.hasSensor())
result = cgRadSens.runOnce();
#endif
}
return result;
Expand Down Expand Up @@ -243,6 +247,11 @@ void EnvironmentTelemetryModule::drawFrame(OLEDDisplay *display, OLEDDisplayUiSt
if (lastMeasurement.variant.environment_metrics.weight != 0)
display->drawString(x, y += _fontHeight(FONT_SMALL),
"Weight: " + String(lastMeasurement.variant.environment_metrics.weight, 0) + "kg");

if (lastMeasurement.variant.environment_metrics.radiation != 0)
display->drawString(x, y += _fontHeight(FONT_SMALL),
"Radiation: " + String(lastMeasurement.variant.environment_metrics.radiation, 0) + "µR/h");

}

bool EnvironmentTelemetryModule::handleReceivedProtobuf(const meshtastic_MeshPacket &mp, meshtastic_Telemetry *t)
Expand All @@ -263,6 +272,8 @@ bool EnvironmentTelemetryModule::handleReceivedProtobuf(const meshtastic_MeshPac
t->variant.environment_metrics.wind_speed, t->variant.environment_metrics.wind_direction,
t->variant.environment_metrics.weight);

LOG_INFO("(Received from %s): radiation=%fµR/h", sender, t->variant.environment_metrics.radiation);

#endif
// release previous packet before occupying a new spot
if (lastMeasurementPacket != nullptr)
Expand Down Expand Up @@ -390,6 +401,10 @@ bool EnvironmentTelemetryModule::getEnvironmentTelemetry(meshtastic_Telemetry *m
valid = valid && max17048Sensor.getMetrics(m);
hasSensor = true;
}
if (cgRadSens.hasSensor()) {
valid = valid && cgRadSens.getMetrics(m);
hasSensor = true;
}

#endif
return valid && hasSensor;
Expand Down Expand Up @@ -443,6 +458,8 @@ bool EnvironmentTelemetryModule::sendTelemetry(NodeNum dest, bool phoneOnly)
LOG_INFO("Send: wind speed=%fm/s, direction=%d degrees, weight=%fkg", m.variant.environment_metrics.wind_speed,
m.variant.environment_metrics.wind_direction, m.variant.environment_metrics.weight);

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

sensor_read_error_count = 0;

meshtastic_MeshPacket *p = allocDataProtobuf(m);
Expand Down Expand Up @@ -585,6 +602,11 @@ AdminMessageHandleResult EnvironmentTelemetryModule::handleAdminMessageForModule
if (result != AdminMessageHandleResult::NOT_HANDLED)
return result;
}
if (cgRadSens.hasSensor()) {
result = cgRadSens.handleAdminMessage(mp, request, response);
if (result != AdminMessageHandleResult::NOT_HANDLED)
return result;
}
return result;
}

Expand Down
65 changes: 65 additions & 0 deletions src/modules/Telemetry/Sensor/CGRadSensSensor.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
#include "configuration.h"

#if !MESHTASTIC_EXCLUDE_ENVIRONMENTAL_SENSOR

#include "../mesh/generated/meshtastic/telemetry.pb.h"
#include "CGRadSensSensor.h"
#include "TelemetrySensor.h"
#include <typeinfo>
#include <Wire.h>

CGRadSensSensor::CGRadSensSensor() : TelemetrySensor(meshtastic_TelemetrySensorType_RADSENS, "RadSens") {}

int32_t CGRadSensSensor::runOnce()
{
LOG_INFO("Init sensor: %s", sensorName);
if (!hasSensor()) {
return DEFAULT_SENSOR_MINIMUM_WAIT_TIME_BETWEEN_READS;
}

status = true;
begin(nodeTelemetrySensorsMap[sensorType].second, nodeTelemetrySensorsMap[sensorType].first);

return initI2CSensor();
}

void CGRadSensSensor::setup() {}

void CGRadSensSensor::begin(TwoWire *wire, uint8_t addr)
{
_wire = wire;
_addr = addr;
_wire->begin();
}

float CGRadSensSensor::getStaticRadiation()
{
uint32_t data;
_wire->beginTransmission(_addr); // Transfer data to addr.
_wire->write(0x06); // Radiation intensity (static period T = 500 sec)
if (_wire->endTransmission() == 0) {
if (_wire->requestFrom(_addr, (uint8_t)3)) { ; // Request 3 bytes
data = _wire->read();
data <<= 8;
data |= _wire->read();
data <<= 8;
data |= _wire->read();

float microRadPerHr = float(data) / 10.0;
return microRadPerHr;
}
}
return -1.0;
}

bool CGRadSensSensor::getMetrics(meshtastic_Telemetry *measurement)
{
LOG_INFO("getMetrics: ClimateGuard RadSense Geiger-Muller Sensor");
measurement->variant.environment_metrics.has_radiation = true;

LOG_DEBUG("CGRADSENS getMetrics");
measurement->variant.environment_metrics.radiation = getStaticRadiation();

return true;
}
#endif
26 changes: 26 additions & 0 deletions src/modules/Telemetry/Sensor/CGRadSensSensor.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
#include "configuration.h"

#if !MESHTASTIC_EXCLUDE_ENVIRONMENTAL_SENSOR

#include "../mesh/generated/meshtastic/telemetry.pb.h"
#include "TelemetrySensor.h"
#include <Wire.h>

class CGRadSensSensor : public TelemetrySensor
{
private:
uint8_t _addr = 0x66;
TwoWire *_wire = &Wire;

protected:
virtual void setup() override;
void begin(TwoWire *wire = &Wire, uint8_t addr = 0x66);
float getStaticRadiation();

public:
CGRadSensSensor();
virtual int32_t runOnce() override;
virtual bool getMetrics(meshtastic_Telemetry *measurement) override;
};

#endif

0 comments on commit 8310a2c

Please sign in to comment.