Compare commits

...

11 Commits
1.4.0 ... 2.0.2

Author SHA1 Message Date
d5c8af68a0 Fixed description 2022-10-02 07:59:36 +07:00
3c7180e642 Fixed display rotation and added example for SGP40 2022-10-02 07:38:44 +07:00
ee40b60aad updated documentations 2022-07-29 16:26:06 +02:00
b9a968ef7a added 90 degree rotation code 2022-07-29 11:11:39 +02:00
4bb434562f new examples 2022-06-11 16:18:21 +02:00
ab1f6c1ae7 corrected version number 2022-01-20 14:08:47 +07:00
63c7e9ca00 updated date and version number 2022-01-20 14:06:23 +07:00
0b8408ef13 improved CO2 code (details https://forum.airgradient.com/t/s8-co2-reading-of-1/69/15) 2022-01-20 08:26:27 +07:00
ff34d2c143 changed HTTP Post delay 2021-12-28 07:08:24 +07:00
73498894e4 added traffic light example 2021-12-10 11:12:26 +07:00
ed3b0ff53f corrected library version number 2021-12-08 10:11:45 +07:00
15 changed files with 909 additions and 244 deletions

View File

@ -607,47 +607,27 @@ const char* AirGradient::getCO2(int retryLimit) {
return Char_CO2;
}
int AirGradient::getCO2_Raw(){
int retry = 0;
CO2_READ_RESULT result;
const byte CO2Command[] = {0xFE, 0X44, 0X00, 0X08, 0X02, 0X9F, 0X25};
byte CO2Response[] = {0,0,0,0,0,0,0};
while(!(_SoftSerial_CO2->available())) {
retry++;
// keep sending request until we start to get a response
_SoftSerial_CO2->write(CO2Command, 7);
delay(50);
if (retry > 10) {
return -1;
}
}
int timeout = 0;
while (_SoftSerial_CO2->available() < 7) {
timeout++;
if (timeout > 10) {
while(_SoftSerial_CO2->available())
_SoftSerial_CO2->read();
break;
}
delay(50);
}
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();
if (byte == -1) {
result.success = false;
return -1;
}
CO2Response[i] = byte;
if (CO2Response[0] != 254) {
return -1; //error code for debugging
}
int valMultiplier = 1;
int high = CO2Response[3];
int low = CO2Response[4];
unsigned long val = high*256 + low;
}
unsigned long val = CO2Response[3]*256 + CO2Response[4];
return val;
}
else
{
return -2; //error code for debugging
}
}
//END CO2 FUNCTIONS //

View File

@ -1,6 +1,6 @@
The MIT License (MIT)
Copyright (c) 2020 AirGradient
Copyright (c) 2022 AirGradient
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal

View File

@ -5,4 +5,4 @@ Build your own low cost air quality sensor with optional display measuring PM2.5
This library makes it easy to read the sensor data from the Plantower PMS5003 PM2.5 sensor, the Senseair S8 and the SHT30/31 Temperature and Humidity sensor. Visit our DIY section for detailed build instructions and PCB layout.
https://www.airgradient.com/diy/
https://www.airgradient.com/open-airgradient/instructions/

View File

