mirror of
https://github.com/meshtastic/firmware.git
synced 2025-04-25 17:42:48 +00:00
INA3221 sensor: use for bus voltage & environment metrics (#4215)
* use INA3221 for bus voltage; fixes for telemetry variants - add to sensors available for environment telemetry (to report voltage/current) - add vars to define channels to use for battery voltage (for getBusVoltage) and environment metrics (default to CH1 for both) - write to the correct fields on the measurement struct depending on the measurement variant, and DRY up the sensor measurement collection code a bit - this might be suitable for a common implementation for the INA* sensors in a future PR... * formatting * derp --------- Co-authored-by: Ben Meadors <benmmeadors@gmail.com>
This commit is contained in:
parent
e79a7dce07
commit
974fc31856
@ -449,6 +449,11 @@ class AnalogBatteryLevel : public HasBatteryLevel
|
||||
if (!ina260Sensor.isInitialized())
|
||||
return ina260Sensor.runOnce() > 0;
|
||||
return ina260Sensor.isRunning();
|
||||
} else if (nodeTelemetrySensorsMap[meshtastic_TelemetrySensorType_INA3221].first ==
|
||||
config.power.device_battery_ina_address) {
|
||||
if (!ina3221Sensor.isInitialized())
|
||||
return ina3221Sensor.runOnce() > 0;
|
||||
return ina3221Sensor.isRunning();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
@ -115,6 +115,8 @@ int32_t EnvironmentTelemetryModule::runOnce()
|
||||
result = ina219Sensor.runOnce();
|
||||
if (ina260Sensor.hasSensor())
|
||||
result = ina260Sensor.runOnce();
|
||||
if (ina3221Sensor.hasSensor())
|
||||
result = ina3221Sensor.runOnce();
|
||||
if (veml7700Sensor.hasSensor())
|
||||
result = veml7700Sensor.runOnce();
|
||||
if (tsl2591Sensor.hasSensor())
|
||||
@ -325,6 +327,10 @@ bool EnvironmentTelemetryModule::getEnvironmentTelemetry(meshtastic_Telemetry *m
|
||||
valid = valid && ina260Sensor.getMetrics(m);
|
||||
hasSensor = true;
|
||||
}
|
||||
if (ina3221Sensor.hasSensor()) {
|
||||
valid = valid && ina3221Sensor.getMetrics(m);
|
||||
hasSensor = true;
|
||||
}
|
||||
if (veml7700Sensor.hasSensor()) {
|
||||
valid = valid && veml7700Sensor.getMetrics(m);
|
||||
hasSensor = true;
|
||||
@ -499,6 +505,11 @@ AdminMessageHandleResult EnvironmentTelemetryModule::handleAdminMessageForModule
|
||||
if (result != AdminMessageHandleResult::NOT_HANDLED)
|
||||
return result;
|
||||
}
|
||||
if (ina3221Sensor.hasSensor()) {
|
||||
result = ina3221Sensor.handleAdminMessage(mp, request, response);
|
||||
if (result != AdminMessageHandleResult::NOT_HANDLED)
|
||||
return result;
|
||||
}
|
||||
if (veml7700Sensor.hasSensor()) {
|
||||
result = veml7700Sensor.handleAdminMessage(mp, request, response);
|
||||
if (result != AdminMessageHandleResult::NOT_HANDLED)
|
||||
|
@ -27,22 +27,69 @@ int32_t INA3221Sensor::runOnce()
|
||||
|
||||
void INA3221Sensor::setup() {}
|
||||
|
||||
struct _INA3221Measurement INA3221Sensor::getMeasurement(ina3221_ch_t ch)
|
||||
{
|
||||
struct _INA3221Measurement measurement;
|
||||
|
||||
measurement.voltage = ina3221.getVoltage(ch);
|
||||
measurement.current = ina3221.getCurrent(ch);
|
||||
|
||||
return measurement;
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
return measurements;
|
||||
}
|
||||
|
||||
bool INA3221Sensor::getMetrics(meshtastic_Telemetry *measurement)
|
||||
{
|
||||
measurement->variant.environment_metrics.voltage = ina3221.getVoltage(INA3221_CH1);
|
||||
measurement->variant.environment_metrics.current = ina3221.getCurrent(INA3221_CH1);
|
||||
measurement->variant.power_metrics.ch1_voltage = ina3221.getVoltage(INA3221_CH1);
|
||||
measurement->variant.power_metrics.ch1_current = ina3221.getCurrent(INA3221_CH1);
|
||||
measurement->variant.power_metrics.ch2_voltage = ina3221.getVoltage(INA3221_CH2);
|
||||
measurement->variant.power_metrics.ch2_current = ina3221.getCurrent(INA3221_CH2);
|
||||
measurement->variant.power_metrics.ch3_voltage = ina3221.getVoltage(INA3221_CH3);
|
||||
measurement->variant.power_metrics.ch3_current = ina3221.getCurrent(INA3221_CH3);
|
||||
switch (measurement->which_variant) {
|
||||
case meshtastic_Telemetry_environment_metrics_tag:
|
||||
return getEnvironmentMetrics(measurement);
|
||||
|
||||
case meshtastic_Telemetry_power_metrics_tag:
|
||||
return getPowerMetrics(measurement);
|
||||
}
|
||||
|
||||
// unsupported metric
|
||||
return false;
|
||||
}
|
||||
|
||||
bool INA3221Sensor::getEnvironmentMetrics(meshtastic_Telemetry *measurement)
|
||||
{
|
||||
struct _INA3221Measurement m = getMeasurement(ENV_CH);
|
||||
|
||||
measurement->variant.environment_metrics.voltage = m.voltage;
|
||||
measurement->variant.environment_metrics.current = m.current;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool INA3221Sensor::getPowerMetrics(meshtastic_Telemetry *measurement)
|
||||
{
|
||||
struct _INA3221Measurements m = getMeasurements();
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
uint16_t INA3221Sensor::getBusVoltageMv()
|
||||
{
|
||||
return lround(ina3221.getVoltage(INA3221_CH1) * 1000);
|
||||
return lround(ina3221.getVoltage(BAT_CH) * 1000);
|
||||
}
|
||||
|
||||
#endif
|
@ -12,6 +12,21 @@ class INA3221Sensor : public TelemetrySensor, VoltageSensor
|
||||
private:
|
||||
INA3221 ina3221 = INA3221(INA3221_ADDR42_SDA);
|
||||
|
||||
// channel to report voltage/current for environment metrics
|
||||
ina3221_ch_t ENV_CH = INA3221_CH1;
|
||||
|
||||
// channel to report battery voltage for device_battery_ina_address
|
||||
ina3221_ch_t BAT_CH = INA3221_CH1;
|
||||
|
||||
// get a single measurement for a channel
|
||||
struct _INA3221Measurement getMeasurement(ina3221_ch_t ch);
|
||||
|
||||
// get all measurements for all channels
|
||||
struct _INA3221Measurements getMeasurements();
|
||||
|
||||
bool getEnvironmentMetrics(meshtastic_Telemetry *measurement);
|
||||
bool getPowerMetrics(meshtastic_Telemetry *measurement);
|
||||
|
||||
protected:
|
||||
void setup() override;
|
||||
|
||||
@ -22,4 +37,14 @@ class INA3221Sensor : public TelemetrySensor, VoltageSensor
|
||||
virtual uint16_t getBusVoltageMv() override;
|
||||
};
|
||||
|
||||
struct _INA3221Measurement {
|
||||
float voltage;
|
||||
float current;
|
||||
};
|
||||
|
||||
struct _INA3221Measurements {
|
||||
// INA3221 has 3 channels
|
||||
struct _INA3221Measurement measurements[3];
|
||||
};
|
||||
|
||||
#endif
|
Loading…
Reference in New Issue
Block a user