From 91bb66678f476927f96277ed47f78f423852e85e Mon Sep 17 00:00:00 2001 From: brentru Date: Tue, 14 Nov 2023 15:17:35 -0500 Subject: [PATCH 01/10] add compatability and detection for Cubic PM1006 sensor --- Adafruit_PM25AQI.cpp | 82 ++++++++++++++++++++++++++++++++------------ 1 file changed, 61 insertions(+), 21 deletions(-) diff --git a/Adafruit_PM25AQI.cpp b/Adafruit_PM25AQI.cpp index a6aee3b..93084cb 100644 --- a/Adafruit_PM25AQI.cpp +++ b/Adafruit_PM25AQI.cpp @@ -70,6 +70,8 @@ bool Adafruit_PM25AQI::begin_UART(Stream *theSerial) { bool Adafruit_PM25AQI::read(PM25_AQI_Data *data) { uint8_t buffer[32]; uint16_t sum = 0; + bool is_pm1006 = false; + uint8_t bufLen = 32; if (!data) { return false; @@ -84,48 +86,86 @@ bool Adafruit_PM25AQI::read(PM25_AQI_Data *data) { return false; } int skipped = 0; - while ((skipped < 32) && (serial_dev->peek() != 0x42)) { + // Find the start character in the stream (0x42 for Adafruit PM sensors, + // 0x16 for the Cubic PM1006) + while ((skipped < 32) && (serial_dev->peek() != 0x42) && + (serial_dev->peek != 0x16)) { serial_dev->read(); skipped++; if (!serial_dev->available()) { return false; } } - if (serial_dev->peek() != 0x42) { + // Check for the start character in the stream + if ((serial_dev->peek() != 0x42) || (serial_dev->peek() != 0x16)) { serial_dev->read(); - return false; + return false; // We did not find the start character } - // Now read all 32 bytes - if (serial_dev->available() < 32) { - return false; + // Are we using the PM1006? + if (serial_dev->peek() == 0x16) { + is_pm1006 = true; + } + + // TODO: Can we do the check above in here instead to optimize? + if (!is_pm1006) { + // Start character was found, now read all 32 bytes + if (serial_dev->available() < 32) { + return false; + } + serial_dev->readBytes(buffer, 32); + } else { + // Start character was found, now read 20 bytes + // Note: PM1006 only requires 20 bytes, but we will ignore the last 12 + // bytes when parsing + if (serial_dev->available() < 20) { + return false; + } + serial_dev->readBytes(buffer, 20); } - serial_dev->readBytes(buffer, 32); } else { return false; } - // Check that start byte is correct! - if (buffer[0] != 0x42) { + // Validate start byte is correct for Adafruit PM sensors + if ((!is_pm1006 && buffer[0] != 0x42)) { return false; } - // get checksum ready - for (uint8_t i = 0; i < 30; i++) { - sum += buffer[i]; + // Validate start header is correct for Cubic PM1006 + if (is_pm1006 && + (buffer[0] != 0x16 || buffer[1] != 0x11 || buffer[2] != 0x0B)) { + return false; } - // The data comes in endian'd, this solves it so it works on all platforms - uint16_t buffer_u16[15]; - for (uint8_t i = 0; i < 15; i++) { - buffer_u16[i] = buffer[2 + i * 2 + 1]; - buffer_u16[i] += (buffer[2 + i * 2] << 8); + // TODO: Could we make this better? + if (is_pm1006) { + bufLen = 20; } - // put it into a nice struct :) - memcpy((void *)data, (void *)buffer_u16, 30); + // Calculate the checksum + for (uint8_t i = 0; i < bufLen; i++) { + sum += buffer[i]; + } + // Validate checksum + if ((is_pm1006 && sum != 0) || (!is_pm1006 && sum != data->checksum)) { + return false; // Invalid checksum + } - if (sum != data->checksum) { - return false; + // Since header and checksum are OK, parse data from the buffer + if (!is_pm1006) { + // The data comes in endian'd, this solves it so it works on all platforms + uint16_t buffer_u16[15]; + for (uint8_t i = 0; i < 15; i++) { + buffer_u16[i] = buffer[2 + i * 2 + 1]; + buffer_u16[i] += (buffer[2 + i * 2] << 8); + } + // put it into a nice struct :) + memcpy((void *)data, (void *)buffer_u16, 30); + } else { + // Parse from PM1006 + // NOTE: PM1006 only produces a pm25_env reading! + data.pm25_env = (serialRxBuf[5] << 8) | serialRxBuf[6]; + data.checksum = sum; } // success! From beea9524346093005e2a64cc36551ac0f8a7b161 Mon Sep 17 00:00:00 2001 From: brentru Date: Tue, 14 Nov 2023 18:31:43 -0500 Subject: [PATCH 02/10] instrumentation on read loop --- Adafruit_PM25AQI.cpp | 18 +++++++++++++++--- 1 file changed, 15 insertions(+), 3 deletions(-) diff --git a/Adafruit_PM25AQI.cpp b/Adafruit_PM25AQI.cpp index 93084cb..a99a448 100644 --- a/Adafruit_PM25AQI.cpp +++ b/Adafruit_PM25AQI.cpp @@ -88,25 +88,35 @@ bool Adafruit_PM25AQI::read(PM25_AQI_Data *data) { int skipped = 0; // Find the start character in the stream (0x42 for Adafruit PM sensors, // 0x16 for the Cubic PM1006) + Serial.println("L91"); while ((skipped < 32) && (serial_dev->peek() != 0x42) && - (serial_dev->peek != 0x16)) { + (serial_dev->peek() != 0x16)) { serial_dev->read(); + Serial.print("peek L94: "); + Serial.println(serial_dev->peek()); + delay(15); skipped++; if (!serial_dev->available()) { return false; } } // Check for the start character in the stream + Serial.println("Checking for start character in stream"); if ((serial_dev->peek() != 0x42) || (serial_dev->peek() != 0x16)) { + Serial.println("ERROR: Did not find start character in stream!"); + Serial.println(serial_dev->peek()); serial_dev->read(); + delay(15); return false; // We did not find the start character } // Are we using the PM1006? + Serial.println("Checking for PM1006"); if (serial_dev->peek() == 0x16) { is_pm1006 = true; } // TODO: Can we do the check above in here instead to optimize? + Serial.println("Reading all bytes"); if (!is_pm1006) { // Start character was found, now read all 32 bytes if (serial_dev->available() < 32) { @@ -120,12 +130,14 @@ bool Adafruit_PM25AQI::read(PM25_AQI_Data *data) { if (serial_dev->available() < 20) { return false; } + Serial.println("reading pm1006 all bytes"); serial_dev->readBytes(buffer, 20); } } else { return false; } + Serial.println("Validating start bytes"); // Validate start byte is correct for Adafruit PM sensors if ((!is_pm1006 && buffer[0] != 0x42)) { return false; @@ -164,8 +176,8 @@ bool Adafruit_PM25AQI::read(PM25_AQI_Data *data) { } else { // Parse from PM1006 // NOTE: PM1006 only produces a pm25_env reading! - data.pm25_env = (serialRxBuf[5] << 8) | serialRxBuf[6]; - data.checksum = sum; + data->pm25_env = (buffer[5] << 8) | buffer[6]; + data->checksum = sum; } // success! From 3b7def6903264921db364114476b3359952e22c8 Mon Sep 17 00:00:00 2001 From: brentru Date: Tue, 14 Nov 2023 19:20:36 -0500 Subject: [PATCH 03/10] remove instrumentation, working code for PM1006 --- Adafruit_PM25AQI.cpp | 30 ++++++--------- examples/PM1006_test/PM1006_test.ino | 57 ++++++++++++++++++++++++++++ 2 files changed, 69 insertions(+), 18 deletions(-) create mode 100644 examples/PM1006_test/PM1006_test.ino diff --git a/Adafruit_PM25AQI.cpp b/Adafruit_PM25AQI.cpp index a99a448..85e10d2 100644 --- a/Adafruit_PM25AQI.cpp +++ b/Adafruit_PM25AQI.cpp @@ -85,32 +85,24 @@ bool Adafruit_PM25AQI::read(PM25_AQI_Data *data) { if (!serial_dev->available()) { return false; } - int skipped = 0; // Find the start character in the stream (0x42 for Adafruit PM sensors, // 0x16 for the Cubic PM1006) - Serial.println("L91"); - while ((skipped < 32) && (serial_dev->peek() != 0x42) && - (serial_dev->peek() != 0x16)) { - serial_dev->read(); - Serial.print("peek L94: "); - Serial.println(serial_dev->peek()); - delay(15); + // TODO: Put back check for cubic! + int skipped = 0; + while ((skipped < 20) && (serial_dev->peek() != 0x16)) { + Serial.println(serial_dev->read()); skipped++; if (!serial_dev->available()) { return false; } } + // Check for the start character in the stream - Serial.println("Checking for start character in stream"); - if ((serial_dev->peek() != 0x42) || (serial_dev->peek() != 0x16)) { - Serial.println("ERROR: Did not find start character in stream!"); - Serial.println(serial_dev->peek()); + if ((serial_dev->peek() != 0x16)) { serial_dev->read(); - delay(15); return false; // We did not find the start character } // Are we using the PM1006? - Serial.println("Checking for PM1006"); if (serial_dev->peek() == 0x16) { is_pm1006 = true; } @@ -130,7 +122,6 @@ bool Adafruit_PM25AQI::read(PM25_AQI_Data *data) { if (serial_dev->available() < 20) { return false; } - Serial.println("reading pm1006 all bytes"); serial_dev->readBytes(buffer, 20); } } else { @@ -154,12 +145,15 @@ bool Adafruit_PM25AQI::read(PM25_AQI_Data *data) { bufLen = 20; } - // Calculate the checksum + // Calculate checksum + // TODO: This is only for PM1006, the PM25 sensor uses int for sum! + uint8_t csum = 0; for (uint8_t i = 0; i < bufLen; i++) { - sum += buffer[i]; + csum += buffer[i]; } + // Validate checksum - if ((is_pm1006 && sum != 0) || (!is_pm1006 && sum != data->checksum)) { + if ((is_pm1006 && csum != 0) || (!is_pm1006 && sum != data->checksum)) { return false; // Invalid checksum } diff --git a/examples/PM1006_test/PM1006_test.ino b/examples/PM1006_test/PM1006_test.ino new file mode 100644 index 0000000..5a93f8f --- /dev/null +++ b/examples/PM1006_test/PM1006_test.ino @@ -0,0 +1,57 @@ +/* Test sketch for Adafruit PM2.5 sensor with UART or I2C */ + +#include "Adafruit_PM25AQI.h" + +// If your PM2.5 is UART only, for UNO and others (without hardware serial) +// we must use software serial... +// pin #2 is IN from sensor (TX pin on sensor), leave pin #3 disconnected +// comment these two lines if using hardware serial +//#include +//SoftwareSerial pmSerial(2, 3); + +Adafruit_PM25AQI aqi = Adafruit_PM25AQI(); + +void setup() { + // Wait for serial monitor to open + Serial.begin(115200); + while (!Serial) delay(10); + + Serial.println("Cubic PM1006 Air Quality Sensor"); + + // Wait one second for sensor to boot up! + delay(1000); + + // If using serial, initialize it and set baudrate before starting! + // Uncomment one of the following + Serial1.begin(9600); + //pmSerial.begin(9600); + + if (! aqi.begin_UART(&Serial1)) { // connect to the sensor over hardware serial + //if (! aqi.begin_UART(&pmSerial)) { // connect to the sensor over software serial + Serial.println("Could not find PM 2.5 sensor!"); + while (1) delay(10); + } + + Serial.println("PM25 found!"); +} + +void loop() { + PM25_AQI_Data data; + + if (! aqi.read(&data)) { + Serial.println("Could not read from AQI"); + delay(500); // try again in a bit! + return; + } + Serial.println("AQI reading success"); + + Serial.println(); + Serial.println(F("---------------------------------------")); + Serial.println(F("Concentration Units (environmental)")); + Serial.println(F("---------------------------------------")); + Serial.print(F("PM 1.0: ")); Serial.print(data.pm25_env); + Serial.println(F("---------------------------------------")); + + + delay(1000); +} From d50dd9e54a5eb85c77f02c9b9650763ad3d572af Mon Sep 17 00:00:00 2001 From: brentru Date: Wed, 15 Nov 2023 12:11:31 -0500 Subject: [PATCH 04/10] refactor the read bytes procedure --- Adafruit_PM25AQI.cpp | 52 ++++++++++++++++++-------------------------- 1 file changed, 21 insertions(+), 31 deletions(-) diff --git a/Adafruit_PM25AQI.cpp b/Adafruit_PM25AQI.cpp index 85e10d2..b5e4561 100644 --- a/Adafruit_PM25AQI.cpp +++ b/Adafruit_PM25AQI.cpp @@ -69,9 +69,9 @@ bool Adafruit_PM25AQI::begin_UART(Stream *theSerial) { */ bool Adafruit_PM25AQI::read(PM25_AQI_Data *data) { uint8_t buffer[32]; + size_t bufLen = sizeof(buffer); uint16_t sum = 0; bool is_pm1006 = false; - uint8_t bufLen = 32; if (!data) { return false; @@ -85,50 +85,46 @@ bool Adafruit_PM25AQI::read(PM25_AQI_Data *data) { if (!serial_dev->available()) { return false; } + // TODO: Test compatibilituy with adafruit pm25 uart sensor + // TOOD: Test with adafruit pm25 i2c sensor + // TODO: Test with cubic pm1006 sensor + + // TODO: go back and re-read all this code + // Find the start character in the stream (0x42 for Adafruit PM sensors, // 0x16 for the Cubic PM1006) // TODO: Put back check for cubic! int skipped = 0; while ((skipped < 20) && (serial_dev->peek() != 0x16)) { - Serial.println(serial_dev->read()); - skipped++; + serial_dev->read() skipped++; if (!serial_dev->available()) { return false; } } - // Check for the start character in the stream + // Check for the start character in the stream for the Cubic PM1006 + // TODO: put back check for adafruit AQ if ((serial_dev->peek() != 0x16)) { serial_dev->read(); return false; // We did not find the start character } // Are we using the PM1006? if (serial_dev->peek() == 0x16) { - is_pm1006 = true; + is_pm1006 = true; // Set flag + bufLen = 20; // Reduce buffer read length to 20 bytes. Last 12 bytes will + // be ignored. } - // TODO: Can we do the check above in here instead to optimize? - Serial.println("Reading all bytes"); - if (!is_pm1006) { - // Start character was found, now read all 32 bytes - if (serial_dev->available() < 32) { - return false; - } - serial_dev->readBytes(buffer, 32); - } else { - // Start character was found, now read 20 bytes - // Note: PM1006 only requires 20 bytes, but we will ignore the last 12 - // bytes when parsing - if (serial_dev->available() < 20) { - return false; - } - serial_dev->readBytes(buffer, 20); - } + // Are there enough bytes to read from? + if (serial_dev->available() < bufLen) + return false; + // Start character was found, now read the desired amount of bytes + serial_dev->readBytes(buffer, 32); + } else { return false; } - Serial.println("Validating start bytes"); // Validate start byte is correct for Adafruit PM sensors if ((!is_pm1006 && buffer[0] != 0x42)) { return false; @@ -140,11 +136,6 @@ bool Adafruit_PM25AQI::read(PM25_AQI_Data *data) { return false; } - // TODO: Could we make this better? - if (is_pm1006) { - bufLen = 20; - } - // Calculate checksum // TODO: This is only for PM1006, the PM25 sensor uses int for sum! uint8_t csum = 0; @@ -154,7 +145,7 @@ bool Adafruit_PM25AQI::read(PM25_AQI_Data *data) { // Validate checksum if ((is_pm1006 && csum != 0) || (!is_pm1006 && sum != data->checksum)) { - return false; // Invalid checksum + return false; // Invalid checksum! } // Since header and checksum are OK, parse data from the buffer @@ -168,8 +159,7 @@ bool Adafruit_PM25AQI::read(PM25_AQI_Data *data) { // put it into a nice struct :) memcpy((void *)data, (void *)buffer_u16, 30); } else { - // Parse from PM1006 - // NOTE: PM1006 only produces a pm25_env reading! + // Parse from PM1006. This sensor only produces a pm25_env reading! data->pm25_env = (buffer[5] << 8) | buffer[6]; data->checksum = sum; } From 7c001c938b5ace0e97c08a8b251a5e4c60ac8540 Mon Sep 17 00:00:00 2001 From: brentru Date: Wed, 15 Nov 2023 13:52:22 -0500 Subject: [PATCH 05/10] switch between readbytes dynamic read --- Adafruit_PM25AQI.cpp | 46 +++++++++++++++++++++++--------------------- 1 file changed, 24 insertions(+), 22 deletions(-) diff --git a/Adafruit_PM25AQI.cpp b/Adafruit_PM25AQI.cpp index b5e4561..92e6dc5 100644 --- a/Adafruit_PM25AQI.cpp +++ b/Adafruit_PM25AQI.cpp @@ -71,6 +71,7 @@ bool Adafruit_PM25AQI::read(PM25_AQI_Data *data) { uint8_t buffer[32]; size_t bufLen = sizeof(buffer); uint16_t sum = 0; + uint8_t csum = 0; bool is_pm1006 = false; if (!data) { @@ -89,28 +90,25 @@ bool Adafruit_PM25AQI::read(PM25_AQI_Data *data) { // TOOD: Test with adafruit pm25 i2c sensor // TODO: Test with cubic pm1006 sensor - // TODO: go back and re-read all this code - - // Find the start character in the stream (0x42 for Adafruit PM sensors, - // 0x16 for the Cubic PM1006) - // TODO: Put back check for cubic! int skipped = 0; - while ((skipped < 20) && (serial_dev->peek() != 0x16)) { - serial_dev->read() skipped++; + while ((skipped < 32) && (serial_dev->peek() != 0x42) && + (serial_dev->peek() != 0x16)) { + serial_dev->read(); + skipped++; if (!serial_dev->available()) { return false; } } - // Check for the start character in the stream for the Cubic PM1006 - // TODO: put back check for adafruit AQ - if ((serial_dev->peek() != 0x16)) { + // Check for the start character in the stream for both sensors + if ((serial_dev->peek() != 0x42) && (serial_dev->peek() != 0x16)) { serial_dev->read(); return false; // We did not find the start character } - // Are we using the PM1006? + + // Are we using the Cubic PM1006 sensor? if (serial_dev->peek() == 0x16) { - is_pm1006 = true; // Set flag + is_pm1006 = true; // Set flag to indicate we are using the PM1006 bufLen = 20; // Reduce buffer read length to 20 bytes. Last 12 bytes will // be ignored. } @@ -118,34 +116,38 @@ bool Adafruit_PM25AQI::read(PM25_AQI_Data *data) { // Are there enough bytes to read from? if (serial_dev->available() < bufLen) return false; - // Start character was found, now read the desired amount of bytes - serial_dev->readBytes(buffer, 32); + // Read all available bytes from the serial stream + serial_dev->readBytes(buffer, bufLen); } else { return false; } - // Validate start byte is correct for Adafruit PM sensors + // Validate start byte is correct if using Adafruit PM sensors if ((!is_pm1006 && buffer[0] != 0x42)) { return false; } - // Validate start header is correct for Cubic PM1006 + // Validate start header is correct if using Cubic PM1006 sensor if (is_pm1006 && (buffer[0] != 0x16 || buffer[1] != 0x11 || buffer[2] != 0x0B)) { return false; } // Calculate checksum - // TODO: This is only for PM1006, the PM25 sensor uses int for sum! - uint8_t csum = 0; - for (uint8_t i = 0; i < bufLen; i++) { - csum += buffer[i]; + if (!is_pm1006) { + for (uint8_t i = 0; i < 30; i++) { + sum += buffer[i]; + } + } else { + for (uint8_t i = 0; i < bufLen; i++) { + csum += buffer[i]; + } } // Validate checksum if ((is_pm1006 && csum != 0) || (!is_pm1006 && sum != data->checksum)) { - return false; // Invalid checksum! + return false; } // Since header and checksum are OK, parse data from the buffer @@ -159,7 +161,7 @@ bool Adafruit_PM25AQI::read(PM25_AQI_Data *data) { // put it into a nice struct :) memcpy((void *)data, (void *)buffer_u16, 30); } else { - // Parse from PM1006. This sensor only produces a pm25_env reading! + // Cubic PM1006 sensor only produces a pm25_env reading data->pm25_env = (buffer[5] << 8) | buffer[6]; data->checksum = sum; } From 1130b8e6544855616adec54accaea9af0e76b95c Mon Sep 17 00:00:00 2001 From: brentru Date: Wed, 15 Nov 2023 15:10:15 -0500 Subject: [PATCH 06/10] tested with adafruit uart sensor, fix checksum validation issue at the end --- Adafruit_PM25AQI.cpp | 22 ++++++++++------------ 1 file changed, 10 insertions(+), 12 deletions(-) diff --git a/Adafruit_PM25AQI.cpp b/Adafruit_PM25AQI.cpp index 92e6dc5..6f5349f 100644 --- a/Adafruit_PM25AQI.cpp +++ b/Adafruit_PM25AQI.cpp @@ -86,9 +86,6 @@ bool Adafruit_PM25AQI::read(PM25_AQI_Data *data) { if (!serial_dev->available()) { return false; } - // TODO: Test compatibilituy with adafruit pm25 uart sensor - // TOOD: Test with adafruit pm25 i2c sensor - // TODO: Test with cubic pm1006 sensor int skipped = 0; while ((skipped < 32) && (serial_dev->peek() != 0x42) && @@ -103,19 +100,20 @@ bool Adafruit_PM25AQI::read(PM25_AQI_Data *data) { // Check for the start character in the stream for both sensors if ((serial_dev->peek() != 0x42) && (serial_dev->peek() != 0x16)) { serial_dev->read(); - return false; // We did not find the start character + return false; } // Are we using the Cubic PM1006 sensor? if (serial_dev->peek() == 0x16) { is_pm1006 = true; // Set flag to indicate we are using the PM1006 - bufLen = 20; // Reduce buffer read length to 20 bytes. Last 12 bytes will - // be ignored. + bufLen = + 20; // Reduce buffer read length to 20 bytes. Last 12 bytes ignored. } // Are there enough bytes to read from? - if (serial_dev->available() < bufLen) + if (serial_dev->available() < bufLen) { return false; + } // Read all available bytes from the serial stream serial_dev->readBytes(buffer, bufLen); @@ -145,11 +143,6 @@ bool Adafruit_PM25AQI::read(PM25_AQI_Data *data) { } } - // Validate checksum - if ((is_pm1006 && csum != 0) || (!is_pm1006 && sum != data->checksum)) { - return false; - } - // Since header and checksum are OK, parse data from the buffer if (!is_pm1006) { // The data comes in endian'd, this solves it so it works on all platforms @@ -166,6 +159,11 @@ bool Adafruit_PM25AQI::read(PM25_AQI_Data *data) { data->checksum = sum; } + // Validate checksum + if ((is_pm1006 && csum != 0) || (!is_pm1006 && sum != data->checksum)) { + return false; + } + // success! return true; } From 4b889a6e5985939c5ef0219c8caaf22591ec97b3 Mon Sep 17 00:00:00 2001 From: brentru Date: Wed, 15 Nov 2023 15:18:29 -0500 Subject: [PATCH 07/10] update readme.md --- Adafruit_PM25AQI.cpp | 5 ++++- README.md | 2 ++ examples/PM1006_test/PM1006_test.ino | 31 +++++++++++++++++++++------- library.properties | 2 +- 4 files changed, 30 insertions(+), 10 deletions(-) diff --git a/Adafruit_PM25AQI.cpp b/Adafruit_PM25AQI.cpp index 6f5349f..27f2aab 100644 --- a/Adafruit_PM25AQI.cpp +++ b/Adafruit_PM25AQI.cpp @@ -9,6 +9,8 @@ * Arduino platform. It is designed specifically to work with the * Adafruit PM2.5 Air quality sensors: http://www.adafruit.com/products/4632 * + * This library also works with the Cubic PM1006 UART Air Quality Sensor. + * * These sensors use I2C or UART to communicate. * * Adafruit invests time and resources providing this open source code, @@ -18,7 +20,8 @@ * * @section author Author * Written by Ladyada for Adafruit Industries. - * + * Modified by Brent Rubell for Adafruit Industries for use with Cubic PM1006 Air Quality Sensor. + * * @section license License * BSD license, all text here must be included in any redistribution. * diff --git a/README.md b/README.md index 527954a..3a50b4a 100644 --- a/README.md +++ b/README.md @@ -5,6 +5,8 @@ Tested and works great with the Adafruit PM2.5 Air Quality Sensor and Breadboard [](https://www.adafruit.com/products/3686) +This library also works with the Cubic PM1006 air quality sensor present on the [IKEA VINDSTYRKA](https://www.ikea.com/us/en/p/vindriktning-air-quality-sensor-60515911/). Please use the `pm1006_test.ino` sketch to use this sensor. + Adafruit invests time and resources providing this open source code, please support Adafruit and open-source hardware by purchasing products from Adafruit! # Installation diff --git a/examples/PM1006_test/PM1006_test.ino b/examples/PM1006_test/PM1006_test.ino index 5a93f8f..8c0e87a 100644 --- a/examples/PM1006_test/PM1006_test.ino +++ b/examples/PM1006_test/PM1006_test.ino @@ -1,9 +1,24 @@ -/* Test sketch for Adafruit PM2.5 sensor with UART or I2C */ +/**************************************************************************************** + Test sketch for using the Adafruit_PM25AQI library with + the Cubic PM1006 UART Air Quality Sensor. + This sensor is present on the VINDRIKTNING Air Quality sensor, sold by IKEA. + + Check out the guide below for the wiring diagram: + https://learn.adafruit.com/ikea-vindriktning-hack-with-qt-py-esp32-s3-and-adafruit-io + + + 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. + Modified by Brent Rubell for Adafruit Industries + MIT license, all text above must be included in any redistribution + *****************************************************************************************/ #include "Adafruit_PM25AQI.h" -// If your PM2.5 is UART only, for UNO and others (without hardware serial) -// we must use software serial... +// For UNO and others (without hardware serial) we must use software serial... // pin #2 is IN from sensor (TX pin on sensor), leave pin #3 disconnected // comment these two lines if using hardware serial //#include @@ -22,25 +37,25 @@ void setup() { delay(1000); // If using serial, initialize it and set baudrate before starting! - // Uncomment one of the following Serial1.begin(9600); + // Uncomment the following for use with software serial //pmSerial.begin(9600); if (! aqi.begin_UART(&Serial1)) { // connect to the sensor over hardware serial //if (! aqi.begin_UART(&pmSerial)) { // connect to the sensor over software serial - Serial.println("Could not find PM 2.5 sensor!"); + Serial.println("Could not find Cubic PM1006 sensor!"); while (1) delay(10); } - Serial.println("PM25 found!"); + Serial.println("Cubic PM1006 found!"); } void loop() { PM25_AQI_Data data; if (! aqi.read(&data)) { - Serial.println("Could not read from AQI"); - delay(500); // try again in a bit! + Serial.println("Could not read from PM1006 sensor"); + delay(10000); // try again in a bit! return; } Serial.println("AQI reading success"); diff --git a/library.properties b/library.properties index 1bc0d65..13178e7 100644 --- a/library.properties +++ b/library.properties @@ -1,5 +1,5 @@ name=Adafruit PM25 AQI Sensor -version=1.0.6 +version=1.1.0 author=Adafruit maintainer=Adafruit sentence=This is an Arduino library for the Adafruit PM2.5 Air Quality Sensor From 58df02622e6a3bb770869f3b7f5914736f72da5e Mon Sep 17 00:00:00 2001 From: brentru Date: Wed, 15 Nov 2023 17:02:47 -0500 Subject: [PATCH 08/10] add skipfile for uno --- examples/PM1006_test/.uno.test.skip | 1 + 1 file changed, 1 insertion(+) create mode 100644 examples/PM1006_test/.uno.test.skip diff --git a/examples/PM1006_test/.uno.test.skip b/examples/PM1006_test/.uno.test.skip new file mode 100644 index 0000000..8b13789 --- /dev/null +++ b/examples/PM1006_test/.uno.test.skip @@ -0,0 +1 @@ + From 1deff2a8baf9c7ad24c9591476647a33443dc976 Mon Sep 17 00:00:00 2001 From: brentru Date: Wed, 15 Nov 2023 17:09:51 -0500 Subject: [PATCH 09/10] clang --- Adafruit_PM25AQI.cpp | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/Adafruit_PM25AQI.cpp b/Adafruit_PM25AQI.cpp index 27f2aab..010c7d0 100644 --- a/Adafruit_PM25AQI.cpp +++ b/Adafruit_PM25AQI.cpp @@ -10,7 +10,7 @@ * Adafruit PM2.5 Air quality sensors: http://www.adafruit.com/products/4632 * * This library also works with the Cubic PM1006 UART Air Quality Sensor. - * + * * These sensors use I2C or UART to communicate. * * Adafruit invests time and resources providing this open source code, @@ -20,8 +20,9 @@ * * @section author Author * Written by Ladyada for Adafruit Industries. - * Modified by Brent Rubell for Adafruit Industries for use with Cubic PM1006 Air Quality Sensor. - * + * Modified by Brent Rubell for Adafruit Industries for use with Cubic PM1006 + * Air Quality Sensor. + * * @section license License * BSD license, all text here must be included in any redistribution. * From fe11513d63c65065b63ad07baa8b2623ee0e3637 Mon Sep 17 00:00:00 2001 From: brentru Date: Thu, 16 Nov 2023 11:03:17 -0500 Subject: [PATCH 10/10] fix intervals for sampling --- examples/PM1006_test/PM1006_test.ino | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/examples/PM1006_test/PM1006_test.ino b/examples/PM1006_test/PM1006_test.ino index 8c0e87a..26faa11 100644 --- a/examples/PM1006_test/PM1006_test.ino +++ b/examples/PM1006_test/PM1006_test.ino @@ -55,7 +55,7 @@ void loop() { if (! aqi.read(&data)) { Serial.println("Could not read from PM1006 sensor"); - delay(10000); // try again in a bit! + delay(5000); // Sample every 5 seconds return; } Serial.println("AQI reading success"); @@ -66,7 +66,6 @@ void loop() { Serial.println(F("---------------------------------------")); Serial.print(F("PM 1.0: ")); Serial.print(data.pm25_env); Serial.println(F("---------------------------------------")); - - delay(1000); + delay(20000); // Wait 20 seconds and get another reading from the IKEA Vindriktning }