mirror of
https://github.com/airgradienthq/arduino.git
synced 2025-07-19 11:42:09 +02:00
new examples
This commit is contained in:
229
examples/DIY_BASIC/DIY_BASIC.ino
Normal file
229
examples/DIY_BASIC/DIY_BASIC.ino
Normal file
@ -0,0 +1,229 @@
|
|||||||
|
/*
|
||||||
|
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/
|
||||||
|
|
||||||
|
The codes needs the following libraries installed:
|
||||||
|
“WifiManager by tzapu, tablatronix” tested with version 2.0.11-beta
|
||||||
|
"ESP8266 and ESP32 OLED driver for SSD1306 displays by ThingPulse, Fabrice Weinberg" tested with Version 4.1.0
|
||||||
|
|
||||||
|
Configuration:
|
||||||
|
Please 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/
|
||||||
|
|
||||||
|
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);
|
||||||
|
|
||||||
|
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/";
|
||||||
|
|
||||||
|
// 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 = true;
|
||||||
|
|
||||||
|
// 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;
|
||||||
|
|
||||||
|
|
||||||
|
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(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;
|
||||||
|
};
|
242
examples/DIY_PRO/DIY_PRO.ino
Normal file
242
examples/DIY_PRO/DIY_PRO.ino
Normal file
@ -0,0 +1,242 @@
|
|||||||
|
/*
|
||||||
|
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/
|
||||||
|
|
||||||
|
Instructions on using the TVOC sensor (SGP30) instead of the Temperature / Humidity sensor (SHT3x).
|
||||||
|
|
||||||
|
https://www.airgradient.com/resources/tvoc-on-airgradient-diy-sensor/
|
||||||
|
|
||||||
|
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 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/
|
||||||
|
|
||||||
|
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;
|
||||||
|
U8G2_SH1106_128X64_NONAME_F_HW_I2C u8g2(U8G2_R0, /* reset=*/ U8X8_PIN_NONE);
|
||||||
|
|
||||||
|
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;
|
||||||
|
|
||||||
|
String APIROOT = "http://hw.airgradient.com/";
|
||||||
|
|
||||||
|
// 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 = true;
|
||||||
|
|
||||||
|
// 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;
|
||||||
|
|
||||||
|
|
||||||
|
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 ln1;
|
||||||
|
String ln2;
|
||||||
|
if (inUSaqi) {
|
||||||
|
ln1 = "CO2:" + String(Co2) + " AQI:" + String(PM_TO_AQI_US(pm25));
|
||||||
|
} else {
|
||||||
|
ln1 = "CO2:" + String(Co2) + " PM:" + String(pm25);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (inF) {
|
||||||
|
ln2 = "F:" + String((temp* 9 / 5) + 32) + " H:" + String(hum)+"%";
|
||||||
|
} else {
|
||||||
|
ln2 = "C:" + String(temp) + " H:" + String(hum)+"%";
|
||||||
|
}
|
||||||
|
|
||||||
|
String ln3 = "TVOC:" + String(TVOC) ;
|
||||||
|
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("To setup connect", "to Wifi Hotspot", HOTSPOT);
|
||||||
|
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;
|
||||||
|
};
|
@ -1,5 +1,5 @@
|
|||||||
name=AirGradient Air Quality Sensor
|
name=AirGradient Air Quality Sensor
|
||||||
version=1.4.2
|
version=1.5.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 and Humidity with OLED display.
|
sentence=ESP8266 library for an air quality sensor featuring PM2.5, CO2, Temperature and Humidity with OLED display.
|
||||||
|
Reference in New Issue
Block a user