@ -1,181 +0,0 @@
/*
This is the code for the AirGradient DIY Air Quality Sensor with an ESP8266 Microcontroller.
It is a high quality sensor showing PM2.5, CO2, Temperature and Humidity on a small display and can send data over Wifi.
For build instructions please visit https://www.airgradient.com/diy/
Compatible with the following sensors:
Plantower PMS5003 (Fine Particle Sensor)
SenseAir S8 (CO2 Sensor)
SHT30/31 (Temperature/Humidity Sensor)
Please install ESP8266 board manager (tested with version 3.0.0)
The codes needs the following libraries installed:
"WifiManager by tzapu, tablatronix" tested with Version 2.0.3-alpha
"ESP8266 and ESP32 OLED driver for SSD1306 displays by ThingPulse, Fabrice Weinberg" tested with Version 4.1.0
If you have any questions please visit our forum at https://forum.airgradient.com/
Configuration:
Please set in the code below which sensor you are using and if you want to connect it to WiFi.
You can also switch PM2.5 from ug/m3 to US AQI and Celcius to Fahrenheit
If you are a school or university contact us for a free trial on the AirGradient platform.
https://www.airgradient.com/schools/
Kits with all required components are available at https://www.airgradient.com/diyshop/
MIT License
*/
#include <AirGradient.h>
#include <WiFiManager.h>
#include <ESP8266WiFi.h>
#include <ESP8266HTTPClient.h>
#include <Wire.h>
#include "SSD1306Wire.h"
AirGradient ag = AirGradient();
SSD1306Wire display(0x3c, SDA, SCL);
// set sensors that you do not use to false
boolean hasPM = true;
boolean hasCO2 = true;
boolean hasSHT = true;
// set to true to switch PM2.5 from ug/m3 to US AQI
boolean inUSaqi = false;
// set to true to switch from Celcius to Fahrenheit
boolean inF = false;
// set to true if you want to connect to wifi. The display will show values only when the sensor has wifi connection
boolean connectWIFI = false;
// change if you want to send the data to another server
String APIROOT = "http://hw.airgradient.com/";
void setup() {
Serial.begin(9600);
display.init();
display.flipScreenVertically();
showTextRectangle("Init", String(ESP.getChipId(), HEX), true);
if (hasPM) ag.PMS_Init();
if (hasCO2) ag.CO2_Init();
if (hasSHT) ag.TMP_RH_Init(0x44);
if (connectWIFI) connectToWifi();
delay(2000);
}
void loop() {
// create payload
String payload = "{\"wifi\":" + String(WiFi.RSSI()) + ",";
if (hasPM) {
int PM2 = ag.getPM2_Raw();
payload = payload + "\"pm02\":" + String(PM2);
if (inUSaqi) {
showTextRectangle("AQI", String(PM_TO_AQI_US(PM2)), false);
} else {
showTextRectangle("PM2", String(PM2), false);
}
delay(3000);
}
if (hasCO2) {
if (hasPM) payload = payload + ",";
int CO2 = ag.getCO2_Raw();
payload = payload + "\"rco2\":" + String(CO2);
showTextRectangle("CO2", String(CO2), false);
delay(3000);
}
if (hasSHT) {
if (hasCO2 || hasPM) payload = payload + ",";
TMP_RH result = ag.periodicFetchData();
payload = payload + "\"atmp\":" + String(result.t) + ",\"rhum\":" + String(result.rh);
if (inF) {
showTextRectangle(String((result.t * 9 / 5) + 32), String(result.rh) + "%", false);
} else {
showTextRectangle(String(result.t), String(result.rh) + "%", false);
}
delay(3000);
}
payload = payload + "}";
// send payload
if (connectWIFI) {
Serial.println(payload);
String POSTURL = APIROOT + "sensors/airgradient:" + String(ESP.getChipId(), HEX) + "/measures";
Serial.println(POSTURL);
WiFiClient client;
HTTPClient http;
http.begin(client, POSTURL);
http.addHeader("content-type", "application/json");
int httpCode = http.POST(payload);
String response = http.getString();
Serial.println(httpCode);
Serial.println(response);
http.end();
}
}
// DISPLAY
void showTextRectangle(String ln1, String ln2, boolean small) {
display.clear();
display.setTextAlignment(TEXT_ALIGN_LEFT);
if (small) {
display.setFont(ArialMT_Plain_16);
} else {
display.setFont(ArialMT_Plain_24);
}
display.drawString(32, 16, ln1);
display.drawString(32, 36, ln2);
display.display();
}
// Wifi Manager
void connectToWifi() {
WiFiManager wifiManager;
//WiFi.disconnect(); //to delete previous saved hotspot
String HOTSPOT = "AIRGRADIENT-" + String(ESP.getChipId(), HEX);
wifiManager.setTimeout(120);
if (!wifiManager.autoConnect((const char * ) HOTSPOT.c_str())) {
Serial.println("failed to connect and hit timeout");
delay(3000);
ESP.restart();
delay(5000);
}
}
// Calculate PM2.5 US AQI
int PM_TO_AQI_US(int pm02) {
if (pm02 <= 12.0) return ((50 - 0) / (12.0 - .0) * (pm02 - .0) + 0);
else if (pm02 <= 35.4) return ((100 - 50) / (35.4 - 12.0) * (pm02 - 12.0) + 50);
else if (pm02 <= 55.4) return ((150 - 100) / (55.4 - 35.4) * (pm02 - 35.4) + 100);
else if (pm02 <= 150.4) return ((200 - 150) / (150.4 - 55.4) * (pm02 - 55.4) + 150);
else if (pm02 <= 250.4) return ((300 - 200) / (250.4 - 150.4) * (pm02 - 150.4) + 200);
else if (pm02 <= 350.4) return ((400 - 300) / (350.4 - 250.4) * (pm02 - 250.4) + 300);
else if (pm02 <= 500.4) return ((500 - 400) / (500.4 - 350.4) * (pm02 - 350.4) + 400);
else return 500;
};

View File

@ -3,7 +3,7 @@ This is the code for the AirGradient DIY Air Quality Sensor with an ESP8266 Micr
It is a high quality sensor showing PM2.5, CO2, Temperature and Humidity on a small display and can send data over Wifi.
For build instructions please visit https://www.airgradient.com/diy/
For build instructions please visit https://www.airgradient.com/open-airgradient/instructions/
Compatible with the following sensors:
SenseAir S8 (CO2 Sensor)
@ -13,9 +13,9 @@ Please install ESP8266 board manager (tested with version 3.0.0)
If you have any questions please visit our forum at https://forum.airgradient.com/
If you are a school or university contact us for a free trial on the AirGradient platform.
https://www.airgradient.com/schools/
https://www.airgradient.com/
Kits with all required components are available at https://www.airgradient.com/diyshop/
Kits with all required components are available at https://www.airgradient.com/open-airgradient/shop/
MIT License
*/

View File

