Compare commits

..

5 Commits
2.3.0 ... 2.4.0

Author SHA1 Message Date
8ec543e9c1 Updated Arduino library version tag 2023-02-22 08:44:08 +07:00
9722eda5fa Set bus clock for u8g2 to 100kHz for increased stability.
Changed SenseAir CO2 request code to 0X04 ...
2023-02-22 08:37:56 +07:00
253d8a6810 Updated outdoor example (removed HEX from Chip ID) 2023-01-13 08:27:48 +07:00
6101429d30 Updated outdoor example 2023-01-13 06:56:17 +07:00
47c55ae0dd Updated example sketches 2022-12-20 07:59:52 +07:00
9 changed files with 126 additions and 168 deletions

View File

@ -725,48 +725,6 @@ void AirGradient::CO2_Init(int rx_pin,int tx_pin,int baudRate){
delay(10000);
}
}
//const char* AirGradient::getCO2(int retryLimit) {
// int ctr = 0;
// int result_CO2 = getCO2_Raw();
// while(result_CO2 == -1){
// result_CO2 = getCO2_Raw();
// if((ctr == retryLimit) || (result_CO2 == -1)){
// Char_CO2[0] = 'N';
// Char_CO2[1] = 'U';
// Char_CO2[2] = 'L';
// Char_CO2[3] = 'L';
// return Char_CO2;
// }
// ctr++;
// }
// sprintf(Char_CO2,"%d", result_CO2);
// return Char_CO2;
//}
//int AirGradient::getCO2_Raw(){
// const byte CO2Command[] = {0xFE, 0X44, 0X00, 0X08, 0X02, 0X9F, 0X25};
// byte CO2Response[] = {0,0,0,0,0,0,0};
//
// _SoftSerial_CO2->write(CO2Command, 7);
// delay(100); //give the sensor a bit of time to respond
//
// if (_SoftSerial_CO2->available()){
// for (int i=0; i < 7; i++) {
// int byte = _SoftSerial_CO2->read();
// CO2Response[i] = byte;
// if (CO2Response[0] != 254) {
// return -1; //error code for debugging
// }
// }
// unsigned long val = CO2Response[3]*256 + CO2Response[4];
// return val;
// }
// else
// {
// return -2; //error code for debugging
// }
//}
int AirGradient::getCO2(int numberOfSamplesToTake) {
int successfulSamplesCounter = 0;
@ -800,14 +758,12 @@ int AirGradient::getCO2_Raw() {
while(_SoftSerial_CO2->available()) // flush whatever we might have
_SoftSerial_CO2->read();
const byte CO2Command[] = {0xFE, 0X44, 0X00, 0X08, 0X02, 0X9F, 0X25};
const byte CO2Command[] = {0XFE, 0X04, 0X00, 0X03, 0X00, 0X01, 0XD5, 0XC5};
byte CO2Response[] = {0,0,0,0,0,0,0};
// tt
int datapos = -1;
//
const int commandSize = 7;
const int commandSize = 8;
const int responseSize = 7;
int numberOfBytesWritten = _SoftSerial_CO2->write(CO2Command, commandSize);
@ -818,7 +774,7 @@ int AirGradient::getCO2_Raw() {
// attempt to read response
int timeoutCounter = 0;
while (_SoftSerial_CO2->available() < commandSize) {
while (_SoftSerial_CO2->available() < responseSize) {
timeoutCounter++;
if (timeoutCounter > 10) {
// timeout when reading response
@ -828,22 +784,15 @@ int AirGradient::getCO2_Raw() {
}
// we have 7 bytes ready to be read
for (int i=0; i < commandSize; i++) {
for (int i=0; i < responseSize; i++) {
CO2Response[i] = _SoftSerial_CO2->read();
// tt
if ((CO2Response[i] == 0xFE) && (datapos == -1)){
datapos = i;
}
Serial.print (CO2Response[i],HEX);
Serial.print (":");
//
}
// return CO2Response[3]*256 + CO2Response[4];
// tt
return CO2Response[datapos + 3]*256 + CO2Response[datapos + 4];
//
}
//END CO2 FUNCTIONS //

View File

@ -78,7 +78,7 @@ long val;
void setup()
{
Serial.begin(115200);
u8g2.setBusClock(100000);
u8g2.begin();
updateOLED();

View File

@ -1,3 +1,22 @@
/*
Important: This code is only for the AirGradient DIY OUTDOOR.
Build Instructions: https://www.airgradient.com/open-airgradient/instructions/diy-outdoor/
Kits (including a pre-soldered version) are available: https://www.airgradient.com/open-airgradient/kits/
Configuration:
Install required libraries
Patch PMS library to accept temperature and humidity from PMS5003T
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/
License: CC BY-NC 4.0 Attribution-NonCommercial 4.0 International
*/
#include "PMS.h"
#include "SoftwareSerial.h"
#include <Wire.h>
@ -7,21 +26,20 @@
#include <ESP8266HTTPClient.h>
#include <WiFiClient.h>
#include "ClosedCube_SHT31D.h"
SoftwareSerial softSerial(D6, D5);
SoftwareSerial soft2(D3, D7);
SoftwareSerial softSerial(D6, D5); //(RX, TX)
SoftwareSerial soft2(D3, D7); //(RX, TX)
ClosedCube_SHT31D sht3xd;
PMS pms(softSerial);
PMS pms2(soft2);
PMS::DATA data;
PMS::DATA data2;
int pm1 = 0;
int pm2 = 0;
float temp = 0;
int hum = 0;
float pm1Value=0;
int pm1Position = 0;
float pm2Value=0;
int pm2Position = 0;
float temp_pm1 = 0;
float hum_pm1 = 0;
@ -29,107 +47,101 @@ float hum_pm1 = 0;
float temp_pm2 = 0;
float hum_pm2 = 0;
unsigned long currentMillis = 0;
const int pm1Interval = 5000;
unsigned long previousPm1 = 0;
const int pm2Interval = 5000;
unsigned long previousPm2 = 0;
String APIROOT = "http://hw.airgradient.com/";
void setup()
{
Serial.begin(9600);
Serial.println("hhi");
Serial.begin(115200);
Serial.println("Chip ID: "+String(ESP.getChipId()));
softSerial.begin(9600);
soft2.begin(9600);
Wire.begin();
sht3xd.begin(0x44);
pinMode(D7, OUTPUT);
connectToWifi();
}
void loop()
{
if (digitalRead(D8) == HIGH) {
digitalWrite(D7, HIGH);
}
else {
digitalWrite(D7, LOW);
}
if (pms.read(data)){
pm1 = data.PM_AE_UG_2_5;
temp_pm1 = data.AMB_TMP;
hum_pm1 = data.AMB_HUM;
Serial.print("PMS 1: PM 2.5 (ug/m3): ");
Serial.println(pm1);
Serial.print("PMS 1: Temp: ");
Serial.println(temp_pm1);
Serial.print("PMS 1: Hum: ");
Serial.println(hum_pm1);
Serial.println();
delay(1000);
}
if (pms2.read(data)){
pm2 = data.PM_AE_UG_2_5;
temp_pm2 = data.AMB_TMP ;
hum_pm2 = data.AMB_HUM;
Serial.print("PMS 2: PM 2.5 (ug/m3): ");
Serial.println(pm2);
Serial.print("PMS 2: Temp: ");
Serial.println(temp_pm2);
Serial.print("PMS 2: Hum: ");
Serial.println(hum_pm2);
Serial.println();
delay(1000);
temp = sht3xd.readTempAndHumidity(SHT3XD_REPEATABILITY_LOW, SHT3XD_MODE_CLOCK_STRETCH, 50).t;
hum = sht3xd.readTempAndHumidity(SHT3XD_REPEATABILITY_LOW, SHT3XD_MODE_CLOCK_STRETCH, 50).rh;
Serial.println(temp);
Serial.println(hum);
sendToServer();
delay(1000);
sendToServerPM1();
delay(1000);
sendToServerPM2();
}
currentMillis = millis();
updatePm1();
updatePm2();
}
void sendToServer() {
String payload = "{\"wifi\":" + String(WiFi.RSSI())
+ ", \"pm02\":" + String((pm1+pm2)/2)
+ ", \"atmp\":" + String(temp)
+ ", \"rhum\":" + String(hum)
+ "}";
if(WiFi.status()== WL_CONNECTED){
digitalWrite(D7, HIGH);
delay(300);
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();
digitalWrite(D7, LOW);
}
else {
Serial.println("WiFi Disconnected");
}
void updatePm1()
{
if (currentMillis - previousPm1 >= pm1Interval) {
digitalWrite(D7, HIGH);
delay(400);
digitalWrite(D7, LOW);
Serial.println("updatePm1: "+String(pm1Position));
previousPm1 += pm1Interval;
pms.requestRead();
if (pms.readUntil(data)){
Serial.println("success read");
int pm1 = data.PM_AE_UG_2_5;
temp_pm1 = data.AMB_TMP;
hum_pm1 = data.AMB_HUM;
Serial.print("PMS 1: PM 2.5 (ug/m3): ");
Serial.println(pm1);
Serial.print("PMS 1: Temp: ");
Serial.println(temp_pm1);
Serial.print("PMS 1: Hum: ");
Serial.println(hum_pm1);
Serial.println();
delay(1000);
pm1Value=pm1Value+pm1;
pm1Position++;
if (pm1Position==20) {
sendToServerPM1(pm1Value);
pm1Position=0;
pm1Value=0;
}
}
}
}
void sendToServerPM1() {
void updatePm2()
{
if (currentMillis - previousPm2 >= pm2Interval) {
Serial.println("updatePm2: "+String(pm2Position));
previousPm2 += pm2Interval;
pms2.requestRead();
if (pms2.readUntil(data2)){
int pm2 = data2.PM_AE_UG_2_5;
temp_pm2 = data2.AMB_TMP ;
hum_pm2 = data2.AMB_HUM;
Serial.print("PMS 2: PM 2.5 (ug/m3): ");
Serial.println(pm2);
Serial.print("PMS 2: Temp: ");
Serial.println(temp_pm2);
Serial.print("PMS 2: Hum: ");
Serial.println(hum_pm2);
Serial.println();
delay(1000);
pm2Value=pm2Value+pm2;
pm2Position++;
if (pm2Position==20) {
sendToServerPM2(pm2Value);
pm2Position=0;
pm2Value=0;
}
}
}
}
void sendToServerPM1(float pm1Value) {
String payload = "{\"wifi\":" + String(WiFi.RSSI())
+ ", \"pm02\":" + String(pm1)
+ ", \"pm02\":" + String(pm1Value/20)
+ ", \"atmp\":" + String(temp_pm1/10)
+ ", \"rhum\":" + String(hum_pm1/10)
+ "}";
@ -138,7 +150,7 @@ void sendToServerPM1() {
digitalWrite(D7, HIGH);
delay(300);
Serial.println(payload);
String POSTURL = APIROOT + "sensors/airgradient:" + String(ESP.getChipId(), HEX) + "pm1/measures";
String POSTURL = APIROOT + "sensors/airgradient:" + String(ESP.getChipId()) + "-1/measures";
Serial.println(POSTURL);
WiFiClient client;
HTTPClient http;
@ -157,9 +169,9 @@ void sendToServerPM1() {
}
void sendToServerPM2() {
void sendToServerPM2(float pm2Value) {
String payload = "{\"wifi\":" + String(WiFi.RSSI())
+ ", \"pm02\":" + String(pm2)
+ ", \"pm02\":" + String(pm2Value/20)
+ ", \"atmp\":" + String(temp_pm2/10)
+ ", \"rhum\":" + String(hum_pm2/10)
+ "}";
@ -168,7 +180,7 @@ void sendToServerPM2() {
digitalWrite(D7, HIGH);
delay(300);
Serial.println(payload);
String POSTURL = APIROOT + "sensors/airgradient:" + String(ESP.getChipId(), HEX) + "pm2/measures";
String POSTURL = APIROOT + "sensors/airgradient:" + String(ESP.getChipId()) + "-2/measures";
Serial.println(POSTURL);
WiFiClient client;
HTTPClient http;
@ -191,11 +203,10 @@ void sendToServerPM2() {
void connectToWifi() {
WiFiManager wifiManager;
//WiFi.disconnect(); //to delete previous saved hotspot
String HOTSPOT = "AIRGRADIENT-" + String(ESP.getChipId(), HEX);
String HOTSPOT = "AIRGRADIENT-" + String(ESP.getChipId());
wifiManager.setTimeout(60);
if (!wifiManager.autoConnect((const char * ) HOTSPOT.c_str())) {
Serial.println("failed to connect and hit timeout");
delay(6000);
}
}

View File

@ -78,7 +78,7 @@ int hum = 0;
void setup()
{
Serial.begin(115200);
u8g2.setBusClock(100000);
u8g2.begin();
updateOLED();

View File

@ -23,7 +23,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/
MIT License
License: CC BY-NC 4.0 Attribution-NonCommercial 4.0 International
*/
@ -51,7 +51,7 @@ NOxGasIndexAlgorithm nox_algorithm;
// time in seconds needed for NOx conditioning
uint16_t conditioning_s = 10;
// for peristent saving and loading
// for persistent saving and loading
int addr = 0;
byte value;
@ -117,6 +117,7 @@ unsigned long releasedTime = 0;
void setup() {
Serial.begin(115200);
Serial.println("Hello");
u8g2.setBusClock(100000);
u8g2.begin();
//u8g2.setDisplayRotation(U8G2_R0);
@ -232,32 +233,29 @@ void setConfig() {
inUSAQI = true;
}
if (buttonConfig == 4) {
updateOLED2("Temp. in C", "PM in ug/m3", "Display Top");
updateOLED2("Temp. in C", "PM in ug/m3", "Display Bottom");
u8g2.setDisplayRotation(U8G2_R0);
inF = false;
inUSAQI = false;
}
if (buttonConfig == 5) {
updateOLED2("Temp. in C", "PM in US AQI", "Display Top");
updateOLED2("Temp. in C", "PM in US AQI", "Display Bottom");
u8g2.setDisplayRotation(U8G2_R0);
inF = false;
inUSAQI = true;
}
if (buttonConfig == 6) {
updateOLED2("Temp. in F", "PM in ug/m3", "Display Top");
updateOLED2("Temp. in F", "PM in ug/m3", "Display Bottom");
u8g2.setDisplayRotation(U8G2_R0);
inF = true;
inUSAQI = false;
}
if (buttonConfig == 7) {
updateOLED2("Temp. in F", "PM in US AQI", "Display Top");
updateOLED2("Temp. in F", "PM in US AQI", "Display Bottom");
u8g2.setDisplayRotation(U8G2_R0);
inF = true;
inUSAQI = true;
}
// to do
// if (buttonConfig == 8) {
// updateOLED2("CO2", "Manual", "Calibration");

View File

@ -97,7 +97,7 @@ int hum = 0;
void setup()
{
Serial.begin(115200);
u8g2.setBusClock(100000);
u8g2.begin();
updateOLED();

View File

@ -91,7 +91,7 @@ int hum = 0;
void setup()
{
Serial.begin(115200);
u8g2.setBusClock(100000);
u8g2.begin();
updateOLED();

View File

@ -87,7 +87,7 @@ int hum = 0;
void setup()
{
Serial.begin(115200);
u8g2.setBusClock(100000);
u8g2.begin();
updateOLED();

View File

@ -1,5 +1,5 @@
name=AirGradient Air Quality Sensor
version=2.2.0
version=2.4.0
author=AirGradient <support@airgradient.com>
maintainer=AirGradient <support@airgradient.com>
sentence=ESP8266 library for an air quality sensor featuring PM2.5, CO2, Temperature, TVOC and Humidity with OLED display.