diff --git a/Adafruit_SPA06_003.cpp b/Adafruit_SPA06_003.cpp index bc91e2a..1736660 100644 --- a/Adafruit_SPA06_003.cpp +++ b/Adafruit_SPA06_003.cpp @@ -97,7 +97,7 @@ bool Adafruit_SPA06_003::begin(int8_t cspin, SPIClass *theSPI) { } spi_dev = new Adafruit_SPIDevice(cspin, SPA06_003_DEFAULT_SPIFREQ, - SPI_BITORDER_MSBFIRST, SPI_MODE0, theSPI); + SPI_BITORDER_MSBFIRST, SPI_MODE3, theSPI); if (!spi_dev->begin()) { return false; @@ -126,7 +126,7 @@ bool Adafruit_SPA06_003::begin(int8_t cspin, int8_t mosipin, int8_t misopin, spi_dev = new Adafruit_SPIDevice(cspin, sckpin, misopin, mosipin, SPA06_003_DEFAULT_SPIFREQ, - SPI_BITORDER_MSBFIRST, SPI_MODE0); + SPI_BITORDER_MSBFIRST, SPI_MODE3); if (!spi_dev->begin()) { return false; @@ -685,15 +685,38 @@ float Adafruit_SPA06_003::getScalingFactor(spa06_003_oversample_t oversample) { * @return Temperature in degrees Celsius */ float Adafruit_SPA06_003::readTemperature() { - // Get current temperature oversampling setting and scale factor - spa06_003_oversample_t oversample = getTemperatureOversampling(); - float kT = getScalingFactor(oversample); - // Read raw temperature data (24-bit 2's complement) uint32_t temp_raw = getTemperatureData(); + // Use the calculation function + return calculateTemperature(temp_raw); +} + +/*! + * @brief Reads compensated pressure value in hectopascals + * @return Pressure in hectopascals (hPa) + */ +float Adafruit_SPA06_003::readPressure() { + // Read raw pressure and temperature data (24-bit 2's complement) + uint32_t pres_raw = getPressureData(); + uint32_t temp_raw = getTemperatureData(); + + // Use the calculation function + return calculatePressure(pres_raw, temp_raw); +} + +/*! + * @brief Calculates compensated temperature from raw data + * @param raw_temp Raw 24-bit temperature data + * @return Temperature in degrees Celsius + */ +float Adafruit_SPA06_003::calculateTemperature(uint32_t raw_temp) { + // Get temperature oversampling setting for scaling + spa06_003_oversample_t oversample = getTemperatureOversampling(); + float kT = getScalingFactor(oversample); + // Convert to signed 32-bit - int32_t temp_raw_signed = (int32_t)temp_raw; + int32_t temp_raw_signed = (int32_t)raw_temp; // Calculate scaled measurement result float temp_raw_sc = (float)temp_raw_signed / kT; @@ -705,21 +728,23 @@ float Adafruit_SPA06_003::readTemperature() { } /*! - * @brief Reads compensated pressure value in hectopascals + * @brief Calculates compensated pressure from raw data + * @param raw_pres Raw 24-bit pressure data + * @param raw_temp Raw 24-bit temperature data (for compensation) * @return Pressure in hectopascals (hPa) */ -float Adafruit_SPA06_003::readPressure() { - // Get scaling factors based on current oversampling settings - float kP = getScalingFactor(getPressureOversampling()); - float kT = getScalingFactor(getTemperatureOversampling()); +float Adafruit_SPA06_003::calculatePressure(uint32_t raw_pres, + uint32_t raw_temp) { + // Get oversampling settings for scaling + spa06_003_oversample_t pres_oversample = getPressureOversampling(); + spa06_003_oversample_t temp_oversample = getTemperatureOversampling(); - // Read raw pressure and temperature data (24-bit 2's complement) - uint32_t pres_raw = getPressureData(); - uint32_t temp_raw = getTemperatureData(); + float kP = getScalingFactor(pres_oversample); + float kT = getScalingFactor(temp_oversample); // Convert to signed 32-bit - int32_t pres_raw_signed = (int32_t)pres_raw; - int32_t temp_raw_signed = (int32_t)temp_raw; + int32_t pres_raw_signed = (int32_t)raw_pres; + int32_t temp_raw_signed = (int32_t)raw_temp; // Calculate scaled measurement results float pres_raw_sc = (float)pres_raw_signed / kP; @@ -733,14 +758,13 @@ float Adafruit_SPA06_003::readPressure() { // Calculate compensated pressure using the formula: // Pcomp = c00 + c10*Praw_sc + c20*Praw_sc^2 + c30*Praw_sc^3 + c40*Praw_sc^4 + // Traw_sc*(c01 + c11*Praw_sc + c21*Praw_sc^2 + c31*Praw_sc^3) - float pres_comp = (float)c00 + (float)c10 * pres_raw_sc + (float)c20 * pres_raw_sc_2 + (float)c30 * pres_raw_sc_3 + (float)c40 * pres_raw_sc_4 + temp_raw_sc * ((float)c01 + (float)c11 * pres_raw_sc + (float)c21 * pres_raw_sc_2 + (float)c31 * pres_raw_sc_3); - // Convert from Pascals to hectopascals (hPa) + // Convert from Pa to hPa (divide by 100) return pres_comp / 100.0f; } @@ -838,4 +862,4 @@ bool Adafruit_SPA06_003_Pressure::getEvent(sensors_event_t *event) { event->timestamp = millis(); event->pressure = _theSPA06003->readPressure(); return true; -} \ No newline at end of file +} diff --git a/Adafruit_SPA06_003.h b/Adafruit_SPA06_003.h index e8e671c..eb59106 100644 --- a/Adafruit_SPA06_003.h +++ b/Adafruit_SPA06_003.h @@ -212,6 +212,8 @@ class Adafruit_SPA06_003 { bool reset(); float readTemperature(); float readPressure(); + float calculateTemperature(uint32_t raw_temp); + float calculatePressure(uint32_t raw_pres, uint32_t raw_temp); Adafruit_Sensor *getTemperatureSensor(); Adafruit_Sensor *getPressureSensor(); diff --git a/examples/fifotest/fifotest.ino b/examples/fifotest/fifotest.ino new file mode 100644 index 0000000..daf3fde --- /dev/null +++ b/examples/fifotest/fifotest.ino @@ -0,0 +1,142 @@ +/*! + * @file fifotest.ino + * + * Demonstrates using the SPA06_003 FIFO functionality with I2C interface. + * This example enables the FIFO, fills it up, then reads all data at once + * when the FIFO becomes full. + * + * The FIFO can store up to 32 pressure and temperature measurements, + * allowing for burst data collection and reducing I2C traffic. + * + * Designed specifically to work with the Adafruit SPA06_003 Breakout + * ----> https://www.adafruit.com/products/xxxx + * + * These sensors use I2C to communicate, 2 pins are required to interface. + * + * Written by Limor 'ladyada' Fried with assistance from Claude Code + * for Adafruit Industries. + * MIT license, check license.txt for more information + * All text above must be included in any redistribution + */ + +#include + +Adafruit_SPA06_003 spa; + +void setup() { + Serial.begin(115200); + while (!Serial) + delay(10); // will pause Zero, Leonardo, etc until serial console opens + + Serial.println("Adafruit SPA06_003 FIFO Test"); + + // Try to initialize! + if (!spa.begin()) { + Serial.println("Failed to find SPA06_003 chip"); + while (1) { + delay(10); + } + } + Serial.println("SPA06_003 Found!"); + + // Configure for FIFO operation + Serial.println("Configuring sensor for FIFO operation..."); + + // Set moderate precision for faster sampling + spa.setPressureOversampling(SPA06_003_OVERSAMPLE_8); // 8x oversampling + spa.setTemperatureOversampling(SPA06_003_OVERSAMPLE_8); // 8x oversampling + + // Set high measurement rate to fill FIFO quickly + spa.setPressureMeasureRate(SPA06_003_RATE_32); // 32 Hz + spa.setTemperatureMeasureRate(SPA06_003_RATE_32); // 32 Hz + + // Enable FIFO and FIFO full interrupt + spa.enableFIFO(true); + spa.setInterruptSource(true, false, + false); // Enable only FIFO full interrupt + + // Start continuous measurement + spa.setMeasurementMode(SPA06_003_MEAS_CONTINUOUS_BOTH); + + Serial.println("FIFO enabled and continuous measurement started"); + Serial.println("Waiting for FIFO to fill..."); + Serial.println("FIFO holds up to 32 measurements"); + Serial.println(); +} + +void loop() { + // Check if FIFO is full + if (spa.isFIFOFull()) { + Serial.println("*** FIFO IS FULL! ***"); + Serial.println("Reading all data from FIFO..."); + + uint8_t count = 0; + + // Read all data from FIFO until empty + uint32_t last_temp_raw = + 0; // Store last temperature for pressure compensation + while (!spa.isFIFOEmpty() && count < 64) { // Safety limit + // Read raw 24-bit data from FIFO (always from pressure registers) + uint32_t raw_data = spa.getPressureData(); + + // Check LSB to determine measurement type + bool is_pressure = (raw_data & 0x01) == 1; + + // Clear the LSB for actual measurement calculation and properly handle + // sign extension + uint32_t measurement_data = raw_data & 0xFFFFFE; + + // After clearing LSB, we now have a 23-bit signed value + // Check if bit 22 is set (sign bit of the 23-bit number) + if (measurement_data & 0x400000) { + // Sign extend from 23 bits to 32 bits + measurement_data |= 0xFF800000; + } + + Serial.print("Sample "); + Serial.print(count + 1); + Serial.print(": "); + + if (is_pressure) { + // This is pressure data - need temperature for compensation + float pressure = spa.calculatePressure(measurement_data, last_temp_raw); + Serial.print("Pressure="); + Serial.print(pressure, 2); + Serial.println(" hPa"); + } else { + // This is temperature data + last_temp_raw = measurement_data; // Store for pressure compensation + float temperature = spa.calculateTemperature(measurement_data); + Serial.print("Temperature="); + Serial.print(temperature, 2); + Serial.println(" °C"); + } + + count++; + delay(10); // Small delay between reads + } + + Serial.print("Total samples read from FIFO: "); + Serial.println(count); + Serial.println(); + Serial.println("FIFO emptied. Waiting for next fill..."); + Serial.println("-----------------------------------"); + Serial.println(); + } + + // Check FIFO status periodically + static unsigned long lastStatusCheck = 0; + if (millis() - lastStatusCheck > 1000) { // Check every second + Serial.print("FIFO Status - "); + Serial.print("Empty: "); + Serial.print(spa.isFIFOEmpty() ? "Yes" : "No"); + Serial.print(", Full: "); + Serial.print(spa.isFIFOFull() ? "Yes" : "No"); + Serial.print(", Enabled: "); + Serial.println(spa.isFIFOEnabled() ? "Yes" : "No"); + + lastStatusCheck = millis(); + } + + delay(100); // Check FIFO status every 100ms +} \ No newline at end of file diff --git a/examples/fulltest_spa06_003/fulltest_spa06_003.ino b/examples/fulltest/fulltest.ino similarity index 96% rename from examples/fulltest_spa06_003/fulltest_spa06_003.ino rename to examples/fulltest/fulltest.ino index e639886..4ab534a 100644 --- a/examples/fulltest_spa06_003/fulltest_spa06_003.ino +++ b/examples/fulltest/fulltest.ino @@ -1,8 +1,8 @@ /* Basic test sketch for SPA06_003 Digital Pressure Sensor - + This sketch initializes the sensor and verifies communication. - + Written by Limor 'ladyada' Fried with assistance from Claude Code for Adafruit Industries. MIT license, check license.txt for more information @@ -102,23 +102,25 @@ void printOversampling(spa06_003_oversample_t prc) { void setup() { Serial.begin(115200); - while (!Serial) delay(10); - + while (!Serial) + delay(10); + Serial.println("SPA06_003 test!"); - + if (!spa.begin()) { Serial.println("Could not find a valid SPA06_003 sensor, check wiring!"); - while (1) delay(10); + while (1) + delay(10); } - + Serial.println(F("SPA06_003 sensor found and initialized!")); - + Serial.println(F("Setting measurement mode to continuous both...")); spa.setMeasurementMode(SPA06_003_MEAS_CONTINUOUS_BOTH); - + Serial.print(F("Current measurement mode: ")); spa06_003_meas_mode_t current_mode = spa.getMeasurementMode(); - + switch (current_mode) { case SPA06_003_MEAS_IDLE: Serial.println(F("Idle")); @@ -142,33 +144,34 @@ void setup() { Serial.println(F("Unknown")); break; } - + spa.enableFIFO(false); - + spa.setInterruptPolarity(SPA06_003_INT_ACTIVE_HIGH); - - spa.setInterruptSource(false /*fifo*/, true /*temp_ready*/, true /*pres_ready*/); - + + spa.setInterruptSource(false /*fifo*/, true /*temp_ready*/, + true /*pres_ready*/); + spa.setTemperatureOversampling(SPA06_003_OVERSAMPLE_8); - + spa06_003_oversample_t temp_prc = spa.getTemperatureOversampling(); Serial.print(F("Current temperature oversampling: ")); printOversampling(temp_prc); - + spa.setTemperatureMeasureRate(SPA06_003_RATE_64); - + spa06_003_rate_t temp_rate = spa.getTemperatureMeasureRate(); Serial.print(F("Current temperature measurement rate: ")); printMeasureRate(temp_rate); - + spa.setPressureMeasureRate(SPA06_003_RATE_128); - + spa06_003_rate_t current_rate = spa.getPressureMeasureRate(); Serial.print(F("Current pressure measurement rate: ")); printMeasureRate(current_rate); - + spa.setPressureOversampling(SPA06_003_OVERSAMPLE_8); - + spa06_003_oversample_t current_prc = spa.getPressureOversampling(); Serial.print(F("Current pressure oversampling: ")); printOversampling(current_prc); @@ -180,18 +183,18 @@ void loop() { Serial.print(spa.readTemperature()); Serial.print(F("°C")); } - + if (spa.isPresDataReady()) { Serial.print(F(", Pressure: ")); Serial.print(spa.readPressure()); Serial.print(F(" hPa")); } - + uint8_t status_flags = spa.getStatusFlags(); Serial.print(F(", Status flags: 0x")); Serial.print(status_flags, HEX); Serial.print(F(" [")); - + if (status_flags & SPA06_003_INT_FIFO_FULL) { Serial.print(F("FIFO_FULL ")); } @@ -204,9 +207,9 @@ void loop() { if (status_flags == 0) { Serial.print(F("NONE")); } - + Serial.println(F("]")); - + Serial.print(F(", FIFO: ")); if (spa.isFIFOEnabled()) { Serial.print(F("enabled ")); @@ -221,6 +224,6 @@ void loop() { Serial.print(F("disabled")); } Serial.println(); - + delay(1000); } \ No newline at end of file diff --git a/examples/sensorapi/sensorapi.ino b/examples/sensorapi/sensorapi.ino index 54b2b10..501819f 100644 --- a/examples/sensorapi/sensorapi.ino +++ b/examples/sensorapi/sensorapi.ino @@ -1,10 +1,10 @@ /*! * @file sensorapi.ino * - * Demonstrates using the SPA06_003 sensor with Adafruit's Unified Sensor interface. - * This example shows how to get sensor information and read values using the - * standardized Adafruit Sensor API, which allows easy integration with other - * sensor libraries and data logging systems. + * Demonstrates using the SPA06_003 sensor with Adafruit's Unified Sensor + * interface. This example shows how to get sensor information and read values + * using the standardized Adafruit Sensor API, which allows easy integration + * with other sensor libraries and data logging systems. * * The begin() function automatically configures the sensor for: * - Highest precision (128x oversampling) @@ -34,21 +34,24 @@ Adafruit_Sensor *spa_pressure; void setup() { Serial.begin(115200); - while (!Serial) delay(10); // will pause Zero, Leonardo, etc until serial console opens + while (!Serial) + delay(10); // will pause Zero, Leonardo, etc until serial console opens Serial.println("Adafruit SPA06_003 Unified Sensor API Test"); // Try to initialize the sensor if (!spa.begin()) { Serial.println("Failed to find SPA06_003 chip"); - while (1) { delay(10); } + while (1) { + delay(10); + } } Serial.println("SPA06_003 Found!"); - + // Get sensor objects for temperature and pressure spa_temp = spa.getTemperatureSensor(); spa_pressure = spa.getPressureSensor(); - + // Print sensor details printSensorDetails(); } @@ -61,47 +64,65 @@ void loop() { Serial.print(temp_event.temperature); Serial.print(" °C"); } - - // Read pressure using unified sensor interface + + // Read pressure using unified sensor interface sensors_event_t pressure_event; if (spa_pressure->getEvent(&pressure_event)) { Serial.print("\tPressure: "); Serial.print(pressure_event.pressure); Serial.print(" hPa"); - + Serial.print("\tTimestamp: "); Serial.println(pressure_event.timestamp); } - + delay(500); // Wait 500ms between readings } void printSensorDetails() { Serial.println("------------------------------------"); - + // Print temperature sensor details sensor_t sensor; spa_temp->getSensor(&sensor); Serial.println("Temperature Sensor:"); - Serial.print(" Sensor Type: "); Serial.println(sensor.name); - Serial.print(" Driver Ver: "); Serial.println(sensor.version); - Serial.print(" Unique ID: "); Serial.println(sensor.sensor_id); - Serial.print(" Max Value: "); Serial.print(sensor.max_value); Serial.println(" °C"); - Serial.print(" Min Value: "); Serial.print(sensor.min_value); Serial.println(" °C"); - Serial.print(" Resolution: "); Serial.print(sensor.resolution); Serial.println(" °C"); + Serial.print(" Sensor Type: "); + Serial.println(sensor.name); + Serial.print(" Driver Ver: "); + Serial.println(sensor.version); + Serial.print(" Unique ID: "); + Serial.println(sensor.sensor_id); + Serial.print(" Max Value: "); + Serial.print(sensor.max_value); + Serial.println(" °C"); + Serial.print(" Min Value: "); + Serial.print(sensor.min_value); + Serial.println(" °C"); + Serial.print(" Resolution: "); + Serial.print(sensor.resolution); + Serial.println(" °C"); Serial.println(""); // Print pressure sensor details spa_pressure->getSensor(&sensor); Serial.println("Pressure Sensor:"); - Serial.print(" Sensor Type: "); Serial.println(sensor.name); - Serial.print(" Driver Ver: "); Serial.println(sensor.version); - Serial.print(" Unique ID: "); Serial.println(sensor.sensor_id); - Serial.print(" Max Value: "); Serial.print(sensor.max_value); Serial.println(" hPa"); - Serial.print(" Min Value: "); Serial.print(sensor.min_value); Serial.println(" hPa"); - Serial.print(" Resolution: "); Serial.print(sensor.resolution); Serial.println(" hPa"); + Serial.print(" Sensor Type: "); + Serial.println(sensor.name); + Serial.print(" Driver Ver: "); + Serial.println(sensor.version); + Serial.print(" Unique ID: "); + Serial.println(sensor.sensor_id); + Serial.print(" Max Value: "); + Serial.print(sensor.max_value); + Serial.println(" hPa"); + Serial.print(" Min Value: "); + Serial.print(sensor.min_value); + Serial.println(" hPa"); + Serial.print(" Resolution: "); + Serial.print(sensor.resolution); + Serial.println(" hPa"); Serial.println(""); - + Serial.println("------------------------------------"); Serial.println(""); } \ No newline at end of file diff --git a/examples/simpletest/simpletest.ino b/examples/simpletest/simpletest.ino index 82fcaa7..a396171 100644 --- a/examples/simpletest/simpletest.ino +++ b/examples/simpletest/simpletest.ino @@ -3,9 +3,9 @@ * * A simple test for the SPA06_003 pressure and temperature sensor. * This example shows basic pressure and temperature readings using the sensor. - * + * * The begin() function automatically configures the sensor for: - * - Highest precision (128x oversampling) + * - Highest precision (128x oversampling) * - Highest sample rate (200 Hz) * - Continuous measurement mode * @@ -26,14 +26,17 @@ Adafruit_SPA06_003 spa; void setup() { Serial.begin(115200); - while (!Serial) delay(10); // will pause Zero, Leonardo, etc until serial console opens + while (!Serial) + delay(10); // will pause Zero, Leonardo, etc until serial console opens Serial.println("Adafruit SPA06_003 Simple Test"); // Try to initialize! if (!spa.begin()) { Serial.println("Failed to find SPA06_003 chip"); - while (1) { delay(10); } + while (1) { + delay(10); + } } Serial.println("SPA06_003 Found!"); } @@ -43,15 +46,15 @@ void loop() { if (spa.isTempDataReady() || spa.isPresDataReady()) { float temperature = spa.readTemperature(); float pressure = spa.readPressure(); - + Serial.print("Temperature: "); Serial.print(temperature); Serial.print(" °C"); - + Serial.print("\tPressure: "); Serial.print(pressure); Serial.println(" hPa"); } - + delay(10); // Short delay to avoid overwhelming the sensor } \ No newline at end of file diff --git a/examples/spi_test/spi_test.ino b/examples/spi_test/spi_test.ino index d2bcd88..920af62 100644 --- a/examples/spi_test/spi_test.ino +++ b/examples/spi_test/spi_test.ino @@ -35,7 +35,8 @@ Adafruit_SPA06_003 spa; void setup() { Serial.begin(115200); - while (!Serial) delay(10); // will pause Zero, Leonardo, etc until serial console opens + while (!Serial) + delay(10); // will pause Zero, Leonardo, etc until serial console opens Serial.println("Adafruit SPA06_003 SPI Test"); @@ -44,10 +45,20 @@ void setup() { if (!spa.begin(SPA_CS_PIN, &SPI)) { Serial.println("Failed to find SPA06_003 chip via hardware SPI"); Serial.println("Check wiring and try software SPI example"); - while (1) { delay(10); } + while (1) { + delay(10); + } } Serial.println("SPA06_003 Found via Hardware SPI!"); + // Alternative: Software SPI (uncomment to use instead of hardware SPI) + // Default ATmega328 pins: MOSI=11, MISO=12, SCK=13, CS=10 + // if (!spa.begin(10, 11, 12, 13)) { + // Serial.println("Failed to find SPA06_003 chip via software SPI"); + // while (1) { delay(10); } + // } + // Serial.println("SPA06_003 Found via Software SPI!"); + Serial.println("Starting continuous measurement..."); Serial.println("Temperature and pressure readings:"); Serial.println("Format: Temp (°C) | Pressure (hPa)"); @@ -62,7 +73,7 @@ void loop() { Serial.print(" °C"); } - // Check if new pressure data is available + // Check if new pressure data is available if (spa.isPresDataReady()) { float pressure = spa.readPressure(); Serial.print(" | ");