@ -0,0 +1,131 @@
/*
This is the code for the AirGradient DIY CO2 Traffic light with an ESP8266 Microcontroller.
For build instructions please visit:
https://www.airgradient.com/open-airgradient/instructions/diy-co2-traffic-light/
Kits (including a pre-soldered version) are available:
https://www.airgradient.com/open-airgradient/kits/
Compatible with the following sensors:
SenseAir S8 (CO2 Sensor)
Please install ESP8266 board manager (tested with version 3.0.0)
Please install the following libraries:
"Adafruit NeoMatrix" Library (tested with 1.2.0)
"WifiManager by tzapu, tablatronix" tested with Version 2.0.3-alpha
If you have any questions please visit our forum at https://forum.airgradient.com/
If you are a school or university contact us for a free trial on the AirGradient platform.
https://www.airgradient.com/
MIT License
*/
#include <AirGradient.h>
#include <WiFiManager.h>
#include <ESP8266WiFi.h>
#include <ESP8266HTTPClient.h>
#include <Adafruit_GFX.h>
#include <Adafruit_NeoMatrix.h>
#include <Adafruit_NeoPixel.h>
#ifndef PSTR
#define PSTR // Make Arduino Due happy
#endif
AirGradient ag = AirGradient();
#define PIN D8
int co2 = 0;
String text = "AirGradient CO2";
// set to true if you want to connect to wifi. The display will show values only when the sensor has wifi connection
boolean connectWIFI=true;
int greenToOrange = 800;
int orangeToRed = 1200;
// change if you want to send the data to another server
String APIROOT = "http://hw.airgradient.com/";
Adafruit_NeoMatrix matrix = Adafruit_NeoMatrix(8, 8, PIN,
NEO_MATRIX_TOP + NEO_MATRIX_RIGHT +
NEO_MATRIX_COLUMNS + NEO_MATRIX_PROGRESSIVE,
NEO_GRB + NEO_KHZ800);
void setup() {
Serial.begin(9600);
ag.CO2_Init();
matrix.begin();
matrix.setRotation(1); // change rotation
matrix.setTextWrap(false);
matrix.setBrightness(40);
matrix.setTextColor(matrix.Color(70,130,180));
Serial.println("Chip ID: "+String(ESP.getChipId(),HEX));
if (connectWIFI) connectToWifi();
delay(2000);
}
void loop() {
showText();
}
int x = matrix.width();
void showText() {
Serial.println("in loop");
matrix.fillScreen(0);
matrix.setCursor(x, 0);
matrix.print(String(text));
if(--x < -100) {
x = matrix.width();
Serial.println("end text");
co2 = ag.getCO2_Raw();
text = String(co2)+"ppm";
if (co2>350) matrix.setTextColor(matrix.Color(0, 255, 0));
if (co2>greenToOrange) matrix.setTextColor(matrix.Color(255, 90, 0));
if (co2>orangeToRed) matrix.setTextColor(matrix.Color(255,0, 0));
// send payload
String payload = "{\"wifi\":" + String(WiFi.RSSI()) + ",";
payload = payload + "\"rco2\":" + String(co2);
payload = payload + "}";
if (connectWIFI) {
Serial.println(payload);
String POSTURL = APIROOT + "sensors/airgradient:" + String(ESP.getChipId(), HEX) + "/measures";
Serial.println(POSTURL);
WiFiClient client;
HTTPClient http;
http.begin(client, POSTURL);
http.addHeader("content-type", "application/json");
int httpCode = http.POST(payload);
String response = http.getString();
Serial.println(httpCode);
Serial.println(response);
http.end();
delay(20000);
}
delay(10000);
}
matrix.show();
delay(100);
}
// Wifi Manager
void connectToWifi(){
WiFiManager wifiManager;
//WiFi.disconnect(); //to delete previous saved hotspot
String HOTSPOT = "AIRGRADIENT-"+String(ESP.getChipId(),HEX);
wifiManager.setTimeout(120);
if(!wifiManager.autoConnect((const char*)HOTSPOT.c_str())) {
Serial.println("failed to connect and hit timeout");
delay(3000);
ESP.restart();
delay(5000);
}
}

View File

