In my project I must use the ESP12-E NodeMcu board and three sensors, temperature and humidity (DHT22), VOC's (CCS811) and particles (PPD42).
When I use only the PPD42 sensor the returned values are correct (range 0 - 1000), but when when I connect the three sensors + wifi, the values are either 0 or they are too large (+1,000,000).
Could you help me?
#include <ESP8266WiFi.h>
#include <WiFiClient.h>
#include <ESP8266WebServer.h>
#include <ESP8266HTTPClient.h>
#include <ESP8266mDNS.h>
#include <WiFiManager.h>
#include <DHT.h>
#include <Wire.h>
#include "SparkFunCCS811.h" //Click here to get the library: http://librarymanager/All#SparkFun_CCS811
#define CCS811_ADDR 0x5A //Alternate I2C Address
//SEND_DATA
const char* serverName = "http://****";
String serial_numb = "****";
//SEND_DATA
//CCS811
CCS811 myCCS811(CCS811_ADDR);
float CCS811_CO2 = 0;
float CCS811_tVOC = 0;
//CCS811
//for LED status
#include <Ticker.h>
Ticker ticker;
//PPD42
//Set variables for PM10 and PM2,5 readings
unsigned long starttime;
unsigned long triggerOnP1;
unsigned long triggerOffP1;
unsigned long pulseLengthP1;
unsigned long durationP1;
boolean valP1 = HIGH;
boolean triggerP1 = false;
unsigned long triggerOnP2;
unsigned long triggerOffP2;
unsigned long pulseLengthP2;
unsigned long durationP2;
boolean valP2 = HIGH;
boolean triggerP2 = false;
float ratioP1 = 0;
float ratioP2 = 0;
unsigned long sampletime_ms = 30000;
float countP1;
float countP2;
float concLarge = 0;
float concSmall = 0;
//PPD42
//DHT22
#define PIN_CONEXION D3// A cuál pin está conectado el lector
#define TIPO_SENSOR DHT22 // Puede ser DHT11 también
DHT dht(PIN_CONEXION, TIPO_SENSOR);
float DHThumid, DHTtempC = 0;
//DHT22
#ifndef LED_BUILTIN
#define LED_BUILTIN 13 // ESP32 DOES NOT DEFINE LED_BUILTIN
#endif
int LED = LED_BUILTIN;
void tick()
{
//toggle state
digitalWrite(LED, !digitalRead(LED)); // set pin to the opposite state
}
//gets called when WiFiManager enters configuration mode
void configModeCallback (WiFiManager *myWiFiManager) {
Serial.println("Entered config mode");
Serial.println(WiFi.softAPIP());
//if you used auto generated SSID, print it
Serial.println(myWiFiManager->getConfigPortalSSID());
//entered config mode, make led toggle faster
ticker.attach(0.2, tick);
}
void setup() {
wifi();
setup_CSS811();
}
void wifi() {
WiFi.mode(WIFI_STA); // explicitly set mode, esp defaults to STA+AP
// put your setup code here, to run once:
Serial.begin(115200);
//set led pin as output
pinMode(LED, OUTPUT);
// start ticker with 0.5 because we start in AP mode and try to connect
ticker.attach(0.6, tick);
//WiFiManager
//Local intialization. Once its business is done, there is no need to keep it around
WiFiManager wm;
//reset settings - for testing
// wm.resetSettings();
//set callback that gets called when connecting to previous WiFi fails, and enters Access Point mode
wm.setAPCallback(configModeCallback);
//fetches ssid and pass and tries to connect
//if it does not connect it starts an access point with the specified name
//here "AutoConnectAP"
//and goes into a blocking loop awaiting configuration
if (!wm.autoConnect("wifi")) {
Serial.println("failed to connect and hit timeout");
//reset and try again, or maybe put it to deep sleep
ESP.restart();
delay(1000);
}
//if you get here you have connected to the WiFi
Serial.println("connected...yeey :)");
ticker.detach();
//keep LED on
digitalWrite(LED, LOW);
}
void loop() {
run_PPD42();
run_CSS811();
senddata();
delay(30000);
}
void setup_CSS811()
{
Serial.begin(115200);
Serial.println();
Serial.println("Apply DHT22 data to CCS811 for compensation.");
Wire.begin();
//This begins the CCS811 sensor and prints error status of .beginWithStatus()
CCS811Core::CCS811_Status_e returnCode = myCCS811.beginWithStatus();
Serial.print("CCS811 begin exited with: ");
Serial.println(myCCS811.statusString(returnCode));
//Calling .begin() causes the settings to be loaded
delay(10); //Make sure sensor had enough time to turn on. BME280 requires 2ms to start up.
dht.begin();
}
void run_CSS811()
{
//Check to see if data is available
if (myCCS811.dataAvailable())
{
//Calling this function updates the global tVOC and eCO2 variables
myCCS811.readAlgorithmResults();
//printInfoSerial fetches the values of tVOC and eCO2
printInfoSerial();
DHTtempC = dht.readTemperature();
DHThumid = dht.readHumidity();
Serial.print("Applying new values (ªC, Humedad): ");
Serial.print(DHTtempC);
Serial.print(",");
Serial.println(DHThumid);
Serial.println();
//This sends the temperature data to the CCS811
myCCS811.setEnvironmentalData(DHThumid, DHTtempC);
}
else if (myCCS811.checkForStatusError())
{
//If the CCS811 found an internal error, print it.
printSensorError();
}
}
void printInfoSerial()
{
//getCO2() gets the previously read data from the library
Serial.println("CCS811 data:");
Serial.print(" CO2 concentration : ");
CCS811_CO2 = myCCS811.getCO2();
Serial.print(CCS811_CO2);
Serial.println(" ppm");
//getTVOC() gets the previously read data from the library
Serial.print(" TVOC concentration : ");
CCS811_tVOC = myCCS811.getTVOC();
Serial.print(CCS811_tVOC);
Serial.println(" ppb");
Serial.println("DHT22 data:");
Serial.print(" Temperatura: ");
Serial.print(dht.readTemperature(), 2);
Serial.println(" ºC");
Serial.print(" Humedad: ");
Serial.print(dht.readHumidity(), 2);
Serial.println("%");
Serial.println();
}
void printSensorError()
{
uint8_t error = myCCS811.getErrorRegister();
if (error == 0xFF) //comm error
{
Serial.println("Failed to get ERROR_ID register.");
}
else
{
Serial.print("Error: ");
if (error & 1 << 5)
Serial.print("HeaterSupply");
if (error & 1 << 4)
Serial.print("HeaterFault");
if (error & 1 << 3)
Serial.print("MaxResistance");
if (error & 1 << 2)
Serial.print("MeasModeInvalid");
if (error & 1 << 1)
Serial.print("ReadRegInvalid");
if (error & 1 << 0)
Serial.print("MsgInvalid");
Serial.println();
}
}
void run_PPD42()
{
valP1 = digitalRead(14);
valP2 = digitalRead(12);
if(valP1 == LOW && triggerP1 == false){
triggerP1 = true;
triggerOnP1 = micros();
}
if (valP1 == HIGH && triggerP1 == true){
triggerOffP1 = micros();
pulseLengthP1 = triggerOffP1 - triggerOnP1;
durationP1 = durationP1 + pulseLengthP1;
triggerP1 = false;
}
if(valP2 == LOW && triggerP2 == false){
triggerP2 = true;
triggerOnP2 = micros();
}
if (valP2 == HIGH && triggerP2 == true){
triggerOffP2 = micros();
pulseLengthP2 = triggerOffP2 - triggerOnP2;
durationP2 = durationP2 + pulseLengthP2;
triggerP2 = false;
}
if ((millis() - starttime) > sampletime_ms) {
ratioP1 = durationP1/(sampletime_ms*10.0); // Integer percentage 0=>100
ratioP2 = durationP2/(sampletime_ms*10.0);
countP1 = 1.1*pow(ratioP1,3)-3.8*pow(ratioP1,2)+520*ratioP1+0.62;
countP2 = 1.1*pow(ratioP2,3)-3.8*pow(ratioP2,2)+520*ratioP2+0.62;
float PM10count = countP2;
float PM25count = countP1 - countP2;
// first, PM10 count to mass concentration conversion
double r10 = 2.6*pow(10,-6);
double pi = 3.14159;
double vol10 = (4.0/3.0)*pi*pow(r10,3);
double density = 1.65*pow(10,12);
double mass10 = density*vol10;
double K = 3531.5;
concLarge = (PM10count)*K*mass10;
// next, PM2.5 count to mass concentration conversion
double r25 = 0.44*pow(10,-6);
double vol25 = (4.0/3.0)*pi*pow(r25,3);
double mass25 = density*vol25;
concSmall = (PM25count)*K*mass25;
Serial.print("PM10=");
Serial.print(concLarge);
Serial.print(", PM25=");
Serial.println(concSmall);
durationP1 = 0;
durationP2 = 0;
starttime = millis();
}
}
void senddata(){
//Check WiFi connection status
if(WiFi.status()== WL_CONNECTED){
HTTPClient http;
// Your Domain name with URL path or IP address with path
http.begin(serverName);
// Specify content-type header
http.addHeader("Content-Type", "application/x-www-form-urlencoded");
// Prepare your HTTP POST request data
String httpRequestData = "serial_numb=" + serial_numb + "&DHTtempC=" + String(DHTtempC)
+ "&DHThumid=" + String(DHThumid) + "&CCS811_CO2=" + String(CCS811_CO2) + "&CCS811_tVOC=" + String(CCS811_tVOC) + "&PM10=" + String(concLarge) + "&PM25=" + String(concSmall) + "";
Serial.print("httpRequestData: ");
Serial.println(httpRequestData);
int httpResponseCode = http.POST(httpRequestData);
if (httpResponseCode>0) {
Serial.print("HTTP Response code: ");
Serial.println(httpResponseCode);
}
else {
Serial.print("Error code: ");
Serial.println(httpResponseCode);
}
// Free resources
http.end();
}
else {
Serial.println("WiFi Disconnected");
}
}