I have a problem with the ENS160 air quality sensor. I hooked it up to an ESP8266 via I2C (0x53) and it worked perfectly fine, until I started using WiFi simultaneously. The communicating with the ENS160 is still possible. However, instead of transmitting useful data (like it did before), it just sends the value 0 back and I just can't figure out why. It seems like the problem occurs as soon as i call WiFi.begin(), because the ENS160 sends useful data before that line. Could It be that there is a problem with interrupts? But the I2C communication should still work. The BME280 sensor that I connected via I2C as well, still works perfectly fine. The WiFi connection itself works perfectly fine as well.
Here is the code:
#include <Wire.h> //I2C
#include <Adafruit_Sensor.h> //BME280
#include <Adafruit_BME280.h> //BME280
#include <ScioSense_ENS160.h> //ENS160
#include <ESP8266WiFi.h> //WiFi
#include <ESP8266HTTPClient.h> //WiFi
#include <WiFiClient.h> //WiFi
#define USE_ENS160 //Use ENS160
//Sensors
Adafruit_BME280 bme; //Create a bme object (I2C interface)
#ifdef USE_ENS160
ScioSense_ENS160 ens160(ENS160_I2CADDR_1); //Create a ens160 object with the I2C-Address 0x53
#endif
//Network
const char* ssid = "ssid"; //Network SSID
const char* password = "password"; //Network Password
const char* serverPath = "path"; //The server domain and path where the sensor data is posted
//Sensor data variables
float temperature = 0.0; //The current temperature (°C)
float humidity = 0.0; //The current humidity (%)
float pressure = 0.0; //The current barometric pressure (hPa)
int co2 = 0; //The current CO2 values (parts per million)
unsigned long lastTime = 0;
unsigned long timerDelay = 5000;
//Prototypes
//void blinkLedErrorLoop
void setup() {
//PinModes
pinMode(LED_BUILTIN, OUTPUT); //The internal LED is an output
//Start the serial connection
Serial.begin(115200); //Start the serial monitor with a baud rate of 115200 bps
Serial.println("\nCO2 sensor program started..."); //Print to check if the serial connection works
//Init the BME sensor
Serial.println("Initializing BME280...");
bool bmeStatus = bme.begin(0x76); //Start the I2C-Communication with the bme on address 0x76 and save the status of the initialization in bmeStatus
//Check if the connection was sucessful
if(!bmeStatus){ //Error -> Could not connect to BME280
Serial.println("ERROR: Could not connect to BME280. Check the connection and restart the Controller!");
blinkLedErrorLoop(); //Endless error loop
}
Serial.println("Initialization of BME280 complete.");
//Init the ENS160 CO2 etc. sensor
#ifdef USE_ENS160
ETS_GPIO_INTR_ENABLE();
Serial.print("Initializing ENS160...");
ens160.begin(); //Begin the communication with the ENS160
bool ensStatus = ens160.available(); //Is the ENS160 available? yes: true, no: false
if(!ensStatus){ //Error -> Could not connect to ENS160
Serial.println("ERROR: Could not connect to ENS160. Check the connection and restart the..)
blinkLedErrorLoop(); //Endless error loop
}
//Connection sucessful -> print ENS160 versions
Serial.print("\tRev: "); Serial.print(ens160.getMajorRev());
Serial.print("."); Serial.print(ens160.getMinorRev());
Serial.print("."); Serial.println(ens160.getBuild());
Serial.print("\tStandard mode ");
Serial.println(ens160.setMode(ENS160_OPMODE_STD) ? "done." : "failed!");
Serial.println("Initialization of ENS160 complete.");
#endif
connectToWiFi(); //Connect to the network
}
void loop() {
if((millis() - lastTime) > timerDelay){
//Read the values from the BME280
readBMEValues(); //Read the sensor values from the BME280
printBMEValuesToConsole(); //Print the values from the BME280 to the console
//Read the values from the ENS160
#ifdef USE_ENS160
if (ens160.available()) {
ens160.measure(true);
ens160.measureRaw(true);
readENSValues(); //Read the sensor values from the ENS160
printENSValuesToConsole(); //Print the sensor values from the ENS160 to the console
}
#endif
//Send the sensor data to the server
bool sendingSuccessful = postSensorData();
lastTime = millis();
}
}
void blinkLedErrorLoop(){
bool ledOnOff = true; //Write the internal LED HIGH (true) or LOW (false)
while(1){ //Endless loop
ledOnOff = !ledOnOff; //Toggle HIGH and LOW
digitalWrite(LED_BUILTIN, ledOnOff); //Write the LED HIGH or LOW
delay(500); //Wait for 1s
}
}
//Read the sensor values from the BME280
void readBMEValues(){
Serial.println("Reading the values from the BME280...");
temperature = bme.readTemperature(); //Read the temperature
humidity = bme.readHumidity(); //Read the humidity
pressure = bme.readPressure() / 100.0f;
}
//Print the sensor readings from the BME280 to the console
void printBMEValuesToConsole(){
Serial.println("Temperature: " + (String)temperature + "°C, Humidity: " + (String)humidity + "%, Pressure: " + (String)pressure + "hPa"); //Print the values of the BME280 to the console
}
#ifdef USE_ENS160
//Read the sensor values from the ENS160
void readENSValues(){
Serial.println("Reading the values from the ENS160...");
co2 = ens160.geteCO2(); //Read the CO2 value
}
//Print the sensor readings from the ENS160 to the console
void printENSValuesToConsole(){
Serial.println("CO2: " + (String)co2 + "ppm");
}
#endif
void connectToWiFi(){
WiFi.begin(ssid, password); //Connect to the network
Serial.print("Connecting to WiFi");
while(WiFi.status() != WL_CONNECTED){ //Print dots while not connected
Serial.print(".");
delay(500); //Wait half a second
}
Serial.println("\nConnected to network! IP: " + WiFi.localIP().toString() + ", Subnet mask: " + WiFi.subnetMask().toString() + ", Gateway: " + WiFi.gatewayIP().toString()); //Connection sucessful. Print IP address, subnet mask and gateway ip
}
void disconnectFromWiFi(){
Serial.print("Diconnecting from WiFi");
WiFi.disconnect(); //Disconnect and turn off WiFi
while(WiFi.status() == WL_CONNECTED){
Serial.print(".");
delay(500);
}
Serial.println("\nDisconnecting from WiFi sucessful.");
WiFi.mode(WIFI_OFF);
}
//Send the sensor data to the specified webserver using the post method and json format
bool postSensorData(){
if(WiFi.status() == WL_CONNECTED){ //Connected to the network
WiFiClient client; //WiFi client
HTTPClient http; //Http request client
http.begin(client, serverPath); //Begin a http request
http.addHeader("Content-Type", "application/json"); //Specify that the data format is json
//Specify the request data
//JSON format: {"key1":"value1", "key2":"value2", ...}
String requestDataJSON = "{\"mac_address\":\"" + WiFi.macAddress() + "\","; //Add the mac_address (unique id) to the request
requestDataJSON += "\"co2\":\"" + (String)co2 + "\","; //Add the co2 sensor value to the request
requestDataJSON += "\"temperature\":\"" + (String)temperature + "\","; //Add the temperature sensor value to the request
requestDataJSON += "\"humidity\":\"" + (String)humidity + "\"}"; //Add the humidity sensor value to the request
Serial.println("Sending JSON: " + requestDataJSON); //Print the request string
int httpResponseCode = http.POST(requestDataJSON); //Send the request with the JSON sensor data
Serial.println("Request sent! Response code: " + (String)httpResponseCode); //Print the response code
http.end(); //End the http request
return true;
}
else{ // ERROR: Not connected to the network
return false;
}
}
The serial output looks like this:
Initializing BME280...
Initialization of BME280 complete.
Initializing ENS160... Rev: 5.4.6
Standard mode done.
Initialization of ENS160 complete.
Connecting to WiFi.......
Connected to network! IP: 192.168.77.128, Subnet mask: 255.255.255.0, Gateway: 192.168.77.9
Reading the values from the BME280... Temperature: 21.88°C, Humidity: 43.15%, Pressure: 986.26hPa
Reading the values from the ENS160...
CO2: 0ppm
Sending JSON:{"mac_address":"40:91:51:45:21:15","co2":"0","temperature":"21.88","humidity":"43.15"} Request sent! Response code: 200
Any help is appreciated :) Thank you in advance!