@ -0,0 +1,235 @@
/*
This is the code for the AirGradient DIY BASIC Air Quality Sensor with an ESP8266 Microcontroller.
It is a high quality sensor showing PM2.5, CO2, Temperature and Humidity on a small display and can send data over Wifi.
Build Instructions: https://www.airgradient.com/open-airgradient/instructions/diy/
Kits (including a pre-soldered version) are available: https://www.airgradient.com/open-airgradient/kits/
The codes needs the following libraries installed:
“WifiManager by tzapu, tablatronix” tested with version 2.0.11-beta
“U8g2” by oliver tested with version 2.32.15
Configuration:
Please set in the code below the configuration parameters.
If you have any questions please visit our forum at https://forum.airgradient.com/
If you are a school or university contact us for a free trial on the AirGradient platform.
https://www.airgradient.com/
MIT License
*/
#include <AirGradient.h>
#include <WiFiManager.h>
#include <ESP8266WiFi.h>
#include <ESP8266HTTPClient.h>
#include <WiFiClient.h>
#include <Wire.h>
#include "SSD1306Wire.h"
AirGradient ag = AirGradient();
SSD1306Wire display(0x3c, SDA, SCL);
// CONFIGURATION START
// set to true to switch PM2.5 from ug/m3 to US AQI
boolean inUSaqi = true;
// set to true to switch from Celcius to Fahrenheit
boolean inF = false;
// set to true if you want to connect to wifi. The display will show values only when the sensor has wifi connection
boolean connectWIFI=true;
// CONFIGURATION END
unsigned long currentMillis = 0;
const int oledInterval = 5000;
unsigned long previousOled = 0;
const int sendToServerInterval = 10000;
unsigned long previoussendToServer = 0;
const int co2Interval = 5000;
unsigned long previousCo2 = 0;
int Co2 = 0;
const int pm25Interval = 5000;
unsigned long previousPm25 = 0;
int pm25 = 0;
const int tempHumInterval = 2500;
unsigned long previousTempHum = 0;
float temp = 0;
int hum = 0;
int displaypage = 0;
String APIROOT = "http://hw.airgradient.com/";
void setup()
{
Serial.begin(115200);
display.init();
display.flipScreenVertically();
if (connectWIFI) {
connectToWifi();
}
showTextRectangle("Init", String(ESP.getChipId(), HEX), true);
ag.CO2_Init();
ag.PMS_Init();
ag.TMP_RH_Init(0x44);
}
void loop()
{
currentMillis = millis();
updateOLED();
updateCo2();
updatePm25();
updateTempHum();
sendToServer();
}
void updateCo2()
{
if (currentMillis - previousCo2 >= co2Interval) {
previousCo2 += co2Interval;
Co2 = ag.getCO2_Raw();
Serial.println(String(Co2));
}
}
void updatePm25()
{
if (currentMillis - previousPm25 >= pm25Interval) {
previousPm25 += pm25Interval;
pm25 = ag.getPM2_Raw();
Serial.println(String(pm25));
}
}
void updateTempHum()
{
if (currentMillis - previousTempHum >= tempHumInterval) {
previousTempHum += tempHumInterval;
TMP_RH result = ag.periodicFetchData();
temp = result.t;
hum = result.rh;
Serial.println(String(temp));
}
}
void updateOLED() {
if (currentMillis - previousOled >= oledInterval) {
previousOled += oledInterval;
switch (displaypage) {
case 0:
if (inUSaqi) {
showTextRectangle("AQI", String(PM_TO_AQI_US(pm25)), false);
} else {
showTextRectangle("PM2", String(pm25), false);
}
displaypage = 1;
break;
case 1:
showTextRectangle("CO2", String(Co2), false);
displaypage = 2;
break;
case 2:
if (inF) {
showTextRectangle("F", String((temp * 9 / 5) + 32), false);
} else {
showTextRectangle("C", String(temp), false);
}
displaypage = 3;
break;
case 3:
showTextRectangle("Hum", String(hum)+"%", false);
displaypage = 0;
break;
}
}
}
void showTextRectangle(String ln1, String ln2, boolean small) {
display.clear();
display.setTextAlignment(TEXT_ALIGN_LEFT);
if (small) {
display.setFont(ArialMT_Plain_16);
} else {
display.setFont(ArialMT_Plain_24);
}
display.drawString(32, 16, ln1);
display.drawString(32, 38, ln2);
display.display();
}
void sendToServer() {
if (currentMillis - previoussendToServer >= sendToServerInterval) {
previoussendToServer += sendToServerInterval;
String payload = "{\"wifi\":" + String(WiFi.RSSI())
+ ", \"rco2\":" + String(Co2)
+ ", \"pm02\":" + String(pm25)
+ ", \"atmp\":" + String(temp)
+ ", \"rhum\":" + String(hum)
+ "}";
if(WiFi.status()== WL_CONNECTED){
Serial.println(payload);
String POSTURL = APIROOT + "sensors/airgradient:" + String(ESP.getChipId(), HEX) + "/measures";
Serial.println(POSTURL);
WiFiClient client;
HTTPClient http;
http.begin(client, POSTURL);
http.addHeader("content-type", "application/json");
int httpCode = http.POST(payload);
String response = http.getString();
Serial.println(httpCode);
Serial.println(response);
http.end();
}
else {
Serial.println("WiFi Disconnected");
}
}
}
// Wifi Manager
void connectToWifi() {
WiFiManager wifiManager;
//WiFi.disconnect(); //to delete previous saved hotspot
String HOTSPOT = "AIRGRADIENT-" + String(ESP.getChipId(), HEX);
wifiManager.setTimeout(60);
if (!wifiManager.autoConnect((const char * ) HOTSPOT.c_str())) {
showTextRectangle("offline", "mode", true);
Serial.println("failed to connect and hit timeout");
delay(6000);
}
}
// Calculate PM2.5 US AQI
int PM_TO_AQI_US(int pm02) {
if (pm02 <= 12.0) return ((50 - 0) / (12.0 - .0) * (pm02 - .0) + 0);
else if (pm02 <= 35.4) return ((100 - 50) / (35.4 - 12.0) * (pm02 - 12.0) + 50);
else if (pm02 <= 55.4) return ((150 - 100) / (55.4 - 35.4) * (pm02 - 35.4) + 100);
else if (pm02 <= 150.4) return ((200 - 150) / (150.4 - 55.4) * (pm02 - 55.4) + 150);
else if (pm02 <= 250.4) return ((300 - 200) / (250.4 - 150.4) * (pm02 - 150.4) + 200);
else if (pm02 <= 350.4) return ((400 - 300) / (350.4 - 250.4) * (pm02 - 250.4) + 300);
else if (pm02 <= 500.4) return ((500 - 400) / (500.4 - 350.4) * (pm02 - 350.4) + 400);
else return 500;
};

View File

