add ltr329, ltr303, ltr390, max1704x, mcp3421

This commit is contained in:
brentru 2025-02-04 16:20:16 -05:00
parent dc5783001b
commit ee7a0f4467
6 changed files with 511 additions and 0 deletions

View file

@ -132,6 +132,31 @@ static std::map<std::string, FnCreateI2CDriver> I2cFactory = {
[](TwoWire *i2c, uint16_t addr, uint32_t mux_channel,
const char *driver_name) -> drvBase * {
return new drvLps25hb(i2c, addr, mux_channel, driver_name);
}},
{"ltr329",
[](TwoWire *i2c, uint16_t addr, uint32_t mux_channel,
const char *driver_name) -> drvBase * {
return new drvLtr329_Ltr303(i2c, addr, mux_channel, driver_name);
}},
{"ltr303",
[](TwoWire *i2c, uint16_t addr, uint32_t mux_channel,
const char *driver_name) -> drvBase * {
return new drvLtr329_Ltr303(i2c, addr, mux_channel, driver_name);
}},
{"ltr390",
[](TwoWire *i2c, uint16_t addr, uint32_t mux_channel,
const char *driver_name) -> drvBase * {
return new drvLtr390(i2c, addr, mux_channel, driver_name);
}},
{"max17048",
[](TwoWire *i2c, uint16_t addr, uint32_t mux_channel,
const char *driver_name) -> drvBase * {
return new drvMax1704x(i2c, addr, mux_channel, driver_name);
}},
{"mcp3421",
[](TwoWire *i2c, uint16_t addr, uint32_t mux_channel,
const char *driver_name) -> drvBase * {
return new drvMax1704x(i2c, addr, mux_channel, driver_name);
}}};
drvBase *createI2CDriverByName(const char *driver_name, TwoWire *i2c,

View file

@ -36,6 +36,10 @@
#include "drivers/drvLps22hb.h"
#include "drivers/drvLps25hb.h"
#include "drivers/drvLps3xhw.h"
#include "drivers/drvLtr329_Ltr303.h"
#include "drivers/drvLtr390.h"
#include "drivers/drvMax1704x.h"
#include "drivers/drvMcp3421.h"
class Wippersnapper_V2; ///< Forward declaration
class I2cModel; ///< Forward declaration

View file

@ -0,0 +1,127 @@
/*!
* @file drvLtr329_Ltr303.h
*
* Device driver for the LTR329 + LTR303 (329+interrupt) light sensors.
*
* 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 DRV_LTR329_LTR303_H
#define DRV_LTR329_LTR303_H
#include "drvBase.h"
#include <Adafruit_LTR329_LTR303.h>
/**************************************************************************/
/*!
@brief Class that provides a driver interface for a LTR329/303 sensor.
*/
/**************************************************************************/
class drvLtr329_Ltr303 : public drvBase {
public:
/*******************************************************************************/
/*!
@brief Constructor for a LTR329/303 sensor.
@param i2c
The I2C interface.
@param sensorAddress
The 7-bit I2C address of the sensor.
*/
/*******************************************************************************/
drvLtr329_Ltr303(TwoWire *i2c, uint16_t sensorAddress, uint32_t mux_channel,
const char *driver_name)
: drvBase(i2c, sensorAddress, mux_channel, driver_name) {
_i2c = i2c;
_address = sensorAddress;
_i2c_mux_channel = mux_channel;
strncpy(_name, driver_name, sizeof(_name) - 1);
_name[sizeof(_name) - 1] = '\0';
}
/*******************************************************************************/
/*!
@brief Destructor for an LTR329/303 sensor.
*/
/*******************************************************************************/
~drvLtr329_Ltr303() { delete _LTR329; }
/*******************************************************************************/
/*!
@brief Initializes the LTR329/303 sensor and begins I2C.
@returns True if initialized successfully, False otherwise.
*/
/*******************************************************************************/
bool begin() override {
_LTR329 = new Adafruit_LTR329();
// Attempt to initialize LTR329
if (!_LTR329->begin(_i2c))
return false;
// Configure LTR329 sensor - tested on a dull British day Oct'23 @7kLux
// Matches similar lux value from LTR390 with default configuration.
_LTR329->setGain(LTR3XX_GAIN_48);
_LTR329->setIntegrationTime(LTR3XX_INTEGTIME_100);
_LTR329->setMeasurementRate(LTR3XX_MEASRATE_100);
_delayBetweenReads = 110; // 100ms measurement time + 10ms fudge-factor
return true;
}
/*******************************************************************************/
/*!
@brief Reads the LTR329's ambient light level ([Visible+IR] - IR-only)
@param lightEvent
Light sensor reading.
@returns True if the sensor event was obtained successfully, False
otherwise.
*/
/*******************************************************************************/
bool getEventLight(sensors_event_t *lightEvent) {
if (!_LTR329->newDataAvailable())
return false;
uint16_t visible_plus_ir, infrared;
_LTR329->readBothChannels(visible_plus_ir, infrared);
lightEvent->light = visible_plus_ir - infrared;
return true;
}
/*******************************************************************************/
/*!
@brief Reads the LTR329's infrared value into an event.
@param rawEvent
Pointer to an adafruit sensor event.
@returns True if the sensor event was obtained successfully, False
otherwise.
*/
/*******************************************************************************/
bool getEventRaw(sensors_event_t *rawEvent) {
if (!_LTR329->newDataAvailable()) {
delay(
_delayBetweenReads); // Raw comes after Light event and needs new data
if (!_LTR329->newDataAvailable())
return false;
}
uint16_t visible_plus_ir, infrared;
_LTR329->readBothChannels(visible_plus_ir, infrared);
rawEvent->data[0] = (float)infrared;
return true;
}
protected:
Adafruit_LTR329 *_LTR329; ///< Pointer to LTR329 light sensor object
/**
* @brief The delay between consecutive reads in milliseconds.
*/
uint16_t _delayBetweenReads;
};
#endif // drvLtr329_Ltr303

View file

@ -0,0 +1,124 @@
/*!
* @file drvLtr390.h
*
* Device driver for the LTR390 light sensor.
*
* 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 DRV_LTR390_H
#define DRV_LTR390_H
#include "drvBase.h"
#include <Adafruit_LTR390.h>
/**************************************************************************/
/*!
@brief Class that provides a driver interface for a LTR390 sensor.
*/
/**************************************************************************/
class drvLtr390 : public drvBase {
public:
/*******************************************************************************/
/*!
@brief Constructor for a LTR390 sensor.
@param i2c
The I2C interface.
@param sensorAddress
The 7-bit I2C address of the sensor.
*/
/*******************************************************************************/
drvLtr390(TwoWire *i2c, uint16_t sensorAddress, uint32_t mux_channel,
const char *driver_name)
: drvBase(i2c, sensorAddress, mux_channel, driver_name) {
_i2c = i2c;
_address = sensorAddress;
_i2c_mux_channel = mux_channel;
strncpy(_name, driver_name, sizeof(_name) - 1);
_name[sizeof(_name) - 1] = '\0';
}
/*******************************************************************************/
/*!
@brief Destructor for an LTR390 sensor.
*/
/*******************************************************************************/
~drvLtr390() { delete _ltr390; }
/*******************************************************************************/
/*!
@brief Initializes the LTR390 sensor and begins I2C.
@returns True if initialized successfully, False otherwise.
*/
/*******************************************************************************/
bool begin() override {
_ltr390 = new Adafruit_LTR390();
// Attempt to initialize LTR390
if (!_ltr390->begin(_i2c))
return false;
// Configure LTR390 sensor
// Note: This driver uses the default configuration from
// https://github.com/adafruit/Adafruit_LTR390/blob/master/examples/ltr390_test/ltr390_test.ino
_ltr390->setMode(LTR390_MODE_UVS);
_ltr390->setGain(LTR390_GAIN_3);
_ltr390->setResolution(LTR390_RESOLUTION_16BIT);
return true;
}
/*******************************************************************************/
/*!
@brief Performs a light sensor read using the Adafruit
Unified Sensor API.
@param lightEvent
Light sensor reading, in lux.
@returns True if the sensor event was obtained successfully, False
otherwise.
*/
/*******************************************************************************/
bool getEventLight(sensors_event_t *lightEvent) {
if (_ltr390->getMode() != LTR390_MODE_ALS) {
_ltr390->setMode(LTR390_MODE_ALS);
delay(110);
}
if (!_ltr390->newDataAvailable())
return false;
lightEvent->light = _ltr390->readALS();
return true;
}
/*******************************************************************************/
/*!
@brief Reads the LTR390's UV value into an event.
@param rawEvent
Pointer to an adafruit sensor event.
@returns True if the sensor event was obtained successfully, False
otherwise.
*/
/*******************************************************************************/
bool getEventRaw(sensors_event_t *rawEvent) {
if (_ltr390->getMode() != LTR390_MODE_UVS) {
_ltr390->setMode(LTR390_MODE_UVS);
delay(110);
}
if (!_ltr390->newDataAvailable())
return false;
rawEvent->data[0] = (float)_ltr390->readUVS();
return true;
}
protected:
Adafruit_LTR390 *_ltr390; ///< Pointer to LTR390 light sensor object
};
#endif // drvLtr390

View file

@ -0,0 +1,100 @@
/*!
* @file drvMax1704x.h
*
* Device driver for the MAX17048/MAX17049 LiPoly / LiIon Fuel Gauge and Battery
* 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) Brent Rubell 2023 for Adafruit Industries.
*
* MIT license, all text here must be included in any redistribution.
*
*/
#ifndef DRV_MAX1704x_H
#define DRV_MAX1704x_H
#include "drvBase.h"
#include <Adafruit_MAX1704X.h>
/**************************************************************************/
/*!
@brief Class that provides a driver interface for a MAX17048 sensor.
*/
/**************************************************************************/
class drvMax1704x : public drvBase {
public:
/*******************************************************************************/
/*!
@brief Constructor for a MAX17048 sensor.
@param i2c
The I2C interface.
@param sensorAddress
The 7-bit I2C address of the sensor.
*/
/*******************************************************************************/
drvMax1704x(TwoWire *i2c, uint16_t sensorAddress, uint32_t mux_channel,
const char *driver_name)
: drvBase(i2c, sensorAddress, mux_channel, driver_name) {
_i2c = i2c;
_address = sensorAddress;
_i2c_mux_channel = mux_channel;
strncpy(_name, driver_name, sizeof(_name) - 1);
_name[sizeof(_name) - 1] = '\0';
}
/*******************************************************************************/
/*!
@brief Destructor for an MAX17048 sensor.
*/
/*******************************************************************************/
~drvMax1704x() { delete _maxlipo; }
/*******************************************************************************/
/*!
@brief Initializes the MAX17048 sensor and begins I2C.
@returns True if initialized successfully, False otherwise.
*/
/*******************************************************************************/
bool begin() override {
_maxlipo = new Adafruit_MAX17048();
return _maxlipo->begin(_i2c);
}
/*******************************************************************************/
/*!
@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) {
voltageEvent->voltage = _maxlipo->cellVoltage();
return true;
}
/*******************************************************************************/
/*!
@brief Reads a sensor's unitless % reading and
converts the reading into the expected SI unit.
@param unitlessPercentEvent
unitless % sensor reading.
@returns True if the sensor event was obtained successfully, False
otherwise.
*/
/*******************************************************************************/
bool getEventUnitlessPercent(sensors_event_t *unitlessPercentEvent) {
unitlessPercentEvent->unitless_percent = _maxlipo->cellPercent();
return true;
}
protected:
Adafruit_MAX17048 *_maxlipo; ///< Pointer to MAX17048 sensor object
};
#endif // drvMax1704x

View file

@ -0,0 +1,131 @@
/*!
* @file drvMcp3421.h
*
* Device driver for the MCP3421 18-bit ADC sensor.
*
* 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 2024 for Adafruit Industries.
*
* MIT license, all text here must be included in any redistribution.
*
*/
#ifndef DRV_MCP3421_H
#define DRV_MCP3421_H
#include "Wippersnapper.h"
#include "drvBase.h"
#include <Adafruit_MCP3421.h>
/**************************************************************************/
/*!
@brief Class that provides a driver interface for a MCP3421 sensor.
*/
/**************************************************************************/
class drvMcp3421 : public drvBase {
public:
/*******************************************************************************/
/*!
@brief Constructor for the MCP3421 sensor.
@param i2c
The I2C interface.
@param sensorAddress
7-bit device address.
*/
/*******************************************************************************/
drvMcp3421(TwoWire *i2c, uint16_t sensorAddress, uint32_t mux_channel,
const char *driver_name)
: drvBase(i2c, sensorAddress, mux_channel, driver_name) {
_i2c = i2c;
_address = sensorAddress;
_i2c_mux_channel = mux_channel;
strncpy(_name, driver_name, sizeof(_name) - 1);
_name[sizeof(_name) - 1] = '\0';
}
/*******************************************************************************/
/*!
@brief Destructor for an MCP3421 sensor.
*/
/*******************************************************************************/
~drvMcp3421() { delete _mcp3421; }
/*******************************************************************************/
/*!
@brief Initializes the MCP3421 sensor and begins I2C.
@returns True if initialized successfully, False otherwise.
*/
/*******************************************************************************/
bool begin() override {
_mcp3421 = new Adafruit_MCP3421();
if (!_mcp3421->begin((uint8_t)_address, _i2c))
return false;
return configureSensor();
}
/*******************************************************************************/
/*!
@brief Configures the MCP3421 sensor.
@returns True if the sensor was configured successfully, False otherwise.
*/
/*******************************************************************************/
bool configureSensor() {
// NOTE: We should allow the gain to be set in future, like resolution
// 12_BIT (240 SPS), 14_BIT (60 SPS), 16_BIT (15 SPS), 18_BIT (3.75 SPS)
_mcp3421->setResolution(RESOLUTION_18_BIT);
if (_mcp3421->getResolution() != RESOLUTION_18_BIT) {
WS_DEBUG_PRINTLN("Failed to set resolution to 18-bit");
return false;
}
_mcp3421->setGain(GAIN_8X);
if (_mcp3421->getGain() != GAIN_8X) {
WS_DEBUG_PRINTLN("Failed to set gain to 8x");
return false;
}
_mcp3421->setMode(MODE_ONE_SHOT);
if (_mcp3421->getMode() != MODE_ONE_SHOT) {
WS_DEBUG_PRINTLN("Failed to set mode to One-Shot");
return false;
}
return true;
}
/*******************************************************************************/
/*!
@brief Reads the ADC sensor with short wait for data.
@param rawEvent
ADC sensor reading
@returns True if the sensor event was obtained successfully, False
otherwise.
*/
/*******************************************************************************/
bool getEventRaw(sensors_event_t *rawEvent) {
ulong start = millis();
if (!_mcp3421->startOneShotConversion()) {
WS_DEBUG_PRINTLN("Failed to start one-shot conversion");
return false;
}
while (!_mcp3421->isReady()) {
ulong newMillis = millis();
if (newMillis - start > 500) {
WS_DEBUG_PRINTLN("Timeout waiting for conversion to complete");
return false;
} else if (start > newMillis) {
start = millis(); // rollover
}
delay(50);
}
rawEvent->data[0] = (float)_mcp3421->readADC();
return true;
}
protected:
Adafruit_MCP3421 *_mcp3421; ///< Pointer to MCP3421 sensor object
};
#endif // drvMcp3421