mirror of
https://github.com/airgradienthq/arduino.git
synced 2025-06-26 16:21:33 +02:00
Compare commits
11 Commits
Author | SHA1 | Date | |
---|---|---|---|
d5c8af68a0 | |||
3c7180e642 | |||
ee40b60aad | |||
b9a968ef7a | |||
4bb434562f | |||
ab1f6c1ae7 | |||
63c7e9ca00 | |||
0b8408ef13 | |||
ff34d2c143 | |||
73498894e4 | |||
ed3b0ff53f |
@ -607,47 +607,27 @@ const char* AirGradient::getCO2(int retryLimit) {
|
|||||||
return Char_CO2;
|
return Char_CO2;
|
||||||
}
|
}
|
||||||
int AirGradient::getCO2_Raw(){
|
int AirGradient::getCO2_Raw(){
|
||||||
int retry = 0;
|
const byte CO2Command[] = {0xFE, 0X44, 0X00, 0X08, 0X02, 0X9F, 0X25};
|
||||||
CO2_READ_RESULT result;
|
byte CO2Response[] = {0,0,0,0,0,0,0};
|
||||||
const byte CO2Command[] = {0xFE, 0X44, 0X00, 0X08, 0X02, 0X9F, 0X25};
|
|
||||||
byte CO2Response[] = {0,0,0,0,0,0,0};
|
|
||||||
|
|
||||||
while(!(_SoftSerial_CO2->available())) {
|
_SoftSerial_CO2->write(CO2Command, 7);
|
||||||
retry++;
|
delay(100); //give the sensor a bit of time to respond
|
||||||
// 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);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
if (_SoftSerial_CO2->available()){
|
||||||
for (int i=0; i < 7; i++) {
|
for (int i=0; i < 7; i++) {
|
||||||
int byte = _SoftSerial_CO2->read();
|
int byte = _SoftSerial_CO2->read();
|
||||||
if (byte == -1) {
|
CO2Response[i] = byte;
|
||||||
result.success = false;
|
if (CO2Response[0] != 254) {
|
||||||
return -1;
|
return -1; //error code for debugging
|
||||||
}
|
}
|
||||||
CO2Response[i] = byte;
|
}
|
||||||
}
|
unsigned long val = CO2Response[3]*256 + CO2Response[4];
|
||||||
int valMultiplier = 1;
|
|
||||||
int high = CO2Response[3];
|
|
||||||
int low = CO2Response[4];
|
|
||||||
unsigned long val = high*256 + low;
|
|
||||||
|
|
||||||
return val;
|
return val;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return -2; //error code for debugging
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//END CO2 FUNCTIONS //
|
//END CO2 FUNCTIONS //
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
The MIT License (MIT)
|
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
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
of this software and associated documentation files (the "Software"), to deal
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
|
@ -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.
|
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/
|
||||||
|
@ -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;
|
|
||||||
};
|
|
@ -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.
|
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:
|
Compatible with the following sensors:
|
||||||
SenseAir S8 (CO2 Sensor)
|
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 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.
|
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
|
MIT License
|
||||||
*/
|
*/
|
||||||
|
131
examples/CO2_TRAFFIC_LIGHT/CO2_TRAFFIC_LIGHT_SIMPLE.ino
Normal file
131
examples/CO2_TRAFFIC_LIGHT/CO2_TRAFFIC_LIGHT_SIMPLE.ino
Normal 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);
|
||||||
|
}
|
||||||
|
}
|
235
examples/DIY_BASIC/DIY_BASIC.ino
Normal file
235
examples/DIY_BASIC/DIY_BASIC.ino
Normal 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;
|
||||||
|
};
|
@ -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/open-airgradient/instructions/
|
||||||
|
|
||||||
For build instructions please visit https://www.airgradient.com/diy/
|
|
||||||
|
|
||||||
Instructions on using the TVOC sensor (SGP30) instead of the Temperature / Humidity sensor (SHT3x).
|
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:
|
The codes needs the following libraries installed:
|
||||||
"WifiManager by tzapu, tablatronix" tested with Version 2.0.3-alpha
|
"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
|
"SGP30" by Rob Tillaart tested with Version 0.1.4
|
||||||
|
|
||||||
Configuration:
|
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 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.
|
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
|
MIT License
|
||||||
*/
|
*/
|
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 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;
|
||||||
|
};
|
261
examples/DIY_PRO_WITH_SGP40/DIY_PRO_WITH_SGP40.ino
Normal file
261
examples/DIY_PRO_WITH_SGP40/DIY_PRO_WITH_SGP40.ino
Normal 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(¶meter);
|
||||||
|
|
||||||
|
|
||||||
|
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;
|
||||||
|
};
|
@ -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
|
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:
|
The codes needs the following libraries installed:
|
||||||
"WifiManager by tzapu, tablatronix" tested with Version 2.0.5-alpha
|
"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.
|
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
|
MIT License
|
||||||
*/
|
*/
|
||||||
|
@ -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.
|
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:
|
Compatible with the following sensors:
|
||||||
Plantower PMS5003 (Fine Particle Sensor)
|
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 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.
|
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
|
MIT License
|
||||||
*/
|
*/
|
||||||
|
@ -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.
|
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:
|
Compatible with the following sensors:
|
||||||
SHT30/31 (Temperature/Humidity Sensor)
|
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)
|
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.
|
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/
|
If you have any questions please visit our forum at https://forum.airgradient.com/
|
||||||
|
|
||||||
|
@ -1,9 +1,9 @@
|
|||||||
name=AirGradient Air Quality Sensor
|
name=AirGradient Air Quality Sensor
|
||||||
version=1.3.5
|
version=2.0.2
|
||||||
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, TVOC 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.
|
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
|
category=Sensors
|
||||||
url=https://github.com/airgradienthq/arduino
|
url=https://www.airgradient.com/open-airgradient/instructions/
|
||||||
architectures=*
|
architectures=*
|
||||||
|
@ -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.
|
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/
|
||||||
|
Reference in New Issue
Block a user