@ -1,13 +1,11 @@
/*
This is the code for the AirGradient DIY Air Quality Sensor with an ESP8266 Microcontroller.
This is the code for the AirGradient DIY BASIC Air Quality Sensor with an ESP8266 Microcontroller with Sensirion SGP30 instead of the SHT30. Due to instabilities on the I2C line running both SHT30 and SGP30 at the same time is not recommended. We recommend to switch to the DIY_PRO board and use the Sensirion SGP40.
It is a high quality sensor showing PM2.5, CO2, Temperature and Humidity on a small display and can send data over Wifi.
For build instructions please visit https://www.airgradient.com/diy/
For build instructions please visit https://www.airgradient.com/open-airgradient/instructions/
Instructions on using the TVOC sensor (SGP30) instead of the Temperature / Humidity sensor (SHT3x).
https://www.airgradient.com/resources/tvoc-on-airgradient-diy-sensor/
https://www.airgradient.com/open-airgradient/instructions/tvoc-on-airgradient-diy-sensor/
The codes needs the following libraries installed:
"WifiManager by tzapu, tablatronix" tested with Version 2.0.3-alpha
@ -15,12 +13,12 @@ The codes needs the following libraries installed:
"SGP30" by Rob Tillaart tested with Version 0.1.4
Configuration:
Please set in the code below which sensor you are using and if you want to connect it to WiFi.
Set in the code below which sensor you are using and if you want to connect it to WiFi.
If you have any questions please visit our forum at https://forum.airgradient.com/
If you are a school or university contact us for a free trial on the AirGradient platform.
https://www.airgradient.com/schools/
https://www.airgradient.com/
MIT License
*/

View File

