Skip to content

Commit

Permalink
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add INA219 driver + Current stubs
Browse files Browse the repository at this point in the history
tyeth committed Sep 5, 2023
1 parent efec657 commit 6630d7b
Showing 6 changed files with 203 additions and 1 deletion.
2 changes: 1 addition & 1 deletion library.properties
Original file line number Diff line number Diff line change
@@ -7,4 +7,4 @@ paragraph=Arduino client for Adafruit.io WipperSnapper
category=Communication
url=https://github.com/adafruit/Adafruit_IO_Arduino
architectures=*
depends=Adafruit NeoPixel, Adafruit SPIFlash, ArduinoJson, Adafruit DotStar, Adafruit SleepyDog Library, Adafruit TMP117, Adafruit TinyUSB Library, Adafruit AHTX0, Adafruit BME280 Library, Adafruit BMP280 Library, Adafruit BMP3XX Library, Adafruit DPS310, Adafruit SCD30, Adafruit SGP30 Sensor, Sensirion I2C SCD4x, Sensirion I2C SEN5X, arduino-sht, Adafruit Si7021 Library, Adafruit MQTT Library, Adafruit MS8607, Adafruit MCP9808 Library, Adafruit MCP9600 Library, Adafruit MPL115A2, Adafruit TSL2591 Library, Adafruit_VL53L0X, Adafruit PM25 AQI Sensor, Adafruit VEML7700 Library, Adafruit LC709203F, Adafruit LPS35HW, Adafruit seesaw Library, Adafruit BME680 Library, Adafruit MAX1704X, Adafruit ADT7410 Library, Adafruit HTS221, Adafruit PCT2075, hp_BH1750
depends=Adafruit NeoPixel, Adafruit SPIFlash, ArduinoJson, Adafruit DotStar, Adafruit INA219, Adafruit SleepyDog Library, Adafruit TMP117, Adafruit TinyUSB Library, Adafruit AHTX0, Adafruit BME280 Library, Adafruit BMP280 Library, Adafruit BMP3XX Library, Adafruit DPS310, Adafruit SCD30, Adafruit SGP30 Sensor, Sensirion I2C SCD4x, Sensirion I2C SEN5X, arduino-sht, Adafruit Si7021 Library, Adafruit MQTT Library, Adafruit MS8607, Adafruit MCP9808 Library, Adafruit MCP9600 Library, Adafruit MPL115A2, Adafruit TSL2591 Library, Adafruit_VL53L0X, Adafruit PM25 AQI Sensor, Adafruit VEML7700 Library, Adafruit LC709203F, Adafruit LPS35HW, Adafruit seesaw Library, Adafruit BME680 Library, Adafruit MAX1704X, Adafruit ADT7410 Library, Adafruit HTS221, Adafruit PCT2075, hp_BH1750
1 change: 1 addition & 0 deletions platformio.ini
Original file line number Diff line number Diff line change
@@ -27,6 +27,7 @@ lib_deps =
adafruit/Adafruit BMP280 Library
adafruit/Adafruit BMP3XX Library
adafruit/Adafruit DPS310
adafruit/Adafruit INA219
adafruit/Adafruit HTS221
adafruit/Adafruit PCT2075
adafruit/Adafruit SCD30
38 changes: 38 additions & 0 deletions src/components/i2c/WipperSnapper_I2C.cpp
Original file line number Diff line number Diff line change
@@ -318,6 +318,17 @@ bool WipperSnapper_Component_I2C::initI2CDevice(
_scd30->configureDriver(msgDeviceInitReq);
drivers.push_back(_scd30);
WS_DEBUG_PRINTLN("SCD30 Initialized Successfully!");
} else if (strcmp("ina219", msgDeviceInitReq->i2c_device_name) == 0) {
_ina219 = new WipperSnapper_I2C_Driver_INA219(this->_i2c, i2cAddress);
if (!_ina219->begin()) {
WS_DEBUG_PRINTLN("ERROR: Failed to initialize INA219");
_busStatusResponse =
wippersnapper_i2c_v1_BusResponse_BUS_RESPONSE_DEVICE_INIT_FAIL;
return false;
}
_ina219->configureDriver(msgDeviceInitReq);
drivers.push_back(_ina219);
WS_DEBUG_PRINTLN("INA219 Initialized Successfully!");
} else if (strcmp("sgp30", msgDeviceInitReq->i2c_device_name) == 0) {
_sgp30 = new WipperSnapper_I2C_Driver_SGP30(this->_i2c, i2cAddress);
if (!_sgp30->begin()) {
@@ -756,6 +767,9 @@ void WipperSnapper_Component_I2C::displayDeviceEventMessage(
case wippersnapper_i2c_v1_SensorType_SENSOR_TYPE_VOLTAGE:
snprintf(buffer, 100, "[I2C: %x] Read: %0.3f V\n", sensorAddress, value);
break;
case wippersnapper_i2c_v1_SensorType_SENSOR_TYPE_CURRENT:
snprintf(buffer, 100, "[I2C: %x] Read: %0.3f mA\n", sensorAddress, value);
break;
case wippersnapper_i2c_v1_SensorType_SENSOR_TYPE_RAW:
case wippersnapper_i2c_v1_SensorType_SENSOR_TYPE_PROXIMITY:
snprintf(buffer, 100, "[I2C: %x] Read: %0.3f\n", sensorAddress, value);
@@ -1151,6 +1165,30 @@ void WipperSnapper_Component_I2C::update() {
(*iter)->setSensorVoltagePeriodPrv(curTime);
}


// Current sensor
curTime = millis();
if ((*iter)->getSensorCurrentPeriod() != 0L &&
curTime - (*iter)->getSensorCurrentPeriodPrv() >
(*iter)->getSensorCurrentPeriod()) {
if ((*iter)->getEventCurrent(&event)) {
WS_DEBUG_PRINT("Sensor 0x");
WS_DEBUG_PRINTHEX((*iter)->getI2CAddress());
WS_DEBUG_PRINTLN("");
WS_DEBUG_PRINT("\tCurrent: ");
WS_DEBUG_PRINT(event.current);
WS_DEBUG_PRINTLN(" mA");

// pack event data into msg
fillEventMessage(&msgi2cResponse, event.current,
wippersnapper_i2c_v1_SensorType_SENSOR_TYPE_CURRENT);
} else {
WS_DEBUG_PRINTLN("ERROR: Failed to get Current sensor reading!");
}
// try again in curTime seconds
(*iter)->setSensorCurrentPeriodPrv(curTime);
}

// Unitless % sensor
curTime = millis();
if ((*iter)->getSensorUnitlessPercentPeriod() != 0L &&
2 changes: 2 additions & 0 deletions src/components/i2c/WipperSnapper_I2C.h
Original file line number Diff line number Diff line change
@@ -29,6 +29,7 @@
#include "drivers/WipperSnapper_I2C_Driver_BMP3XX.h"
#include "drivers/WipperSnapper_I2C_Driver_DPS310.h"
#include "drivers/WipperSnapper_I2C_Driver_HTS221.h"
#include "drivers/WipperSnapper_I2C_Driver_INA219.h"
#include "drivers/WipperSnapper_I2C_Driver_LC709203F.h"
#include "drivers/WipperSnapper_I2C_Driver_LPS3XHW.h"
#include "drivers/WipperSnapper_I2C_Driver_MAX17048.h"
@@ -107,6 +108,7 @@ class WipperSnapper_Component_I2C {
WipperSnapper_I2C_Driver_BMP3XX *_bmp3xx = nullptr;
WipperSnapper_I2C_Driver_BME680 *_bme680 = nullptr;
WipperSnapper_I2C_Driver_HTS221 *_hts221 = nullptr;
WipperSnapper_I2C_Driver_INA219 *_ina219 = nullptr;
WipperSnapper_I2C_Driver_MCP9808 *_mcp9808 = nullptr;
WipperSnapper_I2C_Driver_MPL115A2 *_mpl115a2 = nullptr;
WipperSnapper_I2C_Driver_MS8607 *_ms8607 = nullptr;
54 changes: 54 additions & 0 deletions src/components/i2c/drivers/WipperSnapper_I2C_Driver.h
Original file line number Diff line number Diff line change
@@ -112,6 +112,9 @@ class WipperSnapper_I2C_Driver {
case wippersnapper_i2c_v1_SensorType_SENSOR_TYPE_VOLTAGE:
_voltagePeriod = sensorPeriod;
break;
case wippersnapper_i2c_v1_SensorType_SENSOR_TYPE_CURRENT:
_currentPeriod = sensorPeriod;
break;
case wippersnapper_i2c_v1_SensorType_SENSOR_TYPE_PROXIMITY:
_proximitySensorPeriod = sensorPeriod;
break;
@@ -850,6 +853,53 @@ class WipperSnapper_I2C_Driver {
return false;
}

/**************************** SENSOR_TYPE: CURRENT
* ****************************/
/*********************************************************************************/
/*!
@brief Base implementation - Returns the current sensor's period.
@returns Time when the object current sensor should be polled, in
seconds.
*/
/*********************************************************************************/
virtual long getSensorCurrentPeriod() { return _currentPeriod; }

/*********************************************************************************/
/*!
@brief Base implementation - Returns the previous time interval at
which the current sensor was queried last.
@returns Time when the current sensor was last queried, in seconds.
*/
/*********************************************************************************/
virtual long getSensorCurrentPeriodPrv() { return _currentPeriodPrv; }

/*******************************************************************************/
/*!
@brief Sets a timestamp for when the current sensor was queried.
@param period
The time when the current sensor was queried last.
*/
/*******************************************************************************/
virtual void setSensorCurrentPeriodPrv(long period) {
_currentPeriodPrv = period;
}

/*******************************************************************************/
/*!
@brief Base implementation - Reads a current sensor and converts the
reading into the expected SI unit.
@param currentEvent
current sensor reading, in volts.
@returns True if the sensor event was obtained successfully, False
otherwise.
*/
/*******************************************************************************/
virtual bool getEventCurrent(sensors_event_t *currentEvent) {
(void)currentEvent; // Parameter is intentionally unused in this virtual
// function.
return false;
}

/****************************** SENSOR_TYPE: Raw
* *******************************/
/*********************************************************************************/
@@ -1323,6 +1373,10 @@ class WipperSnapper_I2C_Driver {
///< voltage sensor's value.
long _voltagePeriodPrv = 0L; ///< The time when the voltage sensor
///< was last read.
long _currentPeriod = 0L; ///< The time period between reading the
///< current sensor's value.
long _currentPeriodPrv = 0L; ///< The time when the current sensor
///< was last read.
long _rawSensorPeriod =
0L; ///< The time period between reading the Raw sensor's value.
long _rawSensorPeriodPrv = 0L; ///< The time when the Raw sensor
107 changes: 107 additions & 0 deletions src/components/i2c/drivers/WipperSnapper_I2C_Driver_INA219.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,107 @@
/*!
* @file WipperSnapper_I2C_Driver_INA219.h
*
* Device driver for the INA219 High-side DC Current and Voltage Monitor
*
* Adafruit invests time and resources providing this open source code,
* please support Adafruit and open-source hardware by purchasing
* products from Adafruit!
*
* Copyright (c) Tyeth Gundry 2023 for Adafruit Industries.
*
* MIT license, all text here must be included in any redistribution.
*
*/
#ifndef WipperSnapper_I2C_Driver_INA219_H
#define WipperSnapper_I2C_Driver_INA219_H

#include "WipperSnapper_I2C_Driver.h"
#include <Adafruit_INA219.h>

/**************************************************************************/
/*!
@brief Class that provides a driver interface for a INA219 sensor.
*/
/**************************************************************************/
class WipperSnapper_I2C_Driver_INA219 : public WipperSnapper_I2C_Driver {
public:
/*******************************************************************************/
/*!
@brief Constructor for a INA219 sensor.
@param i2c
The I2C interface.
@param sensorAddress
The 7-bit I2C address of the sensor.
*/
/*******************************************************************************/
WipperSnapper_I2C_Driver_INA219(TwoWire *i2c, uint16_t sensorAddress)
: WipperSnapper_I2C_Driver(i2c, sensorAddress) {
_i2c = i2c;
_sensorAddress = sensorAddress;
}

/*******************************************************************************/
/*!
@brief Destructor for an INA219 sensor.
*/
/*******************************************************************************/
~WipperSnapper_I2C_Driver_INA219() { delete _ina219; }

/*******************************************************************************/
/*!
@brief Initializes the INA219 sensor and begins I2C.
@returns True if initialized successfully, False otherwise.
*/
/*******************************************************************************/
bool begin() {
_ina219 = new Adafruit_INA219(_sensorAddress);
if (!_ina219->begin(_i2c))
return false;

//TODO: When parameters or dual input/output or sensor configuration is added
// To use a slightly lower 32V, 1A range (higher precision on amps):
//ina219.setCalibration_32V_1A();
// Or to use a lower 16V, 400mA range (higher precision on volts and amps):
//ina219.setCalibration_16V_400mA();

return true;
}

/*******************************************************************************/
/*!
@brief Reads a voltage sensor and converts the
reading into the expected SI unit.
@param voltageEvent
voltage sensor reading, in volts.
@returns True if the sensor event was obtained successfully, False
otherwise.
*/
/*******************************************************************************/
bool getEventVoltage(sensors_event_t *voltageEvent) {
float shuntvoltage_mV = _ina219->getShuntVoltage_mV();
float busvoltage_V = _ina219->getBusVoltage_V();

// Compute load voltage
float loadvoltage = busvoltage_V + (shuntvoltage_mV / 1000);
voltageEvent->voltage = loadvoltage;
return true;
}

/**
* @brief Get the current sensor event.
*
* @param currentEvent Pointer to the current sensor event.
*
* @returns True if the sensor event was obtained successfully, False otherwise.
*/
bool getEventCurrent(sensors_event_t *currentEvent) {
float current_mA = _ina219->getCurrent_mA();
currentEvent->current = current_mA;
return true;
}

protected:
Adafruit_INA219 *_ina219; ///< Pointer to INA219 sensor object
};

#endif // WipperSnapper_I2C_Driver_INA219

0 comments on commit 6630d7b

Please sign in to comment.