From 8267c607a33b5890d68a495dec068acd4adde1e0 Mon Sep 17 00:00:00 2001 From: ladyada Date: Thu, 30 Jan 2025 11:52:54 -0500 Subject: [PATCH] add unified --- Adafruit_LPS28.cpp | 160 +++++++++++++++++- Adafruit_LPS28.h | 60 ++++++- .../LPS28_simpletest/LPS28_simpletest.ino | 3 + .../LPS28_unifiedtest/LPS28_unifiedtest.ino | 73 ++++++++ 4 files changed, 293 insertions(+), 3 deletions(-) create mode 100644 examples/LPS28_unifiedtest/LPS28_unifiedtest.ino diff --git a/Adafruit_LPS28.cpp b/Adafruit_LPS28.cpp index 38cf02f..606b1f0 100644 --- a/Adafruit_LPS28.cpp +++ b/Adafruit_LPS28.cpp @@ -29,9 +29,17 @@ #include "Adafruit_LPS28.h" /** - * @brief Construct a new Adafruit LPS28 object + * @brief Main LPS28 driver class constructor + * + * @param sensor_id ID to differentiate multiple sensors in the same sketch. + * If not specified, defaults to 0x28. Temperature sensor will + * use this ID and pressure sensor will use sensor_id + 1 */ -Adafruit_LPS28::Adafruit_LPS28() {} +Adafruit_LPS28::Adafruit_LPS28(int32_t sensor_id) { + _sensorid = sensor_id; + _sensorid_temp = sensor_id; + _sensorid_pressure = sensor_id + 1; +} /** * @brief Initializes the sensor with given parameters, tried reading @@ -572,3 +580,151 @@ float Adafruit_LPS28::getFIFOpressure() { return pressure_hpa; } + +/******************** Sensor interface */ + +/** + * @brief Gets a pointer to the temperature sensor object + * + * @return Adafruit_Sensor* Pointer to an Adafruit_Sensor object for temperature + * readings + */ +Adafruit_Sensor *Adafruit_LPS28::getTemperatureSensor(void) { + if (!temp_sensor) { + temp_sensor = new Adafruit_LPS28_Temp(this); + } + return temp_sensor; +} + +/** + * @brief Gets a pointer to the pressure sensor object + * + * @return Adafruit_Sensor* Pointer to an Adafruit_Sensor object for pressure + * readings + */ +Adafruit_Sensor *Adafruit_LPS28::getPressureSensor(void) { + if (!pressure_sensor) { + pressure_sensor = new Adafruit_LPS28_Pressure(this); + } + return pressure_sensor; +} + +/** + * @brief Gets both pressure and temperature readings in unified sensor format + * + * @param pressure Pointer to pressure event structure to be filled + * @param temp Pointer to temperature event structure to be filled + * @return true if reading was successful + * @return false if reading failed + */ +bool Adafruit_LPS28::getEvent(sensors_event_t *pressure, + sensors_event_t *temp) { + uint32_t timestamp = millis(); + + // Read the sensor + float pressure_hPa = getPressure(); + float temperature_C = getTemperature(); + + fillTempEvent(temp, timestamp); + fillPressureEvent(pressure, timestamp); + + return true; +} + +/** + * @brief Populates a temperature event structure with current readings + * + * @param temp Pointer to temperature event structure to be filled + * @param timestamp Current timestamp in milliseconds + */ +void Adafruit_LPS28::fillTempEvent(sensors_event_t *temp, uint32_t timestamp) { + memset(temp, 0, sizeof(sensors_event_t)); + temp->version = sizeof(sensors_event_t); + temp->sensor_id = _sensorid_temp; // Use _sensorid_temp instead of _sensorID + temp->type = SENSOR_TYPE_AMBIENT_TEMPERATURE; + temp->timestamp = timestamp; + temp->temperature = getTemperature(); +} + +/** + * @brief Populates a pressure event structure with current readings + * + * @param pressure Pointer to pressure event structure to be filled + * @param timestamp Current timestamp in milliseconds + */ +void Adafruit_LPS28::fillPressureEvent(sensors_event_t *pressure, + uint32_t timestamp) { + memset(pressure, 0, sizeof(sensors_event_t)); + pressure->version = sizeof(sensors_event_t); + pressure->sensor_id = + _sensorid_pressure; // Use _sensorid_pressure instead of _sensorID + pressure->type = SENSOR_TYPE_PRESSURE; + pressure->timestamp = timestamp; + pressure->pressure = getPressure(); +} + +/** + * @brief Gets the current temperature reading in unified sensor format + * + * @param event Pointer to sensor event structure to be filled with temperature + * data + * @return true Always returns true as reading cannot fail + */ +bool Adafruit_LPS28_Temp::getEvent(sensors_event_t *event) { + _theLPS28->fillTempEvent(event, millis()); + return true; +} + +/** + * @brief Gets the temperature sensor details + * + * Provides metadata about the temperature sensor including its + * range, resolution, and other capabilities. + * + * @param sensor Pointer to sensor metadata structure to be filled + */ +void Adafruit_LPS28_Temp::getSensor(sensor_t *sensor) { + memset(sensor, 0, sizeof(sensor_t)); + strncpy(sensor->name, "LPS28", sizeof(sensor->name) - 1); + sensor->name[sizeof(sensor->name) - 1] = 0; + sensor->version = 1; + sensor->sensor_id = _sensorID; + sensor->type = SENSOR_TYPE_AMBIENT_TEMPERATURE; + sensor->min_delay = 0; + sensor->min_value = -40.0; // -40 degree C + sensor->max_value = 85.0; // 85 degree C + sensor->resolution = 0.01; // 0.01 degree C +} + +/** + * @brief Gets the current pressure reading in unified sensor format + * + * @param event Pointer to sensor event structure to be filled with pressure + * data + * @return true Always returns true as reading cannot fail + */ +bool Adafruit_LPS28_Pressure::getEvent(sensors_event_t *event) { + _theLPS28->fillPressureEvent(event, millis()); + return true; +} + +/** + * @brief Gets the pressure sensor details + * + * Provides metadata about the pressure sensor including its + * range, resolution, and other capabilities. + * + * @param sensor Pointer to sensor metadata structure to be filled + */ +void Adafruit_LPS28_Pressure::getSensor(sensor_t *sensor) { + memset(sensor, 0, sizeof(sensor_t)); + strncpy(sensor->name, "LPS28", sizeof(sensor->name) - 1); + sensor->name[sizeof(sensor->name) - 1] = 0; + sensor->version = 1; + sensor->sensor_id = _sensorID; + sensor->type = SENSOR_TYPE_PRESSURE; + sensor->min_delay = 0; + sensor->min_value = 260.0; // 260 hPa + sensor->max_value = 4060.0; // 4060 hPa + sensor->resolution = 0.0002; // Based on full-scale mode +} diff --git a/Adafruit_LPS28.h b/Adafruit_LPS28.h index 59566a0..c4c7ad0 100644 --- a/Adafruit_LPS28.h +++ b/Adafruit_LPS28.h @@ -20,6 +20,7 @@ #include #include +#include #include // I2C Address and Register Definitions @@ -115,6 +116,42 @@ typedef enum { 0b111 ///< Continuous-to-FIFO mode (TRIG = 1, F_MODE[1:0] = 11) } lps28_fifo_mode_t; +/** Adafruit Unified Sensor interface for temperature component of LPS28 */ +class Adafruit_LPS28; + +/** + * @brief Adafruit Unified Sensor interface for temperature component of LPS28 + * + * Implements temperature-specific functionality using the Adafruit + * Unified Sensor interface for the LPS28 sensor. + */ +class Adafruit_LPS28_Temp : public Adafruit_Sensor { +public: + /** @brief Create an Adafruit_Sensor compatible object for the temp sensor + @param parent A pointer to the LPS28 class */ + Adafruit_LPS28_Temp(Adafruit_LPS28 *parent) { _theLPS28 = parent; } + bool getEvent(sensors_event_t *); + void getSensor(sensor_t *); + +private: + int _sensorID = 0x280; ///< Unique sensor identifier for temperature + Adafruit_LPS28 *_theLPS28 = NULL; ///< Pointer to parent LPS28 object +}; + +/** Adafruit Unified Sensor interface for pressure component of LPS28 */ +class Adafruit_LPS28_Pressure : public Adafruit_Sensor { +public: + /** @brief Create an Adafruit_Sensor compatible object for the pressure sensor + @param parent A pointer to the LPS28 class */ + Adafruit_LPS28_Pressure(Adafruit_LPS28 *parent) { _theLPS28 = parent; } + bool getEvent(sensors_event_t *); + void getSensor(sensor_t *); + +private: + int _sensorID = 0x281; ///< Unique sensor identifier for pressure + Adafruit_LPS28 *_theLPS28 = NULL; ///< Pointer to parent LPS28 object +}; + /** * @brief Main LPS28 sensor class * @@ -124,7 +161,12 @@ typedef enum { */ class Adafruit_LPS28 { public: - Adafruit_LPS28(); + Adafruit_LPS28( + int32_t sensor_id = 0x28); // Default ID of 0x28 if none provided + + Adafruit_Sensor *getTemperatureSensor(void); + Adafruit_Sensor *getPressureSensor(void); + bool getEvent(sensors_event_t *pressure, sensors_event_t *temp); bool begin(TwoWire *theWire = &Wire, uint8_t i2c_addr = LPS28_DEFAULT_ADDRESS); @@ -187,6 +229,22 @@ class Adafruit_LPS28 { float getFIFOpressure(); private: + Adafruit_LPS28_Temp *temp_sensor = NULL; ///< Temperature sensor data object + Adafruit_LPS28_Pressure *pressure_sensor = + NULL; ///< Pressure sensor data object + + uint16_t _sensorid, + _sensorid_pressure, ///< ID number for pressure + _sensorid_temp; ///< ID number for temperature + + friend class Adafruit_LPS28_Temp; ///< Gives access to private members to + ///< Temperature data object + friend class Adafruit_LPS28_Pressure; ///< Gives access to private members to + ///< Pressure data object + + void fillPressureEvent(sensors_event_t *pressure, uint32_t timestamp); + void fillTempEvent(sensors_event_t *temp, uint32_t timestamp); + Adafruit_I2CDevice *i2c_dev = nullptr; ///< Pointer to I2C device interface }; diff --git a/examples/LPS28_simpletest/LPS28_simpletest.ino b/examples/LPS28_simpletest/LPS28_simpletest.ino index eb97571..8e11958 100644 --- a/examples/LPS28_simpletest/LPS28_simpletest.ino +++ b/examples/LPS28_simpletest/LPS28_simpletest.ino @@ -22,6 +22,9 @@ void setup() { lps28.setDataRate(LPS28_ODR_200_HZ); lps28.setAveraging(LPS28_AVG_4); + // Set range to 4060 hPa + lps28.setFullScaleMode(true); + // Enable DRDY interrupt on the interrupt pin lps28.setInterruptPin( true, // Polarity: Active high diff --git a/examples/LPS28_unifiedtest/LPS28_unifiedtest.ino b/examples/LPS28_unifiedtest/LPS28_unifiedtest.ino new file mode 100644 index 0000000..fe49254 --- /dev/null +++ b/examples/LPS28_unifiedtest/LPS28_unifiedtest.ino @@ -0,0 +1,73 @@ +/*************************************************************************** + This is a library for the LPS28 Pressure & Temperature Sensor + + Designed specifically to work with the Adafruit LPS28 Breakout + ----> http://www.adafruit.com/products/XXXX + + These sensors use I2C to communicate, 2 pins are required to interface. + + Adafruit invests time and resources providing this open source code, + please support Adafruit and open-source hardware by purchasing products + from Adafruit! + + Written by Limor Fried/Ladyada for Adafruit Industries. + BSD license, all text above must be included in any redistribution + ***************************************************************************/ + +#include + +Adafruit_LPS28 lps; +Adafruit_Sensor *lps_temp, *lps_pressure; + +void setup(void) { + Serial.begin(115200); + while (!Serial) delay(10); // will pause Zero, Leonardo, etc until serial console opens + + Serial.println("Adafruit LPS28 test!"); + + // Try to initialize! + if (!lps.begin()) { + Serial.println("Failed to find LPS28 chip"); + while (1) { delay(10); } + } + Serial.println("LPS28 Found!"); + + // Set range to 4060 hPa + lps28.setFullScaleMode(true); + + // Get pointers to the sensors for the unified sensor API + lps_temp = lps.getTemperatureSensor(); + lps_temp->printSensorDetails(); + + lps_pressure = lps.getPressureSensor(); + lps_pressure->printSensorDetails(); +} + +void loop() { + sensors_event_t pressure; + sensors_event_t temp; + + // Get readings from both sensors + lps_pressure->getEvent(&pressure); + lps_temp->getEvent(&temp); + + // Pretty print for standard output + Serial.print("Temperature: "); + Serial.print(temp.temperature); + Serial.println(" °C"); + + Serial.print("Pressure: "); + Serial.print(pressure.pressure); + Serial.println(" hPa"); + + Serial.println(); + delay(100); + + /* Uncomment for serial plotter format + // Serial plotter friendly format + Serial.print(temp.temperature); + Serial.print(","); + Serial.println(pressure.pressure); + delay(10); + */ +}