@ -0,0 +1,242 @@
/*
This is the code for the AirGradient DIY PRO Air Quality Sensor with an ESP8266 Microcontroller.
It is a high quality sensor showing PM2.5, CO2, Temperature and Humidity on a small display and can send data over Wifi.
Build Instructions: https://www.airgradient.com/open-airgradient/instructions/diy-pro/
Kits (including a pre-soldered version) are available: https://www.airgradient.com/open-airgradient/kits/
The codes needs the following libraries installed:
“WifiManager by tzapu, tablatronix” tested with version 2.0.11-beta
“U8g2” by oliver tested with version 2.32.15
“SGP30” by Rob Tilaart tested with Version 0.1.5
Configuration:
Please set in the code below the configuration parameters.
If you have any questions please visit our forum at https://forum.airgradient.com/
If you are a school or university contact us for a free trial on the AirGradient platform.
https://www.airgradient.com/
MIT License
*/
#include <AirGradient.h>
#include <WiFiManager.h>
#include <ESP8266WiFi.h>
#include <ESP8266HTTPClient.h>
#include <WiFiClient.h>
#include "SGP30.h"
#include <U8g2lib.h>
AirGradient ag = AirGradient();
SGP30 SGP;
// Display bottom right
U8G2_SH1106_128X64_NONAME_F_HW_I2C u8g2(U8G2_R0, /* reset=*/ U8X8_PIN_NONE);
// Replace above if you have display on top left
//U8G2_SH1106_128X64_NONAME_F_HW_I2C u8g2(U8G2_R2, /* reset=*/ U8X8_PIN_NONE);
// CONFIGURATION START
//set to the endpoint you would like to use
String APIROOT = "http://hw.airgradient.com/";
// set to true to switch from Celcius to Fahrenheit
boolean inF = false;
// set to true if you want to connect to wifi. You have 60 seconds to connect. Then it will go into an offline mode.
boolean connectWIFI=true;
// CONFIGURATION END
unsigned long currentMillis = 0;
const int oledInterval = 5000;
unsigned long previousOled = 0;
const int sendToServerInterval = 10000;
unsigned long previoussendToServer = 0;
const int tvocInterval = 1000;
unsigned long previousTVOC = 0;
int TVOC = 0;
const int co2Interval = 5000;
unsigned long previousCo2 = 0;
int Co2 = 0;
const int pm25Interval = 5000;
unsigned long previousPm25 = 0;
int pm25 = 0;
const int tempHumInterval = 2500;
unsigned long previousTempHum = 0;
float temp = 0;
int hum = 0;
void setup()
{
Serial.begin(115200);
u8g2.begin();
updateOLED();
if (connectWIFI) {
connectToWifi();
}
updateOLED2("Warming up the", "sensors.", "");
Serial.println(SGP.begin());
SGP.GenericReset();
ag.CO2_Init();
ag.PMS_Init();
ag.TMP_RH_Init(0x44);
}
void loop()
{
currentMillis = millis();
updateTVOC();
updateOLED();
updateCo2();
updatePm25();
updateTempHum();
sendToServer();
}
void updateTVOC()
{
if (currentMillis - previousTVOC >= tvocInterval) {
previousTVOC += tvocInterval;
SGP.measure(true);
TVOC = SGP.getTVOC();
Serial.println(String(TVOC));
}
}
void updateCo2()
{
if (currentMillis - previousCo2 >= co2Interval) {
previousCo2 += co2Interval;
Co2 = ag.getCO2_Raw();
Serial.println(String(Co2));
}
}
void updatePm25()
{
if (currentMillis - previousPm25 >= pm25Interval) {
previousPm25 += pm25Interval;
pm25 = ag.getPM2_Raw();
Serial.println(String(pm25));
}
}
void updateTempHum()
{
if (currentMillis - previousTempHum >= tempHumInterval) {
previousTempHum += tempHumInterval;
TMP_RH result = ag.periodicFetchData();
temp = result.t;
hum = result.rh;
Serial.println(String(temp));
}
}
void updateOLED() {
if (currentMillis - previousOled >= oledInterval) {
previousOled += oledInterval;
String ln3;
String ln1 = "PM:" + String(pm25) + " CO2:" + String(Co2);
String ln2 = "AQI:" + String(PM_TO_AQI_US(pm25)) + " TVOC:" + String(TVOC);
if (inF) {
ln3 = "F:" + String((temp* 9 / 5) + 32) + " H:" + String(hum)+"%";
} else {
ln3 = "C:" + String(temp) + " H:" + String(hum)+"%";
}
updateOLED2(ln1, ln2, ln3);
}
}
void updateOLED2(String ln1, String ln2, String ln3) {
char buf[9];
u8g2.firstPage();
u8g2.firstPage();
do {
u8g2.setFont(u8g2_font_t0_16_tf);
u8g2.drawStr(1, 10, String(ln1).c_str());
u8g2.drawStr(1, 30, String(ln2).c_str());
u8g2.drawStr(1, 50, String(ln3).c_str());
} while ( u8g2.nextPage() );
}
void sendToServer() {
if (currentMillis - previoussendToServer >= sendToServerInterval) {
previoussendToServer += sendToServerInterval;
String payload = "{\"wifi\":" + String(WiFi.RSSI())
+ ", \"rco2\":" + String(Co2)
+ ", \"pm02\":" + String(pm25)
+ ", \"tvoc\":" + String(TVOC)
+ ", \"atmp\":" + String(temp)
+ ", \"rhum\":" + String(hum)
+ "}";
if(WiFi.status()== WL_CONNECTED){
Serial.println(payload);
String POSTURL = APIROOT + "sensors/airgradient:" + String(ESP.getChipId(), HEX) + "/measures";
Serial.println(POSTURL);
WiFiClient client;
HTTPClient http;
http.begin(client, POSTURL);
http.addHeader("content-type", "application/json");
int httpCode = http.POST(payload);
String response = http.getString();
Serial.println(httpCode);
Serial.println(response);
http.end();
}
else {
Serial.println("WiFi Disconnected");
}
}
}
// Wifi Manager
void connectToWifi() {
WiFiManager wifiManager;
//WiFi.disconnect(); //to delete previous saved hotspot
String HOTSPOT = "AG-" + String(ESP.getChipId(), HEX);
updateOLED2("60s to connect", "to Wifi Hotspot", HOTSPOT);
wifiManager.setTimeout(60);
if (!wifiManager.autoConnect((const char * ) HOTSPOT.c_str())) {
updateOLED2("booting into", "offline mode", "");
Serial.println("failed to connect and hit timeout");
delay(6000);
}
}
// Calculate PM2.5 US AQI
int PM_TO_AQI_US(int pm02) {
if (pm02 <= 12.0) return ((50 - 0) / (12.0 - .0) * (pm02 - .0) + 0);
else if (pm02 <= 35.4) return ((100 - 50) / (35.4 - 12.0) * (pm02 - 12.0) + 50);
else if (pm02 <= 55.4) return ((150 - 100) / (55.4 - 35.4) * (pm02 - 35.4) + 100);
else if (pm02 <= 150.4) return ((200 - 150) / (150.4 - 55.4) * (pm02 - 55.4) + 150);
else if (pm02 <= 250.4) return ((300 - 200) / (250.4 - 150.4) * (pm02 - 150.4) + 200);
else if (pm02 <= 350.4) return ((400 - 300) / (350.4 - 250.4) * (pm02 - 250.4) + 300);
else if (pm02 <= 500.4) return ((500 - 400) / (500.4 - 350.4) * (pm02 - 350.4) + 400);
else return 500;
};

View File

