add a .clang-format file (#9154)

This commit is contained in:
Jorropo
2026-01-03 21:19:24 +01:00
committed by GitHub
parent abab6ce815
commit 0d11331d18
771 changed files with 77752 additions and 83184 deletions

View File

@@ -15,35 +15,33 @@
AHT10Sensor::AHT10Sensor() : TelemetrySensor(meshtastic_TelemetrySensorType_AHT10, "AHT10") {}
bool AHT10Sensor::initDevice(TwoWire *bus, ScanI2C::FoundDevice *dev)
{
LOG_INFO("Init sensor: %s", sensorName);
aht10 = Adafruit_AHTX0();
status = aht10.begin(bus, 0, dev->address.address);
bool AHT10Sensor::initDevice(TwoWire *bus, ScanI2C::FoundDevice *dev) {
LOG_INFO("Init sensor: %s", sensorName);
aht10 = Adafruit_AHTX0();
status = aht10.begin(bus, 0, dev->address.address);
initI2CSensor();
return status;
initI2CSensor();
return status;
}
bool AHT10Sensor::getMetrics(meshtastic_Telemetry *measurement)
{
LOG_DEBUG("AHT10 getMetrics");
bool AHT10Sensor::getMetrics(meshtastic_Telemetry *measurement) {
LOG_DEBUG("AHT10 getMetrics");
sensors_event_t humidity, temp;
aht10.getEvent(&humidity, &temp);
sensors_event_t humidity, temp;
aht10.getEvent(&humidity, &temp);
// prefer other sensors like bmp280, bmp3xx
if (!measurement->variant.environment_metrics.has_temperature) {
measurement->variant.environment_metrics.has_temperature = true;
measurement->variant.environment_metrics.temperature = temp.temperature + AHT10_TEMP_OFFSET;
}
// prefer other sensors like bmp280, bmp3xx
if (!measurement->variant.environment_metrics.has_temperature) {
measurement->variant.environment_metrics.has_temperature = true;
measurement->variant.environment_metrics.temperature = temp.temperature + AHT10_TEMP_OFFSET;
}
if (!measurement->variant.environment_metrics.has_relative_humidity) {
measurement->variant.environment_metrics.has_relative_humidity = true;
measurement->variant.environment_metrics.relative_humidity = humidity.relative_humidity;
}
if (!measurement->variant.environment_metrics.has_relative_humidity) {
measurement->variant.environment_metrics.has_relative_humidity = true;
measurement->variant.environment_metrics.relative_humidity = humidity.relative_humidity;
}
return true;
return true;
}
#endif

View File

@@ -14,15 +14,14 @@
#include "TelemetrySensor.h"
#include <Adafruit_AHTX0.h>
class AHT10Sensor : public TelemetrySensor
{
private:
Adafruit_AHTX0 aht10;
class AHT10Sensor : public TelemetrySensor {
private:
Adafruit_AHTX0 aht10;
public:
AHT10Sensor();
virtual bool getMetrics(meshtastic_Telemetry *measurement) override;
virtual bool initDevice(TwoWire *bus, ScanI2C::FoundDevice *dev) override;
public:
AHT10Sensor();
virtual bool getMetrics(meshtastic_Telemetry *measurement) override;
virtual bool initDevice(TwoWire *bus, ScanI2C::FoundDevice *dev) override;
};
#endif

View File

@@ -13,42 +13,40 @@
BH1750Sensor::BH1750Sensor() : TelemetrySensor(meshtastic_TelemetrySensorType_BH1750, "BH1750") {}
bool BH1750Sensor::initDevice(TwoWire *bus, ScanI2C::FoundDevice *dev)
{
LOG_INFO("Init sensor: %s with mode %d", sensorName, BH1750_SENSOR_MODE);
bool BH1750Sensor::initDevice(TwoWire *bus, ScanI2C::FoundDevice *dev) {
LOG_INFO("Init sensor: %s with mode %d", sensorName, BH1750_SENSOR_MODE);
bh1750 = BH1750_WE(bus, dev->address.address);
status = bh1750.init();
if (!status) {
return status;
}
bh1750.setMode(BH1750_SENSOR_MODE);
initI2CSensor();
bh1750 = BH1750_WE(bus, dev->address.address);
status = bh1750.init();
if (!status) {
return status;
}
bh1750.setMode(BH1750_SENSOR_MODE);
initI2CSensor();
return status;
}
bool BH1750Sensor::getMetrics(meshtastic_Telemetry *measurement)
{
bool BH1750Sensor::getMetrics(meshtastic_Telemetry *measurement) {
/* An OTH and OTH_2 measurement takes ~120 ms. I suggest to wait
140 ms to be on the safe side.
An OTL measurement takes about 16 ms. I suggest to wait 20 ms
to be on the safe side. */
if (BH1750_SENSOR_MODE == BH1750Mode::OTH || BH1750_SENSOR_MODE == BH1750Mode::OTH_2) {
bh1750.setMode(BH1750_SENSOR_MODE);
delay(140); // wait for measurement to be completed
} else if (BH1750_SENSOR_MODE == BH1750Mode::OTL) {
bh1750.setMode(BH1750_SENSOR_MODE);
delay(20);
}
/* An OTH and OTH_2 measurement takes ~120 ms. I suggest to wait
140 ms to be on the safe side.
An OTL measurement takes about 16 ms. I suggest to wait 20 ms
to be on the safe side. */
if (BH1750_SENSOR_MODE == BH1750Mode::OTH || BH1750_SENSOR_MODE == BH1750Mode::OTH_2) {
bh1750.setMode(BH1750_SENSOR_MODE);
delay(140); // wait for measurement to be completed
} else if (BH1750_SENSOR_MODE == BH1750Mode::OTL) {
bh1750.setMode(BH1750_SENSOR_MODE);
delay(20);
}
measurement->variant.environment_metrics.has_lux = true;
float lightIntensity = bh1750.getLux();
measurement->variant.environment_metrics.has_lux = true;
float lightIntensity = bh1750.getLux();
measurement->variant.environment_metrics.lux = lightIntensity;
return true;
measurement->variant.environment_metrics.lux = lightIntensity;
return true;
}
#endif

View File

@@ -7,15 +7,14 @@
#include "TelemetrySensor.h"
#include <BH1750_WE.h>
class BH1750Sensor : public TelemetrySensor
{
private:
BH1750_WE bh1750;
class BH1750Sensor : public TelemetrySensor {
private:
BH1750_WE bh1750;
public:
BH1750Sensor();
virtual bool getMetrics(meshtastic_Telemetry *measurement) override;
virtual bool initDevice(TwoWire *bus, ScanI2C::FoundDevice *dev) override;
public:
BH1750Sensor();
virtual bool getMetrics(meshtastic_Telemetry *measurement) override;
virtual bool initDevice(TwoWire *bus, ScanI2C::FoundDevice *dev) override;
};
#endif

View File

@@ -10,36 +10,34 @@
BME280Sensor::BME280Sensor() : TelemetrySensor(meshtastic_TelemetrySensorType_BME280, "BME280") {}
bool BME280Sensor::initDevice(TwoWire *bus, ScanI2C::FoundDevice *dev)
{
LOG_INFO("Init sensor: %s", sensorName);
status = bme280.begin(dev->address.address, bus);
if (!status) {
return status;
}
bme280.setSampling(Adafruit_BME280::MODE_FORCED,
Adafruit_BME280::SAMPLING_X1, // Temp. oversampling
Adafruit_BME280::SAMPLING_X1, // Pressure oversampling
Adafruit_BME280::SAMPLING_X1, // Humidity oversampling
Adafruit_BME280::FILTER_OFF, Adafruit_BME280::STANDBY_MS_1000);
initI2CSensor();
bool BME280Sensor::initDevice(TwoWire *bus, ScanI2C::FoundDevice *dev) {
LOG_INFO("Init sensor: %s", sensorName);
status = bme280.begin(dev->address.address, bus);
if (!status) {
return status;
}
bme280.setSampling(Adafruit_BME280::MODE_FORCED,
Adafruit_BME280::SAMPLING_X1, // Temp. oversampling
Adafruit_BME280::SAMPLING_X1, // Pressure oversampling
Adafruit_BME280::SAMPLING_X1, // Humidity oversampling
Adafruit_BME280::FILTER_OFF, Adafruit_BME280::STANDBY_MS_1000);
initI2CSensor();
return status;
}
bool BME280Sensor::getMetrics(meshtastic_Telemetry *measurement)
{
measurement->variant.environment_metrics.has_temperature = true;
measurement->variant.environment_metrics.has_relative_humidity = true;
measurement->variant.environment_metrics.has_barometric_pressure = true;
bool BME280Sensor::getMetrics(meshtastic_Telemetry *measurement) {
measurement->variant.environment_metrics.has_temperature = true;
measurement->variant.environment_metrics.has_relative_humidity = true;
measurement->variant.environment_metrics.has_barometric_pressure = true;
LOG_DEBUG("BME280 getMetrics");
bme280.takeForcedMeasurement();
measurement->variant.environment_metrics.temperature = bme280.readTemperature();
measurement->variant.environment_metrics.relative_humidity = bme280.readHumidity();
measurement->variant.environment_metrics.barometric_pressure = bme280.readPressure() / 100.0F;
LOG_DEBUG("BME280 getMetrics");
bme280.takeForcedMeasurement();
measurement->variant.environment_metrics.temperature = bme280.readTemperature();
measurement->variant.environment_metrics.relative_humidity = bme280.readHumidity();
measurement->variant.environment_metrics.barometric_pressure = bme280.readPressure() / 100.0F;
return true;
return true;
}
#endif

View File

@@ -6,15 +6,14 @@
#include "TelemetrySensor.h"
#include <Adafruit_BME280.h>
class BME280Sensor : public TelemetrySensor
{
private:
Adafruit_BME280 bme280;
class BME280Sensor : public TelemetrySensor {
private:
Adafruit_BME280 bme280;
public:
BME280Sensor();
virtual bool getMetrics(meshtastic_Telemetry *measurement) override;
virtual bool initDevice(TwoWire *bus, ScanI2C::FoundDevice *dev) override;
public:
BME280Sensor();
virtual bool getMetrics(meshtastic_Telemetry *measurement) override;
virtual bool initDevice(TwoWire *bus, ScanI2C::FoundDevice *dev) override;
};
#endif

View File

@@ -10,139 +10,132 @@
BME680Sensor::BME680Sensor() : TelemetrySensor(meshtastic_TelemetrySensorType_BME680, "BME680") {}
int32_t BME680Sensor::runOnce()
{
if (!bme680.run()) {
checkStatus("runTrigger");
int32_t BME680Sensor::runOnce() {
if (!bme680.run()) {
checkStatus("runTrigger");
}
return 35;
}
bool BME680Sensor::initDevice(TwoWire *bus, ScanI2C::FoundDevice *dev) {
status = 0;
if (!bme680.begin(dev->address.address, *bus))
checkStatus("begin");
if (bme680.status == BSEC_OK) {
status = 1;
if (!bme680.setConfig(bsec_config)) {
checkStatus("setConfig");
status = 0;
}
return 35;
}
bool BME680Sensor::initDevice(TwoWire *bus, ScanI2C::FoundDevice *dev)
{
status = 0;
if (!bme680.begin(dev->address.address, *bus))
checkStatus("begin");
if (bme680.status == BSEC_OK) {
status = 1;
if (!bme680.setConfig(bsec_config)) {
checkStatus("setConfig");
status = 0;
}
loadState();
if (!bme680.updateSubscription(sensorList, ARRAY_LEN(sensorList), BSEC_SAMPLE_RATE_LP)) {
checkStatus("updateSubscription");
status = 0;
}
LOG_INFO("Init sensor: %s with the BSEC Library version %d.%d.%d.%d ", sensorName, bme680.version.major,
bme680.version.minor, bme680.version.major_bugfix, bme680.version.minor_bugfix);
loadState();
if (!bme680.updateSubscription(sensorList, ARRAY_LEN(sensorList), BSEC_SAMPLE_RATE_LP)) {
checkStatus("updateSubscription");
status = 0;
}
LOG_INFO("Init sensor: %s with the BSEC Library version %d.%d.%d.%d ", sensorName, bme680.version.major, bme680.version.minor,
bme680.version.major_bugfix, bme680.version.minor_bugfix);
}
if (status == 0)
LOG_DEBUG("BME680Sensor::runOnce: bme680.status %d", bme680.status);
if (status == 0)
LOG_DEBUG("BME680Sensor::runOnce: bme680.status %d", bme680.status);
initI2CSensor();
return status;
initI2CSensor();
return status;
}
bool BME680Sensor::getMetrics(meshtastic_Telemetry *measurement)
{
if (bme680.getData(BSEC_OUTPUT_RAW_PRESSURE).signal == 0)
return false;
bool BME680Sensor::getMetrics(meshtastic_Telemetry *measurement) {
if (bme680.getData(BSEC_OUTPUT_RAW_PRESSURE).signal == 0)
return false;
measurement->variant.environment_metrics.has_temperature = true;
measurement->variant.environment_metrics.has_relative_humidity = true;
measurement->variant.environment_metrics.has_barometric_pressure = true;
measurement->variant.environment_metrics.has_gas_resistance = true;
measurement->variant.environment_metrics.has_iaq = true;
measurement->variant.environment_metrics.has_temperature = true;
measurement->variant.environment_metrics.has_relative_humidity = true;
measurement->variant.environment_metrics.has_barometric_pressure = true;
measurement->variant.environment_metrics.has_gas_resistance = true;
measurement->variant.environment_metrics.has_iaq = true;
measurement->variant.environment_metrics.temperature = bme680.getData(BSEC_OUTPUT_SENSOR_HEAT_COMPENSATED_TEMPERATURE).signal;
measurement->variant.environment_metrics.relative_humidity =
bme680.getData(BSEC_OUTPUT_SENSOR_HEAT_COMPENSATED_HUMIDITY).signal;
measurement->variant.environment_metrics.barometric_pressure = bme680.getData(BSEC_OUTPUT_RAW_PRESSURE).signal;
measurement->variant.environment_metrics.gas_resistance = bme680.getData(BSEC_OUTPUT_RAW_GAS).signal / 1000.0;
// Check if we need to save state to filesystem (every STATE_SAVE_PERIOD ms)
measurement->variant.environment_metrics.iaq = bme680.getData(BSEC_OUTPUT_IAQ).signal;
updateState();
return true;
measurement->variant.environment_metrics.temperature = bme680.getData(BSEC_OUTPUT_SENSOR_HEAT_COMPENSATED_TEMPERATURE).signal;
measurement->variant.environment_metrics.relative_humidity = bme680.getData(BSEC_OUTPUT_SENSOR_HEAT_COMPENSATED_HUMIDITY).signal;
measurement->variant.environment_metrics.barometric_pressure = bme680.getData(BSEC_OUTPUT_RAW_PRESSURE).signal;
measurement->variant.environment_metrics.gas_resistance = bme680.getData(BSEC_OUTPUT_RAW_GAS).signal / 1000.0;
// Check if we need to save state to filesystem (every STATE_SAVE_PERIOD ms)
measurement->variant.environment_metrics.iaq = bme680.getData(BSEC_OUTPUT_IAQ).signal;
updateState();
return true;
}
void BME680Sensor::loadState()
{
void BME680Sensor::loadState() {
#ifdef FSCom
spiLock->lock();
auto file = FSCom.open(bsecConfigFileName, FILE_O_READ);
spiLock->lock();
auto file = FSCom.open(bsecConfigFileName, FILE_O_READ);
if (file) {
file.read((uint8_t *)&bsecState, BSEC_MAX_STATE_BLOB_SIZE);
file.close();
bme680.setState(bsecState);
LOG_INFO("%s state read from %s", sensorName, bsecConfigFileName);
} else {
LOG_INFO("No %s state found (File: %s)", sensorName, bsecConfigFileName);
}
spiLock->unlock();
#else
LOG_ERROR("ERROR: Filesystem not implemented");
#endif
}
void BME680Sensor::updateState() {
#ifdef FSCom
spiLock->lock();
bool update = false;
if (stateUpdateCounter == 0) {
/* First state update when IAQ accuracy is >= 3 */
accuracy = bme680.getData(BSEC_OUTPUT_IAQ).accuracy;
if (accuracy >= 2) {
LOG_DEBUG("%s state update IAQ accuracy %u >= 2", sensorName, accuracy);
update = true;
stateUpdateCounter++;
} else {
LOG_DEBUG("%s not updated, IAQ accuracy is %u < 2", sensorName, accuracy);
}
} else {
/* Update every STATE_SAVE_PERIOD minutes */
if ((stateUpdateCounter * STATE_SAVE_PERIOD) < millis()) {
LOG_DEBUG("%s state update every %d minutes", sensorName, STATE_SAVE_PERIOD / 60000);
update = true;
stateUpdateCounter++;
}
}
if (update) {
bme680.getState(bsecState);
if (FSCom.exists(bsecConfigFileName) && !FSCom.remove(bsecConfigFileName)) {
LOG_WARN("Can't remove old state file");
}
auto file = FSCom.open(bsecConfigFileName, FILE_O_WRITE);
if (file) {
file.read((uint8_t *)&bsecState, BSEC_MAX_STATE_BLOB_SIZE);
file.close();
bme680.setState(bsecState);
LOG_INFO("%s state read from %s", sensorName, bsecConfigFileName);
LOG_INFO("%s state write to %s", sensorName, bsecConfigFileName);
file.write((uint8_t *)&bsecState, BSEC_MAX_STATE_BLOB_SIZE);
file.flush();
file.close();
} else {
LOG_INFO("No %s state found (File: %s)", sensorName, bsecConfigFileName);
LOG_INFO("Can't write %s state (File: %s)", sensorName, bsecConfigFileName);
}
spiLock->unlock();
}
spiLock->unlock();
#else
LOG_ERROR("ERROR: Filesystem not implemented");
LOG_ERROR("ERROR: Filesystem not implemented");
#endif
}
void BME680Sensor::updateState()
{
#ifdef FSCom
spiLock->lock();
bool update = false;
if (stateUpdateCounter == 0) {
/* First state update when IAQ accuracy is >= 3 */
accuracy = bme680.getData(BSEC_OUTPUT_IAQ).accuracy;
if (accuracy >= 2) {
LOG_DEBUG("%s state update IAQ accuracy %u >= 2", sensorName, accuracy);
update = true;
stateUpdateCounter++;
} else {
LOG_DEBUG("%s not updated, IAQ accuracy is %u < 2", sensorName, accuracy);
}
} else {
/* Update every STATE_SAVE_PERIOD minutes */
if ((stateUpdateCounter * STATE_SAVE_PERIOD) < millis()) {
LOG_DEBUG("%s state update every %d minutes", sensorName, STATE_SAVE_PERIOD / 60000);
update = true;
stateUpdateCounter++;
}
}
void BME680Sensor::checkStatus(const char *functionName) {
if (bme680.status < BSEC_OK)
LOG_ERROR("%s BSEC2 code: %d", functionName, bme680.status);
else if (bme680.status > BSEC_OK)
LOG_WARN("%s BSEC2 code: %d", functionName, bme680.status);
if (update) {
bme680.getState(bsecState);
if (FSCom.exists(bsecConfigFileName) && !FSCom.remove(bsecConfigFileName)) {
LOG_WARN("Can't remove old state file");
}
auto file = FSCom.open(bsecConfigFileName, FILE_O_WRITE);
if (file) {
LOG_INFO("%s state write to %s", sensorName, bsecConfigFileName);
file.write((uint8_t *)&bsecState, BSEC_MAX_STATE_BLOB_SIZE);
file.flush();
file.close();
} else {
LOG_INFO("Can't write %s state (File: %s)", sensorName, bsecConfigFileName);
}
}
spiLock->unlock();
#else
LOG_ERROR("ERROR: Filesystem not implemented");
#endif
}
void BME680Sensor::checkStatus(const char *functionName)
{
if (bme680.status < BSEC_OK)
LOG_ERROR("%s BSEC2 code: %d", functionName, bme680.status);
else if (bme680.status > BSEC_OK)
LOG_WARN("%s BSEC2 code: %d", functionName, bme680.status);
if (bme680.sensor.status < BME68X_OK)
LOG_ERROR("%s BME68X code: %d", functionName, bme680.sensor.status);
else if (bme680.sensor.status > BME68X_OK)
LOG_WARN("%s BME68X code: %d", functionName, bme680.sensor.status);
if (bme680.sensor.status < BME68X_OK)
LOG_ERROR("%s BME68X code: %d", functionName, bme680.sensor.status);
else if (bme680.sensor.status > BME68X_OK)
LOG_WARN("%s BME68X code: %d", functionName, bme680.sensor.status);
}
#endif

View File

@@ -12,34 +12,33 @@ const uint8_t bsec_config[] = {
#include "config/bme680/bme680_iaq_33v_3s_4d/bsec_iaq.txt"
};
class BME680Sensor : public TelemetrySensor
{
private:
Bsec2 bme680;
class BME680Sensor : public TelemetrySensor {
private:
Bsec2 bme680;
protected:
const char *bsecConfigFileName = "/prefs/bsec.dat";
uint8_t bsecState[BSEC_MAX_STATE_BLOB_SIZE] = {0};
uint8_t accuracy = 0;
uint16_t stateUpdateCounter = 0;
bsecSensor sensorList[9] = {BSEC_OUTPUT_IAQ,
BSEC_OUTPUT_RAW_TEMPERATURE,
BSEC_OUTPUT_RAW_PRESSURE,
BSEC_OUTPUT_RAW_HUMIDITY,
BSEC_OUTPUT_RAW_GAS,
BSEC_OUTPUT_STABILIZATION_STATUS,
BSEC_OUTPUT_RUN_IN_STATUS,
BSEC_OUTPUT_SENSOR_HEAT_COMPENSATED_TEMPERATURE,
BSEC_OUTPUT_SENSOR_HEAT_COMPENSATED_HUMIDITY};
void loadState();
void updateState();
void checkStatus(const char *functionName);
protected:
const char *bsecConfigFileName = "/prefs/bsec.dat";
uint8_t bsecState[BSEC_MAX_STATE_BLOB_SIZE] = {0};
uint8_t accuracy = 0;
uint16_t stateUpdateCounter = 0;
bsecSensor sensorList[9] = {BSEC_OUTPUT_IAQ,
BSEC_OUTPUT_RAW_TEMPERATURE,
BSEC_OUTPUT_RAW_PRESSURE,
BSEC_OUTPUT_RAW_HUMIDITY,
BSEC_OUTPUT_RAW_GAS,
BSEC_OUTPUT_STABILIZATION_STATUS,
BSEC_OUTPUT_RUN_IN_STATUS,
BSEC_OUTPUT_SENSOR_HEAT_COMPENSATED_TEMPERATURE,
BSEC_OUTPUT_SENSOR_HEAT_COMPENSATED_HUMIDITY};
void loadState();
void updateState();
void checkStatus(const char *functionName);
public:
BME680Sensor();
virtual int32_t runOnce() override;
virtual bool getMetrics(meshtastic_Telemetry *measurement) override;
virtual bool initDevice(TwoWire *bus, ScanI2C::FoundDevice *dev) override;
public:
BME680Sensor();
virtual int32_t runOnce() override;
virtual bool getMetrics(meshtastic_Telemetry *measurement) override;
virtual bool initDevice(TwoWire *bus, ScanI2C::FoundDevice *dev) override;
};
#endif

View File

@@ -10,27 +10,25 @@
BMP085Sensor::BMP085Sensor() : TelemetrySensor(meshtastic_TelemetrySensorType_BMP085, "BMP085") {}
bool BMP085Sensor::initDevice(TwoWire *bus, ScanI2C::FoundDevice *dev)
{
LOG_INFO("Init sensor: %s", sensorName);
bool BMP085Sensor::initDevice(TwoWire *bus, ScanI2C::FoundDevice *dev) {
LOG_INFO("Init sensor: %s", sensorName);
bmp085 = Adafruit_BMP085();
status = bmp085.begin(dev->address.address, bus);
bmp085 = Adafruit_BMP085();
status = bmp085.begin(dev->address.address, bus);
initI2CSensor();
return status;
initI2CSensor();
return status;
}
bool BMP085Sensor::getMetrics(meshtastic_Telemetry *measurement)
{
measurement->variant.environment_metrics.has_temperature = true;
measurement->variant.environment_metrics.has_barometric_pressure = true;
bool BMP085Sensor::getMetrics(meshtastic_Telemetry *measurement) {
measurement->variant.environment_metrics.has_temperature = true;
measurement->variant.environment_metrics.has_barometric_pressure = true;
LOG_DEBUG("BMP085 getMetrics");
measurement->variant.environment_metrics.temperature = bmp085.readTemperature();
measurement->variant.environment_metrics.barometric_pressure = bmp085.readPressure() / 100.0F;
LOG_DEBUG("BMP085 getMetrics");
measurement->variant.environment_metrics.temperature = bmp085.readTemperature();
measurement->variant.environment_metrics.barometric_pressure = bmp085.readPressure() / 100.0F;
return true;
return true;
}
#endif

View File

@@ -6,15 +6,14 @@
#include "TelemetrySensor.h"
#include <Adafruit_BMP085.h>
class BMP085Sensor : public TelemetrySensor
{
private:
Adafruit_BMP085 bmp085;
class BMP085Sensor : public TelemetrySensor {
private:
Adafruit_BMP085 bmp085;
public:
BMP085Sensor();
virtual bool getMetrics(meshtastic_Telemetry *measurement) override;
virtual bool initDevice(TwoWire *bus, ScanI2C::FoundDevice *dev) override;
public:
BMP085Sensor();
virtual bool getMetrics(meshtastic_Telemetry *measurement) override;
virtual bool initDevice(TwoWire *bus, ScanI2C::FoundDevice *dev) override;
};
#endif

View File

@@ -10,36 +10,34 @@
BMP280Sensor::BMP280Sensor() : TelemetrySensor(meshtastic_TelemetrySensorType_BMP280, "BMP280") {}
bool BMP280Sensor::initDevice(TwoWire *bus, ScanI2C::FoundDevice *dev)
{
LOG_INFO("Init sensor: %s", sensorName);
bool BMP280Sensor::initDevice(TwoWire *bus, ScanI2C::FoundDevice *dev) {
LOG_INFO("Init sensor: %s", sensorName);
bmp280 = Adafruit_BMP280(bus);
status = bmp280.begin(dev->address.address);
if (!status) {
return status;
}
bmp280.setSampling(Adafruit_BMP280::MODE_FORCED,
Adafruit_BMP280::SAMPLING_X1, // Temp. oversampling
Adafruit_BMP280::SAMPLING_X1, // Pressure oversampling
Adafruit_BMP280::FILTER_OFF, Adafruit_BMP280::STANDBY_MS_1000);
initI2CSensor();
bmp280 = Adafruit_BMP280(bus);
status = bmp280.begin(dev->address.address);
if (!status) {
return status;
}
bmp280.setSampling(Adafruit_BMP280::MODE_FORCED,
Adafruit_BMP280::SAMPLING_X1, // Temp. oversampling
Adafruit_BMP280::SAMPLING_X1, // Pressure oversampling
Adafruit_BMP280::FILTER_OFF, Adafruit_BMP280::STANDBY_MS_1000);
initI2CSensor();
return status;
}
bool BMP280Sensor::getMetrics(meshtastic_Telemetry *measurement)
{
measurement->variant.environment_metrics.has_temperature = true;
measurement->variant.environment_metrics.has_barometric_pressure = true;
bool BMP280Sensor::getMetrics(meshtastic_Telemetry *measurement) {
measurement->variant.environment_metrics.has_temperature = true;
measurement->variant.environment_metrics.has_barometric_pressure = true;
LOG_DEBUG("BMP280 getMetrics");
bmp280.takeForcedMeasurement();
measurement->variant.environment_metrics.temperature = bmp280.readTemperature();
measurement->variant.environment_metrics.barometric_pressure = bmp280.readPressure() / 100.0F;
LOG_DEBUG("BMP280 getMetrics");
bmp280.takeForcedMeasurement();
measurement->variant.environment_metrics.temperature = bmp280.readTemperature();
measurement->variant.environment_metrics.barometric_pressure = bmp280.readPressure() / 100.0F;
return true;
return true;
}
#endif

View File

@@ -6,15 +6,14 @@
#include "TelemetrySensor.h"
#include <Adafruit_BMP280.h>
class BMP280Sensor : public TelemetrySensor
{
private:
Adafruit_BMP280 bmp280;
class BMP280Sensor : public TelemetrySensor {
private:
Adafruit_BMP280 bmp280;
public:
BMP280Sensor();
virtual bool getMetrics(meshtastic_Telemetry *measurement) override;
virtual bool initDevice(TwoWire *bus, ScanI2C::FoundDevice *dev) override;
public:
BMP280Sensor();
virtual bool getMetrics(meshtastic_Telemetry *measurement) override;
virtual bool initDevice(TwoWire *bus, ScanI2C::FoundDevice *dev) override;
};
#endif

View File

@@ -6,65 +6,61 @@
BMP3XXSensor::BMP3XXSensor() : TelemetrySensor(meshtastic_TelemetrySensorType_BMP3XX, "BMP3XX") {}
bool BMP3XXSensor::initDevice(TwoWire *bus, ScanI2C::FoundDevice *dev)
{
LOG_INFO("Init sensor: %s", sensorName);
bool BMP3XXSensor::initDevice(TwoWire *bus, ScanI2C::FoundDevice *dev) {
LOG_INFO("Init sensor: %s", sensorName);
// Get a singleton instance and initialise the bmp3xx
if (bmp3xx == nullptr) {
bmp3xx = BMP3XXSingleton::GetInstance();
}
status = bmp3xx->begin_I2C(dev->address.address, bus);
if (!status) {
return status;
}
// set up oversampling and filter initialization
bmp3xx->setTemperatureOversampling(BMP3_OVERSAMPLING_4X);
bmp3xx->setPressureOversampling(BMP3_OVERSAMPLING_8X);
bmp3xx->setIIRFilterCoeff(BMP3_IIR_FILTER_COEFF_3);
bmp3xx->setOutputDataRate(BMP3_ODR_25_HZ);
// take a couple of initial readings to settle the sensor filters
for (int i = 0; i < 3; i++) {
bmp3xx->performReading();
}
initI2CSensor();
// Get a singleton instance and initialise the bmp3xx
if (bmp3xx == nullptr) {
bmp3xx = BMP3XXSingleton::GetInstance();
}
status = bmp3xx->begin_I2C(dev->address.address, bus);
if (!status) {
return status;
}
// set up oversampling and filter initialization
bmp3xx->setTemperatureOversampling(BMP3_OVERSAMPLING_4X);
bmp3xx->setPressureOversampling(BMP3_OVERSAMPLING_8X);
bmp3xx->setIIRFilterCoeff(BMP3_IIR_FILTER_COEFF_3);
bmp3xx->setOutputDataRate(BMP3_ODR_25_HZ);
// take a couple of initial readings to settle the sensor filters
for (int i = 0; i < 3; i++) {
bmp3xx->performReading();
}
initI2CSensor();
return status;
}
bool BMP3XXSensor::getMetrics(meshtastic_Telemetry *measurement)
{
if (bmp3xx == nullptr) {
bmp3xx = BMP3XXSingleton::GetInstance();
}
if ((int)measurement->which_variant == meshtastic_Telemetry_environment_metrics_tag) {
bmp3xx->performReading();
bool BMP3XXSensor::getMetrics(meshtastic_Telemetry *measurement) {
if (bmp3xx == nullptr) {
bmp3xx = BMP3XXSingleton::GetInstance();
}
if ((int)measurement->which_variant == meshtastic_Telemetry_environment_metrics_tag) {
bmp3xx->performReading();
measurement->variant.environment_metrics.has_temperature = true;
measurement->variant.environment_metrics.has_barometric_pressure = true;
measurement->variant.environment_metrics.has_relative_humidity = false;
measurement->variant.environment_metrics.has_temperature = true;
measurement->variant.environment_metrics.has_barometric_pressure = true;
measurement->variant.environment_metrics.has_relative_humidity = false;
measurement->variant.environment_metrics.temperature = static_cast<float>(bmp3xx->temperature);
measurement->variant.environment_metrics.barometric_pressure = static_cast<float>(bmp3xx->pressure) / 100.0F;
measurement->variant.environment_metrics.relative_humidity = 0.0f;
measurement->variant.environment_metrics.temperature = static_cast<float>(bmp3xx->temperature);
measurement->variant.environment_metrics.barometric_pressure = static_cast<float>(bmp3xx->pressure) / 100.0F;
measurement->variant.environment_metrics.relative_humidity = 0.0f;
LOG_DEBUG("BMP3XX getMetrics id: %i temp: %.1f press %.1f", measurement->which_variant,
measurement->variant.environment_metrics.temperature,
measurement->variant.environment_metrics.barometric_pressure);
} else {
LOG_DEBUG("BMP3XX getMetrics id: %i", measurement->which_variant);
}
return true;
LOG_DEBUG("BMP3XX getMetrics id: %i temp: %.1f press %.1f", measurement->which_variant, measurement->variant.environment_metrics.temperature,
measurement->variant.environment_metrics.barometric_pressure);
} else {
LOG_DEBUG("BMP3XX getMetrics id: %i", measurement->which_variant);
}
return true;
}
// Get a singleton wrapper for an Adafruit_bmp3xx
BMP3XXSingleton *BMP3XXSingleton::GetInstance()
{
if (pinstance == nullptr) {
pinstance = new BMP3XXSingleton();
}
return pinstance;
BMP3XXSingleton *BMP3XXSingleton::GetInstance() {
if (pinstance == nullptr) {
pinstance = new BMP3XXSingleton();
}
return pinstance;
}
BMP3XXSingleton::BMP3XXSingleton() {}
@@ -73,16 +69,15 @@ BMP3XXSingleton::~BMP3XXSingleton() {}
BMP3XXSingleton *BMP3XXSingleton::pinstance{nullptr};
bool BMP3XXSingleton::performReading()
{
bool result = Adafruit_BMP3XX::performReading();
if (result) {
double atmospheric = this->pressure / 100.0;
altitudeAmslMetres = 44330.0 * (1.0 - pow(atmospheric / SEAL_LEVEL_HPA, 0.1903));
} else {
altitudeAmslMetres = 0.0;
}
return result;
bool BMP3XXSingleton::performReading() {
bool result = Adafruit_BMP3XX::performReading();
if (result) {
double atmospheric = this->pressure / 100.0;
altitudeAmslMetres = 44330.0 * (1.0 - pow(atmospheric / SEAL_LEVEL_HPA, 0.1903));
} else {
altitudeAmslMetres = 0.0;
}
return result;
}
#endif

View File

@@ -12,42 +12,40 @@
#include <typeinfo>
// Singleton wrapper for the Adafruit_BMP3XX class
class BMP3XXSingleton : public Adafruit_BMP3XX
{
private:
static BMP3XXSingleton *pinstance;
class BMP3XXSingleton : public Adafruit_BMP3XX {
private:
static BMP3XXSingleton *pinstance;
protected:
BMP3XXSingleton();
~BMP3XXSingleton();
protected:
BMP3XXSingleton();
~BMP3XXSingleton();
public:
// Create a singleton instance (not thread safe)
static BMP3XXSingleton *GetInstance();
public:
// Create a singleton instance (not thread safe)
static BMP3XXSingleton *GetInstance();
// Singletons should not be cloneable.
BMP3XXSingleton(BMP3XXSingleton &other) = delete;
// Singletons should not be cloneable.
BMP3XXSingleton(BMP3XXSingleton &other) = delete;
// Singletons should not be assignable.
void operator=(const BMP3XXSingleton &) = delete;
// Singletons should not be assignable.
void operator=(const BMP3XXSingleton &) = delete;
// Performs a full reading of all sensors in the BMP3XX. Assigns
// the internal temperature, pressure and altitudeAmsl variables
bool performReading();
// Performs a full reading of all sensors in the BMP3XX. Assigns
// the internal temperature, pressure and altitudeAmsl variables
bool performReading();
// Altitude in metres above mean sea level, assigned after calling performReading()
double altitudeAmslMetres = 0.0f;
// Altitude in metres above mean sea level, assigned after calling performReading()
double altitudeAmslMetres = 0.0f;
};
class BMP3XXSensor : public TelemetrySensor
{
protected:
BMP3XXSingleton *bmp3xx = nullptr;
class BMP3XXSensor : public TelemetrySensor {
protected:
BMP3XXSingleton *bmp3xx = nullptr;
public:
BMP3XXSensor();
virtual bool getMetrics(meshtastic_Telemetry *measurement) override;
virtual bool initDevice(TwoWire *bus, ScanI2C::FoundDevice *dev) override;
public:
BMP3XXSensor();
virtual bool getMetrics(meshtastic_Telemetry *measurement) override;
virtual bool initDevice(TwoWire *bus, ScanI2C::FoundDevice *dev) override;
};
#endif

View File

@@ -14,55 +14,51 @@
CGRadSensSensor::CGRadSensSensor() : TelemetrySensor(meshtastic_TelemetrySensorType_RADSENS, "RadSens") {}
bool CGRadSensSensor::initDevice(TwoWire *bus, ScanI2C::FoundDevice *dev)
{
// Initialize the sensor following the same pattern as RCWL9620Sensor
LOG_INFO("Init sensor: %s", sensorName);
status = true;
begin(bus, dev->address.address);
initI2CSensor();
return status;
bool CGRadSensSensor::initDevice(TwoWire *bus, ScanI2C::FoundDevice *dev) {
// Initialize the sensor following the same pattern as RCWL9620Sensor
LOG_INFO("Init sensor: %s", sensorName);
status = true;
begin(bus, dev->address.address);
initI2CSensor();
return status;
}
void CGRadSensSensor::begin(TwoWire *wire, uint8_t addr)
{
// Store the Wire and address to the sensor following the same pattern as RCWL9620Sensor
_wire = wire;
_addr = addr;
_wire->begin();
void CGRadSensSensor::begin(TwoWire *wire, uint8_t addr) {
// Store the Wire and address to the sensor following the same pattern as RCWL9620Sensor
_wire = wire;
_addr = addr;
_wire->begin();
}
float CGRadSensSensor::getStaticRadiation()
{
// Read a register, following the same pattern as the RCWL9620Sensor
_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
uint32_t data = _wire->read();
data <<= 8;
data |= _wire->read();
data <<= 8;
data |= _wire->read();
float CGRadSensSensor::getStaticRadiation() {
// Read a register, following the same pattern as the RCWL9620Sensor
_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
uint32_t data = _wire->read();
data <<= 8;
data |= _wire->read();
data <<= 8;
data |= _wire->read();
// As per the data sheet for the RadSens
// Register 0x06 contains the reading in 0.1 * μR / h
float microRadPerHr = float(data) / 10.0;
return microRadPerHr;
}
// As per the data sheet for the RadSens
// Register 0x06 contains the reading in 0.1 * μR / h
float microRadPerHr = float(data) / 10.0;
return microRadPerHr;
}
return -1.0;
}
return -1.0;
}
bool CGRadSensSensor::getMetrics(meshtastic_Telemetry *measurement)
{
// Store the meansurement in the the appropriate fields of the protobuf
measurement->variant.environment_metrics.has_radiation = true;
bool CGRadSensSensor::getMetrics(meshtastic_Telemetry *measurement) {
// Store the meansurement in the the appropriate fields of the protobuf
measurement->variant.environment_metrics.has_radiation = true;
LOG_DEBUG("CGRADSENS getMetrics");
measurement->variant.environment_metrics.radiation = getStaticRadiation();
LOG_DEBUG("CGRADSENS getMetrics");
measurement->variant.environment_metrics.radiation = getStaticRadiation();
return true;
return true;
}
#endif

View File

@@ -10,20 +10,19 @@
#include "TelemetrySensor.h"
#include <Wire.h>
class CGRadSensSensor : public TelemetrySensor
{
private:
uint8_t _addr = 0x66;
TwoWire *_wire = &Wire;
class CGRadSensSensor : public TelemetrySensor {
private:
uint8_t _addr = 0x66;
TwoWire *_wire = &Wire;
protected:
void begin(TwoWire *wire = &Wire, uint8_t addr = 0x66);
float getStaticRadiation();
protected:
void begin(TwoWire *wire = &Wire, uint8_t addr = 0x66);
float getStaticRadiation();
public:
CGRadSensSensor();
virtual bool getMetrics(meshtastic_Telemetry *measurement) override;
virtual bool initDevice(TwoWire *bus, ScanI2C::FoundDevice *dev) override;
public:
CGRadSensSensor();
virtual bool getMetrics(meshtastic_Telemetry *measurement) override;
virtual bool initDevice(TwoWire *bus, ScanI2C::FoundDevice *dev) override;
};
#endif

View File

@@ -4,10 +4,9 @@
#pragma once
class CurrentSensor
{
public:
virtual int16_t getCurrentMa() = 0;
class CurrentSensor {
public:
virtual int16_t getCurrentMa() = 0;
};
#endif

View File

@@ -10,46 +10,43 @@
DFRobotGravitySensor::DFRobotGravitySensor() : TelemetrySensor(meshtastic_TelemetrySensorType_DFROBOT_RAIN, "DFROBOT_RAIN") {}
DFRobotGravitySensor::~DFRobotGravitySensor()
{
if (gravity) {
DFRobotGravitySensor::~DFRobotGravitySensor() {
if (gravity) {
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wdelete-non-virtual-dtor"
delete gravity;
delete gravity;
#pragma GCC diagnostic pop
gravity = nullptr;
}
gravity = nullptr;
}
}
bool DFRobotGravitySensor::initDevice(TwoWire *bus, ScanI2C::FoundDevice *dev)
{
LOG_INFO("Init sensor: %s", sensorName);
bool DFRobotGravitySensor::initDevice(TwoWire *bus, ScanI2C::FoundDevice *dev) {
LOG_INFO("Init sensor: %s", sensorName);
gravity = new DFRobot_RainfallSensor_I2C(bus);
status = gravity->begin();
gravity = new DFRobot_RainfallSensor_I2C(bus);
status = gravity->begin();
LOG_DEBUG("%s VID: %x, PID: %x, Version: %s", sensorName, gravity->vid, gravity->pid, gravity->getFirmwareVersion().c_str());
LOG_DEBUG("%s VID: %x, PID: %x, Version: %s", sensorName, gravity->vid, gravity->pid, gravity->getFirmwareVersion().c_str());
initI2CSensor();
return status;
initI2CSensor();
return status;
}
bool DFRobotGravitySensor::getMetrics(meshtastic_Telemetry *measurement)
{
if (!gravity) {
LOG_ERROR("DFRobotGravitySensor not initialized");
return false;
}
bool DFRobotGravitySensor::getMetrics(meshtastic_Telemetry *measurement) {
if (!gravity) {
LOG_ERROR("DFRobotGravitySensor not initialized");
return false;
}
measurement->variant.environment_metrics.has_rainfall_1h = true;
measurement->variant.environment_metrics.has_rainfall_24h = true;
measurement->variant.environment_metrics.has_rainfall_1h = true;
measurement->variant.environment_metrics.has_rainfall_24h = true;
measurement->variant.environment_metrics.rainfall_1h = gravity->getRainfall(1);
measurement->variant.environment_metrics.rainfall_24h = gravity->getRainfall(24);
measurement->variant.environment_metrics.rainfall_1h = gravity->getRainfall(1);
measurement->variant.environment_metrics.rainfall_24h = gravity->getRainfall(24);
LOG_INFO("Rain 1h: %f mm", measurement->variant.environment_metrics.rainfall_1h);
LOG_INFO("Rain 24h: %f mm", measurement->variant.environment_metrics.rainfall_24h);
return true;
LOG_INFO("Rain 1h: %f mm", measurement->variant.environment_metrics.rainfall_1h);
LOG_INFO("Rain 24h: %f mm", measurement->variant.environment_metrics.rainfall_24h);
return true;
}
#endif

View File

@@ -11,16 +11,15 @@
#include <DFRobot_RainfallSensor.h>
#include <string>
class DFRobotGravitySensor : public TelemetrySensor
{
private:
DFRobot_RainfallSensor_I2C *gravity = nullptr;
class DFRobotGravitySensor : public TelemetrySensor {
private:
DFRobot_RainfallSensor_I2C *gravity = nullptr;
public:
DFRobotGravitySensor();
~DFRobotGravitySensor();
virtual bool getMetrics(meshtastic_Telemetry *measurement) override;
virtual bool initDevice(TwoWire *bus, ScanI2C::FoundDevice *dev) override;
public:
DFRobotGravitySensor();
~DFRobotGravitySensor();
virtual bool getMetrics(meshtastic_Telemetry *measurement) override;
virtual bool initDevice(TwoWire *bus, ScanI2C::FoundDevice *dev) override;
};
#endif

View File

@@ -11,44 +11,42 @@
DFRobotLarkSensor::DFRobotLarkSensor() : TelemetrySensor(meshtastic_TelemetrySensorType_DFROBOT_LARK, "DFROBOT_LARK") {}
bool DFRobotLarkSensor::initDevice(TwoWire *bus, ScanI2C::FoundDevice *dev)
{
LOG_INFO("Init sensor: %s", sensorName);
lark = DFRobot_LarkWeatherStation_I2C(dev->address.address, bus);
bool DFRobotLarkSensor::initDevice(TwoWire *bus, ScanI2C::FoundDevice *dev) {
LOG_INFO("Init sensor: %s", sensorName);
lark = DFRobot_LarkWeatherStation_I2C(dev->address.address, bus);
if (lark.begin() == 0) // DFRobotLarkSensor init
{
LOG_DEBUG("DFRobotLarkSensor Init Succeed");
status = true;
} else {
LOG_ERROR("DFRobotLarkSensor Init Failed");
status = false;
}
initI2CSensor();
return status;
if (lark.begin() == 0) // DFRobotLarkSensor init
{
LOG_DEBUG("DFRobotLarkSensor Init Succeed");
status = true;
} else {
LOG_ERROR("DFRobotLarkSensor Init Failed");
status = false;
}
initI2CSensor();
return status;
}
bool DFRobotLarkSensor::getMetrics(meshtastic_Telemetry *measurement)
{
measurement->variant.environment_metrics.has_temperature = true;
measurement->variant.environment_metrics.has_relative_humidity = true;
measurement->variant.environment_metrics.has_wind_speed = true;
measurement->variant.environment_metrics.has_wind_direction = true;
measurement->variant.environment_metrics.has_barometric_pressure = true;
bool DFRobotLarkSensor::getMetrics(meshtastic_Telemetry *measurement) {
measurement->variant.environment_metrics.has_temperature = true;
measurement->variant.environment_metrics.has_relative_humidity = true;
measurement->variant.environment_metrics.has_wind_speed = true;
measurement->variant.environment_metrics.has_wind_direction = true;
measurement->variant.environment_metrics.has_barometric_pressure = true;
measurement->variant.environment_metrics.temperature = lark.getValue("Temp").toFloat();
measurement->variant.environment_metrics.relative_humidity = lark.getValue("Humi").toFloat();
measurement->variant.environment_metrics.wind_speed = lark.getValue("Speed").toFloat();
measurement->variant.environment_metrics.wind_direction = GeoCoord::bearingToDegrees(lark.getValue("Dir").c_str());
measurement->variant.environment_metrics.barometric_pressure = lark.getValue("Pressure").toFloat();
measurement->variant.environment_metrics.temperature = lark.getValue("Temp").toFloat();
measurement->variant.environment_metrics.relative_humidity = lark.getValue("Humi").toFloat();
measurement->variant.environment_metrics.wind_speed = lark.getValue("Speed").toFloat();
measurement->variant.environment_metrics.wind_direction = GeoCoord::bearingToDegrees(lark.getValue("Dir").c_str());
measurement->variant.environment_metrics.barometric_pressure = lark.getValue("Pressure").toFloat();
LOG_INFO("Temperature: %f", measurement->variant.environment_metrics.temperature);
LOG_INFO("Humidity: %f", measurement->variant.environment_metrics.relative_humidity);
LOG_INFO("Wind Speed: %f", measurement->variant.environment_metrics.wind_speed);
LOG_INFO("Wind Direction: %d", measurement->variant.environment_metrics.wind_direction);
LOG_INFO("Barometric Pressure: %f", measurement->variant.environment_metrics.barometric_pressure);
LOG_INFO("Temperature: %f", measurement->variant.environment_metrics.temperature);
LOG_INFO("Humidity: %f", measurement->variant.environment_metrics.relative_humidity);
LOG_INFO("Wind Speed: %f", measurement->variant.environment_metrics.wind_speed);
LOG_INFO("Wind Direction: %d", measurement->variant.environment_metrics.wind_direction);
LOG_INFO("Barometric Pressure: %f", measurement->variant.environment_metrics.barometric_pressure);
return true;
return true;
}
#endif

View File

@@ -11,15 +11,14 @@
#include <DFRobot_LarkWeatherStation.h>
#include <string>
class DFRobotLarkSensor : public TelemetrySensor
{
private:
DFRobot_LarkWeatherStation_I2C lark = DFRobot_LarkWeatherStation_I2C();
class DFRobotLarkSensor : public TelemetrySensor {
private:
DFRobot_LarkWeatherStation_I2C lark = DFRobot_LarkWeatherStation_I2C();
public:
DFRobotLarkSensor();
virtual bool getMetrics(meshtastic_Telemetry *measurement) override;
virtual bool initDevice(TwoWire *bus, ScanI2C::FoundDevice *dev) override;
public:
DFRobotLarkSensor();
virtual bool getMetrics(meshtastic_Telemetry *measurement) override;
virtual bool initDevice(TwoWire *bus, ScanI2C::FoundDevice *dev) override;
};
#endif

View File

@@ -9,36 +9,34 @@
DPS310Sensor::DPS310Sensor() : TelemetrySensor(meshtastic_TelemetrySensorType_DPS310, "DPS310") {}
bool DPS310Sensor::initDevice(TwoWire *bus, ScanI2C::FoundDevice *dev)
{
LOG_INFO("Init sensor: %s", sensorName);
status = dps310.begin_I2C(dev->address.address, bus);
if (!status) {
return status;
}
dps310.configurePressure(DPS310_1HZ, DPS310_4SAMPLES);
dps310.configureTemperature(DPS310_1HZ, DPS310_4SAMPLES);
dps310.setMode(DPS310_CONT_PRESTEMP);
initI2CSensor();
bool DPS310Sensor::initDevice(TwoWire *bus, ScanI2C::FoundDevice *dev) {
LOG_INFO("Init sensor: %s", sensorName);
status = dps310.begin_I2C(dev->address.address, bus);
if (!status) {
return status;
}
dps310.configurePressure(DPS310_1HZ, DPS310_4SAMPLES);
dps310.configureTemperature(DPS310_1HZ, DPS310_4SAMPLES);
dps310.setMode(DPS310_CONT_PRESTEMP);
initI2CSensor();
return status;
}
bool DPS310Sensor::getMetrics(meshtastic_Telemetry *measurement)
{
sensors_event_t temp, press;
bool DPS310Sensor::getMetrics(meshtastic_Telemetry *measurement) {
sensors_event_t temp, press;
if (!dps310.getEvents(&temp, &press)) {
LOG_DEBUG("DPS310 getEvents no data");
return false;
}
if (!dps310.getEvents(&temp, &press)) {
LOG_DEBUG("DPS310 getEvents no data");
return false;
}
measurement->variant.environment_metrics.has_temperature = true;
measurement->variant.environment_metrics.has_barometric_pressure = true;
measurement->variant.environment_metrics.temperature = temp.temperature;
measurement->variant.environment_metrics.barometric_pressure = press.pressure;
measurement->variant.environment_metrics.has_temperature = true;
measurement->variant.environment_metrics.has_barometric_pressure = true;
measurement->variant.environment_metrics.temperature = temp.temperature;
measurement->variant.environment_metrics.barometric_pressure = press.pressure;
return true;
return true;
}
#endif

View File

@@ -6,15 +6,14 @@
#include "TelemetrySensor.h"
#include <Adafruit_DPS310.h>
class DPS310Sensor : public TelemetrySensor
{
private:
Adafruit_DPS310 dps310;
class DPS310Sensor : public TelemetrySensor {
private:
Adafruit_DPS310 dps310;
public:
DPS310Sensor();
virtual bool getMetrics(meshtastic_Telemetry *measurement) override;
virtual bool initDevice(TwoWire *bus, ScanI2C::FoundDevice *dev) override;
public:
DPS310Sensor();
virtual bool getMetrics(meshtastic_Telemetry *measurement) override;
virtual bool initDevice(TwoWire *bus, ScanI2C::FoundDevice *dev) override;
};
#endif

View File

@@ -13,41 +13,33 @@
INA219Sensor::INA219Sensor() : TelemetrySensor(meshtastic_TelemetrySensorType_INA219, "INA219") {}
int32_t INA219Sensor::runOnce()
{
LOG_INFO("Init sensor: %s", sensorName);
if (!hasSensor()) {
return DEFAULT_SENSOR_MINIMUM_WAIT_TIME_BETWEEN_READS;
}
if (!ina219.success()) {
ina219 = Adafruit_INA219(nodeTelemetrySensorsMap[sensorType].first);
status = ina219.begin(nodeTelemetrySensorsMap[sensorType].second);
} else {
status = ina219.success();
}
return initI2CSensor();
int32_t INA219Sensor::runOnce() {
LOG_INFO("Init sensor: %s", sensorName);
if (!hasSensor()) {
return DEFAULT_SENSOR_MINIMUM_WAIT_TIME_BETWEEN_READS;
}
if (!ina219.success()) {
ina219 = Adafruit_INA219(nodeTelemetrySensorsMap[sensorType].first);
status = ina219.begin(nodeTelemetrySensorsMap[sensorType].second);
} else {
status = ina219.success();
}
return initI2CSensor();
}
void INA219Sensor::setup() {}
bool INA219Sensor::getMetrics(meshtastic_Telemetry *measurement)
{
measurement->variant.environment_metrics.has_voltage = true;
measurement->variant.environment_metrics.has_current = true;
bool INA219Sensor::getMetrics(meshtastic_Telemetry *measurement) {
measurement->variant.environment_metrics.has_voltage = true;
measurement->variant.environment_metrics.has_current = true;
measurement->variant.environment_metrics.voltage = ina219.getBusVoltage_V();
measurement->variant.environment_metrics.current = ina219.getCurrent_mA() * INA219_MULTIPLIER;
return true;
measurement->variant.environment_metrics.voltage = ina219.getBusVoltage_V();
measurement->variant.environment_metrics.current = ina219.getCurrent_mA() * INA219_MULTIPLIER;
return true;
}
uint16_t INA219Sensor::getBusVoltageMv()
{
return lround(ina219.getBusVoltage_V() * 1000);
}
uint16_t INA219Sensor::getBusVoltageMv() { return lround(ina219.getBusVoltage_V() * 1000); }
int16_t INA219Sensor::getCurrentMa()
{
return lround(ina219.getCurrent_mA());
}
int16_t INA219Sensor::getCurrentMa() { return lround(ina219.getCurrent_mA()); }
#endif

View File

@@ -8,20 +8,19 @@
#include "VoltageSensor.h"
#include <Adafruit_INA219.h>
class INA219Sensor : public TelemetrySensor, VoltageSensor, CurrentSensor
{
private:
Adafruit_INA219 ina219;
class INA219Sensor : public TelemetrySensor, VoltageSensor, CurrentSensor {
private:
Adafruit_INA219 ina219;
protected:
virtual void setup() override;
protected:
virtual void setup() override;
public:
INA219Sensor();
virtual int32_t runOnce() override;
virtual bool getMetrics(meshtastic_Telemetry *measurement) override;
virtual uint16_t getBusVoltageMv() override;
virtual int16_t getCurrentMa() override;
public:
INA219Sensor();
virtual int32_t runOnce() override;
virtual bool getMetrics(meshtastic_Telemetry *measurement) override;
virtual uint16_t getBusVoltageMv() override;
virtual int16_t getCurrentMa() override;
};
#endif

View File

@@ -9,76 +9,65 @@
INA226Sensor::INA226Sensor() : TelemetrySensor(meshtastic_TelemetrySensorType_INA226, "INA226") {}
int32_t INA226Sensor::runOnce()
{
LOG_INFO("Init sensor: %s", sensorName);
if (!hasSensor()) {
return DEFAULT_SENSOR_MINIMUM_WAIT_TIME_BETWEEN_READS;
}
int32_t INA226Sensor::runOnce() {
LOG_INFO("Init sensor: %s", sensorName);
if (!hasSensor()) {
return DEFAULT_SENSOR_MINIMUM_WAIT_TIME_BETWEEN_READS;
}
begin(nodeTelemetrySensorsMap[sensorType].second, nodeTelemetrySensorsMap[sensorType].first);
begin(nodeTelemetrySensorsMap[sensorType].second, nodeTelemetrySensorsMap[sensorType].first);
if (!status) {
status = ina226.begin();
}
return initI2CSensor();
if (!status) {
status = ina226.begin();
}
return initI2CSensor();
}
void INA226Sensor::setup() {}
void INA226Sensor::begin(TwoWire *wire, uint8_t addr)
{
_wire = wire;
_addr = addr;
ina226 = INA226(_addr, _wire);
_wire->begin();
ina226.setMaxCurrentShunt(0.8, 0.100);
void INA226Sensor::begin(TwoWire *wire, uint8_t addr) {
_wire = wire;
_addr = addr;
ina226 = INA226(_addr, _wire);
_wire->begin();
ina226.setMaxCurrentShunt(0.8, 0.100);
}
bool INA226Sensor::getMetrics(meshtastic_Telemetry *measurement)
{
switch (measurement->which_variant) {
case meshtastic_Telemetry_environment_metrics_tag:
return getEnvironmentMetrics(measurement);
bool INA226Sensor::getMetrics(meshtastic_Telemetry *measurement) {
switch (measurement->which_variant) {
case meshtastic_Telemetry_environment_metrics_tag:
return getEnvironmentMetrics(measurement);
case meshtastic_Telemetry_power_metrics_tag:
return getPowerMetrics(measurement);
}
case meshtastic_Telemetry_power_metrics_tag:
return getPowerMetrics(measurement);
}
// unsupported metric
return false;
// unsupported metric
return false;
}
bool INA226Sensor::getEnvironmentMetrics(meshtastic_Telemetry *measurement)
{
measurement->variant.environment_metrics.has_voltage = true;
measurement->variant.environment_metrics.has_current = true;
bool INA226Sensor::getEnvironmentMetrics(meshtastic_Telemetry *measurement) {
measurement->variant.environment_metrics.has_voltage = true;
measurement->variant.environment_metrics.has_current = true;
measurement->variant.environment_metrics.voltage = ina226.getBusVoltage();
measurement->variant.environment_metrics.current = ina226.getCurrent_mA();
measurement->variant.environment_metrics.voltage = ina226.getBusVoltage();
measurement->variant.environment_metrics.current = ina226.getCurrent_mA();
return true;
return true;
}
bool INA226Sensor::getPowerMetrics(meshtastic_Telemetry *measurement)
{
measurement->variant.power_metrics.has_ch1_voltage = true;
measurement->variant.power_metrics.has_ch1_current = true;
bool INA226Sensor::getPowerMetrics(meshtastic_Telemetry *measurement) {
measurement->variant.power_metrics.has_ch1_voltage = true;
measurement->variant.power_metrics.has_ch1_current = true;
measurement->variant.power_metrics.ch1_voltage = ina226.getBusVoltage();
measurement->variant.power_metrics.ch1_current = ina226.getCurrent_mA();
measurement->variant.power_metrics.ch1_voltage = ina226.getBusVoltage();
measurement->variant.power_metrics.ch1_current = ina226.getCurrent_mA();
return true;
return true;
}
uint16_t INA226Sensor::getBusVoltageMv()
{
return lround(ina226.getBusVoltage() * 1000);
}
uint16_t INA226Sensor::getBusVoltageMv() { return lround(ina226.getBusVoltage() * 1000); }
int16_t INA226Sensor::getCurrentMa()
{
return lround(ina226.getCurrent_mA());
}
int16_t INA226Sensor::getCurrentMa() { return lround(ina226.getCurrent_mA()); }
#endif

View File

@@ -8,26 +8,25 @@
#include "VoltageSensor.h"
#include <INA226.h>
class INA226Sensor : public TelemetrySensor, VoltageSensor, CurrentSensor
{
private:
uint8_t _addr = INA_ADDR;
TwoWire *_wire = &Wire;
INA226 ina226 = INA226(_addr, _wire);
class INA226Sensor : public TelemetrySensor, VoltageSensor, CurrentSensor {
private:
uint8_t _addr = INA_ADDR;
TwoWire *_wire = &Wire;
INA226 ina226 = INA226(_addr, _wire);
bool getEnvironmentMetrics(meshtastic_Telemetry *measurement);
bool getPowerMetrics(meshtastic_Telemetry *measurement);
bool getEnvironmentMetrics(meshtastic_Telemetry *measurement);
bool getPowerMetrics(meshtastic_Telemetry *measurement);
protected:
virtual void setup() override;
void begin(TwoWire *wire = &Wire, uint8_t addr = INA_ADDR);
protected:
virtual void setup() override;
void begin(TwoWire *wire = &Wire, uint8_t addr = INA_ADDR);
public:
INA226Sensor();
virtual int32_t runOnce() override;
virtual bool getMetrics(meshtastic_Telemetry *measurement) override;
virtual uint16_t getBusVoltageMv() override;
virtual int16_t getCurrentMa() override;
public:
INA226Sensor();
virtual int32_t runOnce() override;
virtual bool getMetrics(meshtastic_Telemetry *measurement) override;
virtual uint16_t getBusVoltageMv() override;
virtual int16_t getCurrentMa() override;
};
#endif

View File

@@ -9,35 +9,30 @@
INA260Sensor::INA260Sensor() : TelemetrySensor(meshtastic_TelemetrySensorType_INA260, "INA260") {}
int32_t INA260Sensor::runOnce()
{
LOG_INFO("Init sensor: %s", sensorName);
if (!hasSensor()) {
return DEFAULT_SENSOR_MINIMUM_WAIT_TIME_BETWEEN_READS;
}
int32_t INA260Sensor::runOnce() {
LOG_INFO("Init sensor: %s", sensorName);
if (!hasSensor()) {
return DEFAULT_SENSOR_MINIMUM_WAIT_TIME_BETWEEN_READS;
}
if (!status) {
status = ina260.begin(nodeTelemetrySensorsMap[sensorType].first, nodeTelemetrySensorsMap[sensorType].second);
}
return initI2CSensor();
if (!status) {
status = ina260.begin(nodeTelemetrySensorsMap[sensorType].first, nodeTelemetrySensorsMap[sensorType].second);
}
return initI2CSensor();
}
void INA260Sensor::setup() {}
bool INA260Sensor::getMetrics(meshtastic_Telemetry *measurement)
{
measurement->variant.environment_metrics.has_voltage = true;
measurement->variant.environment_metrics.has_current = true;
bool INA260Sensor::getMetrics(meshtastic_Telemetry *measurement) {
measurement->variant.environment_metrics.has_voltage = true;
measurement->variant.environment_metrics.has_current = true;
// mV conversion to V
measurement->variant.environment_metrics.voltage = ina260.readBusVoltage() / 1000;
measurement->variant.environment_metrics.current = ina260.readCurrent();
return true;
// mV conversion to V
measurement->variant.environment_metrics.voltage = ina260.readBusVoltage() / 1000;
measurement->variant.environment_metrics.current = ina260.readCurrent();
return true;
}
uint16_t INA260Sensor::getBusVoltageMv()
{
return lround(ina260.readBusVoltage());
}
uint16_t INA260Sensor::getBusVoltageMv() { return lround(ina260.readBusVoltage()); }
#endif

View File

@@ -7,19 +7,18 @@
#include "VoltageSensor.h"
#include <Adafruit_INA260.h>
class INA260Sensor : public TelemetrySensor, VoltageSensor
{
private:
Adafruit_INA260 ina260 = Adafruit_INA260();
class INA260Sensor : public TelemetrySensor, VoltageSensor {
private:
Adafruit_INA260 ina260 = Adafruit_INA260();
protected:
virtual void setup() override;
protected:
virtual void setup() override;
public:
INA260Sensor();
virtual int32_t runOnce() override;
virtual bool getMetrics(meshtastic_Telemetry *measurement) override;
virtual uint16_t getBusVoltageMv() override;
public:
INA260Sensor();
virtual int32_t runOnce() override;
virtual bool getMetrics(meshtastic_Telemetry *measurement) override;
virtual uint16_t getBusVoltageMv() override;
};
#endif

View File

@@ -9,102 +9,90 @@
INA3221Sensor::INA3221Sensor() : TelemetrySensor(meshtastic_TelemetrySensorType_INA3221, "INA3221"){};
int32_t INA3221Sensor::runOnce()
{
LOG_INFO("Init sensor: %s", sensorName);
if (!hasSensor()) {
return DEFAULT_SENSOR_MINIMUM_WAIT_TIME_BETWEEN_READS;
}
if (!status) {
ina3221.begin(nodeTelemetrySensorsMap[sensorType].second);
ina3221.setShuntRes(100, 100, 100); // 0.1 Ohm shunt resistors
status = true;
} else {
status = true;
}
return initI2CSensor();
int32_t INA3221Sensor::runOnce() {
LOG_INFO("Init sensor: %s", sensorName);
if (!hasSensor()) {
return DEFAULT_SENSOR_MINIMUM_WAIT_TIME_BETWEEN_READS;
}
if (!status) {
ina3221.begin(nodeTelemetrySensorsMap[sensorType].second);
ina3221.setShuntRes(100, 100, 100); // 0.1 Ohm shunt resistors
status = true;
} else {
status = true;
}
return initI2CSensor();
};
void INA3221Sensor::setup() {}
struct _INA3221Measurement INA3221Sensor::getMeasurement(ina3221_ch_t ch)
{
struct _INA3221Measurement measurement;
struct _INA3221Measurement INA3221Sensor::getMeasurement(ina3221_ch_t ch) {
struct _INA3221Measurement measurement;
measurement.voltage = ina3221.getVoltage(ch);
measurement.current = ina3221.getCurrent(ch);
measurement.voltage = ina3221.getVoltage(ch);
measurement.current = ina3221.getCurrent(ch);
return measurement;
return measurement;
}
struct _INA3221Measurements INA3221Sensor::getMeasurements()
{
struct _INA3221Measurements measurements;
struct _INA3221Measurements INA3221Sensor::getMeasurements() {
struct _INA3221Measurements measurements;
// INA3221 has 3 channels starting from 0
for (int i = 0; i < 3; i++) {
measurements.measurements[i] = getMeasurement((ina3221_ch_t)i);
}
// INA3221 has 3 channels starting from 0
for (int i = 0; i < 3; i++) {
measurements.measurements[i] = getMeasurement((ina3221_ch_t)i);
}
return measurements;
return measurements;
}
bool INA3221Sensor::getMetrics(meshtastic_Telemetry *measurement)
{
switch (measurement->which_variant) {
case meshtastic_Telemetry_environment_metrics_tag:
return getEnvironmentMetrics(measurement);
bool INA3221Sensor::getMetrics(meshtastic_Telemetry *measurement) {
switch (measurement->which_variant) {
case meshtastic_Telemetry_environment_metrics_tag:
return getEnvironmentMetrics(measurement);
case meshtastic_Telemetry_power_metrics_tag:
return getPowerMetrics(measurement);
}
case meshtastic_Telemetry_power_metrics_tag:
return getPowerMetrics(measurement);
}
// unsupported metric
return false;
// unsupported metric
return false;
}
bool INA3221Sensor::getEnvironmentMetrics(meshtastic_Telemetry *measurement)
{
struct _INA3221Measurement m = getMeasurement(ENV_CH);
bool INA3221Sensor::getEnvironmentMetrics(meshtastic_Telemetry *measurement) {
struct _INA3221Measurement m = getMeasurement(ENV_CH);
measurement->variant.environment_metrics.has_voltage = true;
measurement->variant.environment_metrics.has_current = true;
measurement->variant.environment_metrics.has_voltage = true;
measurement->variant.environment_metrics.has_current = true;
measurement->variant.environment_metrics.voltage = m.voltage;
measurement->variant.environment_metrics.current = m.current;
measurement->variant.environment_metrics.voltage = m.voltage;
measurement->variant.environment_metrics.current = m.current;
return true;
return true;
}
bool INA3221Sensor::getPowerMetrics(meshtastic_Telemetry *measurement)
{
struct _INA3221Measurements m = getMeasurements();
bool INA3221Sensor::getPowerMetrics(meshtastic_Telemetry *measurement) {
struct _INA3221Measurements m = getMeasurements();
measurement->variant.power_metrics.has_ch1_voltage = true;
measurement->variant.power_metrics.has_ch1_current = true;
measurement->variant.power_metrics.has_ch2_voltage = true;
measurement->variant.power_metrics.has_ch2_current = true;
measurement->variant.power_metrics.has_ch3_voltage = true;
measurement->variant.power_metrics.has_ch3_current = true;
measurement->variant.power_metrics.has_ch1_voltage = true;
measurement->variant.power_metrics.has_ch1_current = true;
measurement->variant.power_metrics.has_ch2_voltage = true;
measurement->variant.power_metrics.has_ch2_current = true;
measurement->variant.power_metrics.has_ch3_voltage = true;
measurement->variant.power_metrics.has_ch3_current = true;
measurement->variant.power_metrics.ch1_voltage = m.measurements[INA3221_CH1].voltage;
measurement->variant.power_metrics.ch1_current = m.measurements[INA3221_CH1].current;
measurement->variant.power_metrics.ch2_voltage = m.measurements[INA3221_CH2].voltage;
measurement->variant.power_metrics.ch2_current = m.measurements[INA3221_CH2].current;
measurement->variant.power_metrics.ch3_voltage = m.measurements[INA3221_CH3].voltage;
measurement->variant.power_metrics.ch3_current = m.measurements[INA3221_CH3].current;
measurement->variant.power_metrics.ch1_voltage = m.measurements[INA3221_CH1].voltage;
measurement->variant.power_metrics.ch1_current = m.measurements[INA3221_CH1].current;
measurement->variant.power_metrics.ch2_voltage = m.measurements[INA3221_CH2].voltage;
measurement->variant.power_metrics.ch2_current = m.measurements[INA3221_CH2].current;
measurement->variant.power_metrics.ch3_voltage = m.measurements[INA3221_CH3].voltage;
measurement->variant.power_metrics.ch3_current = m.measurements[INA3221_CH3].current;
return true;
return true;
}
uint16_t INA3221Sensor::getBusVoltageMv()
{
return lround(ina3221.getVoltage(BAT_CH) * 1000);
}
uint16_t INA3221Sensor::getBusVoltageMv() { return lround(ina3221.getVoltage(BAT_CH) * 1000); }
int16_t INA3221Sensor::getCurrentMa()
{
return lround(ina3221.getCurrent(BAT_CH));
}
int16_t INA3221Sensor::getCurrentMa() { return lround(ina3221.getCurrent(BAT_CH)); }
#endif

View File

@@ -16,45 +16,44 @@
#define INA3221_BAT_CH INA3221_CH1
#endif
class INA3221Sensor : public TelemetrySensor, VoltageSensor, CurrentSensor
{
private:
INA3221 ina3221 = INA3221(INA3221_ADDR42_SDA);
class INA3221Sensor : public TelemetrySensor, VoltageSensor, CurrentSensor {
private:
INA3221 ina3221 = INA3221(INA3221_ADDR42_SDA);
// channel to report voltage/current for environment metrics
static const ina3221_ch_t ENV_CH = INA3221_ENV_CH;
// channel to report voltage/current for environment metrics
static const ina3221_ch_t ENV_CH = INA3221_ENV_CH;
// channel to report battery voltage for device_battery_ina_address
static const ina3221_ch_t BAT_CH = INA3221_BAT_CH;
// channel to report battery voltage for device_battery_ina_address
static const ina3221_ch_t BAT_CH = INA3221_BAT_CH;
// get a single measurement for a channel
struct _INA3221Measurement getMeasurement(ina3221_ch_t ch);
// get a single measurement for a channel
struct _INA3221Measurement getMeasurement(ina3221_ch_t ch);
// get all measurements for all channels
struct _INA3221Measurements getMeasurements();
// get all measurements for all channels
struct _INA3221Measurements getMeasurements();
bool getEnvironmentMetrics(meshtastic_Telemetry *measurement);
bool getPowerMetrics(meshtastic_Telemetry *measurement);
bool getEnvironmentMetrics(meshtastic_Telemetry *measurement);
bool getPowerMetrics(meshtastic_Telemetry *measurement);
protected:
void setup() override;
protected:
void setup() override;
public:
INA3221Sensor();
int32_t runOnce() override;
bool getMetrics(meshtastic_Telemetry *measurement) override;
virtual uint16_t getBusVoltageMv() override;
virtual int16_t getCurrentMa() override;
public:
INA3221Sensor();
int32_t runOnce() override;
bool getMetrics(meshtastic_Telemetry *measurement) override;
virtual uint16_t getBusVoltageMv() override;
virtual int16_t getCurrentMa() override;
};
struct _INA3221Measurement {
float voltage;
float current;
float voltage;
float current;
};
struct _INA3221Measurements {
// INA3221 has 3 channels
struct _INA3221Measurement measurements[3];
// INA3221 has 3 channels
struct _INA3221Measurement measurements[3];
};
#endif

View File

@@ -19,148 +19,144 @@ uint8_t data[SENSOR_BUF_SIZE]; // decode
#define ACK_PKT_PARA "ACK"
enum sensor_pkt_type {
PKT_TYPE_ACK = 0x00, // uin32_t
PKT_TYPE_CMD_COLLECT_INTERVAL = 0xA0, // uin32_t
PKT_TYPE_CMD_BEEP_ON = 0xA1, // uin32_t ms: on time
PKT_TYPE_CMD_BEEP_OFF = 0xA2,
PKT_TYPE_CMD_SHUTDOWN = 0xA3, // uin32_t
PKT_TYPE_CMD_POWER_ON = 0xA4,
PKT_TYPE_SENSOR_SCD41_TEMP = 0xB0, // float
PKT_TYPE_SENSOR_SCD41_HUMIDITY = 0xB1, // float
PKT_TYPE_SENSOR_SCD41_CO2 = 0xB2, // float
PKT_TYPE_SENSOR_AHT20_TEMP = 0xB3, // float
PKT_TYPE_SENSOR_AHT20_HUMIDITY = 0xB4, // float
PKT_TYPE_SENSOR_TVOC_INDEX = 0xB5, // float
PKT_TYPE_ACK = 0x00, // uin32_t
PKT_TYPE_CMD_COLLECT_INTERVAL = 0xA0, // uin32_t
PKT_TYPE_CMD_BEEP_ON = 0xA1, // uin32_t ms: on time
PKT_TYPE_CMD_BEEP_OFF = 0xA2,
PKT_TYPE_CMD_SHUTDOWN = 0xA3, // uin32_t
PKT_TYPE_CMD_POWER_ON = 0xA4,
PKT_TYPE_SENSOR_SCD41_TEMP = 0xB0, // float
PKT_TYPE_SENSOR_SCD41_HUMIDITY = 0xB1, // float
PKT_TYPE_SENSOR_SCD41_CO2 = 0xB2, // float
PKT_TYPE_SENSOR_AHT20_TEMP = 0xB3, // float
PKT_TYPE_SENSOR_AHT20_HUMIDITY = 0xB4, // float
PKT_TYPE_SENSOR_TVOC_INDEX = 0xB5, // float
};
static int cmd_send(uint8_t cmd, const char *p_data, uint8_t len)
{
uint8_t send_buf[32] = {0};
uint8_t send_data[32] = {0};
if (len > 31) {
return -1;
}
uint8_t index = 1;
send_data[0] = cmd;
if (len > 0 && p_data != NULL) {
memcpy(&send_data[1], p_data, len);
index += len;
}
cobs_encode_result ret = cobs_encode(send_buf, sizeof(send_buf), send_data, index);
// LOG_DEBUG("cobs TX status:%d, len:%d, type 0x%x", ret.status, ret.out_len, cmd);
if (ret.status == COBS_ENCODE_OK) {
return uart_write_bytes(SENSOR_PORT_NUM, send_buf, ret.out_len + 1);
}
static int cmd_send(uint8_t cmd, const char *p_data, uint8_t len) {
uint8_t send_buf[32] = {0};
uint8_t send_data[32] = {0};
if (len > 31) {
return -1;
}
uint8_t index = 1;
send_data[0] = cmd;
if (len > 0 && p_data != NULL) {
memcpy(&send_data[1], p_data, len);
index += len;
}
cobs_encode_result ret = cobs_encode(send_buf, sizeof(send_buf), send_data, index);
// LOG_DEBUG("cobs TX status:%d, len:%d, type 0x%x", ret.status, ret.out_len, cmd);
if (ret.status == COBS_ENCODE_OK) {
return uart_write_bytes(SENSOR_PORT_NUM, send_buf, ret.out_len + 1);
}
return -1;
}
bool IndicatorSensor::initDevice(TwoWire *bus, ScanI2C::FoundDevice *dev)
{
LOG_INFO("%s: init", sensorName);
setup();
return true;
bool IndicatorSensor::initDevice(TwoWire *bus, ScanI2C::FoundDevice *dev) {
LOG_INFO("%s: init", sensorName);
setup();
return true;
}
void IndicatorSensor::setup()
{
uart_config_t uart_config = {
.baud_rate = SENSOR_BAUD_RATE,
.data_bits = UART_DATA_8_BITS,
.parity = UART_PARITY_DISABLE,
.stop_bits = UART_STOP_BITS_1,
.flow_ctrl = UART_HW_FLOWCTRL_DISABLE,
.source_clk = UART_SCLK_APB,
};
int intr_alloc_flags = 0;
char buffer[11];
void IndicatorSensor::setup() {
uart_config_t uart_config = {
.baud_rate = SENSOR_BAUD_RATE,
.data_bits = UART_DATA_8_BITS,
.parity = UART_PARITY_DISABLE,
.stop_bits = UART_STOP_BITS_1,
.flow_ctrl = UART_HW_FLOWCTRL_DISABLE,
.source_clk = UART_SCLK_APB,
};
int intr_alloc_flags = 0;
char buffer[11];
uart_driver_install(SENSOR_PORT_NUM, SENSOR_BUF_SIZE * 2, 0, 0, NULL, intr_alloc_flags);
uart_param_config(SENSOR_PORT_NUM, &uart_config);
uart_set_pin(SENSOR_PORT_NUM, SENSOR_RP2040_TXD, SENSOR_RP2040_RXD, UART_PIN_NO_CHANGE, UART_PIN_NO_CHANGE);
cmd_send(PKT_TYPE_CMD_POWER_ON, NULL, 0);
// measure and send only once every minute, for the phone API
const char *interval = ultoa(60000, buffer, 10);
cmd_send(PKT_TYPE_CMD_COLLECT_INTERVAL, interval, strlen(interval) + 1);
uart_driver_install(SENSOR_PORT_NUM, SENSOR_BUF_SIZE * 2, 0, 0, NULL, intr_alloc_flags);
uart_param_config(SENSOR_PORT_NUM, &uart_config);
uart_set_pin(SENSOR_PORT_NUM, SENSOR_RP2040_TXD, SENSOR_RP2040_RXD, UART_PIN_NO_CHANGE, UART_PIN_NO_CHANGE);
cmd_send(PKT_TYPE_CMD_POWER_ON, NULL, 0);
// measure and send only once every minute, for the phone API
const char *interval = ultoa(60000, buffer, 10);
cmd_send(PKT_TYPE_CMD_COLLECT_INTERVAL, interval, strlen(interval) + 1);
}
bool IndicatorSensor::getMetrics(meshtastic_Telemetry *measurement)
{
cobs_decode_result ret;
int len = uart_read_bytes(SENSOR_PORT_NUM, buf, (SENSOR_BUF_SIZE - 1), 100 / portTICK_PERIOD_MS);
bool IndicatorSensor::getMetrics(meshtastic_Telemetry *measurement) {
cobs_decode_result ret;
int len = uart_read_bytes(SENSOR_PORT_NUM, buf, (SENSOR_BUF_SIZE - 1), 100 / portTICK_PERIOD_MS);
float value = 0.0;
uint8_t *p_buf_start = buf;
uint8_t *p_buf_end = buf;
if (len > 0) {
while (p_buf_start < (buf + len)) {
p_buf_end = p_buf_start;
while (p_buf_end < (buf + len)) {
if (*p_buf_end == 0x00) {
break;
}
p_buf_end++;
}
// decode buf
memset(data, 0, sizeof(data));
ret = cobs_decode(data, sizeof(data), p_buf_start, p_buf_end - p_buf_start);
// LOG_DEBUG("cobs RX status:%d, len:%d, type:0x%x ", ret.status, ret.out_len, data[0]);
if (ret.out_len > 1 && ret.status == COBS_DECODE_OK) {
value = 0.0;
uint8_t pkt_type = data[0];
switch (pkt_type) {
case PKT_TYPE_SENSOR_SCD41_CO2: {
memcpy(&value, &data[1], sizeof(value));
// LOG_DEBUG("CO2: %.1f", value);
cmd_send(PKT_TYPE_ACK, ACK_PKT_PARA, 4);
break;
}
case PKT_TYPE_SENSOR_AHT20_TEMP: {
memcpy(&value, &data[1], sizeof(value));
// LOG_DEBUG("Temp: %.1f", value);
cmd_send(PKT_TYPE_ACK, ACK_PKT_PARA, 4);
measurement->variant.environment_metrics.has_temperature = true;
measurement->variant.environment_metrics.temperature = value;
break;
}
case PKT_TYPE_SENSOR_AHT20_HUMIDITY: {
memcpy(&value, &data[1], sizeof(value));
// LOG_DEBUG("Humidity: %.1f", value);
cmd_send(PKT_TYPE_ACK, ACK_PKT_PARA, 4);
measurement->variant.environment_metrics.has_relative_humidity = true;
measurement->variant.environment_metrics.relative_humidity = value;
break;
}
case PKT_TYPE_SENSOR_TVOC_INDEX: {
memcpy(&value, &data[1], sizeof(value));
// LOG_DEBUG("Tvoc: %.1f", value);
cmd_send(PKT_TYPE_ACK, ACK_PKT_PARA, 4);
measurement->variant.environment_metrics.has_iaq = true;
measurement->variant.environment_metrics.iaq = value;
break;
}
default:
break;
}
}
p_buf_start = p_buf_end + 1; // next message
float value = 0.0;
uint8_t *p_buf_start = buf;
uint8_t *p_buf_end = buf;
if (len > 0) {
while (p_buf_start < (buf + len)) {
p_buf_end = p_buf_start;
while (p_buf_end < (buf + len)) {
if (*p_buf_end == 0x00) {
break;
}
return true;
p_buf_end++;
}
// decode buf
memset(data, 0, sizeof(data));
ret = cobs_decode(data, sizeof(data), p_buf_start, p_buf_end - p_buf_start);
// LOG_DEBUG("cobs RX status:%d, len:%d, type:0x%x ", ret.status, ret.out_len, data[0]);
if (ret.out_len > 1 && ret.status == COBS_DECODE_OK) {
value = 0.0;
uint8_t pkt_type = data[0];
switch (pkt_type) {
case PKT_TYPE_SENSOR_SCD41_CO2: {
memcpy(&value, &data[1], sizeof(value));
// LOG_DEBUG("CO2: %.1f", value);
cmd_send(PKT_TYPE_ACK, ACK_PKT_PARA, 4);
break;
}
case PKT_TYPE_SENSOR_AHT20_TEMP: {
memcpy(&value, &data[1], sizeof(value));
// LOG_DEBUG("Temp: %.1f", value);
cmd_send(PKT_TYPE_ACK, ACK_PKT_PARA, 4);
measurement->variant.environment_metrics.has_temperature = true;
measurement->variant.environment_metrics.temperature = value;
break;
}
case PKT_TYPE_SENSOR_AHT20_HUMIDITY: {
memcpy(&value, &data[1], sizeof(value));
// LOG_DEBUG("Humidity: %.1f", value);
cmd_send(PKT_TYPE_ACK, ACK_PKT_PARA, 4);
measurement->variant.environment_metrics.has_relative_humidity = true;
measurement->variant.environment_metrics.relative_humidity = value;
break;
}
case PKT_TYPE_SENSOR_TVOC_INDEX: {
memcpy(&value, &data[1], sizeof(value));
// LOG_DEBUG("Tvoc: %.1f", value);
cmd_send(PKT_TYPE_ACK, ACK_PKT_PARA, 4);
measurement->variant.environment_metrics.has_iaq = true;
measurement->variant.environment_metrics.iaq = value;
break;
}
default:
break;
}
}
p_buf_start = p_buf_end + 1; // next message
}
return false;
return true;
}
return false;
}
#endif

View File

@@ -5,15 +5,14 @@
#include "../mesh/generated/meshtastic/telemetry.pb.h"
#include "TelemetrySensor.h"
class IndicatorSensor : public TelemetrySensor
{
public:
IndicatorSensor();
virtual bool getMetrics(meshtastic_Telemetry *measurement) override;
virtual bool initDevice(TwoWire *bus, ScanI2C::FoundDevice *dev) override;
class IndicatorSensor : public TelemetrySensor {
public:
IndicatorSensor();
virtual bool getMetrics(meshtastic_Telemetry *measurement) override;
virtual bool initDevice(TwoWire *bus, ScanI2C::FoundDevice *dev) override;
private:
void setup();
private:
void setup();
};
#endif

View File

@@ -10,32 +10,30 @@
LPS22HBSensor::LPS22HBSensor() : TelemetrySensor(meshtastic_TelemetrySensorType_LPS22, "LPS22HB") {}
bool LPS22HBSensor::initDevice(TwoWire *bus, ScanI2C::FoundDevice *dev)
{
LOG_INFO("Init sensor: %s", sensorName);
status = lps22hb.begin_I2C(dev->address.address, bus);
if (!status) {
return status;
}
lps22hb.setDataRate(LPS22_RATE_10_HZ);
initI2CSensor();
bool LPS22HBSensor::initDevice(TwoWire *bus, ScanI2C::FoundDevice *dev) {
LOG_INFO("Init sensor: %s", sensorName);
status = lps22hb.begin_I2C(dev->address.address, bus);
if (!status) {
return status;
}
lps22hb.setDataRate(LPS22_RATE_10_HZ);
initI2CSensor();
return status;
}
bool LPS22HBSensor::getMetrics(meshtastic_Telemetry *measurement)
{
measurement->variant.environment_metrics.has_temperature = true;
measurement->variant.environment_metrics.has_barometric_pressure = true;
bool LPS22HBSensor::getMetrics(meshtastic_Telemetry *measurement) {
measurement->variant.environment_metrics.has_temperature = true;
measurement->variant.environment_metrics.has_barometric_pressure = true;
sensors_event_t temp;
sensors_event_t pressure;
lps22hb.getEvent(&pressure, &temp);
sensors_event_t temp;
sensors_event_t pressure;
lps22hb.getEvent(&pressure, &temp);
measurement->variant.environment_metrics.temperature = temp.temperature;
measurement->variant.environment_metrics.barometric_pressure = pressure.pressure;
measurement->variant.environment_metrics.temperature = temp.temperature;
measurement->variant.environment_metrics.barometric_pressure = pressure.pressure;
return true;
return true;
}
#endif

View File

@@ -7,15 +7,14 @@
#include <Adafruit_LPS2X.h>
#include <Adafruit_Sensor.h>
class LPS22HBSensor : public TelemetrySensor
{
private:
Adafruit_LPS22 lps22hb;
class LPS22HBSensor : public TelemetrySensor {
private:
Adafruit_LPS22 lps22hb;
public:
LPS22HBSensor();
virtual bool getMetrics(meshtastic_Telemetry *measurement) override;
virtual bool initDevice(TwoWire *bus, ScanI2C::FoundDevice *dev) override;
public:
LPS22HBSensor();
virtual bool getMetrics(meshtastic_Telemetry *measurement) override;
virtual bool initDevice(TwoWire *bus, ScanI2C::FoundDevice *dev) override;
};
#endif

View File

@@ -9,65 +9,60 @@
LTR390UVSensor::LTR390UVSensor() : TelemetrySensor(meshtastic_TelemetrySensorType_LTR390UV, "LTR390UV") {}
bool LTR390UVSensor::initDevice(TwoWire *bus, ScanI2C::FoundDevice *dev)
{
LOG_INFO("Init sensor: %s", sensorName);
bool LTR390UVSensor::initDevice(TwoWire *bus, ScanI2C::FoundDevice *dev) {
LOG_INFO("Init sensor: %s", sensorName);
status = ltr390uv.begin(bus);
if (!status) {
return status;
}
ltr390uv.setMode(LTR390_MODE_UVS);
ltr390uv.setGain(LTR390_GAIN_18); // Datasheet default
ltr390uv.setResolution(LTR390_RESOLUTION_20BIT); // Datasheet default
initI2CSensor();
status = ltr390uv.begin(bus);
if (!status) {
return status;
}
ltr390uv.setMode(LTR390_MODE_UVS);
ltr390uv.setGain(LTR390_GAIN_18); // Datasheet default
ltr390uv.setResolution(LTR390_RESOLUTION_20BIT); // Datasheet default
initI2CSensor();
return status;
}
bool LTR390UVSensor::getMetrics(meshtastic_Telemetry *measurement)
{
LOG_DEBUG("LTR390UV getMetrics");
bool LTR390UVSensor::getMetrics(meshtastic_Telemetry *measurement) {
LOG_DEBUG("LTR390UV getMetrics");
// Because the sensor does not measure Lux and UV at the same time, we need to read them in two passes.
if (ltr390uv.newDataAvailable()) {
measurement->variant.environment_metrics.has_lux = true;
measurement->variant.environment_metrics.has_uv_lux = true;
// Because the sensor does not measure Lux and UV at the same time, we need to read them in two passes.
if (ltr390uv.newDataAvailable()) {
measurement->variant.environment_metrics.has_lux = true;
measurement->variant.environment_metrics.has_uv_lux = true;
if (ltr390uv.getMode() == LTR390_MODE_ALS) {
lastLuxReading = 0.6 * ltr390uv.readALS() / (1 * 4); // Datasheet page 23 for gain x1 and 20bit resolution
LOG_DEBUG("LTR390UV Lux reading: %f", lastLuxReading);
if (ltr390uv.getMode() == LTR390_MODE_ALS) {
lastLuxReading = 0.6 * ltr390uv.readALS() / (1 * 4); // Datasheet page 23 for gain x1 and 20bit resolution
LOG_DEBUG("LTR390UV Lux reading: %f", lastLuxReading);
measurement->variant.environment_metrics.lux = lastLuxReading;
measurement->variant.environment_metrics.uv_lux = lastUVReading;
measurement->variant.environment_metrics.lux = lastLuxReading;
measurement->variant.environment_metrics.uv_lux = lastUVReading;
ltr390uv.setGain(
LTR390_GAIN_18); // Recommended for UVI - x18. Do not change, 2300 UV Sensitivity only specified for x18 gain
ltr390uv.setMode(LTR390_MODE_UVS);
ltr390uv.setGain(LTR390_GAIN_18); // Recommended for UVI - x18. Do not change, 2300 UV Sensitivity only specified for x18 gain
ltr390uv.setMode(LTR390_MODE_UVS);
return true;
return true;
} else if (ltr390uv.getMode() == LTR390_MODE_UVS) {
lastUVReading = ltr390uv.readUVS() /
2300.f; // Datasheet page 23 and page 6, only characterisation for gain x18 and 20bit resolution
LOG_DEBUG("LTR390UV UV reading: %f", lastUVReading);
} else if (ltr390uv.getMode() == LTR390_MODE_UVS) {
lastUVReading = ltr390uv.readUVS() / 2300.f; // Datasheet page 23 and page 6, only characterisation for gain x18 and 20bit resolution
LOG_DEBUG("LTR390UV UV reading: %f", lastUVReading);
measurement->variant.environment_metrics.lux = lastLuxReading;
measurement->variant.environment_metrics.uv_lux = lastUVReading;
measurement->variant.environment_metrics.lux = lastLuxReading;
measurement->variant.environment_metrics.uv_lux = lastUVReading;
ltr390uv.setGain(
LTR390_GAIN_1); // x1 gain will already max out the sensor at direct sunlight, so no need to increase it
ltr390uv.setMode(LTR390_MODE_ALS);
ltr390uv.setGain(LTR390_GAIN_1); // x1 gain will already max out the sensor at direct sunlight, so no need to increase it
ltr390uv.setMode(LTR390_MODE_ALS);
return true;
}
return true;
}
}
// In case we fail to read the sensor mode, set the has_lux and has_uv_lux back to false
measurement->variant.environment_metrics.has_lux = false;
measurement->variant.environment_metrics.has_uv_lux = false;
// In case we fail to read the sensor mode, set the has_lux and has_uv_lux back to false
measurement->variant.environment_metrics.has_lux = false;
measurement->variant.environment_metrics.has_uv_lux = false;
return false;
return false;
}
#endif

View File

@@ -6,17 +6,16 @@
#include "TelemetrySensor.h"
#include <Adafruit_LTR390.h>
class LTR390UVSensor : public TelemetrySensor
{
private:
Adafruit_LTR390 ltr390uv = Adafruit_LTR390();
float lastLuxReading = 0;
float lastUVReading = 0;
class LTR390UVSensor : public TelemetrySensor {
private:
Adafruit_LTR390 ltr390uv = Adafruit_LTR390();
float lastLuxReading = 0;
float lastUVReading = 0;
public:
LTR390UVSensor();
virtual bool getMetrics(meshtastic_Telemetry *measurement) override;
virtual bool initDevice(TwoWire *bus, ScanI2C::FoundDevice *dev) override;
public:
LTR390UVSensor();
virtual bool getMetrics(meshtastic_Telemetry *measurement) override;
virtual bool initDevice(TwoWire *bus, ScanI2C::FoundDevice *dev) override;
};
#endif

View File

@@ -2,12 +2,11 @@
#if !MESHTASTIC_EXCLUDE_I2C && __has_include(<Adafruit_MAX1704X.h>)
MAX17048Singleton *MAX17048Singleton::GetInstance()
{
if (pinstance == nullptr) {
pinstance = new MAX17048Singleton();
}
return pinstance;
MAX17048Singleton *MAX17048Singleton::GetInstance() {
if (pinstance == nullptr) {
pinstance = new MAX17048Singleton();
}
return pinstance;
}
MAX17048Singleton::MAX17048Singleton() {}
@@ -16,160 +15,147 @@ MAX17048Singleton::~MAX17048Singleton() {}
MAX17048Singleton *MAX17048Singleton::pinstance{nullptr};
bool MAX17048Singleton::runOnce(TwoWire *theWire)
{
initialized = begin(theWire);
LOG_DEBUG("%s::runOnce %s", sensorStr, initialized ? "began ok" : "begin failed");
return initialized;
bool MAX17048Singleton::runOnce(TwoWire *theWire) {
initialized = begin(theWire);
LOG_DEBUG("%s::runOnce %s", sensorStr, initialized ? "began ok" : "begin failed");
return initialized;
}
bool MAX17048Singleton::isBatteryCharging()
{
float volts = cellVoltage();
if (isnan(volts)) {
LOG_DEBUG("%s::isBatteryCharging not connected", sensorStr);
return 0;
}
bool MAX17048Singleton::isBatteryCharging() {
float volts = cellVoltage();
if (isnan(volts)) {
LOG_DEBUG("%s::isBatteryCharging not connected", sensorStr);
return 0;
}
MAX17048ChargeSample sample;
sample.chargeRate = chargeRate(); // charge/discharge rate in percent/hr
sample.cellPercent = cellPercent(); // state of charge in percent 0 to 100
chargeSamples.push(sample); // save a sample into a fifo buffer
MAX17048ChargeSample sample;
sample.chargeRate = chargeRate(); // charge/discharge rate in percent/hr
sample.cellPercent = cellPercent(); // state of charge in percent 0 to 100
chargeSamples.push(sample); // save a sample into a fifo buffer
// Keep the fifo buffer trimmed
while (chargeSamples.size() > MAX17048_CHARGING_SAMPLES)
chargeSamples.pop();
// Keep the fifo buffer trimmed
while (chargeSamples.size() > MAX17048_CHARGING_SAMPLES)
chargeSamples.pop();
// Based on the past n samples, is the lipo charging, discharging or idle
if (chargeSamples.front().chargeRate > MAX17048_CHARGING_MINIMUM_RATE &&
chargeSamples.back().chargeRate > MAX17048_CHARGING_MINIMUM_RATE) {
if (chargeSamples.front().cellPercent > chargeSamples.back().cellPercent)
chargeState = MAX17048ChargeState::EXPORT;
else if (chargeSamples.front().cellPercent < chargeSamples.back().cellPercent)
chargeState = MAX17048ChargeState::IMPORT;
else
chargeState = MAX17048ChargeState::IDLE;
} else {
chargeState = MAX17048ChargeState::IDLE;
}
// Based on the past n samples, is the lipo charging, discharging or idle
if (chargeSamples.front().chargeRate > MAX17048_CHARGING_MINIMUM_RATE && chargeSamples.back().chargeRate > MAX17048_CHARGING_MINIMUM_RATE) {
if (chargeSamples.front().cellPercent > chargeSamples.back().cellPercent)
chargeState = MAX17048ChargeState::EXPORT;
else if (chargeSamples.front().cellPercent < chargeSamples.back().cellPercent)
chargeState = MAX17048ChargeState::IMPORT;
else
chargeState = MAX17048ChargeState::IDLE;
} else {
chargeState = MAX17048ChargeState::IDLE;
}
LOG_DEBUG("%s::isBatteryCharging %s volts: %.3f soc: %.3f rate: %.3f", sensorStr, chargeLabels[chargeState], volts,
sample.cellPercent, sample.chargeRate);
return chargeState == MAX17048ChargeState::IMPORT;
LOG_DEBUG("%s::isBatteryCharging %s volts: %.3f soc: %.3f rate: %.3f", sensorStr, chargeLabels[chargeState], volts, sample.cellPercent,
sample.chargeRate);
return chargeState == MAX17048ChargeState::IMPORT;
}
uint16_t MAX17048Singleton::getBusVoltageMv()
{
float volts = cellVoltage();
if (isnan(volts)) {
LOG_DEBUG("%s::getBusVoltageMv is not connected", sensorStr);
return 0;
}
LOG_DEBUG("%s::getBusVoltageMv %.3fmV", sensorStr, volts);
return (uint16_t)(volts * 1000.0f);
uint16_t MAX17048Singleton::getBusVoltageMv() {
float volts = cellVoltage();
if (isnan(volts)) {
LOG_DEBUG("%s::getBusVoltageMv is not connected", sensorStr);
return 0;
}
LOG_DEBUG("%s::getBusVoltageMv %.3fmV", sensorStr, volts);
return (uint16_t)(volts * 1000.0f);
}
uint8_t MAX17048Singleton::getBusBatteryPercent()
{
float soc = cellPercent();
LOG_DEBUG("%s::getBusBatteryPercent %.1f%%", sensorStr, soc);
return clamp(static_cast<uint8_t>(round(soc)), static_cast<uint8_t>(0), static_cast<uint8_t>(100));
uint8_t MAX17048Singleton::getBusBatteryPercent() {
float soc = cellPercent();
LOG_DEBUG("%s::getBusBatteryPercent %.1f%%", sensorStr, soc);
return clamp(static_cast<uint8_t>(round(soc)), static_cast<uint8_t>(0), static_cast<uint8_t>(100));
}
uint16_t MAX17048Singleton::getTimeToGoSecs()
{
float rate = chargeRate(); // charge/discharge rate in percent/hr
float soc = cellPercent(); // state of charge in percent 0 to 100
soc = clamp(soc, 0.0f, 100.0f); // clamp soc between 0 and 100%
float ttg = ((100.0f - soc) / rate) * 3600.0f; // calculate seconds to charge/discharge
LOG_DEBUG("%s::getTimeToGoSecs %.0f seconds", sensorStr, ttg);
return (uint16_t)ttg;
uint16_t MAX17048Singleton::getTimeToGoSecs() {
float rate = chargeRate(); // charge/discharge rate in percent/hr
float soc = cellPercent(); // state of charge in percent 0 to 100
soc = clamp(soc, 0.0f, 100.0f); // clamp soc between 0 and 100%
float ttg = ((100.0f - soc) / rate) * 3600.0f; // calculate seconds to charge/discharge
LOG_DEBUG("%s::getTimeToGoSecs %.0f seconds", sensorStr, ttg);
return (uint16_t)ttg;
}
bool MAX17048Singleton::isBatteryConnected()
{
float volts = cellVoltage();
if (isnan(volts)) {
LOG_DEBUG("%s::isBatteryConnected is not connected", sensorStr);
return false;
}
bool MAX17048Singleton::isBatteryConnected() {
float volts = cellVoltage();
if (isnan(volts)) {
LOG_DEBUG("%s::isBatteryConnected is not connected", sensorStr);
return false;
}
// if a valid voltage is returned, then battery must be connected
// if a valid voltage is returned, then battery must be connected
return true;
}
bool MAX17048Singleton::isExternallyPowered() {
float volts = cellVoltage();
if (isnan(volts)) {
// if the battery is not connected then there must be external power
LOG_DEBUG("%s::isExternallyPowered battery is", sensorStr);
return true;
}
bool MAX17048Singleton::isExternallyPowered()
{
float volts = cellVoltage();
if (isnan(volts)) {
// if the battery is not connected then there must be external power
LOG_DEBUG("%s::isExternallyPowered battery is", sensorStr);
return true;
}
// if the bus voltage is over MAX17048_BUS_POWER_VOLTS, then the external power
// is assumed to be connected
LOG_DEBUG("%s::isExternallyPowered %s connected", sensorStr, volts >= MAX17048_BUS_POWER_VOLTS ? "is" : "is not");
return volts >= MAX17048_BUS_POWER_VOLTS;
}
// if the bus voltage is over MAX17048_BUS_POWER_VOLTS, then the external power
// is assumed to be connected
LOG_DEBUG("%s::isExternallyPowered %s connected", sensorStr, volts >= MAX17048_BUS_POWER_VOLTS ? "is" : "is not");
return volts >= MAX17048_BUS_POWER_VOLTS;
}
#if (HAS_TELEMETRY && (!MESHTASTIC_EXCLUDE_ENVIRONMENTAL_SENSOR || !MESHTASTIC_EXCLUDE_POWER_TELEMETRY))
MAX17048Sensor::MAX17048Sensor() : TelemetrySensor(meshtastic_TelemetrySensorType_MAX17048, "MAX17048") {}
int32_t MAX17048Sensor::runOnce()
{
if (isInitialized()) {
LOG_INFO("Init sensor: %s is already initialised", sensorName);
return true;
}
int32_t MAX17048Sensor::runOnce() {
if (isInitialized()) {
LOG_INFO("Init sensor: %s is already initialised", sensorName);
return true;
}
LOG_INFO("Init sensor: %s", sensorName);
if (!hasSensor()) {
return DEFAULT_SENSOR_MINIMUM_WAIT_TIME_BETWEEN_READS;
}
LOG_INFO("Init sensor: %s", sensorName);
if (!hasSensor()) {
return DEFAULT_SENSOR_MINIMUM_WAIT_TIME_BETWEEN_READS;
}
// Get a singleton instance and initialise the max17048
if (max17048 == nullptr) {
max17048 = MAX17048Singleton::GetInstance();
}
status = max17048->runOnce(nodeTelemetrySensorsMap[sensorType].second);
return initI2CSensor();
// Get a singleton instance and initialise the max17048
if (max17048 == nullptr) {
max17048 = MAX17048Singleton::GetInstance();
}
status = max17048->runOnce(nodeTelemetrySensorsMap[sensorType].second);
return initI2CSensor();
}
void MAX17048Sensor::setup() {}
bool MAX17048Sensor::getMetrics(meshtastic_Telemetry *measurement)
{
LOG_DEBUG("MAX17048 getMetrics id: %i", measurement->which_variant);
bool MAX17048Sensor::getMetrics(meshtastic_Telemetry *measurement) {
LOG_DEBUG("MAX17048 getMetrics id: %i", measurement->which_variant);
float volts = max17048->cellVoltage();
if (isnan(volts)) {
LOG_DEBUG("MAX17048 getMetrics battery is not connected");
return false;
}
float volts = max17048->cellVoltage();
if (isnan(volts)) {
LOG_DEBUG("MAX17048 getMetrics battery is not connected");
return false;
}
float rate = max17048->chargeRate(); // charge/discharge rate in percent/hr
float soc = max17048->cellPercent(); // state of charge in percent 0 to 100
soc = clamp(soc, 0.0f, 100.0f); // clamp soc between 0 and 100%
float ttg = (100.0f - soc) / rate; // calculate hours to charge/discharge
float rate = max17048->chargeRate(); // charge/discharge rate in percent/hr
float soc = max17048->cellPercent(); // state of charge in percent 0 to 100
soc = clamp(soc, 0.0f, 100.0f); // clamp soc between 0 and 100%
float ttg = (100.0f - soc) / rate; // calculate hours to charge/discharge
LOG_DEBUG("MAX17048 getMetrics volts: %.3fV soc: %.1f%% ttg: %.1f hours", volts, soc, ttg);
if ((int)measurement->which_variant == meshtastic_Telemetry_power_metrics_tag) {
measurement->variant.power_metrics.has_ch1_voltage = true;
measurement->variant.power_metrics.ch1_voltage = volts;
} else if ((int)measurement->which_variant == meshtastic_Telemetry_device_metrics_tag) {
measurement->variant.device_metrics.has_battery_level = true;
measurement->variant.device_metrics.has_voltage = true;
measurement->variant.device_metrics.battery_level = static_cast<uint32_t>(round(soc));
measurement->variant.device_metrics.voltage = volts;
}
return true;
LOG_DEBUG("MAX17048 getMetrics volts: %.3fV soc: %.1f%% ttg: %.1f hours", volts, soc, ttg);
if ((int)measurement->which_variant == meshtastic_Telemetry_power_metrics_tag) {
measurement->variant.power_metrics.has_ch1_voltage = true;
measurement->variant.power_metrics.ch1_voltage = volts;
} else if ((int)measurement->which_variant == meshtastic_Telemetry_device_metrics_tag) {
measurement->variant.device_metrics.has_battery_level = true;
measurement->variant.device_metrics.has_voltage = true;
measurement->variant.device_metrics.battery_level = static_cast<uint32_t>(round(soc));
measurement->variant.device_metrics.voltage = volts;
}
return true;
}
uint16_t MAX17048Sensor::getBusVoltageMv()
{
return max17048->getBusVoltageMv();
};
uint16_t MAX17048Sensor::getBusVoltageMv() { return max17048->getBusVoltageMv(); };
#endif

View File

@@ -25,83 +25,81 @@
#include <queue>
struct MAX17048ChargeSample {
float cellPercent;
float chargeRate;
float cellPercent;
float chargeRate;
};
enum MAX17048ChargeState { IDLE, EXPORT, IMPORT };
// Singleton wrapper for the Adafruit_MAX17048 class
class MAX17048Singleton : public Adafruit_MAX17048
{
private:
static MAX17048Singleton *pinstance;
bool initialized = false;
std::queue<MAX17048ChargeSample> chargeSamples;
MAX17048ChargeState chargeState = IDLE;
const String chargeLabels[3] = {F("idle"), F("export"), F("import")};
const char *sensorStr = "MAX17048Sensor";
class MAX17048Singleton : public Adafruit_MAX17048 {
private:
static MAX17048Singleton *pinstance;
bool initialized = false;
std::queue<MAX17048ChargeSample> chargeSamples;
MAX17048ChargeState chargeState = IDLE;
const String chargeLabels[3] = {F("idle"), F("export"), F("import")};
const char *sensorStr = "MAX17048Sensor";
protected:
MAX17048Singleton();
~MAX17048Singleton();
protected:
MAX17048Singleton();
~MAX17048Singleton();
public:
// Create a singleton instance (not thread safe)
static MAX17048Singleton *GetInstance();
public:
// Create a singleton instance (not thread safe)
static MAX17048Singleton *GetInstance();
// Singletons should not be cloneable.
MAX17048Singleton(MAX17048Singleton &other) = delete;
// Singletons should not be cloneable.
MAX17048Singleton(MAX17048Singleton &other) = delete;
// Singletons should not be assignable.
void operator=(const MAX17048Singleton &) = delete;
// Singletons should not be assignable.
void operator=(const MAX17048Singleton &) = delete;
// Initialise the sensor (not thread safe)
virtual bool runOnce(TwoWire *theWire = &Wire);
// Initialise the sensor (not thread safe)
virtual bool runOnce(TwoWire *theWire = &Wire);
// Get the current bus voltage
uint16_t getBusVoltageMv();
// Get the current bus voltage
uint16_t getBusVoltageMv();
// Get the state of charge in percent 0 to 100
uint8_t getBusBatteryPercent();
// Get the state of charge in percent 0 to 100
uint8_t getBusBatteryPercent();
// Calculate the seconds to charge/discharge
uint16_t getTimeToGoSecs();
// Calculate the seconds to charge/discharge
uint16_t getTimeToGoSecs();
// Returns true if the battery sensor has started
inline virtual bool isInitialised() { return initialized; };
// Returns true if the battery sensor has started
inline virtual bool isInitialised() { return initialized; };
// Returns true if the battery is currently on charge (not thread safe)
bool isBatteryCharging();
// Returns true if the battery is currently on charge (not thread safe)
bool isBatteryCharging();
// Returns true if a battery is actually connected
bool isBatteryConnected();
// Returns true if a battery is actually connected
bool isBatteryConnected();
// Returns true if there is bus or external power connected
bool isExternallyPowered();
// Returns true if there is bus or external power connected
bool isExternallyPowered();
};
#if (HAS_TELEMETRY && (!MESHTASTIC_EXCLUDE_ENVIRONMENTAL_SENSOR || !MESHTASTIC_EXCLUDE_POWER_TELEMETRY))
class MAX17048Sensor : public TelemetrySensor, VoltageSensor
{
private:
MAX17048Singleton *max17048 = nullptr;
class MAX17048Sensor : public TelemetrySensor, VoltageSensor {
private:
MAX17048Singleton *max17048 = nullptr;
protected:
virtual void setup() override;
protected:
virtual void setup() override;
public:
MAX17048Sensor();
public:
MAX17048Sensor();
// Initialise the sensor
virtual int32_t runOnce() override;
// Initialise the sensor
virtual int32_t runOnce() override;
// Get the current bus voltage and state of charge
virtual bool getMetrics(meshtastic_Telemetry *measurement) override;
// Get the current bus voltage and state of charge
virtual bool getMetrics(meshtastic_Telemetry *measurement) override;
// Get the current bus voltage
virtual uint16_t getBusVoltageMv() override;
// Get the current bus voltage
virtual uint16_t getBusVoltageMv() override;
};
#endif

View File

@@ -9,75 +9,71 @@
MAX30102Sensor::MAX30102Sensor() : TelemetrySensor(meshtastic_TelemetrySensorType_MAX30102, "MAX30102") {}
int32_t MAX30102Sensor::runOnce()
{
LOG_INFO("Init sensor: %s", sensorName);
if (!hasSensor()) {
return DEFAULT_SENSOR_MINIMUM_WAIT_TIME_BETWEEN_READS;
}
int32_t MAX30102Sensor::runOnce() {
LOG_INFO("Init sensor: %s", sensorName);
if (!hasSensor()) {
return DEFAULT_SENSOR_MINIMUM_WAIT_TIME_BETWEEN_READS;
}
if (max30102.begin(*nodeTelemetrySensorsMap[sensorType].second, _speed, nodeTelemetrySensorsMap[sensorType].first) ==
true) // MAX30102 init
{
byte brightness = 60; // 0=Off to 255=50mA
byte sampleAverage = 4; // 1, 2, 4, 8, 16, 32
byte leds = 2; // 1 = Red only, 2 = Red + IR
byte sampleRate = 100; // 50, 100, 200, 400, 800, 1000, 1600, 3200
int pulseWidth = 411; // 69, 118, 215, 411
int adcRange = 4096; // 2048, 4096, 8192, 16384
if (max30102.begin(*nodeTelemetrySensorsMap[sensorType].second, _speed, nodeTelemetrySensorsMap[sensorType].first) == true) // MAX30102 init
{
byte brightness = 60; // 0=Off to 255=50mA
byte sampleAverage = 4; // 1, 2, 4, 8, 16, 32
byte leds = 2; // 1 = Red only, 2 = Red + IR
byte sampleRate = 100; // 50, 100, 200, 400, 800, 1000, 1600, 3200
int pulseWidth = 411; // 69, 118, 215, 411
int adcRange = 4096; // 2048, 4096, 8192, 16384
max30102.enableDIETEMPRDY(); // Enable the temperature ready interrupt
max30102.setup(brightness, sampleAverage, leds, sampleRate, pulseWidth, adcRange);
LOG_DEBUG("MAX30102 Init Succeed");
status = true;
} else {
LOG_ERROR("MAX30102 Init Failed");
status = false;
}
return initI2CSensor();
max30102.enableDIETEMPRDY(); // Enable the temperature ready interrupt
max30102.setup(brightness, sampleAverage, leds, sampleRate, pulseWidth, adcRange);
LOG_DEBUG("MAX30102 Init Succeed");
status = true;
} else {
LOG_ERROR("MAX30102 Init Failed");
status = false;
}
return initI2CSensor();
}
void MAX30102Sensor::setup() {}
bool MAX30102Sensor::getMetrics(meshtastic_Telemetry *measurement)
{
uint32_t ir_buff[MAX30102_BUFFER_LEN];
uint32_t red_buff[MAX30102_BUFFER_LEN];
int32_t spo2;
int8_t spo2_valid;
int32_t heart_rate;
int8_t heart_rate_valid;
float temp = max30102.readTemperature();
bool MAX30102Sensor::getMetrics(meshtastic_Telemetry *measurement) {
uint32_t ir_buff[MAX30102_BUFFER_LEN];
uint32_t red_buff[MAX30102_BUFFER_LEN];
int32_t spo2;
int8_t spo2_valid;
int32_t heart_rate;
int8_t heart_rate_valid;
float temp = max30102.readTemperature();
measurement->variant.environment_metrics.temperature = temp;
measurement->variant.environment_metrics.has_temperature = true;
measurement->variant.health_metrics.temperature = temp;
measurement->variant.health_metrics.has_temperature = true;
for (byte i = 0; i < MAX30102_BUFFER_LEN; i++) {
while (max30102.available() == false)
max30102.check();
measurement->variant.environment_metrics.temperature = temp;
measurement->variant.environment_metrics.has_temperature = true;
measurement->variant.health_metrics.temperature = temp;
measurement->variant.health_metrics.has_temperature = true;
for (byte i = 0; i < MAX30102_BUFFER_LEN; i++) {
while (max30102.available() == false)
max30102.check();
red_buff[i] = max30102.getRed();
ir_buff[i] = max30102.getIR();
max30102.nextSample();
}
red_buff[i] = max30102.getRed();
ir_buff[i] = max30102.getIR();
max30102.nextSample();
}
maxim_heart_rate_and_oxygen_saturation(ir_buff, MAX30102_BUFFER_LEN, red_buff, &spo2, &spo2_valid, &heart_rate,
&heart_rate_valid);
LOG_DEBUG("heart_rate=%d(%d), sp02=%d(%d)", heart_rate, heart_rate_valid, spo2, spo2_valid);
if (heart_rate_valid) {
measurement->variant.health_metrics.has_heart_bpm = true;
measurement->variant.health_metrics.heart_bpm = heart_rate;
} else {
measurement->variant.health_metrics.has_heart_bpm = false;
}
if (spo2_valid) {
measurement->variant.health_metrics.has_spO2 = true;
measurement->variant.health_metrics.spO2 = spo2;
} else {
measurement->variant.health_metrics.has_spO2 = true;
}
return true;
maxim_heart_rate_and_oxygen_saturation(ir_buff, MAX30102_BUFFER_LEN, red_buff, &spo2, &spo2_valid, &heart_rate, &heart_rate_valid);
LOG_DEBUG("heart_rate=%d(%d), sp02=%d(%d)", heart_rate, heart_rate_valid, spo2, spo2_valid);
if (heart_rate_valid) {
measurement->variant.health_metrics.has_heart_bpm = true;
measurement->variant.health_metrics.heart_bpm = heart_rate;
} else {
measurement->variant.health_metrics.has_heart_bpm = false;
}
if (spo2_valid) {
measurement->variant.health_metrics.has_spO2 = true;
measurement->variant.health_metrics.spO2 = spo2;
} else {
measurement->variant.health_metrics.has_spO2 = true;
}
return true;
}
#endif

View File

@@ -8,19 +8,18 @@
#define MAX30102_BUFFER_LEN 100
class MAX30102Sensor : public TelemetrySensor
{
private:
MAX30105 max30102 = MAX30105();
uint32_t _speed = 200000UL;
class MAX30102Sensor : public TelemetrySensor {
private:
MAX30105 max30102 = MAX30105();
uint32_t _speed = 200000UL;
protected:
virtual void setup() override;
protected:
virtual void setup() override;
public:
MAX30102Sensor();
virtual int32_t runOnce() override;
virtual bool getMetrics(meshtastic_Telemetry *measurement) override;
public:
MAX30102Sensor();
virtual int32_t runOnce() override;
virtual bool getMetrics(meshtastic_Telemetry *measurement) override;
};
#endif

View File

@@ -9,26 +9,24 @@
MCP9808Sensor::MCP9808Sensor() : TelemetrySensor(meshtastic_TelemetrySensorType_MCP9808, "MCP9808") {}
bool MCP9808Sensor::initDevice(TwoWire *bus, ScanI2C::FoundDevice *dev)
{
LOG_INFO("Init sensor: %s", sensorName);
status = mcp9808.begin(dev->address.address, bus);
if (!status) {
return status;
}
mcp9808.setResolution(2);
initI2CSensor();
bool MCP9808Sensor::initDevice(TwoWire *bus, ScanI2C::FoundDevice *dev) {
LOG_INFO("Init sensor: %s", sensorName);
status = mcp9808.begin(dev->address.address, bus);
if (!status) {
return status;
}
mcp9808.setResolution(2);
initI2CSensor();
return status;
}
bool MCP9808Sensor::getMetrics(meshtastic_Telemetry *measurement)
{
measurement->variant.environment_metrics.has_temperature = true;
bool MCP9808Sensor::getMetrics(meshtastic_Telemetry *measurement) {
measurement->variant.environment_metrics.has_temperature = true;
LOG_DEBUG("MCP9808 getMetrics");
measurement->variant.environment_metrics.temperature = mcp9808.readTempC();
return true;
LOG_DEBUG("MCP9808 getMetrics");
measurement->variant.environment_metrics.temperature = mcp9808.readTempC();
return true;
}
#endif

View File

@@ -6,15 +6,14 @@
#include "TelemetrySensor.h"
#include <Adafruit_MCP9808.h>
class MCP9808Sensor : public TelemetrySensor
{
private:
Adafruit_MCP9808 mcp9808;
class MCP9808Sensor : public TelemetrySensor {
private:
Adafruit_MCP9808 mcp9808;
public:
MCP9808Sensor();
virtual bool getMetrics(meshtastic_Telemetry *measurement) override;
virtual bool initDevice(TwoWire *bus, ScanI2C::FoundDevice *dev) override;
public:
MCP9808Sensor();
virtual bool getMetrics(meshtastic_Telemetry *measurement) override;
virtual bool initDevice(TwoWire *bus, ScanI2C::FoundDevice *dev) override;
};
#endif

View File

@@ -7,38 +7,36 @@
#include "TelemetrySensor.h"
MLX90614Sensor::MLX90614Sensor() : TelemetrySensor(meshtastic_TelemetrySensorType_MLX90614, "MLX90614") {}
int32_t MLX90614Sensor::runOnce()
{
LOG_INFO("Init sensor: %s", sensorName);
if (!hasSensor()) {
return DEFAULT_SENSOR_MINIMUM_WAIT_TIME_BETWEEN_READS;
}
int32_t MLX90614Sensor::runOnce() {
LOG_INFO("Init sensor: %s", sensorName);
if (!hasSensor()) {
return DEFAULT_SENSOR_MINIMUM_WAIT_TIME_BETWEEN_READS;
}
if (mlx.begin(nodeTelemetrySensorsMap[sensorType].first, nodeTelemetrySensorsMap[sensorType].second) == true) // MLX90614 init
{
LOG_DEBUG("MLX90614 emissivity: %f", mlx.readEmissivity());
if (fabs(MLX90614_EMISSIVITY - mlx.readEmissivity()) > 0.001) {
mlx.writeEmissivity(MLX90614_EMISSIVITY);
LOG_INFO("MLX90614 emissivity updated. In case of weird data, power cycle");
}
LOG_DEBUG("MLX90614 Init Succeed");
status = true;
} else {
LOG_ERROR("MLX90614 Init Failed");
status = false;
if (mlx.begin(nodeTelemetrySensorsMap[sensorType].first, nodeTelemetrySensorsMap[sensorType].second) == true) // MLX90614 init
{
LOG_DEBUG("MLX90614 emissivity: %f", mlx.readEmissivity());
if (fabs(MLX90614_EMISSIVITY - mlx.readEmissivity()) > 0.001) {
mlx.writeEmissivity(MLX90614_EMISSIVITY);
LOG_INFO("MLX90614 emissivity updated. In case of weird data, power cycle");
}
return initI2CSensor();
LOG_DEBUG("MLX90614 Init Succeed");
status = true;
} else {
LOG_ERROR("MLX90614 Init Failed");
status = false;
}
return initI2CSensor();
}
void MLX90614Sensor::setup() {}
bool MLX90614Sensor::getMetrics(meshtastic_Telemetry *measurement)
{
measurement->variant.environment_metrics.temperature = mlx.readAmbientTempC();
measurement->variant.environment_metrics.has_temperature = true;
measurement->variant.health_metrics.temperature = mlx.readObjectTempC();
measurement->variant.health_metrics.has_temperature = true;
return true;
bool MLX90614Sensor::getMetrics(meshtastic_Telemetry *measurement) {
measurement->variant.environment_metrics.temperature = mlx.readAmbientTempC();
measurement->variant.environment_metrics.has_temperature = true;
measurement->variant.health_metrics.temperature = mlx.readObjectTempC();
measurement->variant.health_metrics.has_temperature = true;
return true;
}
#endif

View File

@@ -7,18 +7,17 @@
#define MLX90614_EMISSIVITY 0.98 // human skin
class MLX90614Sensor : public TelemetrySensor
{
private:
Adafruit_MLX90614 mlx = Adafruit_MLX90614();
class MLX90614Sensor : public TelemetrySensor {
private:
Adafruit_MLX90614 mlx = Adafruit_MLX90614();
protected:
virtual void setup() override;
protected:
virtual void setup() override;
public:
MLX90614Sensor();
virtual int32_t runOnce() override;
virtual bool getMetrics(meshtastic_Telemetry *measurement) override;
public:
MLX90614Sensor();
virtual int32_t runOnce() override;
virtual bool getMetrics(meshtastic_Telemetry *measurement) override;
};
#endif

View File

@@ -8,29 +8,27 @@
MLX90632Sensor::MLX90632Sensor() : TelemetrySensor(meshtastic_TelemetrySensorType_MLX90632, "MLX90632") {}
bool MLX90632Sensor::initDevice(TwoWire *bus, ScanI2C::FoundDevice *dev)
{
LOG_INFO("Init sensor: %s", sensorName);
bool MLX90632Sensor::initDevice(TwoWire *bus, ScanI2C::FoundDevice *dev) {
LOG_INFO("Init sensor: %s", sensorName);
MLX90632::status returnError;
if (mlx.begin(dev->address.address, *bus, returnError) == true) // MLX90632 init
{
LOG_DEBUG("MLX90632 Init Succeed");
status = true;
} else {
LOG_ERROR("MLX90632 Init Failed");
status = false;
}
initI2CSensor();
return status;
MLX90632::status returnError;
if (mlx.begin(dev->address.address, *bus, returnError) == true) // MLX90632 init
{
LOG_DEBUG("MLX90632 Init Succeed");
status = true;
} else {
LOG_ERROR("MLX90632 Init Failed");
status = false;
}
initI2CSensor();
return status;
}
bool MLX90632Sensor::getMetrics(meshtastic_Telemetry *measurement)
{
measurement->variant.environment_metrics.has_temperature = true;
measurement->variant.environment_metrics.temperature = mlx.getObjectTemp(); // Get the object temperature in Fahrenheit
bool MLX90632Sensor::getMetrics(meshtastic_Telemetry *measurement) {
measurement->variant.environment_metrics.has_temperature = true;
measurement->variant.environment_metrics.temperature = mlx.getObjectTemp(); // Get the object temperature in Fahrenheit
return true;
return true;
}
#endif

View File

@@ -6,15 +6,14 @@
#include "TelemetrySensor.h"
#include <SparkFun_MLX90632_Arduino_Library.h>
class MLX90632Sensor : public TelemetrySensor
{
private:
MLX90632 mlx = MLX90632();
class MLX90632Sensor : public TelemetrySensor {
private:
MLX90632 mlx = MLX90632();
public:
MLX90632Sensor();
virtual bool getMetrics(meshtastic_Telemetry *measurement) override;
virtual bool initDevice(TwoWire *bus, ScanI2C::FoundDevice *dev) override;
public:
MLX90632Sensor();
virtual bool getMetrics(meshtastic_Telemetry *measurement) override;
virtual bool initDevice(TwoWire *bus, ScanI2C::FoundDevice *dev) override;
};
#endif

View File

@@ -16,128 +16,121 @@ meshtastic_Nau7802Config nau7802config = meshtastic_Nau7802Config_init_zero;
NAU7802Sensor::NAU7802Sensor() : TelemetrySensor(meshtastic_TelemetrySensorType_NAU7802, "NAU7802") {}
bool NAU7802Sensor::initDevice(TwoWire *bus, ScanI2C::FoundDevice *dev)
{
LOG_INFO("Init sensor: %s", sensorName);
status = nau7802.begin(*bus);
if (!status) {
return status;
}
nau7802.setSampleRate(NAU7802_SPS_320);
if (!loadCalibrationData()) {
LOG_ERROR("Failed to load calibration data");
}
nau7802.calibrateAFE();
LOG_INFO("Offset: %d, Calibration factor: %.2f", nau7802.getZeroOffset(), nau7802.getCalibrationFactor());
initI2CSensor();
bool NAU7802Sensor::initDevice(TwoWire *bus, ScanI2C::FoundDevice *dev) {
LOG_INFO("Init sensor: %s", sensorName);
status = nau7802.begin(*bus);
if (!status) {
return status;
}
nau7802.setSampleRate(NAU7802_SPS_320);
if (!loadCalibrationData()) {
LOG_ERROR("Failed to load calibration data");
}
nau7802.calibrateAFE();
LOG_INFO("Offset: %d, Calibration factor: %.2f", nau7802.getZeroOffset(), nau7802.getCalibrationFactor());
initI2CSensor();
return status;
}
bool NAU7802Sensor::getMetrics(meshtastic_Telemetry *measurement)
{
LOG_DEBUG("NAU7802 getMetrics");
nau7802.powerUp();
// Wait for the sensor to become ready for one second max
uint32_t start = millis();
while (!nau7802.available()) {
delay(100);
if (!Throttle::isWithinTimespanMs(start, 1000)) {
nau7802.powerDown();
return false;
}
bool NAU7802Sensor::getMetrics(meshtastic_Telemetry *measurement) {
LOG_DEBUG("NAU7802 getMetrics");
nau7802.powerUp();
// Wait for the sensor to become ready for one second max
uint32_t start = millis();
while (!nau7802.available()) {
delay(100);
if (!Throttle::isWithinTimespanMs(start, 1000)) {
nau7802.powerDown();
return false;
}
measurement->variant.environment_metrics.has_weight = true;
// Check if we have correct calibration values after powerup
LOG_DEBUG("Offset: %d, Calibration factor: %.2f", nau7802.getZeroOffset(), nau7802.getCalibrationFactor());
measurement->variant.environment_metrics.weight = nau7802.getWeight() / 1000; // sample is in kg
nau7802.powerDown();
return true;
}
measurement->variant.environment_metrics.has_weight = true;
// Check if we have correct calibration values after powerup
LOG_DEBUG("Offset: %d, Calibration factor: %.2f", nau7802.getZeroOffset(), nau7802.getCalibrationFactor());
measurement->variant.environment_metrics.weight = nau7802.getWeight() / 1000; // sample is in kg
nau7802.powerDown();
return true;
}
void NAU7802Sensor::calibrate(float weight)
{
nau7802.calculateCalibrationFactor(weight * 1000, 64); // internal sample is in grams
if (!saveCalibrationData()) {
LOG_WARN("Failed to save calibration data");
}
LOG_INFO("Offset: %d, Calibration factor: %.2f", nau7802.getZeroOffset(), nau7802.getCalibrationFactor());
void NAU7802Sensor::calibrate(float weight) {
nau7802.calculateCalibrationFactor(weight * 1000, 64); // internal sample is in grams
if (!saveCalibrationData()) {
LOG_WARN("Failed to save calibration data");
}
LOG_INFO("Offset: %d, Calibration factor: %.2f", nau7802.getZeroOffset(), nau7802.getCalibrationFactor());
}
AdminMessageHandleResult NAU7802Sensor::handleAdminMessage(const meshtastic_MeshPacket &mp, meshtastic_AdminMessage *request,
meshtastic_AdminMessage *response)
{
AdminMessageHandleResult result;
meshtastic_AdminMessage *response) {
AdminMessageHandleResult result;
switch (request->which_payload_variant) {
case meshtastic_AdminMessage_set_scale_tag:
if (request->set_scale == 0) {
this->tare();
LOG_DEBUG("Client requested to tare scale");
} else {
this->calibrate(request->set_scale);
LOG_DEBUG("Client requested to calibrate to %d kg", request->set_scale);
}
result = AdminMessageHandleResult::HANDLED;
break;
default:
result = AdminMessageHandleResult::NOT_HANDLED;
}
return result;
}
void NAU7802Sensor::tare()
{
nau7802.calculateZeroOffset(64);
if (!saveCalibrationData()) {
LOG_WARN("Failed to save calibration data");
}
LOG_INFO("Offset: %d, Calibration factor: %.2f", nau7802.getZeroOffset(), nau7802.getCalibrationFactor());
}
bool NAU7802Sensor::saveCalibrationData()
{
auto file = SafeFile(nau7802ConfigFileName);
nau7802config.zeroOffset = nau7802.getZeroOffset();
nau7802config.calibrationFactor = nau7802.getCalibrationFactor();
bool okay = false;
LOG_INFO("%s state write to %s", sensorName, nau7802ConfigFileName);
pb_ostream_t stream = {&writecb, static_cast<Print *>(&file), meshtastic_Nau7802Config_size};
if (!pb_encode(&stream, &meshtastic_Nau7802Config_msg, &nau7802config)) {
LOG_ERROR("Error: can't encode protobuf %s", PB_GET_ERROR(&stream));
switch (request->which_payload_variant) {
case meshtastic_AdminMessage_set_scale_tag:
if (request->set_scale == 0) {
this->tare();
LOG_DEBUG("Client requested to tare scale");
} else {
okay = true;
this->calibrate(request->set_scale);
LOG_DEBUG("Client requested to calibrate to %d kg", request->set_scale);
}
// Note: SafeFile::close() already acquires the lock and releases it internally
okay &= file.close();
result = AdminMessageHandleResult::HANDLED;
break;
return okay;
default:
result = AdminMessageHandleResult::NOT_HANDLED;
}
return result;
}
bool NAU7802Sensor::loadCalibrationData()
{
spiLock->lock();
auto file = FSCom.open(nau7802ConfigFileName, FILE_O_READ);
bool okay = false;
if (file) {
LOG_INFO("%s state read from %s", sensorName, nau7802ConfigFileName);
pb_istream_t stream = {&readcb, &file, meshtastic_Nau7802Config_size};
if (!pb_decode(&stream, &meshtastic_Nau7802Config_msg, &nau7802config)) {
LOG_ERROR("Error: can't decode protobuf %s", PB_GET_ERROR(&stream));
} else {
nau7802.setZeroOffset(nau7802config.zeroOffset);
nau7802.setCalibrationFactor(nau7802config.calibrationFactor);
okay = true;
}
file.close();
void NAU7802Sensor::tare() {
nau7802.calculateZeroOffset(64);
if (!saveCalibrationData()) {
LOG_WARN("Failed to save calibration data");
}
LOG_INFO("Offset: %d, Calibration factor: %.2f", nau7802.getZeroOffset(), nau7802.getCalibrationFactor());
}
bool NAU7802Sensor::saveCalibrationData() {
auto file = SafeFile(nau7802ConfigFileName);
nau7802config.zeroOffset = nau7802.getZeroOffset();
nau7802config.calibrationFactor = nau7802.getCalibrationFactor();
bool okay = false;
LOG_INFO("%s state write to %s", sensorName, nau7802ConfigFileName);
pb_ostream_t stream = {&writecb, static_cast<Print *>(&file), meshtastic_Nau7802Config_size};
if (!pb_encode(&stream, &meshtastic_Nau7802Config_msg, &nau7802config)) {
LOG_ERROR("Error: can't encode protobuf %s", PB_GET_ERROR(&stream));
} else {
okay = true;
}
// Note: SafeFile::close() already acquires the lock and releases it internally
okay &= file.close();
return okay;
}
bool NAU7802Sensor::loadCalibrationData() {
spiLock->lock();
auto file = FSCom.open(nau7802ConfigFileName, FILE_O_READ);
bool okay = false;
if (file) {
LOG_INFO("%s state read from %s", sensorName, nau7802ConfigFileName);
pb_istream_t stream = {&readcb, &file, meshtastic_Nau7802Config_size};
if (!pb_decode(&stream, &meshtastic_Nau7802Config_msg, &nau7802config)) {
LOG_ERROR("Error: can't decode protobuf %s", PB_GET_ERROR(&stream));
} else {
LOG_INFO("No %s state found (File: %s)", sensorName, nau7802ConfigFileName);
nau7802.setZeroOffset(nau7802config.zeroOffset);
nau7802.setCalibrationFactor(nau7802config.calibrationFactor);
okay = true;
}
spiLock->unlock();
return okay;
file.close();
} else {
LOG_INFO("No %s state found (File: %s)", sensorName, nau7802ConfigFileName);
}
spiLock->unlock();
return okay;
}
#endif

View File

@@ -7,24 +7,23 @@
#include "TelemetrySensor.h"
#include <SparkFun_Qwiic_Scale_NAU7802_Arduino_Library.h>
class NAU7802Sensor : public TelemetrySensor
{
private:
NAU7802 nau7802;
class NAU7802Sensor : public TelemetrySensor {
private:
NAU7802 nau7802;
protected:
const char *nau7802ConfigFileName = "/prefs/nau7802.dat";
bool saveCalibrationData();
bool loadCalibrationData();
protected:
const char *nau7802ConfigFileName = "/prefs/nau7802.dat";
bool saveCalibrationData();
bool loadCalibrationData();
public:
NAU7802Sensor();
virtual bool getMetrics(meshtastic_Telemetry *measurement) override;
virtual bool initDevice(TwoWire *bus, ScanI2C::FoundDevice *dev) override;
void tare();
void calibrate(float weight);
AdminMessageHandleResult handleAdminMessage(const meshtastic_MeshPacket &mp, meshtastic_AdminMessage *request,
meshtastic_AdminMessage *response) override;
public:
NAU7802Sensor();
virtual bool getMetrics(meshtastic_Telemetry *measurement) override;
virtual bool initDevice(TwoWire *bus, ScanI2C::FoundDevice *dev) override;
void tare();
void calibrate(float weight);
AdminMessageHandleResult handleAdminMessage(const meshtastic_MeshPacket &mp, meshtastic_AdminMessage *request,
meshtastic_AdminMessage *response) override;
};
#endif

View File

@@ -9,41 +9,39 @@
OPT3001Sensor::OPT3001Sensor() : TelemetrySensor(meshtastic_TelemetrySensorType_OPT3001, "OPT3001") {}
bool OPT3001Sensor::initDevice(TwoWire *bus, ScanI2C::FoundDevice *dev)
{
LOG_INFO("Init sensor: %s", sensorName);
auto errorCode = opt3001.begin(dev->address.address);
status = errorCode == NO_ERROR;
if (!status) {
return status;
}
OPT3001_Config newConfig;
newConfig.RangeNumber = 0b1100;
newConfig.ConvertionTime = 0b0;
newConfig.Latch = 0b1;
newConfig.ModeOfConversionOperation = 0b11;
OPT3001_ErrorCode errorConfig = opt3001.writeConfig(newConfig);
if (errorConfig != NO_ERROR) {
LOG_ERROR("OPT3001 configuration error #%d", errorConfig);
}
status = errorConfig == NO_ERROR;
initI2CSensor();
bool OPT3001Sensor::initDevice(TwoWire *bus, ScanI2C::FoundDevice *dev) {
LOG_INFO("Init sensor: %s", sensorName);
auto errorCode = opt3001.begin(dev->address.address);
status = errorCode == NO_ERROR;
if (!status) {
return status;
}
OPT3001_Config newConfig;
newConfig.RangeNumber = 0b1100;
newConfig.ConvertionTime = 0b0;
newConfig.Latch = 0b1;
newConfig.ModeOfConversionOperation = 0b11;
OPT3001_ErrorCode errorConfig = opt3001.writeConfig(newConfig);
if (errorConfig != NO_ERROR) {
LOG_ERROR("OPT3001 configuration error #%d", errorConfig);
}
status = errorConfig == NO_ERROR;
initI2CSensor();
return status;
}
bool OPT3001Sensor::getMetrics(meshtastic_Telemetry *measurement)
{
measurement->variant.environment_metrics.has_lux = true;
OPT3001 result = opt3001.readResult();
bool OPT3001Sensor::getMetrics(meshtastic_Telemetry *measurement) {
measurement->variant.environment_metrics.has_lux = true;
OPT3001 result = opt3001.readResult();
measurement->variant.environment_metrics.lux = result.lux;
LOG_INFO("Lux: %f", measurement->variant.environment_metrics.lux);
measurement->variant.environment_metrics.lux = result.lux;
LOG_INFO("Lux: %f", measurement->variant.environment_metrics.lux);
return true;
return true;
}
#endif

View File

@@ -7,18 +7,17 @@
#include "TelemetrySensor.h"
#include <ClosedCube_OPT3001.h>
class OPT3001Sensor : public TelemetrySensor
{
private:
ClosedCube_OPT3001 opt3001;
class OPT3001Sensor : public TelemetrySensor {
private:
ClosedCube_OPT3001 opt3001;
public:
OPT3001Sensor();
public:
OPT3001Sensor();
#if WIRE_INTERFACES_COUNT > 1
virtual bool onlyWire1() { return true; }
virtual bool onlyWire1() { return true; }
#endif
virtual bool getMetrics(meshtastic_Telemetry *measurement) override;
virtual bool initDevice(TwoWire *bus, ScanI2C::FoundDevice *dev) override;
virtual bool getMetrics(meshtastic_Telemetry *measurement) override;
virtual bool initDevice(TwoWire *bus, ScanI2C::FoundDevice *dev) override;
};
#endif

View File

@@ -9,21 +9,19 @@
PCT2075Sensor::PCT2075Sensor() : TelemetrySensor(meshtastic_TelemetrySensorType_PCT2075, "PCT2075") {}
bool PCT2075Sensor::initDevice(TwoWire *bus, ScanI2C::FoundDevice *dev)
{
LOG_INFO("Init sensor: %s", sensorName);
status = pct2075.begin(dev->address.address, bus);
bool PCT2075Sensor::initDevice(TwoWire *bus, ScanI2C::FoundDevice *dev) {
LOG_INFO("Init sensor: %s", sensorName);
status = pct2075.begin(dev->address.address, bus);
initI2CSensor();
return status;
initI2CSensor();
return status;
}
bool PCT2075Sensor::getMetrics(meshtastic_Telemetry *measurement)
{
measurement->variant.environment_metrics.has_temperature = true;
measurement->variant.environment_metrics.temperature = pct2075.getTemperature();
bool PCT2075Sensor::getMetrics(meshtastic_Telemetry *measurement) {
measurement->variant.environment_metrics.has_temperature = true;
measurement->variant.environment_metrics.temperature = pct2075.getTemperature();
return true;
return true;
}
#endif

View File

@@ -7,15 +7,14 @@
#include "TelemetrySensor.h"
#include <Adafruit_PCT2075.h>
class PCT2075Sensor : public TelemetrySensor
{
private:
Adafruit_PCT2075 pct2075;
class PCT2075Sensor : public TelemetrySensor {
private:
Adafruit_PCT2075 pct2075;
public:
PCT2075Sensor();
virtual bool getMetrics(meshtastic_Telemetry *measurement) override;
virtual bool initDevice(TwoWire *bus, ScanI2C::FoundDevice *dev) override;
public:
PCT2075Sensor();
virtual bool getMetrics(meshtastic_Telemetry *measurement) override;
virtual bool initDevice(TwoWire *bus, ScanI2C::FoundDevice *dev) override;
};
#endif

View File

@@ -6,105 +6,102 @@
RAK12035Sensor::RAK12035Sensor() : TelemetrySensor(meshtastic_TelemetrySensorType_RAK12035, "RAK12035") {}
bool RAK12035Sensor::initDevice(TwoWire *bus, ScanI2C::FoundDevice *dev)
{
// TODO:: check for up to 2 additional sensors and start them if present.
sensor.set_sensor_addr(RAK120351_ADDR);
delay(100);
sensor.begin(dev->address.address);
bool RAK12035Sensor::initDevice(TwoWire *bus, ScanI2C::FoundDevice *dev) {
// TODO:: check for up to 2 additional sensors and start them if present.
sensor.set_sensor_addr(RAK120351_ADDR);
delay(100);
sensor.begin(dev->address.address);
// Get sensor firmware version
uint8_t data = 0;
sensor.get_sensor_version(&data);
if (data != 0) {
LOG_INFO("Init sensor: %s", sensorName);
LOG_INFO("RAK12035Sensor Init Succeed \nSensor1 Firmware version: %i, Sensor Name: %s", data, sensorName);
status = true;
sensor.sensor_sleep();
} else {
// If we reach here, it means the sensor did not initialize correctly.
LOG_INFO("Init sensor: %s", sensorName);
LOG_ERROR("RAK12035Sensor Init Failed");
status = false;
}
if (!status) {
return status;
}
setup();
initI2CSensor();
// Get sensor firmware version
uint8_t data = 0;
sensor.get_sensor_version(&data);
if (data != 0) {
LOG_INFO("Init sensor: %s", sensorName);
LOG_INFO("RAK12035Sensor Init Succeed \nSensor1 Firmware version: %i, Sensor Name: %s", data, sensorName);
status = true;
sensor.sensor_sleep();
} else {
// If we reach here, it means the sensor did not initialize correctly.
LOG_INFO("Init sensor: %s", sensorName);
LOG_ERROR("RAK12035Sensor Init Failed");
status = false;
}
if (!status) {
return status;
}
setup();
initI2CSensor();
return status;
}
void RAK12035Sensor::setup()
{
// Set the calibration values
// Reading the saved calibration values from the sensor.
// TODO:: Check for and run calibration check for up to 2 additional sensors if present.
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_INFO("Dry calibration value is %d", zero_val);
LOG_INFO("Wet calibration value is %d", hundred_val);
LOG_INFO("This does not make sense. You can recalibrate this sensor using the calibration sketch included here: "
"https://github.com/RAKWireless/RAK12035_SoilMoisture.");
LOG_INFO("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_INFO("Dry calibration reset complete. New value is %d", zero_val);
}
if (hundred_val == 0 || hundred_val >= zero_val) {
LOG_INFO("Dry calibration value is %d", zero_val);
LOG_INFO("Wet calibration value is %d", hundred_val);
LOG_INFO("This does not make sense. You can recalibrate this sensor using the calibration sketch included here: "
"https://github.com/RAKWireless/RAK12035_SoilMoisture.");
LOG_INFO("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_INFO("Wet calibration reset complete. New value is %d", hundred_val);
}
sensor.sensor_sleep();
delay(200);
void RAK12035Sensor::setup() {
// Set the calibration values
// Reading the saved calibration values from the sensor.
// TODO:: Check for and run calibration check for up to 2 additional sensors if present.
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_INFO("Dry calibration value is %d", zero_val);
LOG_INFO("Wet calibration value is %d", hundred_val);
LOG_INFO("This does not make sense. You can recalibrate this sensor using the calibration sketch included here: "
"https://github.com/RAKWireless/RAK12035_SoilMoisture.");
LOG_INFO("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_INFO("Dry calibration reset complete. New value is %d", zero_val);
}
if (hundred_val == 0 || hundred_val >= zero_val) {
LOG_INFO("Dry calibration value is %d", zero_val);
LOG_INFO("Wet calibration value is %d", hundred_val);
LOG_INFO("This does not make sense. You can recalibrate this sensor using the calibration sketch included here: "
"https://github.com/RAKWireless/RAK12035_SoilMoisture.");
LOG_INFO("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_INFO("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)
{
// TODO:: read and send metrics for up to 2 additional soil monitors if present.
// -- how to do this.. this could get a little complex..
// ie - 1> we combine them into an average and send that, 2> we send them as separate metrics
// ^-- these scenarios would require different handling of the metrics in the receiving end and maybe a setting in the
// device ui and an additional proto for that?
measurement->variant.environment_metrics.has_soil_temperature = true;
measurement->variant.environment_metrics.has_soil_moisture = true;
bool RAK12035Sensor::getMetrics(meshtastic_Telemetry *measurement) {
// TODO:: read and send metrics for up to 2 additional soil monitors if present.
// -- how to do this.. this could get a little complex..
// ie - 1> we combine them into an average and send that, 2> we send them as separate metrics
// ^-- these scenarios would require different handling of the metrics in the receiving end and maybe a setting
// in the device ui and an additional proto for that?
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;
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();
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;
}
measurement->variant.environment_metrics.soil_temperature = ((float)temp / 10.0f);
measurement->variant.environment_metrics.soil_moisture = moisture;
if (success == false) {
LOG_ERROR("Failed to read sensor data");
return false;
}
measurement->variant.environment_metrics.soil_temperature = ((float)temp / 10.0f);
measurement->variant.environment_metrics.soil_moisture = moisture;
return true;
return true;
}
#endif

View File

@@ -12,18 +12,17 @@
#include "TelemetrySensor.h"
#include <Arduino.h>
class RAK12035Sensor : public TelemetrySensor
{
private:
RAK12035 sensor;
void setup();
class RAK12035Sensor : public TelemetrySensor {
private:
RAK12035 sensor;
void setup();
public:
RAK12035Sensor();
public:
RAK12035Sensor();
#if WIRE_INTERFACES_COUNT > 1
virtual bool onlyWire1() { return true; }
virtual bool onlyWire1() { return true; }
#endif
virtual bool getMetrics(meshtastic_Telemetry *measurement) override;
virtual bool initDevice(TwoWire *bus, ScanI2C::FoundDevice *dev) override;
virtual bool getMetrics(meshtastic_Telemetry *measurement) override;
virtual bool initDevice(TwoWire *bus, ScanI2C::FoundDevice *dev) override;
};
#endif

View File

@@ -28,182 +28,162 @@ static uint8_t provision = 0;
extern RAK9154Sensor rak9154Sensor;
static void onewire_evt(const uint8_t pid, const uint8_t sid, const SNHUBAPI_EVT_E eid, uint8_t *msg, uint16_t len)
{
switch (eid) {
case SNHUBAPI_EVT_RECV_REQ:
case SNHUBAPI_EVT_RECV_RSP:
break;
static void onewire_evt(const uint8_t pid, const uint8_t sid, const SNHUBAPI_EVT_E eid, uint8_t *msg, uint16_t len) {
switch (eid) {
case SNHUBAPI_EVT_RECV_REQ:
case SNHUBAPI_EVT_RECV_RSP:
break;
case SNHUBAPI_EVT_QSEND:
mySerial.write(msg, len);
break;
case SNHUBAPI_EVT_QSEND:
mySerial.write(msg, len);
break;
case SNHUBAPI_EVT_ADD_SID:
// LOG_INFO("+ADD:SID:[%02x]", msg[0]);
break;
case SNHUBAPI_EVT_ADD_SID:
// LOG_INFO("+ADD:SID:[%02x]", msg[0]);
break;
case SNHUBAPI_EVT_ADD_PID:
// LOG_INFO("+ADD:PID:[%02x]", msg[0]);
case SNHUBAPI_EVT_ADD_PID:
// LOG_INFO("+ADD:PID:[%02x]", msg[0]);
#ifdef BOOT_DATA_REQ
provision = msg[0];
provision = msg[0];
#endif
break;
break;
case SNHUBAPI_EVT_GET_INTV:
break;
case SNHUBAPI_EVT_GET_INTV:
break;
case SNHUBAPI_EVT_GET_ENABLE:
break;
case SNHUBAPI_EVT_GET_ENABLE:
break;
case SNHUBAPI_EVT_SDATA_REQ:
// LOG_INFO("+EVT:PID[%02x],IPSO[%02x]",pid,msg[0]);
// for( uint16_t i=1; i<len; i++)
// {
// LOG_INFO("%02x,", msg[i]);
// }
// LOG_INFO("");
switch (msg[0]) {
case RAK_IPSO_CAPACITY:
dc_prec = msg[1];
if (dc_prec > 100) {
dc_prec = 100;
}
break;
case RAK_IPSO_DC_CURRENT:
dc_cur = (msg[2] << 8) + msg[1];
break;
case RAK_IPSO_DC_VOLTAGE:
dc_vol = (msg[2] << 8) + msg[1];
dc_vol *= 10;
break;
default:
break;
}
rak9154Sensor.setLastRead(millis());
break;
case SNHUBAPI_EVT_REPORT:
// LOG_INFO("+EVT:PID[%02x],IPSO[%02x]",pid,msg[0]);
// for( uint16_t i=1; i<len; i++)
// {
// LOG_INFO("%02x,", msg[i]);
// }
// LOG_INFO("");
switch (msg[0]) {
case RAK_IPSO_CAPACITY:
dc_prec = msg[1];
if (dc_prec > 100) {
dc_prec = 100;
}
break;
case RAK_IPSO_DC_CURRENT:
dc_cur = (msg[1] << 8) + msg[2];
break;
case RAK_IPSO_DC_VOLTAGE:
dc_vol = (msg[1] << 8) + msg[2];
dc_vol *= 10;
break;
default:
break;
}
rak9154Sensor.setLastRead(millis());
break;
case SNHUBAPI_EVT_CHKSUM_ERR:
LOG_INFO("+ERR:CHKSUM");
break;
case SNHUBAPI_EVT_SEQ_ERR:
LOG_INFO("+ERR:SEQUCE");
break;
case SNHUBAPI_EVT_SDATA_REQ:
// LOG_INFO("+EVT:PID[%02x],IPSO[%02x]",pid,msg[0]);
// for( uint16_t i=1; i<len; i++)
// {
// LOG_INFO("%02x,", msg[i]);
// }
// LOG_INFO("");
switch (msg[0]) {
case RAK_IPSO_CAPACITY:
dc_prec = msg[1];
if (dc_prec > 100) {
dc_prec = 100;
}
break;
case RAK_IPSO_DC_CURRENT:
dc_cur = (msg[2] << 8) + msg[1];
break;
case RAK_IPSO_DC_VOLTAGE:
dc_vol = (msg[2] << 8) + msg[1];
dc_vol *= 10;
break;
default:
break;
break;
}
}
rak9154Sensor.setLastRead(millis());
static int32_t onewireHandle()
{
if (provision != 0) {
RakSNHub_Protocl_API.get.data(provision);
provision = 0;
break;
case SNHUBAPI_EVT_REPORT:
// LOG_INFO("+EVT:PID[%02x],IPSO[%02x]",pid,msg[0]);
// for( uint16_t i=1; i<len; i++)
// {
// LOG_INFO("%02x,", msg[i]);
// }
// LOG_INFO("");
switch (msg[0]) {
case RAK_IPSO_CAPACITY:
dc_prec = msg[1];
if (dc_prec > 100) {
dc_prec = 100;
}
break;
case RAK_IPSO_DC_CURRENT:
dc_cur = (msg[1] << 8) + msg[2];
break;
case RAK_IPSO_DC_VOLTAGE:
dc_vol = (msg[1] << 8) + msg[2];
dc_vol *= 10;
break;
default:
break;
}
rak9154Sensor.setLastRead(millis());
while (mySerial.available()) {
char a = mySerial.read();
buff[bufflen++] = a;
delay(2); // continue data, timeout=2ms
}
break;
if (bufflen != 0) {
RakSNHub_Protocl_API.process((uint8_t *)buff, bufflen);
bufflen = 0;
}
case SNHUBAPI_EVT_CHKSUM_ERR:
LOG_INFO("+ERR:CHKSUM");
break;
return 50;
case SNHUBAPI_EVT_SEQ_ERR:
LOG_INFO("+ERR:SEQUCE");
break;
default:
break;
}
}
int32_t RAK9154Sensor::runOnce()
{
if (!rak9154Sensor.isInitialized()) {
onewirePeriodic = new Periodic("onewireHandle", onewireHandle);
static int32_t onewireHandle() {
if (provision != 0) {
RakSNHub_Protocl_API.get.data(provision);
provision = 0;
}
mySerial.begin(9600);
while (mySerial.available()) {
char a = mySerial.read();
buff[bufflen++] = a;
delay(2); // continue data, timeout=2ms
}
RakSNHub_Protocl_API.init(onewire_evt);
if (bufflen != 0) {
RakSNHub_Protocl_API.process((uint8_t *)buff, bufflen);
bufflen = 0;
}
status = true;
initialized = true;
}
return DEFAULT_SENSOR_MINIMUM_WAIT_TIME_BETWEEN_READS;
return 50;
}
void RAK9154Sensor::setup()
{
// Set up oversampling and filter initialization
int32_t RAK9154Sensor::runOnce() {
if (!rak9154Sensor.isInitialized()) {
onewirePeriodic = new Periodic("onewireHandle", onewireHandle);
mySerial.begin(9600);
RakSNHub_Protocl_API.init(onewire_evt);
status = true;
initialized = true;
}
return DEFAULT_SENSOR_MINIMUM_WAIT_TIME_BETWEEN_READS;
}
bool RAK9154Sensor::getMetrics(meshtastic_Telemetry *measurement)
{
if (getBusVoltageMv() > 0) {
measurement->variant.environment_metrics.has_voltage = true;
measurement->variant.environment_metrics.has_current = true;
measurement->variant.environment_metrics.voltage = (float)getBusVoltageMv() / 1000;
measurement->variant.environment_metrics.current = (float)getCurrentMa() / 1000;
return true;
} else {
return false;
}
void RAK9154Sensor::setup() {
// Set up oversampling and filter initialization
}
uint16_t RAK9154Sensor::getBusVoltageMv()
{
return dc_vol;
bool RAK9154Sensor::getMetrics(meshtastic_Telemetry *measurement) {
if (getBusVoltageMv() > 0) {
measurement->variant.environment_metrics.has_voltage = true;
measurement->variant.environment_metrics.has_current = true;
measurement->variant.environment_metrics.voltage = (float)getBusVoltageMv() / 1000;
measurement->variant.environment_metrics.current = (float)getCurrentMa() / 1000;
return true;
} else {
return false;
}
}
int16_t RAK9154Sensor::getCurrentMa()
{
return dc_cur;
}
uint16_t RAK9154Sensor::getBusVoltageMv() { return dc_vol; }
int RAK9154Sensor::getBusBatteryPercent()
{
return (int)dc_prec;
}
int16_t RAK9154Sensor::getCurrentMa() { return dc_cur; }
bool RAK9154Sensor::isCharging()
{
return (dc_cur > 0) ? true : false;
}
void RAK9154Sensor::setLastRead(uint32_t lastRead)
{
this->lastRead = lastRead;
}
int RAK9154Sensor::getBusBatteryPercent() { return (int)dc_prec; }
bool RAK9154Sensor::isCharging() { return (dc_cur > 0) ? true : false; }
void RAK9154Sensor::setLastRead(uint32_t lastRead) { this->lastRead = lastRead; }
#endif // HAS_RAKPROT

View File

@@ -9,22 +9,21 @@
#include "TelemetrySensor.h"
#include "VoltageSensor.h"
class RAK9154Sensor : public TelemetrySensor, VoltageSensor, CurrentSensor
{
private:
protected:
virtual void setup() override;
uint32_t lastRead = 0;
class RAK9154Sensor : public TelemetrySensor, VoltageSensor, CurrentSensor {
private:
protected:
virtual void setup() override;
uint32_t lastRead = 0;
public:
RAK9154Sensor();
virtual int32_t runOnce() override;
virtual bool getMetrics(meshtastic_Telemetry *measurement) override;
virtual uint16_t getBusVoltageMv() override;
virtual int16_t getCurrentMa() override;
int getBusBatteryPercent();
bool isCharging();
void setLastRead(uint32_t lastRead);
public:
RAK9154Sensor();
virtual int32_t runOnce() override;
virtual bool getMetrics(meshtastic_Telemetry *measurement) override;
virtual uint16_t getBusVoltageMv() override;
virtual int16_t getCurrentMa() override;
int getBusBatteryPercent();
bool isCharging();
void setLastRead(uint32_t lastRead);
};
#endif // _RAK9154SENSOR_H
#endif // HAS_RAKPROT

View File

@@ -8,70 +8,66 @@
RCWL9620Sensor::RCWL9620Sensor() : TelemetrySensor(meshtastic_TelemetrySensorType_RCWL9620, "RCWL9620") {}
bool RCWL9620Sensor::initDevice(TwoWire *bus, ScanI2C::FoundDevice *dev)
{
LOG_INFO("Init sensor: %s", sensorName);
status = 1;
begin(bus, dev->address.address);
initI2CSensor();
return status;
bool RCWL9620Sensor::initDevice(TwoWire *bus, ScanI2C::FoundDevice *dev) {
LOG_INFO("Init sensor: %s", sensorName);
status = 1;
begin(bus, dev->address.address);
initI2CSensor();
return status;
}
bool RCWL9620Sensor::getMetrics(meshtastic_Telemetry *measurement)
{
measurement->variant.environment_metrics.has_distance = true;
LOG_DEBUG("RCWL9620 getMetrics");
measurement->variant.environment_metrics.distance = getDistance();
return true;
bool RCWL9620Sensor::getMetrics(meshtastic_Telemetry *measurement) {
measurement->variant.environment_metrics.has_distance = true;
LOG_DEBUG("RCWL9620 getMetrics");
measurement->variant.environment_metrics.distance = getDistance();
return true;
}
void RCWL9620Sensor::begin(TwoWire *wire, uint8_t addr, uint8_t sda, uint8_t scl, uint32_t speed)
{
_wire = wire;
_addr = addr;
_sda = sda;
_scl = scl;
_speed = speed;
_wire->begin();
void RCWL9620Sensor::begin(TwoWire *wire, uint8_t addr, uint8_t sda, uint8_t scl, uint32_t speed) {
_wire = wire;
_addr = addr;
_sda = sda;
_scl = scl;
_speed = speed;
_wire->begin();
}
float RCWL9620Sensor::getDistance()
{
uint32_t data = 0;
uint8_t b1 = 0, b2 = 0, b3 = 0;
float RCWL9620Sensor::getDistance() {
uint32_t data = 0;
uint8_t b1 = 0, b2 = 0, b3 = 0;
LOG_DEBUG("[RCWL9620] Start measure command");
LOG_DEBUG("[RCWL9620] Start measure command");
_wire->beginTransmission(_addr);
_wire->write(0x01); // À tester aussi sans cette ligne si besoin
uint8_t result = _wire->endTransmission();
LOG_DEBUG("[RCWL9620] endTransmission result = %d", result);
delay(100); // délai pour laisser le capteur répondre
_wire->beginTransmission(_addr);
_wire->write(0x01); // À tester aussi sans cette ligne si besoin
uint8_t result = _wire->endTransmission();
LOG_DEBUG("[RCWL9620] endTransmission result = %d", result);
delay(100); // délai pour laisser le capteur répondre
LOG_DEBUG("[RCWL9620] Read i2c data:");
_wire->requestFrom(_addr, (uint8_t)3);
LOG_DEBUG("[RCWL9620] Read i2c data:");
_wire->requestFrom(_addr, (uint8_t)3);
if (_wire->available() < 3) {
LOG_DEBUG("[RCWL9620] less than 3 octets !");
return 0.0;
}
if (_wire->available() < 3) {
LOG_DEBUG("[RCWL9620] less than 3 octets !");
return 0.0;
}
b1 = _wire->read();
b2 = _wire->read();
b3 = _wire->read();
b1 = _wire->read();
b2 = _wire->read();
b3 = _wire->read();
data = ((uint32_t)b1 << 16) | ((uint32_t)b2 << 8) | b3;
data = ((uint32_t)b1 << 16) | ((uint32_t)b2 << 8) | b3;
float Distance = float(data) / 1000.0;
float Distance = float(data) / 1000.0;
LOG_DEBUG("[RCWL9620] Bytes readed = %02X %02X %02X", b1, b2, b3);
LOG_DEBUG("[RCWL9620] data=%.2f, level=%.2f", (double)data, (double)Distance);
LOG_DEBUG("[RCWL9620] Bytes readed = %02X %02X %02X", b1, b2, b3);
LOG_DEBUG("[RCWL9620] data=%.2f, level=%.2f", (double)data, (double)Distance);
if (Distance > 4500.00) {
return 4500.00;
} else {
return Distance;
}
if (Distance > 4500.00) {
return 4500.00;
} else {
return Distance;
}
}
#endif

View File

@@ -6,23 +6,22 @@
#include "TelemetrySensor.h"
#include <Wire.h>
class RCWL9620Sensor : public TelemetrySensor
{
private:
uint8_t _addr = 0x57;
TwoWire *_wire = &Wire;
uint8_t _scl = -1;
uint8_t _sda = -1;
uint32_t _speed = 200000UL;
class RCWL9620Sensor : public TelemetrySensor {
private:
uint8_t _addr = 0x57;
TwoWire *_wire = &Wire;
uint8_t _scl = -1;
uint8_t _sda = -1;
uint32_t _speed = 200000UL;
protected:
void begin(TwoWire *wire = &Wire, uint8_t addr = 0x57, uint8_t sda = -1, uint8_t scl = -1, uint32_t speed = 200000UL);
float getDistance();
protected:
void begin(TwoWire *wire = &Wire, uint8_t addr = 0x57, uint8_t sda = -1, uint8_t scl = -1, uint32_t speed = 200000UL);
float getDistance();
public:
RCWL9620Sensor();
virtual bool getMetrics(meshtastic_Telemetry *measurement) override;
virtual bool initDevice(TwoWire *bus, ScanI2C::FoundDevice *dev) override;
public:
RCWL9620Sensor();
virtual bool getMetrics(meshtastic_Telemetry *measurement) override;
virtual bool initDevice(TwoWire *bus, ScanI2C::FoundDevice *dev) override;
};
#endif

View File

@@ -9,23 +9,21 @@
SHT31Sensor::SHT31Sensor() : TelemetrySensor(meshtastic_TelemetrySensorType_SHT31, "SHT31") {}
bool SHT31Sensor::initDevice(TwoWire *bus, ScanI2C::FoundDevice *dev)
{
LOG_INFO("Init sensor: %s", sensorName);
sht31 = Adafruit_SHT31(bus);
status = sht31.begin(dev->address.address);
initI2CSensor();
return status;
bool SHT31Sensor::initDevice(TwoWire *bus, ScanI2C::FoundDevice *dev) {
LOG_INFO("Init sensor: %s", sensorName);
sht31 = Adafruit_SHT31(bus);
status = sht31.begin(dev->address.address);
initI2CSensor();
return status;
}
bool SHT31Sensor::getMetrics(meshtastic_Telemetry *measurement)
{
measurement->variant.environment_metrics.has_temperature = true;
measurement->variant.environment_metrics.has_relative_humidity = true;
measurement->variant.environment_metrics.temperature = sht31.readTemperature();
measurement->variant.environment_metrics.relative_humidity = sht31.readHumidity();
bool SHT31Sensor::getMetrics(meshtastic_Telemetry *measurement) {
measurement->variant.environment_metrics.has_temperature = true;
measurement->variant.environment_metrics.has_relative_humidity = true;
measurement->variant.environment_metrics.temperature = sht31.readTemperature();
measurement->variant.environment_metrics.relative_humidity = sht31.readHumidity();
return true;
return true;
}
#endif

View File

@@ -6,15 +6,14 @@
#include "TelemetrySensor.h"
#include <Adafruit_SHT31.h>
class SHT31Sensor : public TelemetrySensor
{
private:
Adafruit_SHT31 sht31;
class SHT31Sensor : public TelemetrySensor {
private:
Adafruit_SHT31 sht31;
public:
SHT31Sensor();
virtual bool getMetrics(meshtastic_Telemetry *measurement) override;
virtual bool initDevice(TwoWire *bus, ScanI2C::FoundDevice *dev) override;
public:
SHT31Sensor();
virtual bool getMetrics(meshtastic_Telemetry *measurement) override;
virtual bool initDevice(TwoWire *bus, ScanI2C::FoundDevice *dev) override;
};
#endif

View File

@@ -9,40 +9,38 @@
SHT4XSensor::SHT4XSensor() : TelemetrySensor(meshtastic_TelemetrySensorType_SHT4X, "SHT4X") {}
bool SHT4XSensor::initDevice(TwoWire *bus, ScanI2C::FoundDevice *dev)
{
LOG_INFO("Init sensor: %s", sensorName);
bool SHT4XSensor::initDevice(TwoWire *bus, ScanI2C::FoundDevice *dev) {
LOG_INFO("Init sensor: %s", sensorName);
uint32_t serialNumber = 0;
uint32_t serialNumber = 0;
status = sht4x.begin(bus);
if (!status) {
return status;
}
serialNumber = sht4x.readSerial();
if (serialNumber != 0) {
LOG_DEBUG("serialNumber : %x", serialNumber);
status = 1;
} else {
LOG_DEBUG("Error trying to execute readSerial(): ");
status = 0;
}
initI2CSensor();
status = sht4x.begin(bus);
if (!status) {
return status;
}
serialNumber = sht4x.readSerial();
if (serialNumber != 0) {
LOG_DEBUG("serialNumber : %x", serialNumber);
status = 1;
} else {
LOG_DEBUG("Error trying to execute readSerial(): ");
status = 0;
}
initI2CSensor();
return status;
}
bool SHT4XSensor::getMetrics(meshtastic_Telemetry *measurement)
{
measurement->variant.environment_metrics.has_temperature = true;
measurement->variant.environment_metrics.has_relative_humidity = true;
bool SHT4XSensor::getMetrics(meshtastic_Telemetry *measurement) {
measurement->variant.environment_metrics.has_temperature = true;
measurement->variant.environment_metrics.has_relative_humidity = true;
sensors_event_t humidity, temp;
sht4x.getEvent(&humidity, &temp);
measurement->variant.environment_metrics.temperature = temp.temperature;
measurement->variant.environment_metrics.relative_humidity = humidity.relative_humidity;
return true;
sensors_event_t humidity, temp;
sht4x.getEvent(&humidity, &temp);
measurement->variant.environment_metrics.temperature = temp.temperature;
measurement->variant.environment_metrics.relative_humidity = humidity.relative_humidity;
return true;
}
#endif

View File

@@ -6,15 +6,14 @@
#include "TelemetrySensor.h"
#include <Adafruit_SHT4x.h>
class SHT4XSensor : public TelemetrySensor
{
private:
Adafruit_SHT4x sht4x = Adafruit_SHT4x();
class SHT4XSensor : public TelemetrySensor {
private:
Adafruit_SHT4x sht4x = Adafruit_SHT4x();
public:
SHT4XSensor();
virtual bool getMetrics(meshtastic_Telemetry *measurement) override;
virtual bool initDevice(TwoWire *bus, ScanI2C::FoundDevice *dev) override;
public:
SHT4XSensor();
virtual bool getMetrics(meshtastic_Telemetry *measurement) override;
virtual bool initDevice(TwoWire *bus, ScanI2C::FoundDevice *dev) override;
};
#endif

View File

@@ -9,27 +9,25 @@
SHTC3Sensor::SHTC3Sensor() : TelemetrySensor(meshtastic_TelemetrySensorType_SHTC3, "SHTC3") {}
bool SHTC3Sensor::initDevice(TwoWire *bus, ScanI2C::FoundDevice *dev)
{
LOG_INFO("Init sensor: %s", sensorName);
status = shtc3.begin(bus);
bool SHTC3Sensor::initDevice(TwoWire *bus, ScanI2C::FoundDevice *dev) {
LOG_INFO("Init sensor: %s", sensorName);
status = shtc3.begin(bus);
initI2CSensor();
return status;
initI2CSensor();
return status;
}
bool SHTC3Sensor::getMetrics(meshtastic_Telemetry *measurement)
{
measurement->variant.environment_metrics.has_temperature = true;
measurement->variant.environment_metrics.has_relative_humidity = true;
bool SHTC3Sensor::getMetrics(meshtastic_Telemetry *measurement) {
measurement->variant.environment_metrics.has_temperature = true;
measurement->variant.environment_metrics.has_relative_humidity = true;
sensors_event_t humidity, temp;
shtc3.getEvent(&humidity, &temp);
sensors_event_t humidity, temp;
shtc3.getEvent(&humidity, &temp);
measurement->variant.environment_metrics.temperature = temp.temperature;
measurement->variant.environment_metrics.relative_humidity = humidity.relative_humidity;
measurement->variant.environment_metrics.temperature = temp.temperature;
measurement->variant.environment_metrics.relative_humidity = humidity.relative_humidity;
return true;
return true;
}
#endif

View File

@@ -6,15 +6,14 @@
#include "TelemetrySensor.h"
#include <Adafruit_SHTC3.h>
class SHTC3Sensor : public TelemetrySensor
{
private:
Adafruit_SHTC3 shtc3 = Adafruit_SHTC3();
class SHTC3Sensor : public TelemetrySensor {
private:
Adafruit_SHTC3 shtc3 = Adafruit_SHTC3();
public:
SHTC3Sensor();
virtual bool getMetrics(meshtastic_Telemetry *measurement) override;
virtual bool initDevice(TwoWire *bus, ScanI2C::FoundDevice *dev) override;
public:
SHTC3Sensor();
virtual bool getMetrics(meshtastic_Telemetry *measurement) override;
virtual bool initDevice(TwoWire *bus, ScanI2C::FoundDevice *dev) override;
};
#endif

View File

@@ -17,95 +17,89 @@
// ntc res table
uint32_t ntc_res2[136] = {
113347, 107565, 102116, 96978, 92132, 87559, 83242, 79166, 75316, 71677, 68237, 64991, 61919, 59011, 56258, 53650, 51178,
48835, 46613, 44506, 42506, 40600, 38791, 37073, 35442, 33892, 32420, 31020, 29689, 28423, 27219, 26076, 24988, 23951,
22963, 22021, 21123, 20267, 19450, 18670, 17926, 17214, 16534, 15886, 15266, 14674, 14108, 13566, 13049, 12554, 12081,
11628, 11195, 10780, 10382, 10000, 9634, 9284, 8947, 8624, 8315, 8018, 7734, 7461, 7199, 6948, 6707, 6475,
6253, 6039, 5834, 5636, 5445, 5262, 5086, 4917, 4754, 4597, 4446, 4301, 4161, 4026, 3896, 3771, 3651,
3535, 3423, 3315, 3211, 3111, 3014, 2922, 2834, 2748, 2666, 2586, 2509, 2435, 2364, 2294, 2228, 2163,
2100, 2040, 1981, 1925, 1870, 1817, 1766, 1716, 1669, 1622, 1578, 1535, 1493, 1452, 1413, 1375, 1338,
1303, 1268, 1234, 1202, 1170, 1139, 1110, 1081, 1053, 1026, 999, 974, 949, 925, 902, 880, 858,
113347, 107565, 102116, 96978, 92132, 87559, 83242, 79166, 75316, 71677, 68237, 64991, 61919, 59011, 56258, 53650, 51178, 48835, 46613, 44506,
42506, 40600, 38791, 37073, 35442, 33892, 32420, 31020, 29689, 28423, 27219, 26076, 24988, 23951, 22963, 22021, 21123, 20267, 19450, 18670,
17926, 17214, 16534, 15886, 15266, 14674, 14108, 13566, 13049, 12554, 12081, 11628, 11195, 10780, 10382, 10000, 9634, 9284, 8947, 8624,
8315, 8018, 7734, 7461, 7199, 6948, 6707, 6475, 6253, 6039, 5834, 5636, 5445, 5262, 5086, 4917, 4754, 4597, 4446, 4301,
4161, 4026, 3896, 3771, 3651, 3535, 3423, 3315, 3211, 3111, 3014, 2922, 2834, 2748, 2666, 2586, 2509, 2435, 2364, 2294,
2228, 2163, 2100, 2040, 1981, 1925, 1870, 1817, 1766, 1716, 1669, 1622, 1578, 1535, 1493, 1452, 1413, 1375, 1338, 1303,
1268, 1234, 1202, 1170, 1139, 1110, 1081, 1053, 1026, 999, 974, 949, 925, 902, 880, 858,
};
int8_t ntc_temp2[136] = {
-30, -29, -28, -27, -26, -25, -24, -23, -22, -21, -20, -19, -18, -17, -16, -15, -14, -13, -12, -11, -10, -9, -8,
-7, -6, -5, -4, -3, -2, -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38,
39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61,
62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84,
85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105,
-30, -29, -28, -27, -26, -25, -24, -23, -22, -21, -20, -19, -18, -17, -16, -15, -14, -13, -12, -11, -10, -9, -8, -7, -6, -5, -4, -3,
-2, -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25,
26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53,
54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81,
82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105,
};
T1000xSensor::T1000xSensor() : TelemetrySensor(meshtastic_TelemetrySensorType_SENSOR_UNSET, "T1000x") {}
bool T1000xSensor::initDevice(TwoWire *bus, ScanI2C::FoundDevice *dev)
{
LOG_INFO("Init sensor: %s", sensorName);
return true;
bool T1000xSensor::initDevice(TwoWire *bus, ScanI2C::FoundDevice *dev) {
LOG_INFO("Init sensor: %s", sensorName);
return true;
}
float T1000xSensor::getLux()
{
uint32_t lux_vot = 0;
float lux_level = 0;
float T1000xSensor::getLux() {
uint32_t lux_vot = 0;
float lux_level = 0;
for (uint32_t i = 0; i < T1000X_SENSE_SAMPLES; i++) {
lux_vot += analogRead(T1000X_LUX_PIN);
}
lux_vot = lux_vot / T1000X_SENSE_SAMPLES;
lux_vot = ((1000 * AREF_VOLTAGE) / pow(2, BATTERY_SENSE_RESOLUTION_BITS)) * lux_vot;
for (uint32_t i = 0; i < T1000X_SENSE_SAMPLES; i++) {
lux_vot += analogRead(T1000X_LUX_PIN);
}
lux_vot = lux_vot / T1000X_SENSE_SAMPLES;
lux_vot = ((1000 * AREF_VOLTAGE) / pow(2, BATTERY_SENSE_RESOLUTION_BITS)) * lux_vot;
if (lux_vot <= 80)
lux_level = 0;
else if (lux_vot >= 2480)
lux_level = 100;
else
lux_level = 100 * (lux_vot - 80) / T1000X_LIGHT_REF_VCC;
if (lux_vot <= 80)
lux_level = 0;
else if (lux_vot >= 2480)
lux_level = 100;
else
lux_level = 100 * (lux_vot - 80) / T1000X_LIGHT_REF_VCC;
return lux_level;
return lux_level;
}
float T1000xSensor::getTemp()
{
uint32_t vcc_vot = 0, ntc_vot = 0;
float T1000xSensor::getTemp() {
uint32_t vcc_vot = 0, ntc_vot = 0;
uint8_t u8i = 0;
float Vout = 0, Rt = 0, temp = 0;
float Temp = 0;
uint8_t u8i = 0;
float Vout = 0, Rt = 0, temp = 0;
float Temp = 0;
for (uint32_t i = 0; i < T1000X_SENSE_SAMPLES; i++) {
vcc_vot += analogRead(T1000X_VCC_PIN);
for (uint32_t i = 0; i < T1000X_SENSE_SAMPLES; i++) {
vcc_vot += analogRead(T1000X_VCC_PIN);
}
vcc_vot = vcc_vot / T1000X_SENSE_SAMPLES;
vcc_vot = 2 * ((1000 * AREF_VOLTAGE) / pow(2, BATTERY_SENSE_RESOLUTION_BITS)) * vcc_vot;
for (uint32_t i = 0; i < T1000X_SENSE_SAMPLES; i++) {
ntc_vot += analogRead(T1000X_NTC_PIN);
}
ntc_vot = ntc_vot / T1000X_SENSE_SAMPLES;
ntc_vot = ((1000 * AREF_VOLTAGE) / pow(2, BATTERY_SENSE_RESOLUTION_BITS)) * ntc_vot;
Vout = ntc_vot;
Rt = (HEATER_NTC_RP * vcc_vot) / Vout - HEATER_NTC_RP;
for (u8i = 0; u8i < 135; u8i++) {
if (Rt >= ntc_res2[u8i]) {
break;
}
vcc_vot = vcc_vot / T1000X_SENSE_SAMPLES;
vcc_vot = 2 * ((1000 * AREF_VOLTAGE) / pow(2, BATTERY_SENSE_RESOLUTION_BITS)) * vcc_vot;
}
temp = ntc_temp2[u8i - 1] + 1 * (ntc_res2[u8i - 1] - Rt) / (float)(ntc_res2[u8i - 1] - ntc_res2[u8i]);
Temp = (temp * 100 + 5) / 100; // half adjust
for (uint32_t i = 0; i < T1000X_SENSE_SAMPLES; i++) {
ntc_vot += analogRead(T1000X_NTC_PIN);
}
ntc_vot = ntc_vot / T1000X_SENSE_SAMPLES;
ntc_vot = ((1000 * AREF_VOLTAGE) / pow(2, BATTERY_SENSE_RESOLUTION_BITS)) * ntc_vot;
Vout = ntc_vot;
Rt = (HEATER_NTC_RP * vcc_vot) / Vout - HEATER_NTC_RP;
for (u8i = 0; u8i < 135; u8i++) {
if (Rt >= ntc_res2[u8i]) {
break;
}
}
temp = ntc_temp2[u8i - 1] + 1 * (ntc_res2[u8i - 1] - Rt) / (float)(ntc_res2[u8i - 1] - ntc_res2[u8i]);
Temp = (temp * 100 + 5) / 100; // half adjust
return Temp;
return Temp;
}
bool T1000xSensor::getMetrics(meshtastic_Telemetry *measurement)
{
measurement->variant.environment_metrics.has_temperature = true;
measurement->variant.environment_metrics.has_lux = true;
bool T1000xSensor::getMetrics(meshtastic_Telemetry *measurement) {
measurement->variant.environment_metrics.has_temperature = true;
measurement->variant.environment_metrics.has_lux = true;
measurement->variant.environment_metrics.temperature = getTemp();
measurement->variant.environment_metrics.lux = getLux();
return true;
measurement->variant.environment_metrics.temperature = getTemp();
measurement->variant.environment_metrics.lux = getLux();
return true;
}
#endif

View File

@@ -5,14 +5,13 @@
#include "../mesh/generated/meshtastic/telemetry.pb.h"
#include "TelemetrySensor.h"
class T1000xSensor : public TelemetrySensor
{
public:
T1000xSensor();
virtual bool getMetrics(meshtastic_Telemetry *measurement) override;
virtual bool initDevice(TwoWire *bus, ScanI2C::FoundDevice *dev) override;
virtual float getLux();
virtual float getTemp();
class T1000xSensor : public TelemetrySensor {
public:
T1000xSensor();
virtual bool getMetrics(meshtastic_Telemetry *measurement) override;
virtual bool initDevice(TwoWire *bus, ScanI2C::FoundDevice *dev) override;
virtual float getLux();
virtual float getTemp();
};
#endif

View File

@@ -9,30 +9,28 @@
TSL2561Sensor::TSL2561Sensor() : TelemetrySensor(meshtastic_TelemetrySensorType_TSL2561, "TSL2561") {}
bool TSL2561Sensor::initDevice(TwoWire *bus, ScanI2C::FoundDevice *dev)
{
LOG_INFO("Init sensor: %s", sensorName);
bool TSL2561Sensor::initDevice(TwoWire *bus, ScanI2C::FoundDevice *dev) {
LOG_INFO("Init sensor: %s", sensorName);
status = tsl.begin(bus);
if (!status) {
return status;
}
tsl.setGain(TSL2561_GAIN_1X);
tsl.setIntegrationTime(TSL2561_INTEGRATIONTIME_101MS);
initI2CSensor();
status = tsl.begin(bus);
if (!status) {
return status;
}
tsl.setGain(TSL2561_GAIN_1X);
tsl.setIntegrationTime(TSL2561_INTEGRATIONTIME_101MS);
initI2CSensor();
return status;
}
bool TSL2561Sensor::getMetrics(meshtastic_Telemetry *measurement)
{
measurement->variant.environment_metrics.has_lux = true;
sensors_event_t event;
tsl.getEvent(&event);
measurement->variant.environment_metrics.lux = event.light;
LOG_INFO("Lux: %f", measurement->variant.environment_metrics.lux);
bool TSL2561Sensor::getMetrics(meshtastic_Telemetry *measurement) {
measurement->variant.environment_metrics.has_lux = true;
sensors_event_t event;
tsl.getEvent(&event);
measurement->variant.environment_metrics.lux = event.light;
LOG_INFO("Lux: %f", measurement->variant.environment_metrics.lux);
return true;
return true;
}
#endif

View File

@@ -6,15 +6,14 @@
#include "TelemetrySensor.h"
#include <Adafruit_TSL2561_U.h>
class TSL2561Sensor : public TelemetrySensor
{
private:
// The magic number is a sensor id, the actual value doesn't matter
Adafruit_TSL2561_Unified tsl = Adafruit_TSL2561_Unified(TSL2561_ADDR_LOW, 12345);
class TSL2561Sensor : public TelemetrySensor {
private:
// The magic number is a sensor id, the actual value doesn't matter
Adafruit_TSL2561_Unified tsl = Adafruit_TSL2561_Unified(TSL2561_ADDR_LOW, 12345);
public:
TSL2561Sensor();
virtual bool getMetrics(meshtastic_Telemetry *measurement) override;
virtual bool initDevice(TwoWire *bus, ScanI2C::FoundDevice *dev) override;
public:
TSL2561Sensor();
virtual bool getMetrics(meshtastic_Telemetry *measurement) override;
virtual bool initDevice(TwoWire *bus, ScanI2C::FoundDevice *dev) override;
};
#endif

View File

@@ -10,32 +10,30 @@
TSL2591Sensor::TSL2591Sensor() : TelemetrySensor(meshtastic_TelemetrySensorType_TSL25911FN, "TSL2591") {}
bool TSL2591Sensor::initDevice(TwoWire *bus, ScanI2C::FoundDevice *dev)
{
LOG_INFO("Init sensor: %s", sensorName);
status = tsl.begin(bus);
if (!status) {
return status;
}
tsl.setGain(TSL2591_GAIN_LOW); // 1x gain
tsl.setTiming(TSL2591_INTEGRATIONTIME_100MS);
initI2CSensor();
bool TSL2591Sensor::initDevice(TwoWire *bus, ScanI2C::FoundDevice *dev) {
LOG_INFO("Init sensor: %s", sensorName);
status = tsl.begin(bus);
if (!status) {
return status;
}
tsl.setGain(TSL2591_GAIN_LOW); // 1x gain
tsl.setTiming(TSL2591_INTEGRATIONTIME_100MS);
initI2CSensor();
return status;
}
bool TSL2591Sensor::getMetrics(meshtastic_Telemetry *measurement)
{
measurement->variant.environment_metrics.has_lux = true;
uint32_t lum = tsl.getFullLuminosity();
uint16_t ir, full;
ir = lum >> 16;
full = lum & 0xFFFF;
bool TSL2591Sensor::getMetrics(meshtastic_Telemetry *measurement) {
measurement->variant.environment_metrics.has_lux = true;
uint32_t lum = tsl.getFullLuminosity();
uint16_t ir, full;
ir = lum >> 16;
full = lum & 0xFFFF;
measurement->variant.environment_metrics.lux = tsl.calculateLux(full, ir);
LOG_INFO("Lux: %f", measurement->variant.environment_metrics.lux);
measurement->variant.environment_metrics.lux = tsl.calculateLux(full, ir);
LOG_INFO("Lux: %f", measurement->variant.environment_metrics.lux);
return true;
return true;
}
#endif

View File

@@ -6,14 +6,13 @@
#include "TelemetrySensor.h"
#include <Adafruit_TSL2591.h>
class TSL2591Sensor : public TelemetrySensor
{
private:
Adafruit_TSL2591 tsl;
class TSL2591Sensor : public TelemetrySensor {
private:
Adafruit_TSL2591 tsl;
public:
TSL2591Sensor();
virtual bool getMetrics(meshtastic_Telemetry *measurement) override;
virtual bool initDevice(TwoWire *bus, ScanI2C::FoundDevice *dev) override;
public:
TSL2591Sensor();
virtual bool getMetrics(meshtastic_Telemetry *measurement) override;
virtual bool initDevice(TwoWire *bus, ScanI2C::FoundDevice *dev) override;
};
#endif

View File

@@ -16,59 +16,55 @@ class TwoWire;
#define DEFAULT_SENSOR_MINIMUM_WAIT_TIME_BETWEEN_READS 1000
extern std::pair<uint8_t, TwoWire *> nodeTelemetrySensorsMap[_meshtastic_TelemetrySensorType_MAX + 1];
class TelemetrySensor
{
protected:
TelemetrySensor(meshtastic_TelemetrySensorType sensorType, const char *sensorName)
{
this->sensorName = sensorName;
this->sensorType = sensorType;
this->status = 0;
class TelemetrySensor {
protected:
TelemetrySensor(meshtastic_TelemetrySensorType sensorType, const char *sensorName) {
this->sensorName = sensorName;
this->sensorType = sensorType;
this->status = 0;
}
const char *sensorName;
meshtastic_TelemetrySensorType sensorType = meshtastic_TelemetrySensorType_SENSOR_UNSET;
unsigned status;
bool initialized = false;
int32_t initI2CSensor() {
if (!status) {
LOG_WARN("Can't connect to detected %s sensor. Remove from nodeTelemetrySensorsMap", sensorName);
nodeTelemetrySensorsMap[sensorType].first = 0;
} else {
LOG_INFO("Opened %s sensor on i2c bus", sensorName);
setup();
}
initialized = true;
return DEFAULT_SENSOR_MINIMUM_WAIT_TIME_BETWEEN_READS;
}
const char *sensorName;
meshtastic_TelemetrySensorType sensorType = meshtastic_TelemetrySensorType_SENSOR_UNSET;
unsigned status;
bool initialized = false;
// TODO: check is setup used at all?
virtual void setup() {}
int32_t initI2CSensor()
{
if (!status) {
LOG_WARN("Can't connect to detected %s sensor. Remove from nodeTelemetrySensorsMap", sensorName);
nodeTelemetrySensorsMap[sensorType].first = 0;
} else {
LOG_INFO("Opened %s sensor on i2c bus", sensorName);
setup();
}
initialized = true;
return DEFAULT_SENSOR_MINIMUM_WAIT_TIME_BETWEEN_READS;
}
public:
virtual ~TelemetrySensor() {}
// TODO: check is setup used at all?
virtual void setup() {}
virtual AdminMessageHandleResult handleAdminMessage(const meshtastic_MeshPacket &mp, meshtastic_AdminMessage *request,
meshtastic_AdminMessage *response) {
return AdminMessageHandleResult::NOT_HANDLED;
}
public:
virtual ~TelemetrySensor() {}
virtual AdminMessageHandleResult handleAdminMessage(const meshtastic_MeshPacket &mp, meshtastic_AdminMessage *request,
meshtastic_AdminMessage *response)
{
return AdminMessageHandleResult::NOT_HANDLED;
}
// TODO: delete after migration
bool hasSensor() { return nodeTelemetrySensorsMap[sensorType].first > 0; }
// TODO: delete after migration
bool hasSensor() { return nodeTelemetrySensorsMap[sensorType].first > 0; }
#if WIRE_INTERFACES_COUNT > 1
// Set to true if Implementation only works first I2C port (Wire)
virtual bool onlyWire1() { return false; }
// Set to true if Implementation only works first I2C port (Wire)
virtual bool onlyWire1() { return false; }
#endif
virtual int32_t runOnce() { return INT32_MAX; }
virtual bool isInitialized() { return initialized; }
virtual bool isRunning() { return status > 0; }
virtual int32_t runOnce() { return INT32_MAX; }
virtual bool isInitialized() { return initialized; }
virtual bool isRunning() { return status > 0; }
virtual bool getMetrics(meshtastic_Telemetry *measurement) = 0;
virtual bool initDevice(TwoWire *bus, ScanI2C::FoundDevice *dev) { return false; };
virtual bool getMetrics(meshtastic_Telemetry *measurement) = 0;
virtual bool initDevice(TwoWire *bus, ScanI2C::FoundDevice *dev) { return false; };
};
#endif

View File

@@ -11,20 +11,19 @@
VEML7700Sensor::VEML7700Sensor() : TelemetrySensor(meshtastic_TelemetrySensorType_VEML7700, "VEML7700") {}
bool VEML7700Sensor::initDevice(TwoWire *bus, ScanI2C::FoundDevice *dev)
{
LOG_INFO("Init sensor: %s", sensorName);
status = veml7700.begin(bus);
if (!status) {
return status;
}
veml7700.setLowThreshold(10000);
veml7700.setHighThreshold(20000);
veml7700.interruptEnable(true);
initI2CSensor();
bool VEML7700Sensor::initDevice(TwoWire *bus, ScanI2C::FoundDevice *dev) {
LOG_INFO("Init sensor: %s", sensorName);
status = veml7700.begin(bus);
if (!status) {
return status;
}
veml7700.setLowThreshold(10000);
veml7700.setHighThreshold(20000);
veml7700.interruptEnable(true);
initI2CSensor();
return status;
}
/*!
@@ -33,35 +32,29 @@ bool VEML7700Sensor::initDevice(TwoWire *bus, ScanI2C::FoundDevice *dev)
* @param corrected if true, apply non-linear correction
* @return lux value
*/
float VEML7700Sensor::computeLux(uint16_t rawALS, bool corrected)
{
float lux = getResolution() * rawALS;
if (corrected)
lux = (((6.0135e-13 * lux - 9.3924e-9) * lux + 8.1488e-5) * lux + 1.0023) * lux;
return lux;
float VEML7700Sensor::computeLux(uint16_t rawALS, bool corrected) {
float lux = getResolution() * rawALS;
if (corrected)
lux = (((6.0135e-13 * lux - 9.3924e-9) * lux + 8.1488e-5) * lux + 1.0023) * lux;
return lux;
}
/*!
* @brief Determines resolution for current gain and integration time
* settings.
*/
float VEML7700Sensor::getResolution(void)
{
return MAX_RES * (IT_MAX / veml7700.getIntegrationTimeValue()) * (GAIN_MAX / veml7700.getGainValue());
}
float VEML7700Sensor::getResolution(void) { return MAX_RES * (IT_MAX / veml7700.getIntegrationTimeValue()) * (GAIN_MAX / veml7700.getGainValue()); }
bool VEML7700Sensor::getMetrics(meshtastic_Telemetry *measurement)
{
measurement->variant.environment_metrics.has_lux = true;
measurement->variant.environment_metrics.has_white_lux = true;
bool VEML7700Sensor::getMetrics(meshtastic_Telemetry *measurement) {
measurement->variant.environment_metrics.has_lux = true;
measurement->variant.environment_metrics.has_white_lux = true;
int16_t white;
measurement->variant.environment_metrics.lux = veml7700.readLux(VEML_LUX_AUTO);
white = veml7700.readWhite(true);
measurement->variant.environment_metrics.white_lux = computeLux(white, white > 100);
LOG_INFO("white lux %f, als lux %f", measurement->variant.environment_metrics.white_lux,
measurement->variant.environment_metrics.lux);
int16_t white;
measurement->variant.environment_metrics.lux = veml7700.readLux(VEML_LUX_AUTO);
white = veml7700.readWhite(true);
measurement->variant.environment_metrics.white_lux = computeLux(white, white > 100);
LOG_INFO("white lux %f, als lux %f", measurement->variant.environment_metrics.white_lux, measurement->variant.environment_metrics.lux);
return true;
return true;
}
#endif

View File

@@ -6,19 +6,18 @@
#include "TelemetrySensor.h"
#include <Adafruit_VEML7700.h>
class VEML7700Sensor : public TelemetrySensor
{
private:
const float MAX_RES = 0.0036;
const float GAIN_MAX = 2;
const float IT_MAX = 800;
Adafruit_VEML7700 veml7700;
float computeLux(uint16_t rawALS, bool corrected);
float getResolution(void);
class VEML7700Sensor : public TelemetrySensor {
private:
const float MAX_RES = 0.0036;
const float GAIN_MAX = 2;
const float IT_MAX = 800;
Adafruit_VEML7700 veml7700;
float computeLux(uint16_t rawALS, bool corrected);
float getResolution(void);
public:
VEML7700Sensor();
virtual bool getMetrics(meshtastic_Telemetry *measurement) override;
virtual bool initDevice(TwoWire *bus, ScanI2C::FoundDevice *dev) override;
public:
VEML7700Sensor();
virtual bool getMetrics(meshtastic_Telemetry *measurement) override;
virtual bool initDevice(TwoWire *bus, ScanI2C::FoundDevice *dev) override;
};
#endif

View File

@@ -4,10 +4,9 @@
#pragma once
class VoltageSensor
{
public:
virtual uint16_t getBusVoltageMv() = 0;
class VoltageSensor {
public:
virtual uint16_t getBusVoltageMv() = 0;
};
#endif

View File

@@ -9,26 +9,14 @@
NullSensor::NullSensor() : TelemetrySensor(meshtastic_TelemetrySensorType_SENSOR_UNSET, "nullSensor") {}
int32_t NullSensor::runOnce()
{
return INT32_MAX;
}
int32_t NullSensor::runOnce() { return INT32_MAX; }
void NullSensor::setup() {}
bool NullSensor::getMetrics(meshtastic_Telemetry *measurement)
{
return false;
}
bool NullSensor::getMetrics(meshtastic_Telemetry *measurement) { return false; }
uint16_t NullSensor::getBusVoltageMv()
{
return 0;
}
uint16_t NullSensor::getBusVoltageMv() { return 0; }
int16_t NullSensor::getCurrentMa()
{
return 0;
}
int16_t NullSensor::getCurrentMa() { return 0; }
#endif

View File

@@ -9,20 +9,19 @@
#include "TelemetrySensor.h"
#include "VoltageSensor.h"
class NullSensor : public TelemetrySensor, VoltageSensor, CurrentSensor
{
class NullSensor : public TelemetrySensor, VoltageSensor, CurrentSensor {
protected:
virtual void setup() override;
protected:
virtual void setup() override;
public:
NullSensor();
virtual int32_t runOnce() override;
virtual bool getMetrics(meshtastic_Telemetry *measurement) override;
int32_t runTrigger() { return 0; }
public:
NullSensor();
virtual int32_t runOnce() override;
virtual bool getMetrics(meshtastic_Telemetry *measurement) override;
int32_t runTrigger() { return 0; }
virtual uint16_t getBusVoltageMv() override;
virtual int16_t getCurrentMa() override;
virtual uint16_t getBusVoltageMv() override;
virtual int16_t getCurrentMa() override;
};
#endif