Files
arduino/examples/DIY_BASIC/DIY_BASIC.ino

244 lines
6.5 KiB
Arduino
Raw Normal View History

2022-06-11 16:18:21 +02:00
/*
2022-07-29 11:11:39 +02:00
This is the code for the AirGradient DIY BASIC Air Quality Sensor with an ESP8266 Microcontroller.
2022-06-11 16:18:21 +02:00
It is a high quality sensor showing PM2.5, CO2, Temperature and Humidity on a small display and can send data over Wifi.
2022-07-29 11:11:39 +02:00
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/
2022-06-11 16:18:21 +02:00
The codes needs the following libraries installed:
WifiManager by tzapu, tablatronix tested with version 2.0.11-beta
2022-11-06 19:21:28 +07:00
U8g2 by oliver tested with version 2.32.15
"Arduino-SHT" by Johannes Winkelmann Version 1.2.2
2022-06-11 16:18:21 +02:00
Configuration:
2022-07-29 11:11:39 +02:00
Please set in the code below the configuration parameters.
2022-06-11 16:18:21 +02:00
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.
2022-07-29 16:26:06 +02:00
https://www.airgradient.com/
2022-06-11 16:18:21 +02:00
MIT License
*/
#include <AirGradient.h>
#include <WiFiManager.h>
#include <ESP8266WiFi.h>
#include <ESP8266HTTPClient.h>
#include <WiFiClient.h>
2022-11-06 19:21:28 +07:00
#include <U8g2lib.h>
#include "SHTSensor.h"
2022-06-11 16:18:21 +02:00
AirGradient ag = AirGradient();
SHTSensor sht;
2022-06-11 16:18:21 +02:00
2022-11-06 19:21:28 +07:00
U8G2_SSD1306_64X48_ER_1_HW_I2C u8g2(U8G2_R0, /* reset=*/ U8X8_PIN_NONE); //for DIY BASIC
2022-06-11 16:18:21 +02:00
2022-07-29 11:11:39 +02:00
// CONFIGURATION START
2022-11-06 19:21:28 +07:00
//set to the endpoint you would like to use
String APIROOT = "http://hw.airgradient.com/";
2022-07-29 11:11:39 +02:00
// set to true to switch from Celcius to Fahrenheit
boolean inF = false;
2022-11-06 19:21:28 +07:00
// PM2.5 in US AQI (default ug/m3)
boolean inUSAQI = 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.
2022-07-29 11:11:39 +02:00
boolean connectWIFI=true;
// CONFIGURATION END
2022-11-06 19:21:28 +07:00
2022-06-11 16:18:21 +02:00
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;
2022-11-06 19:21:28 +07:00
long val;
2022-06-11 16:18:21 +02:00
void setup()
{
Serial.begin(115200);
sht.init();
sht.setAccuracy(SHTSensor::SHT_ACCURACY_MEDIUM);
u8g2.setBusClock(100000);
2022-11-06 19:21:28 +07:00
u8g2.begin();
updateOLED();
2022-06-11 16:18:21 +02:00
if (connectWIFI) {
connectToWifi();
}
2023-04-13 09:33:26 +07:00
updateOLED2("Warm Up", "Serial#", String(ESP.getChipId(), HEX));
2022-06-11 16:18:21 +02:00
ag.CO2_Init();
ag.PMS_Init();
//ag.TMP_RH_Init(0x44);
2022-06-11 16:18:21 +02:00
}
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;
if (sht.readSample()) {
Serial.print("SHT:\n");
Serial.print(" RH: ");
Serial.print(sht.getHumidity(), 2);
Serial.print("\n");
Serial.print(" T: ");
Serial.print(sht.getTemperature(), 2);
Serial.print("\n");
temp = sht.getTemperature();
hum = sht.getHumidity();
} else {
Serial.print("Error in readSample()\n");
}
2022-06-11 16:18:21 +02:00
Serial.println(String(temp));
}
}
void updateOLED() {
if (currentMillis - previousOled >= oledInterval) {
previousOled += oledInterval;
2022-11-06 19:21:28 +07:00
String ln1;
String ln2;
String ln3;
if (inUSAQI){
ln1 = "AQI:" + String(PM_TO_AQI_US(pm25)) ;
} else {
ln1 = "PM: " + String(pm25) +"ug" ;
2022-06-11 16:18:21 +02:00
}
2022-11-06 19:21:28 +07:00
ln2 = "CO2:" + String(Co2);
if (inF) {
ln3 = String((temp* 9 / 5) + 32).substring(0,4) + " " + String(hum)+"%";
} else {
ln3 = String(temp).substring(0,4) + " " + String(hum)+"%";
}
updateOLED2(ln1, ln2, ln3);
2022-06-11 16:18:21 +02:00
}
}
2022-11-06 19:21:28 +07:00
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, 28, String(ln2).c_str());
u8g2.drawStr(1, 46, String(ln3).c_str());
} while ( u8g2.nextPage() );
2022-06-11 16:18:21 +02:00
}
void sendToServer() {
if (currentMillis - previoussendToServer >= sendToServerInterval) {
previoussendToServer += sendToServerInterval;
2022-06-11 16:18:21 +02:00
String payload = "{\"wifi\":" + String(WiFi.RSSI())
+ (Co2 < 0 ? "" : ", \"rco2\":" + String(Co2))
+ (pm25 < 0 ? "" : ", \"pm02\":" + String(pm25))
2022-06-11 16:18:21 +02:00
+ ", \"atmp\":" + String(temp)
+ (hum < 0 ? "" : ", \"rhum\":" + String(hum))
2022-06-11 16:18:21 +02:00
+ "}";
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
2022-11-06 19:21:28 +07:00
String HOTSPOT = "AG-" + String(ESP.getChipId(), HEX);
2023-04-13 09:33:26 +07:00
updateOLED2("Connect", "Wifi AG-", String(ESP.getChipId(), HEX));
2022-11-06 19:21:28 +07:00
delay(2000);
2023-04-13 09:33:26 +07:00
wifiManager.setTimeout(90);
2022-06-11 16:18:21 +02:00
if (!wifiManager.autoConnect((const char * ) HOTSPOT.c_str())) {
2022-11-06 19:21:28 +07:00
updateOLED2("Booting", "offline", "mode");
2022-06-11 16:18:21 +02:00
Serial.println("failed to connect and hit timeout");
2022-07-29 11:11:39 +02:00
delay(6000);
2022-06-11 16:18:21 +02:00
}
}
// 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;
};