@ -0,0 +1,261 @@
/*
This is the code for the AirGradient DIY PRO Air Quality Sensor with an ESP8266 Microcontroller with the SGP40 TVOC module from AirGradient.
It is a high quality sensor showing PM2.5, CO2, Temperature and Humidity on a small display and can send data over Wifi.
Build Instructions: https://www.airgradient.com/open-airgradient/instructions/diy-pro/
Kits (including a pre-soldered version) are available: https://www.airgradient.com/open-airgradient/kits/
The codes needs the following libraries installed:
“WifiManager by tzapu, tablatronix” tested with version 2.0.11-beta
“U8g2” by oliver tested with version 2.32.15
“DFRobot_SGP40” by DFRobot tested with Version 1.0.3
Configuration:
Please set in the code below the configuration parameters.
If you have any questions please visit our forum at https://forum.airgradient.com/
If you are a school or university contact us for a free trial on the AirGradient platform.
https://www.airgradient.com/
MIT License
*/
#include <AirGradient.h>
#include <WiFiManager.h>
#include <ESP8266WiFi.h>
#include <ESP8266HTTPClient.h>
#include <WiFiClient.h>
//#include "SGP30.h"
#include <DFRobot_SGP40.h>
#include <U8g2lib.h>
AirGradient ag = AirGradient();
DFRobot_SGP40 mySgp40;
// Display bottom right
U8G2_SH1106_128X64_NONAME_F_HW_I2C u8g2(U8G2_R0, /* reset=*/ U8X8_PIN_NONE);
// Replace above if you have display on top left
//U8G2_SH1106_128X64_NONAME_F_HW_I2C u8g2(U8G2_R2, /* reset=*/ U8X8_PIN_NONE);
// CONFIGURATION START
//set to the endpoint you would like to use
String APIROOT = "http://hw.airgradient.com/";
// set to true to switch from Celcius to Fahrenheit
boolean inF = false;
// set to true if you want to connect to wifi. You have 60 seconds to connect. Then it will go into an offline mode.
boolean connectWIFI=true;
// CONFIGURATION END
unsigned long currentMillis = 0;
const int oledInterval = 5000;
unsigned long previousOled = 0;
const int sendToServerInterval = 10000;
unsigned long previoussendToServer = 0;
const int tvocInterval = 1000;
unsigned long previousTVOC = 0;
int TVOC = 0;
const int co2Interval = 5000;
unsigned long previousCo2 = 0;
int Co2 = 0;
const int pm25Interval = 5000;
unsigned long previousPm25 = 0;
int pm25 = 0;
const int tempHumInterval = 2500;
unsigned long previousTempHum = 0;
float temp = 0;
int hum = 0;
void setup()
{
Serial.begin(115200);
u8g2.begin();
updateOLED();
if (connectWIFI) {
connectToWifi();
}
updateOLED2("Warming up the", "sensors.", "");
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.PMS_Init();
ag.TMP_RH_Init(0x44);
}
void loop()
{
currentMillis = millis();
updateTVOC();
updateOLED();
updateCo2();
updatePm25();
updateTempHum();
sendToServer();
}
void updateTVOC()
{
if (currentMillis - previousTVOC >= tvocInterval) {
previousTVOC += tvocInterval;
TVOC = mySgp40.getVoclndex();
Serial.println(String(TVOC));
}
}
void updateCo2()
{
if (currentMillis - previousCo2 >= co2Interval) {
previousCo2 += co2Interval;
Co2 = ag.getCO2_Raw();
Serial.println(String(Co2));
}
}
void updatePm25()
{
if (currentMillis - previousPm25 >= pm25Interval) {
previousPm25 += pm25Interval;
pm25 = ag.getPM2_Raw();
Serial.println(String(pm25));
}
}
void updateTempHum()
{
if (currentMillis - previousTempHum >= tempHumInterval) {
previousTempHum += tempHumInterval;
TMP_RH result = ag.periodicFetchData();
temp = result.t;
hum = result.rh;
Serial.println(String(temp));
}
}
void updateOLED() {
if (currentMillis - previousOled >= oledInterval) {
previousOled += oledInterval;
String ln3;
String ln1 = "PM:" + String(pm25) + " CO2:" + String(Co2);
String ln2 = "AQI:" + String(PM_TO_AQI_US(pm25)) + " TVOC:" + String(TVOC);
if (inF) {
ln3 = "F:" + String((temp* 9 / 5) + 32) + " H:" + String(hum)+"%";
} else {
ln3 = "C:" + String(temp) + " H:" + String(hum)+"%";
}
updateOLED2(ln1, ln2, ln3);
}
}
void updateOLED2(String ln1, String ln2, String ln3) {
char buf[9];
u8g2.firstPage();
u8g2.firstPage();
do {
u8g2.setFont(u8g2_font_t0_16_tf);
u8g2.drawStr(1, 10, String(ln1).c_str());
u8g2.drawStr(1, 30, String(ln2).c_str());
u8g2.drawStr(1, 50, String(ln3).c_str());
} while ( u8g2.nextPage() );
}
void sendToServer() {
if (currentMillis - previoussendToServer >= sendToServerInterval) {
previoussendToServer += sendToServerInterval;
String payload = "{\"wifi\":" + String(WiFi.RSSI())
+ ", \"rco2\":" + String(Co2)
+ ", \"pm02\":" + String(pm25)
+ ", \"tvoc\":" + String(TVOC)
+ ", \"atmp\":" + String(temp)
+ ", \"rhum\":" + String(hum)
+ "}";
if(WiFi.status()== WL_CONNECTED){
Serial.println(payload);
String POSTURL = APIROOT + "sensors/airgradient:" + String(ESP.getChipId(), HEX) + "/measures";
Serial.println(POSTURL);
WiFiClient client;
HTTPClient http;
http.begin(client, POSTURL);
http.addHeader("content-type", "application/json");
int httpCode = http.POST(payload);
String response = http.getString();
Serial.println(httpCode);
Serial.println(response);
http.end();
}
else {
Serial.println("WiFi Disconnected");
}
}
}
// Wifi Manager
void connectToWifi() {
WiFiManager wifiManager;
//WiFi.disconnect(); //to delete previous saved hotspot
String HOTSPOT = "AG-" + String(ESP.getChipId(), HEX);
updateOLED2("60s to connect", "to Wifi Hotspot", HOTSPOT);
wifiManager.setTimeout(60);
WiFiManagerParameter custom_text("<p>This is just a text paragraph</p>");
wifiManager.addParameter(&custom_text);
WiFiManagerParameter parameter("parameterId", "Parameter Label", "default value", 40);
wifiManager.addParameter(&parameter);
Serial.println("Parameter 1:");
Serial.println(parameter.getValue());
if (!wifiManager.autoConnect((const char * ) HOTSPOT.c_str())) {
updateOLED2("booting into", "offline mode", "");
Serial.println("failed to connect and hit timeout");
delay(6000);
}
Serial.println("Parameter 2:");
Serial.println(parameter.getValue());
}
// Calculate PM2.5 US AQI
int PM_TO_AQI_US(int pm02) {
if (pm02 <= 12.0) return ((50 - 0) / (12.0 - .0) * (pm02 - .0) + 0);
else if (pm02 <= 35.4) return ((100 - 50) / (35.4 - 12.0) * (pm02 - 12.0) + 50);
else if (pm02 <= 55.4) return ((150 - 100) / (55.4 - 35.4) * (pm02 - 35.4) + 100);
else if (pm02 <= 150.4) return ((200 - 150) / (150.4 - 55.4) * (pm02 - 55.4) + 150);
else if (pm02 <= 250.4) return ((300 - 200) / (250.4 - 150.4) * (pm02 - 150.4) + 200);
else if (pm02 <= 350.4) return ((400 - 300) / (350.4 - 250.4) * (pm02 - 250.4) + 300);
else if (pm02 <= 500.4) return ((500 - 400) / (500.4 - 350.4) * (pm02 - 350.4) + 400);
else return 500;
};

