-
Notifications
You must be signed in to change notification settings - Fork 85
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add INA219 sensor and example (#104)
- Loading branch information
Showing
3 changed files
with
198 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,66 @@ | ||
// INA219_example.cpp | ||
|
||
#include <Arduino.h> | ||
|
||
//#define SERIAL_DEBUG_DISABLED | ||
|
||
#define USE_LIB_WEBSOCKET true | ||
|
||
#include "sensesp_app.h" | ||
#include "signalk/signalk_output.h" | ||
#include "sensors/ina219.h" | ||
|
||
ReactESP app([] () { | ||
#ifndef SERIAL_DEBUG_DISABLED | ||
Serial.begin(115200); | ||
|
||
// A small arbitrary delay is required to let the | ||
// serial port catch up | ||
|
||
delay(100); | ||
Debug.setSerialEnabled(true); | ||
#endif | ||
|
||
// true will disable systemHz, freemem, uptime, and ipaddress "sensors" | ||
bool disableStandardSensors = true; | ||
|
||
sensesp_app = new SensESPApp(disableStandardSensors); | ||
|
||
// Create an INA219, which represents the physical sensor. | ||
// 0x40 is the default address. Chips can be modified to use 0x41 (shown here), 0x44, or 0x45. | ||
// The default volt and amp ranges are 32V and 2A (cal32_2). Here, 32v and 1A is specified with cal32_1. | ||
auto* pINA219 = new INA219(0x41, cal32_1); | ||
|
||
|
||
// Define the read_delay you're going to use, if other than the default of 500 ms. | ||
const uint read_delay = 1000; // once per second | ||
|
||
// Create an INA219value, which is used to read a specific value from the INA219, and send its output | ||
// to SignalK as a number (float). This one is for the bus voltage. | ||
auto* pINA219busVoltage = new INA219value(pINA219, bus_voltage, read_delay, "someElectricDevice/busVoltage"); | ||
|
||
pINA219busVoltage->connectTo(new SKOutputNumber("electrical.someelectricdevice.busVoltage")); | ||
|
||
// Do the same for the shunt voltage. | ||
auto* pINA219shuntVoltage = new INA219value(pINA219, shunt_voltage, read_delay, "someElectricDevice/shuntVoltage"); | ||
|
||
pINA219shuntVoltage->connectTo(new SKOutputNumber("electrical.someelectricdevice.shuntVoltage")); | ||
|
||
// Do the same for the current (amperage). | ||
auto* pINA219current = new INA219value(pINA219, current, read_delay, "someElectricDevice/current"); | ||
|
||
pINA219current->connectTo(new SKOutputNumber("electrical.someelectricdevice.current")); | ||
|
||
// Do the same for the power (watts). | ||
auto* pINA219power = new INA219value(pINA219, power, read_delay, "someElectricDevice/power"); | ||
|
||
pINA219power->connectTo(new SKOutputNumber("electrical.someelectricdevice.power")); | ||
|
||
// Do the same for the load voltage. | ||
auto* pINA219loadVoltage = new INA219value(pINA219, load_voltage, read_delay, "someElectricDevice/loadVoltage"); | ||
|
||
pINA219loadVoltage->connectTo(new SKOutputNumber("electrical.someelectricdevice.loadVoltage")); | ||
|
||
|
||
sensesp_app->enable(); | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,85 @@ | ||
#include "ina219.h" | ||
|
||
#include "sensesp.h" | ||
//#include "i2c_tools.h" | ||
#include <RemoteDebug.h> | ||
|
||
|
||
// INA219 represents an ADAfruit (or compatible) INA219 temperature / pressure / humidity sensor. | ||
INA219::INA219(uint8_t addr, INA219CAL_t calibration_setting, String config_path) : | ||
Sensor(config_path) { | ||
className = "INA219"; | ||
load_configuration(); | ||
pAdafruitINA219 = new Adafruit_INA219(addr); | ||
pAdafruitINA219->begin(); | ||
// Default calibration in the Adafruit_INA219 constructor is 32V and 2A, so that's what it will be unless | ||
// it's set to something different in the call to this constructor: | ||
if (calibration_setting == cal32_1) { | ||
pAdafruitINA219->setCalibration_32V_1A(); | ||
} | ||
else if (calibration_setting == cal16_400) { | ||
pAdafruitINA219->setCalibration_16V_400mA(); | ||
} | ||
} | ||
|
||
|
||
|
||
// INA219value reads and outputs the specified type of value of a INA219 sensor | ||
INA219value::INA219value(INA219* pINA219, INA219ValType val_type, uint read_delay, String config_path) : | ||
NumericSensor(config_path), pINA219{pINA219}, val_type{val_type}, read_delay{read_delay} { | ||
className = "INA219value"; | ||
load_configuration(); | ||
} | ||
|
||
// INA219 outputs temp in Celsius. Need to convert to Kelvin before sending to Signal K. | ||
// Pressure is output in Pascals, Humidity is output in relative humidity (0 - 100%) | ||
void INA219value::enable() { | ||
app.onRepeat(read_delay, [this](){ | ||
switch (val_type) { | ||
case bus_voltage: output = pINA219->pAdafruitINA219->getBusVoltage_V(); | ||
break; | ||
case shunt_voltage: output = (pINA219->pAdafruitINA219->getShuntVoltage_mV() / 1000); // SK wants volts, not mV | ||
break; | ||
case current: output = (pINA219->pAdafruitINA219->getCurrent_mA() / 1000); // SK wants amps, not mA | ||
break; | ||
case power: output = (pINA219->pAdafruitINA219->getPower_mW() / 1000); // SK want watts, not mW | ||
break; | ||
case load_voltage: output = (pINA219->pAdafruitINA219->getBusVoltage_V() + (pINA219->pAdafruitINA219->getShuntVoltage_mV() / 1000)); | ||
break; | ||
default: debugE("FATAL: invalid val_type parameter."); | ||
} | ||
|
||
notify(); | ||
}); | ||
} | ||
|
||
JsonObject& INA219value::get_configuration(JsonBuffer& buf) { | ||
JsonObject& root = buf.createObject(); | ||
root["read_delay"] = read_delay; | ||
root["value"] = output; | ||
return root; | ||
}; | ||
|
||
static const char SCHEMA[] PROGMEM = R"###({ | ||
"type": "object", | ||
"properties": { | ||
"read_delay": { "title": "Read delay", "type": "number", "description": "The time, in milliseconds, between each read of the input" }, | ||
"value": { "title": "Last value", "type" : "number", "readOnly": true } | ||
} | ||
})###"; | ||
|
||
|
||
String INA219value::get_config_schema() { | ||
return FPSTR(SCHEMA); | ||
} | ||
|
||
bool INA219value::set_configuration(const JsonObject& config) { | ||
String expected[] = {"read_delay"}; | ||
for (auto str : expected) { | ||
if (!config.containsKey(str)) { | ||
return false; | ||
} | ||
} | ||
read_delay = config["read_delay"]; | ||
return true; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,47 @@ | ||
#ifndef _ina219_H_ | ||
#define _ina219_H_ | ||
|
||
#include <Wire.h> | ||
#include <Adafruit_INA219.h> | ||
|
||
#include "sensor.h" | ||
|
||
// The INA219 classes are based on the ADAfruit_INA219 library. | ||
|
||
// These are the used to tell the constructor what to set for maximum voltage and amperage. | ||
// The default in the Adafruit constructor is 32V and 2A, so we only need to handle the other two. | ||
enum INA219CAL_t { cal32_2, cal32_1, cal16_400 }; | ||
|
||
// INA219 represents an ADAfruit (or compatible) INA219 High Side DC Current Sensor. | ||
// The constructor creates a pointer to the instance, and starts up the sensor. The pointer is | ||
// passed to INA219value, which retrieves the specified value. | ||
// | ||
class INA219 : public Sensor { | ||
public: | ||
INA219(uint8_t addr = 0x40, INA219CAL_t calibration_setting = cal32_2, String config_path = ""); | ||
Adafruit_INA219* pAdafruitINA219; | ||
|
||
}; | ||
|
||
|
||
// Pass one of these in the constructor to INA219value() to tell which type of value you want to output | ||
enum INA219ValType { bus_voltage, shunt_voltage, current, power, load_voltage }; | ||
|
||
// INA219value reads and outputs the specified value of a INA219 sensor. | ||
class INA219value : public NumericSensor { | ||
public: | ||
INA219value(INA219* pINA219, INA219ValType val_type, uint read_delay = 500, String config_path=""); | ||
void enable() override final; | ||
INA219* pINA219; | ||
|
||
private: | ||
|
||
INA219ValType val_type; | ||
uint read_delay; | ||
virtual JsonObject& get_configuration(JsonBuffer& buf) override; | ||
virtual bool set_configuration(const JsonObject& config) override; | ||
virtual String get_config_schema() override; | ||
|
||
}; | ||
|
||
#endif |