mirror of
https://github.com/airgradienthq/arduino.git
synced 2025-06-28 17:20:57 +02:00
Compare commits
1 Commits
Author | SHA1 | Date | |
---|---|---|---|
90eee5d17f |
122
AirGradient.cpp
122
AirGradient.cpp
@ -105,7 +105,7 @@ int AirGradient::getPM2_Raw(){
|
|||||||
pm02 = data.PM_AE_UG_2_5;
|
pm02 = data.PM_AE_UG_2_5;
|
||||||
return pm02;
|
return pm02;
|
||||||
} else {
|
} else {
|
||||||
return 0;
|
return -1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -589,45 +589,109 @@ void AirGradient::CO2_Init(int rx_pin,int tx_pin,int baudRate){
|
|||||||
delay(10000);
|
delay(10000);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
const char* AirGradient::getCO2(int retryLimit) {
|
//const char* AirGradient::getCO2(int retryLimit) {
|
||||||
int ctr = 0;
|
// int ctr = 0;
|
||||||
int result_CO2 = getCO2_Raw();
|
// int result_CO2 = getCO2_Raw();
|
||||||
while(result_CO2 == -1){
|
// while(result_CO2 == -1){
|
||||||
result_CO2 = getCO2_Raw();
|
// result_CO2 = getCO2_Raw();
|
||||||
if((ctr == retryLimit) || (result_CO2 == -1)){
|
// if((ctr == retryLimit) || (result_CO2 == -1)){
|
||||||
Char_CO2[0] = 'N';
|
// Char_CO2[0] = 'N';
|
||||||
Char_CO2[1] = 'U';
|
// Char_CO2[1] = 'U';
|
||||||
Char_CO2[2] = 'L';
|
// Char_CO2[2] = 'L';
|
||||||
Char_CO2[3] = 'L';
|
// Char_CO2[3] = 'L';
|
||||||
return Char_CO2;
|
// return Char_CO2;
|
||||||
|
// }
|
||||||
|
// ctr++;
|
||||||
|
// }
|
||||||
|
// sprintf(Char_CO2,"%d", result_CO2);
|
||||||
|
// return Char_CO2;
|
||||||
|
//}
|
||||||
|
|
||||||
|
|
||||||
|
//int AirGradient::getCO2_Raw(){
|
||||||
|
// const byte CO2Command[] = {0xFE, 0X44, 0X00, 0X08, 0X02, 0X9F, 0X25};
|
||||||
|
// byte CO2Response[] = {0,0,0,0,0,0,0};
|
||||||
|
//
|
||||||
|
// _SoftSerial_CO2->write(CO2Command, 7);
|
||||||
|
// delay(100); //give the sensor a bit of time to respond
|
||||||
|
//
|
||||||
|
// if (_SoftSerial_CO2->available()){
|
||||||
|
// for (int i=0; i < 7; i++) {
|
||||||
|
// int byte = _SoftSerial_CO2->read();
|
||||||
|
// CO2Response[i] = byte;
|
||||||
|
// if (CO2Response[0] != 254) {
|
||||||
|
// return -1; //error code for debugging
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// unsigned long val = CO2Response[3]*256 + CO2Response[4];
|
||||||
|
// return val;
|
||||||
|
// }
|
||||||
|
// else
|
||||||
|
// {
|
||||||
|
// return -2; //error code for debugging
|
||||||
|
// }
|
||||||
|
//}
|
||||||
|
|
||||||
|
int AirGradient::getCO2(int numberOfSamplesToTake) {
|
||||||
|
int successfulSamplesCounter = 0;
|
||||||
|
int co2AsPpmSum = 0;
|
||||||
|
for (int sample = 0; sample < numberOfSamplesToTake; sample++) {
|
||||||
|
int co2AsPpm = getCO2_Raw();
|
||||||
|
if (co2AsPpm > 300 && co2AsPpm < 10000) {
|
||||||
|
Serial.println("CO2 read success " + String(co2AsPpm));
|
||||||
|
successfulSamplesCounter++;
|
||||||
|
co2AsPpmSum += co2AsPpm;
|
||||||
|
} else {
|
||||||
|
Serial.println("CO2 read failed with " + String(co2AsPpm));
|
||||||
}
|
}
|
||||||
ctr++;
|
|
||||||
|
// without delay we get a few 10ms spacing, add some more
|
||||||
|
delay(250);
|
||||||
}
|
}
|
||||||
sprintf(Char_CO2,"%d", result_CO2);
|
|
||||||
return Char_CO2;
|
if (successfulSamplesCounter <= 0) {
|
||||||
|
// total failure
|
||||||
|
return -5;
|
||||||
|
}
|
||||||
|
Serial.println("# of CO2 reads that worked: " + String(successfulSamplesCounter));
|
||||||
|
Serial.println("CO2 reads sum " + String(co2AsPpmSum));
|
||||||
|
return co2AsPpmSum / successfulSamplesCounter;
|
||||||
}
|
}
|
||||||
int AirGradient::getCO2_Raw(){
|
|
||||||
|
// <<>>
|
||||||
|
int AirGradient::getCO2_Raw() {
|
||||||
|
|
||||||
|
while(_SoftSerial_CO2->available()) // flush whatever we might have
|
||||||
|
_SoftSerial_CO2->read();
|
||||||
|
|
||||||
const byte CO2Command[] = {0xFE, 0X44, 0X00, 0X08, 0X02, 0X9F, 0X25};
|
const byte CO2Command[] = {0xFE, 0X44, 0X00, 0X08, 0X02, 0X9F, 0X25};
|
||||||
byte CO2Response[] = {0,0,0,0,0,0,0};
|
byte CO2Response[] = {0,0,0,0,0,0,0};
|
||||||
|
|
||||||
_SoftSerial_CO2->write(CO2Command, 7);
|
const int commandSize = 7;
|
||||||
delay(100); //give the sensor a bit of time to respond
|
|
||||||
|
|
||||||
if (_SoftSerial_CO2->available()){
|
int numberOfBytesWritten = _SoftSerial_CO2->write(CO2Command, commandSize);
|
||||||
for (int i=0; i < 7; i++) {
|
|
||||||
int byte = _SoftSerial_CO2->read();
|
if (numberOfBytesWritten != commandSize) {
|
||||||
CO2Response[i] = byte;
|
// failed to write request
|
||||||
if (CO2Response[0] != 254) {
|
return -2;
|
||||||
return -1; //error code for debugging
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// attempt to read response
|
||||||
|
int timeoutCounter = 0;
|
||||||
|
while (_SoftSerial_CO2->available() < commandSize) {
|
||||||
|
timeoutCounter++;
|
||||||
|
if (timeoutCounter > 10) {
|
||||||
|
// timeout when reading response
|
||||||
|
return -3;
|
||||||
}
|
}
|
||||||
unsigned long val = CO2Response[3]*256 + CO2Response[4];
|
delay(50);
|
||||||
return val;
|
|
||||||
}
|
}
|
||||||
else
|
|
||||||
{
|
// we have 7 bytes ready to be read
|
||||||
return -2; //error code for debugging
|
for (int i=0; i < commandSize; i++) {
|
||||||
|
CO2Response[i] = _SoftSerial_CO2->read();
|
||||||
}
|
}
|
||||||
|
return CO2Response[3]*256 + CO2Response[4];
|
||||||
}
|
}
|
||||||
|
|
||||||
//END CO2 FUNCTIONS //
|
//END CO2 FUNCTIONS //
|
||||||
|
@ -223,7 +223,7 @@ class AirGradient
|
|||||||
void CO2_Init();
|
void CO2_Init();
|
||||||
void CO2_Init(int,int);
|
void CO2_Init(int,int);
|
||||||
void CO2_Init(int,int,int);
|
void CO2_Init(int,int,int);
|
||||||
const char* getCO2(int retryLimit = 5);
|
int getCO2(int numberOfSamplesToTake = 5);
|
||||||
int getCO2_Raw();
|
int getCO2_Raw();
|
||||||
SoftwareSerial *_SoftSerial_CO2;
|
SoftwareSerial *_SoftSerial_CO2;
|
||||||
|
|
||||||
|
@ -24,7 +24,7 @@ MIT License
|
|||||||
AirGradient ag = AirGradient();
|
AirGradient ag = AirGradient();
|
||||||
|
|
||||||
void setup(){
|
void setup(){
|
||||||
Serial.begin(9600);
|
Serial.begin(115200);
|
||||||
ag.CO2_Init();
|
ag.CO2_Init();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -55,7 +55,7 @@ Adafruit_NeoMatrix matrix = Adafruit_NeoMatrix(8, 8, PIN,
|
|||||||
NEO_GRB + NEO_KHZ800);
|
NEO_GRB + NEO_KHZ800);
|
||||||
|
|
||||||
void setup() {
|
void setup() {
|
||||||
Serial.begin(9600);
|
Serial.begin(115200);
|
||||||
ag.CO2_Init();
|
ag.CO2_Init();
|
||||||
matrix.begin();
|
matrix.begin();
|
||||||
matrix.setRotation(1); // change rotation
|
matrix.setRotation(1); // change rotation
|
||||||
|
@ -9,7 +9,7 @@ Kits (including a pre-soldered version) are available: https://www.airgradient.c
|
|||||||
|
|
||||||
The codes needs the following libraries installed:
|
The codes needs the following libraries installed:
|
||||||
“WifiManager by tzapu, tablatronix” tested with version 2.0.11-beta
|
“WifiManager by tzapu, tablatronix” tested with version 2.0.11-beta
|
||||||
“U8g2” by oliver tested with version 2.32.15
|
"ESP8266 and ESP32 OLED driver for SSD1306 displays by ThingPulse, Fabrice Weinberg" tested with Version 4.1.0
|
||||||
|
|
||||||
Configuration:
|
Configuration:
|
||||||
Please set in the code below the configuration parameters.
|
Please set in the code below the configuration parameters.
|
||||||
|
@ -53,7 +53,7 @@ boolean connectWIFI=true;
|
|||||||
String APIROOT = "http://hw.airgradient.com/";
|
String APIROOT = "http://hw.airgradient.com/";
|
||||||
|
|
||||||
void setup(){
|
void setup(){
|
||||||
Serial.begin(9600);
|
Serial.begin(115200);
|
||||||
|
|
||||||
display.init();
|
display.init();
|
||||||
display.flipScreenVertically();
|
display.flipScreenVertically();
|
||||||
|
@ -36,7 +36,7 @@ MIT License
|
|||||||
#include <U8g2lib.h>
|
#include <U8g2lib.h>
|
||||||
|
|
||||||
AirGradient ag = AirGradient();
|
AirGradient ag = AirGradient();
|
||||||
DFRobot_SGP40 mySgp40;
|
DFRobot_SGP40 sgp40;
|
||||||
|
|
||||||
// Display bottom right
|
// Display bottom right
|
||||||
U8G2_SH1106_128X64_NONAME_F_HW_I2C u8g2(U8G2_R0, /* reset=*/ U8X8_PIN_NONE);
|
U8G2_SH1106_128X64_NONAME_F_HW_I2C u8g2(U8G2_R0, /* reset=*/ U8X8_PIN_NONE);
|
||||||
@ -96,12 +96,7 @@ void setup()
|
|||||||
}
|
}
|
||||||
|
|
||||||
updateOLED2("Warming up the", "sensors.", "");
|
updateOLED2("Warming up the", "sensors.", "");
|
||||||
|
sgp40.begin();
|
||||||
while(mySgp40.begin(/*duration = */10000) !=true){
|
|
||||||
Serial.println("failed to init chip, please check if the chip connection is fine");
|
|
||||||
delay(1000);
|
|
||||||
}
|
|
||||||
|
|
||||||
ag.CO2_Init();
|
ag.CO2_Init();
|
||||||
ag.PMS_Init();
|
ag.PMS_Init();
|
||||||
ag.TMP_RH_Init(0x44);
|
ag.TMP_RH_Init(0x44);
|
||||||
@ -123,7 +118,7 @@ void updateTVOC()
|
|||||||
{
|
{
|
||||||
if (currentMillis - previousTVOC >= tvocInterval) {
|
if (currentMillis - previousTVOC >= tvocInterval) {
|
||||||
previousTVOC += tvocInterval;
|
previousTVOC += tvocInterval;
|
||||||
TVOC = mySgp40.getVoclndex();
|
TVOC = sgp40.getVoclndex();
|
||||||
Serial.println(String(TVOC));
|
Serial.println(String(TVOC));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -148,7 +143,6 @@ void updatePm25()
|
|||||||
|
|
||||||
void updateTempHum()
|
void updateTempHum()
|
||||||
{
|
{
|
||||||
|
|
||||||
if (currentMillis - previousTempHum >= tempHumInterval) {
|
if (currentMillis - previousTempHum >= tempHumInterval) {
|
||||||
previousTempHum += tempHumInterval;
|
previousTempHum += tempHumInterval;
|
||||||
TMP_RH result = ag.periodicFetchData();
|
TMP_RH result = ag.periodicFetchData();
|
||||||
|
@ -25,7 +25,7 @@ MIT License
|
|||||||
AirGradient ag = AirGradient();
|
AirGradient ag = AirGradient();
|
||||||
|
|
||||||
void setup() {
|
void setup() {
|
||||||
Serial.begin(9600);
|
Serial.begin(115200);
|
||||||
ag.PMS_Init();
|
ag.PMS_Init();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -24,7 +24,7 @@ MIT License
|
|||||||
AirGradient ag = AirGradient();
|
AirGradient ag = AirGradient();
|
||||||
|
|
||||||
void setup(){
|
void setup(){
|
||||||
Serial.begin(9600);
|
Serial.begin(115200);
|
||||||
ag.TMP_RH_Init(0x44); //check for SHT sensor with address 0x44
|
ag.TMP_RH_Init(0x44); //check for SHT sensor with address 0x44
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,9 +1,9 @@
|
|||||||
name=AirGradient Air Quality Sensor
|
name=AirGradient Air Quality Sensor
|
||||||
version=2.0.2
|
version=2.1.0
|
||||||
author=AirGradient <support@airgradient.com>
|
author=AirGradient <support@airgradient.com>
|
||||||
maintainer=AirGradient <support@airgradient.com>
|
maintainer=AirGradient <support@airgradient.com>
|
||||||
sentence=ESP8266 library for an air quality sensor featuring PM2.5, CO2, Temperature, TVOC and Humidity with OLED display.
|
sentence=ESP8266 library for an air quality sensor featuring PM2.5, CO2, Temperature, TVOC and Humidity with OLED display.
|
||||||
paragraph=Air quality monitoring library supporting the Plantower PMS5003 particle sensor, the Senseair S8 CO2 sensor and the SHT30/31 sensor for humidity and temperature. Kits with all components including a nice enclosure are available in our online shop. You can also connect an OLED display or send the air quality data to the AirGradient platform or any other backend. Optionally you can connect the Sensirion SGP40 TVOC module from AirGradient.
|
paragraph=Air quality monitoring library supporting the Plantower PMS5003 particle sensor, the Senseair S8 CO2 sensor and the SHT30/31 sensor for humidity and temperature. Kits with all components including a nice enclosure are available in our online shop. You can also connect an OLED display or send the air quality data to the AirGradient platform or any other backend. Optionally you can connect the Sensirion SGP4x TVOC module from AirGradient.
|
||||||
category=Sensors
|
category=Sensors
|
||||||
url=https://www.airgradient.com/open-airgradient/instructions/
|
url=https://www.airgradient.com/open-airgradient/instructions/
|
||||||
architectures=*
|
architectures=*
|
||||||
|
Reference in New Issue
Block a user