View File

@ -4,8 +4,7 @@ It can be configures to show the outside air quality as well as one indoor locat
For build instructions please visit
https://www.airgradient.com/resources/airgradient-diy-display/
https://www.airgradient.com/open-airgradient/blog/airgradient-diy-display/
The codes needs the following libraries installed:
"WifiManager by tzapu, tablatronix" tested with Version 2.0.5-alpha
@ -20,7 +19,7 @@ If you have any questions please visit our forum at https://forum.airgradient.co
If you are a school or university contact us for a free trial on the AirGradient platform.
https://www.airgradient.com/schools/
https://www.airgradient.com/
MIT License
*/

View File

@ -3,7 +3,7 @@ This is the code for the AirGradient DIY Air Quality Sensor with an ESP8266 Micr
It is a high quality sensor showing PM2.5, CO2, Temperature and Humidity on a small display and can send data over Wifi.
For build instructions please visit https://www.airgradient.com/diy/
For build instructions please visit https://www.airgradient.com/open-airgradient/instructions/
Compatible with the following sensors:
Plantower PMS5003 (Fine Particle Sensor)
@ -13,9 +13,9 @@ Please install ESP8266 board manager (tested with version 3.0.0)
If you have any questions please visit our forum at https://forum.airgradient.com/
If you are a school or university contact us for a free trial on the AirGradient platform.
https://www.airgradient.com/schools/
https://www.airgradient.com/
Kits with all required components are available at https://www.airgradient.com/diyshop/
Kits with all required components are available at https://www.airgradient.com/open-airgradient/shop/
MIT License
*/

View File

@ -3,7 +3,7 @@ This is the code for the AirGradient DIY Air Quality Sensor with an ESP8266 Micr
It is a high quality sensor showing PM2.5, CO2, Temperature and Humidity on a small display and can send data over Wifi.
For build instructions please visit https://www.airgradient.com/diy/
For build instructions please visit https://www.airgradient.com/open-airgradient/instructions/
Compatible with the following sensors:
SHT30/31 (Temperature/Humidity Sensor)
@ -11,9 +11,9 @@ SHT30/31 (Temperature/Humidity Sensor)
Please install ESP8266 board manager (tested with version 3.0.0)
If you are a school or university contact us for a free trial on the AirGradient platform.
https://www.airgradient.com/schools/
https://www.airgradient.com/
Kits with all required components are available at https://www.airgradient.com/diyshop/
Kits with all required components are available at https://www.airgradient.com/open-airgradient/shop/
If you have any questions please visit our forum at https://forum.airgradient.com/

View File

@ -1,9 +1,9 @@
name=AirGradient Air Quality Sensor
version=1.3.5
version=2.0.2
author=AirGradient <support@airgradient.com>
maintainer=AirGradient <support@airgradient.com>
sentence=ESP8266 library for an air quality sensor featuring PM2.5, CO2, Temperature and Humidity with OLED display.
paragraph=The library is very robust and works with the Plantower PMS5003 particle sensor, the Senseair S8 CO2 sensor and the SHT30/31 sensor for humidity and temperature. You can also connect an OLED display or send the air quality data to the AirGradient platform or any other backend.
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.
category=Sensors
url=https://github.com/airgradienthq/arduino
url=https://www.airgradient.com/open-airgradient/instructions/
architectures=*

View File

@ -5,4 +5,4 @@ Build your own low cost air quality sensor with optional display measuring PM2.5
This library makes it easy to read the sensor data from the Plantower PMS5003 PM2.5 sensor, the Senseair S8 and the SHT30/31 Temperature and Humidity sensor. Visit our DIY section for detailed build instructions and PCB layout.
https://www.airgradient.com/diy/
https://www.airgradient.com/open-airgradient/instructions/