Add ADS1X15 ADC (#9846)
* Add ADS1X15 class * Initialize bus and address in ADS1X15Sensor * Initialize member variables and pass bus to ads1x15 begin object * More register values options for ADS1X15 * Mark constructor as explicit * Move ADS1X15 from PowerTelemetry to EnvironmentTelemetry: * Adds ADS to Environment Telemetry * Adds possibility to use template function with multiple devices of the same type on the same bus with different addresses * Moves moduleConfig dev overrides to i2cScan function * Make logs in env telemetry only show what has been collected * Fix channel naming and logging * Remove scannerToSensorsMap for ADS1X15 * Fix ADS1X15 reclock * Fix merge * Trunk format issue * Set port * Remove status overrride * Return status on boot * Set data rate as per coderabbit request. * Add define for ADS type and use it to set SPS * Add object based on define --------- Co-authored-by: Thomas Göttgens <tgoettgens@gmail.com>
This commit is contained in:
co-authored by
Thomas Göttgens
parent
b4c2eb0b78
commit
a65d9aef39
8 files changed
+308
-21
No files matched your search
@@ -257,6 +257,8 @@ lib_deps =
|
||||
https://github.com/Sensirion/arduino-i2c-scd30/archive/1.1.1.zip
|
||||
# renovate: datasource=github-tags depName=arduino-sht packageName=sensirion/arduino-sht
|
||||
https://github.com/Sensirion/arduino-sht/archive/refs/tags/v1.2.6.zip
|
||||
# renovate: datasource=custom.pio depName=Adafruit ADS1X15 packageName=adafruit/library/Adafruit ADS1X15 Library
|
||||
https://github.com/adafruit/Adafruit_ADS1X15/archive/refs/tags/2.6.2.zip
|
||||
# renovate: datasource=github-tags depName=Adafruit DS248x packageName=adafruit/Adafruit_DS248x
|
||||
https://github.com/adafruit/Adafruit_DS248x/archive/refs/tags/1.2.0.zip
|
||||
|
||||
|
||||
+4
-1
@@ -301,6 +301,10 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
#define LTR553ALS_ADDR 0x23
|
||||
#define SEN5X_ADDR 0x69
|
||||
#define SCD30_ADDR 0x61
|
||||
#define ADS1X15_ADDR 0x48
|
||||
#define ADS1X15_ADDR_ALT1 0x49
|
||||
#define ADS1X15_ADDR_ALT2 0x4A
|
||||
#define ADS1X15_ADDR_ALT3 0x4B
|
||||
#define DS248X_ADDR 0x18 // same as MCP9808_ADDR, STK8BXX_ADDR and LIS3DH_ADDR
|
||||
#define DS248X_ADDR_ALT1 0x19 // same as LIS3DH_ADDR_ALT and BMA423_ADDR
|
||||
#define DS248X_ADDR_ALT2 0x1A // same as CST328_ADDR
|
||||
@@ -311,7 +315,6 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
#define DS248X_ADDR_ALT7 0x1F // same as BBQ10_KB_ADDR
|
||||
#define HM330X_ADDR 0x40
|
||||
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// ACCELEROMETER
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
@@ -99,13 +99,14 @@ class ScanI2C
|
||||
SFA30,
|
||||
CW2015,
|
||||
SCD30,
|
||||
ADS1115,
|
||||
ADS1X15,
|
||||
ADS1X15_ALT,
|
||||
IIS2MDCTR,
|
||||
ISM330DHCX,
|
||||
SPA06,
|
||||
DS248X,
|
||||
HM330X
|
||||
} DeviceType;
|
||||
} DeviceType;
|
||||
|
||||
// typedef uint8_t DeviceAddress;
|
||||
typedef enum I2CPort {
|
||||
|
||||
@@ -1040,10 +1040,11 @@ void ScanI2CTwoWire::scanPort(I2CPort port, uint8_t *address, uint8_t asize)
|
||||
break;
|
||||
}
|
||||
|
||||
// ADS1X15 default config register is 8583h
|
||||
registerValue = getRegisterValue(ScanI2CTwoWire::RegisterLocation(addr, 0x01), 2);
|
||||
if (registerValue == 0x8583 || registerValue == 0x8580) {
|
||||
type = ADS1115;
|
||||
logFoundDevice("ADS1115 ADC", (uint8_t)addr.address);
|
||||
if (registerValue == 0x8583 || registerValue == 0x8580 || registerValue == 0xf700) {
|
||||
type = ADS1X15;
|
||||
logFoundDevice("ADS1X15 ADC", (uint8_t)addr.address);
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -1052,6 +1053,19 @@ void ScanI2CTwoWire::scanPort(I2CPort port, uint8_t *address, uint8_t asize)
|
||||
break;
|
||||
}
|
||||
|
||||
case ADS1X15_ADDR_ALT1:
|
||||
case ADS1X15_ADDR_ALT2:
|
||||
case ADS1X15_ADDR_ALT3: {
|
||||
// ADS1X15 default config register is 8583h
|
||||
registerValue = getRegisterValue(ScanI2CTwoWire::RegisterLocation(addr, 0x01), 2);
|
||||
if (registerValue == 0x8583 || registerValue == 0x8580 || registerValue == 0xf700) {
|
||||
type = ADS1X15_ALT;
|
||||
logFoundDevice("ADS1X15_ALT", (uint8_t)addr.address);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
LOG_INFO("Device found at address 0x%x was not able to be enumerated", (uint8_t)addr.address);
|
||||
}
|
||||
|
||||
@@ -131,6 +131,10 @@ extern void drawCommonHeader(OLEDDisplay *display, int16_t x, int16_t y, const c
|
||||
#include "Sensor/BH1750Sensor.h"
|
||||
#endif
|
||||
|
||||
#if __has_include(<Adafruit_ADS1X15.h>)
|
||||
#include "Sensor/ADS1X15Sensor.h"
|
||||
#endif
|
||||
|
||||
#if __has_include(<Adafruit_DS248x.h>)
|
||||
#include "Sensor/DS248XSensor.h"
|
||||
#endif
|
||||
@@ -347,6 +351,10 @@ void EnvironmentTelemetryModule::i2cScanFinished(ScanI2C *i2cScanner)
|
||||
#if __has_include(<BH1750_WE.h>)
|
||||
addSensor<BH1750Sensor>(i2cScanner, ScanI2C::DeviceType::BH1750);
|
||||
#endif
|
||||
#if __has_include(<Adafruit_ADS1X15.h>)
|
||||
addSensor<ADS1X15Sensor>(i2cScanner, ScanI2C::DeviceType::ADS1X15);
|
||||
addSensor<ADS1X15Sensor>(i2cScanner, ScanI2C::DeviceType::ADS1X15_ALT);
|
||||
#endif
|
||||
#if __has_include(<SHTSensor.h>)
|
||||
// TODO Can we scan for multiple sensors connected on the same bus?
|
||||
addSensor<SHTXXSensor>(i2cScanner, ScanI2C::DeviceType::SHTXX);
|
||||
@@ -759,21 +767,48 @@ bool EnvironmentTelemetryModule::sendTelemetry(NodeNum dest, bool phoneOnly)
|
||||
m.time = getTime();
|
||||
|
||||
bool validTelemetry = getEnvironmentTelemetry(&m);
|
||||
|
||||
if (validTelemetry) {
|
||||
LOG_INFO("Send: barometric_pressure=%f, current=%f, gas_resistance=%f, relative_humidity=%f, temperature=%f",
|
||||
m.variant.environment_metrics.barometric_pressure, m.variant.environment_metrics.current,
|
||||
m.variant.environment_metrics.gas_resistance, m.variant.environment_metrics.relative_humidity,
|
||||
m.variant.environment_metrics.temperature);
|
||||
LOG_INFO("Send: voltage=%f, IAQ=%d, distance=%f, lux=%f", m.variant.environment_metrics.voltage,
|
||||
m.variant.environment_metrics.iaq, m.variant.environment_metrics.distance, m.variant.environment_metrics.lux);
|
||||
if (m.variant.environment_metrics.has_temperature || m.variant.environment_metrics.has_relative_humidity ||
|
||||
m.variant.environment_metrics.has_barometric_pressure)
|
||||
LOG_INFO("Send: barometric_pressure=%fkPa, relative_humidity=%f%RH, temperature=%fdegC",
|
||||
m.variant.environment_metrics.barometric_pressure, m.variant.environment_metrics.relative_humidity,
|
||||
m.variant.environment_metrics.temperature);
|
||||
|
||||
LOG_INFO("Send: wind speed=%fm/s, direction=%d degrees, weight=%fkg", m.variant.environment_metrics.wind_speed,
|
||||
m.variant.environment_metrics.wind_direction, m.variant.environment_metrics.weight);
|
||||
if (m.variant.environment_metrics.has_voltage || m.variant.environment_metrics.has_current ||
|
||||
m.variant.environment_metrics.has_iaq || m.variant.environment_metrics.has_gas_resistance)
|
||||
LOG_INFO("Send: voltage=%f, current=%f, IAQ=%d, gas_resistance=%f", m.variant.environment_metrics.voltage,
|
||||
m.variant.environment_metrics.current, m.variant.environment_metrics.iaq,
|
||||
m.variant.environment_metrics.gas_resistance);
|
||||
|
||||
LOG_INFO("Send: radiation=%fµR/h", m.variant.environment_metrics.radiation);
|
||||
if (m.variant.environment_metrics.has_distance || m.variant.environment_metrics.has_lux)
|
||||
LOG_INFO("Send: distance=%f, lux=%f", m.variant.environment_metrics.distance, m.variant.environment_metrics.lux);
|
||||
|
||||
LOG_INFO("Send: soil_temperature=%f, soil_moisture=%u", m.variant.environment_metrics.soil_temperature,
|
||||
m.variant.environment_metrics.soil_moisture);
|
||||
if (m.variant.environment_metrics.has_wind_speed || m.variant.environment_metrics.has_wind_direction)
|
||||
LOG_INFO("Send: wind speed=%fm/s, direction=%d degrees", m.variant.environment_metrics.wind_speed,
|
||||
m.variant.environment_metrics.wind_direction);
|
||||
|
||||
if (m.variant.environment_metrics.has_weight)
|
||||
LOG_INFO("Send: weight=%fkg", m.variant.environment_metrics.weight);
|
||||
|
||||
if (m.variant.environment_metrics.has_radiation)
|
||||
LOG_INFO("Send: radiation=%fµR/h", m.variant.environment_metrics.radiation);
|
||||
|
||||
if (m.variant.environment_metrics.has_soil_temperature || m.variant.environment_metrics.has_soil_moisture)
|
||||
LOG_INFO("Send: soil_temperature=%f, soil_moisture=%u", m.variant.environment_metrics.soil_temperature,
|
||||
m.variant.environment_metrics.soil_moisture);
|
||||
|
||||
if (m.variant.environment_metrics.has_adc_voltage_ch0 || m.variant.environment_metrics.has_adc_voltage_ch1 ||
|
||||
m.variant.environment_metrics.has_adc_voltage_ch2 || m.variant.environment_metrics.has_adc_voltage_ch3)
|
||||
LOG_INFO("Send: adc_ch0=%f, adc_ch1=%f, adc_ch2=%f, adc_ch3=%f", m.variant.environment_metrics.adc_voltage_ch0,
|
||||
m.variant.environment_metrics.adc_voltage_ch1, m.variant.environment_metrics.adc_voltage_ch2,
|
||||
m.variant.environment_metrics.adc_voltage_ch3);
|
||||
|
||||
if (m.variant.environment_metrics.has_adc_voltage_ch4 || m.variant.environment_metrics.has_adc_voltage_ch5 ||
|
||||
m.variant.environment_metrics.has_adc_voltage_ch6 || m.variant.environment_metrics.has_adc_voltage_ch7)
|
||||
LOG_INFO("Send: adc_ch4=%f, adc_ch5=%f, adc_ch6=%f, adc_ch7=%f", m.variant.environment_metrics.adc_voltage_ch4,
|
||||
m.variant.environment_metrics.adc_voltage_ch5, m.variant.environment_metrics.adc_voltage_ch6,
|
||||
m.variant.environment_metrics.adc_voltage_ch7);
|
||||
|
||||
meshtastic_MeshPacket *p = allocDataProtobuf(m);
|
||||
if (!p) {
|
||||
|
||||
@@ -272,10 +272,15 @@ bool PowerTelemetryModule::sendTelemetry(NodeNum dest, bool phoneOnly)
|
||||
m.time = getTime();
|
||||
bool validTelemetry = getPowerTelemetry(&m);
|
||||
if (validTelemetry) {
|
||||
LOG_INFO("Send: ch1_voltage=%f, ch1_current=%f, ch2_voltage=%f, ch2_current=%f, "
|
||||
"ch3_voltage=%f, ch3_current=%f",
|
||||
m.variant.power_metrics.ch1_voltage, m.variant.power_metrics.ch1_current, m.variant.power_metrics.ch2_voltage,
|
||||
m.variant.power_metrics.ch2_current, m.variant.power_metrics.ch3_voltage, m.variant.power_metrics.ch3_current);
|
||||
LOG_INFO("Send: ch1_voltage=%f, ch2_voltage=%f, ch3_voltage=%f", m.variant.power_metrics.ch1_voltage,
|
||||
m.variant.power_metrics.ch2_voltage, m.variant.power_metrics.ch3_voltage);
|
||||
|
||||
bool hasAnyCurrent = m.variant.power_metrics.has_ch1_current || m.variant.power_metrics.has_ch2_current ||
|
||||
m.variant.power_metrics.has_ch3_current;
|
||||
if (hasAnyCurrent) {
|
||||
LOG_INFO("Send: ch1_current=%f, ch2_current=%f, ch3_current=%f", m.variant.power_metrics.ch1_current,
|
||||
m.variant.power_metrics.ch2_current, m.variant.power_metrics.ch3_current);
|
||||
}
|
||||
|
||||
sensor_read_error_count = 0;
|
||||
|
||||
|
||||
@@ -0,0 +1,175 @@
|
||||
#include "configuration.h"
|
||||
|
||||
#if HAS_TELEMETRY && !MESHTASTIC_EXCLUDE_ENVIRONMENTAL_SENSOR && __has_include(<Adafruit_ADS1X15.h>)
|
||||
|
||||
#include "../mesh/generated/meshtastic/telemetry.pb.h"
|
||||
#include "ADS1X15Sensor.h"
|
||||
#include "TelemetrySensor.h"
|
||||
#include <Adafruit_ADS1X15.h>
|
||||
|
||||
ADS1X15Sensor::ADS1X15Sensor() : TelemetrySensor(meshtastic_TelemetrySensorType_ADS1X15, "ADS1X15") {}
|
||||
|
||||
bool ADS1X15Sensor::initDevice(TwoWire *bus, ScanI2C::FoundDevice *dev)
|
||||
{
|
||||
LOG_INFO("Init sensor: %s (address: 0x%x)", sensorName, dev->address.address);
|
||||
|
||||
_bus = bus;
|
||||
_port = dev->address.port;
|
||||
_address = dev->address.address;
|
||||
_deviceType = dev->type;
|
||||
|
||||
#ifdef ADS1X15_I2C_CLOCK_SPEED
|
||||
reClockI2C.setup(_bus, _port);
|
||||
reClockI2C.setClock(ADS1X15_I2C_CLOCK_SPEED);
|
||||
#endif /* ADS1X15_I2C_CLOCK_SPEED */
|
||||
|
||||
status = ads1x15.begin(_address, _bus);
|
||||
|
||||
#ifdef ADS1X15_I2C_CLOCK_SPEED
|
||||
reClockI2C.restoreClock();
|
||||
#endif /* ADS1X15_I2C_CLOCK_SPEED */
|
||||
|
||||
initI2CSensor();
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
struct _ADS1X15Measurement ADS1X15Sensor::getMeasurement(uint8_t ch)
|
||||
{
|
||||
struct _ADS1X15Measurement measurement;
|
||||
|
||||
// Reset gain
|
||||
ads1x15.setGain(GAIN_TWOTHIRDS);
|
||||
double voltage_range = 6.144;
|
||||
|
||||
// Get value with full range
|
||||
uint16_t value = ads1x15.readADC_SingleEnded(ch);
|
||||
|
||||
// Dynamic gain, to increase resolution of low voltage values
|
||||
// If value is under 4.096v increase the gain depending on voltage
|
||||
if (value < 21845) {
|
||||
if (value > 10922) {
|
||||
|
||||
// 1x gain, 4.096V
|
||||
ads1x15.setGain(GAIN_ONE);
|
||||
voltage_range = 4.096;
|
||||
|
||||
} else if (value > 5461) {
|
||||
|
||||
// 2x gain, 2.048V
|
||||
ads1x15.setGain(GAIN_TWO);
|
||||
voltage_range = 2.048;
|
||||
|
||||
} else if (value > 2730) {
|
||||
|
||||
// 4x gain, 1.024V
|
||||
ads1x15.setGain(GAIN_FOUR);
|
||||
voltage_range = 1.024;
|
||||
|
||||
} else if (value > 1365) {
|
||||
|
||||
// 8x gain, 0.25V
|
||||
ads1x15.setGain(GAIN_EIGHT);
|
||||
voltage_range = 0.512;
|
||||
|
||||
} else {
|
||||
|
||||
// 16x gain, 0.125V
|
||||
ads1x15.setGain(GAIN_SIXTEEN);
|
||||
voltage_range = 0.256;
|
||||
}
|
||||
|
||||
// Get the value again
|
||||
value = ads1x15.readADC_SingleEnded(ch);
|
||||
}
|
||||
|
||||
measurement.voltage = (float)value / 32768 * voltage_range;
|
||||
|
||||
return measurement;
|
||||
}
|
||||
|
||||
struct _ADS1X15Measurements ADS1X15Sensor::getMeasurements()
|
||||
{
|
||||
struct _ADS1X15Measurements measurements;
|
||||
|
||||
// ADS1X15 has 4 channels starting from 0
|
||||
for (int i = 0; i < 4; i++) {
|
||||
measurements.measurements[i] = getMeasurement(i);
|
||||
}
|
||||
|
||||
return measurements;
|
||||
}
|
||||
|
||||
bool ADS1X15Sensor::getMetrics(meshtastic_Telemetry *measurement)
|
||||
{
|
||||
// Done here and not in getMeasurements to avoid the back-and-forth 4-8 times one after the other
|
||||
#ifdef ADS1X15_I2C_CLOCK_SPEED
|
||||
reClockI2C.setClock(ADS1X15_I2C_CLOCK_SPEED);
|
||||
#endif /* ADS1X15_I2C_CLOCK_SPEED */
|
||||
|
||||
struct _ADS1X15Measurements m = getMeasurements();
|
||||
|
||||
#ifdef ADS1X15_I2C_CLOCK_SPEED
|
||||
reClockI2C.restoreClock();
|
||||
#endif /* ADS1X15_I2C_CLOCK_SPEED */
|
||||
|
||||
switch (_deviceType) {
|
||||
case ScanI2C::DeviceType::ADS1X15: {
|
||||
measurement->variant.environment_metrics.has_adc_voltage_ch0 = true;
|
||||
measurement->variant.environment_metrics.has_adc_voltage_ch1 = true;
|
||||
measurement->variant.environment_metrics.has_adc_voltage_ch2 = true;
|
||||
measurement->variant.environment_metrics.has_adc_voltage_ch3 = true;
|
||||
|
||||
measurement->variant.environment_metrics.adc_voltage_ch0 = m.measurements[0].voltage;
|
||||
measurement->variant.environment_metrics.adc_voltage_ch1 = m.measurements[1].voltage;
|
||||
measurement->variant.environment_metrics.adc_voltage_ch2 = m.measurements[2].voltage;
|
||||
measurement->variant.environment_metrics.adc_voltage_ch3 = m.measurements[3].voltage;
|
||||
|
||||
LOG_DEBUG(
|
||||
"Got %s readings: adc_voltage_ch0=%f, adc_voltage_ch1=%f, adc_voltage_ch2=%f, adc_voltage_ch3=%f", sensorName,
|
||||
measurement->variant.environment_metrics.adc_voltage_ch0, measurement->variant.environment_metrics.adc_voltage_ch1,
|
||||
measurement->variant.environment_metrics.adc_voltage_ch2, measurement->variant.environment_metrics.adc_voltage_ch3);
|
||||
|
||||
break;
|
||||
}
|
||||
case ScanI2C::DeviceType::ADS1X15_ALT: {
|
||||
measurement->variant.environment_metrics.has_adc_voltage_ch4 = true;
|
||||
measurement->variant.environment_metrics.has_adc_voltage_ch5 = true;
|
||||
measurement->variant.environment_metrics.has_adc_voltage_ch6 = true;
|
||||
measurement->variant.environment_metrics.has_adc_voltage_ch7 = true;
|
||||
|
||||
measurement->variant.environment_metrics.adc_voltage_ch4 = m.measurements[0].voltage;
|
||||
measurement->variant.environment_metrics.adc_voltage_ch5 = m.measurements[1].voltage;
|
||||
measurement->variant.environment_metrics.adc_voltage_ch6 = m.measurements[2].voltage;
|
||||
measurement->variant.environment_metrics.adc_voltage_ch7 = m.measurements[3].voltage;
|
||||
|
||||
LOG_DEBUG(
|
||||
"Got %s readings: adc_voltage_ch4=%f, adc_voltage_ch5=%f, adc_voltage_ch6=%f, adc_voltage_ch7=%f", sensorName,
|
||||
measurement->variant.environment_metrics.adc_voltage_ch4, measurement->variant.environment_metrics.adc_voltage_ch5,
|
||||
measurement->variant.environment_metrics.adc_voltage_ch6, measurement->variant.environment_metrics.adc_voltage_ch7);
|
||||
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
measurement->variant.environment_metrics.has_adc_voltage_ch0 = true;
|
||||
measurement->variant.environment_metrics.has_adc_voltage_ch1 = true;
|
||||
measurement->variant.environment_metrics.has_adc_voltage_ch2 = true;
|
||||
measurement->variant.environment_metrics.has_adc_voltage_ch3 = true;
|
||||
|
||||
measurement->variant.environment_metrics.adc_voltage_ch0 = m.measurements[0].voltage;
|
||||
measurement->variant.environment_metrics.adc_voltage_ch1 = m.measurements[1].voltage;
|
||||
measurement->variant.environment_metrics.adc_voltage_ch2 = m.measurements[2].voltage;
|
||||
measurement->variant.environment_metrics.adc_voltage_ch3 = m.measurements[3].voltage;
|
||||
|
||||
LOG_DEBUG(
|
||||
"Got %s readings: adc_voltage_ch0=%f, adc_voltage_ch1=%f, adc_voltage_ch2=%f, adc_voltage_ch3=%f", sensorName,
|
||||
measurement->variant.environment_metrics.adc_voltage_ch0, measurement->variant.environment_metrics.adc_voltage_ch1,
|
||||
measurement->variant.environment_metrics.adc_voltage_ch2, measurement->variant.environment_metrics.adc_voltage_ch3);
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,52 @@
|
||||
#include "configuration.h"
|
||||
|
||||
#if HAS_TELEMETRY && !MESHTASTIC_EXCLUDE_ENVIRONMENTAL_SENSOR && __has_include(<Adafruit_ADS1X15.h>)
|
||||
|
||||
#include "../detect/ReClockI2C.h"
|
||||
#include "../mesh/generated/meshtastic/telemetry.pb.h"
|
||||
#include "TelemetrySensor.h"
|
||||
#include <Adafruit_ADS1X15.h>
|
||||
|
||||
#define ADS1X15_I2C_CLOCK_SPEED 100000
|
||||
// ADS1X15 has no practical way to be detected. Use this to toggle
|
||||
// between ADS1015 (0) or ADS1115 (1)
|
||||
#ifndef MESHTASTIC_ADC_ADS1115
|
||||
#define MESHTASTIC_ADC_ADS1115 1
|
||||
#endif
|
||||
|
||||
class ADS1X15Sensor : public TelemetrySensor
|
||||
{
|
||||
private:
|
||||
#if MESHTASTIC_ADC_ADS1115
|
||||
Adafruit_ADS1115 ads1x15{};
|
||||
#else
|
||||
Adafruit_ADS1015 ads1x15{};
|
||||
#endif
|
||||
|
||||
#ifdef ADS1X15_I2C_CLOCK_SPEED
|
||||
ReClockI2C reClockI2C;
|
||||
#endif
|
||||
ScanI2C::DeviceType _deviceType{};
|
||||
|
||||
// get a single measurement for a channel
|
||||
struct _ADS1X15Measurement getMeasurement(uint8_t ch);
|
||||
|
||||
// get all measurements for all channels
|
||||
struct _ADS1X15Measurements getMeasurements();
|
||||
|
||||
public:
|
||||
ADS1X15Sensor();
|
||||
virtual bool initDevice(TwoWire *bus, ScanI2C::FoundDevice *dev) override;
|
||||
virtual bool getMetrics(meshtastic_Telemetry *measurement) override;
|
||||
};
|
||||
|
||||
struct _ADS1X15Measurement {
|
||||
float voltage;
|
||||
};
|
||||
|
||||
struct _ADS1X15Measurements {
|
||||
// ADS1X15 has 4 channels
|
||||
struct _ADS1X15Measurement measurements[4];
|
||||
};
|
||||
|
||||
#endif
|
||||
Reference in New Issue
Block a user