Skip to content

Instantly share code, notes, and snippets.

@bboyho
Last active August 23, 2023 05:50
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save bboyho/7a9b6badab4d0f2726f21984df80a6b2 to your computer and use it in GitHub Desktop.
Save bboyho/7a9b6badab4d0f2726f21984df80a6b2 to your computer and use it in GitHub Desktop.
/******************************************************************************
ENS160_BME280_microOLED.ino
WRITTEN BY: Ho Yun "Bobby" Chan
@ SparkFun Electronics
DATE: 8/22/2023
GITHUB REPO:
DEVELOPMENT ENVIRONMENT SPECIFICS:
Firmware developed using Arduino IDE v2.1.1
========== DESCRIPTION==========
This example code combines example codes from the ENS160 and BME280 libraries.
Most of the steps to obtain the measurements are the same as the example code.
Example 1: Basic w/ ENS160; Written by Elias Santistevan
Example 4: BME280 Temperature/ Relative Humidity Compensation; Originally Written by Elias Santistevan, Modified by Ho Yun "Bobby" Chan
Example 1: Basic Readings w/ BME280; Written by Nathan Seidle
Open a Serial Monitor at 115200 baud to view the readings!
Note: You may need to wait about ~5 minutes after starting up the code before VOC index
has any values.
========== HARDWARE CONNECTIONS ==========
Qwiic Micro => Environmental Combo Breakout - ENS160/BME280
Feel like supporting open source hardware?
Buy a board from SparkFun!
Qwiic Micro (SAMD21E) | https://www.sparkfun.com/products/15423
Environmental Combo Breakout - ENS160/BME280 | https://www.sparkfun.com/products/22858
Qwiic Micro OLED Breakout | https://www.sparkfun.com/products/14532
Instead of using the Qwiic Micro, this was also tested on a good old ATmega328P!
Note that you are getting close to it's limits though as the sketch uses about 95% of its
program storage space after compiling.
RedBoard Qwiic [https://www.sparkfun.com/products/15123]
Arduino Uno [https://www.sparkfun.com/products/11021]!
You can also get the sensors individually.
Qwiic Indoor Air Quality Sensor - ENS160 | https://www.sparkfun.com/products/20844
Qwiic Atmospheric Sensor - BME280 | https://www.sparkfun.com/products/15440
LICENSE: This code is released under the MIT License (http://opensource.org/licenses/MIT)
******************************************************************************/
#include <Wire.h>
// digital I/O pins
const byte STAT1 = 13; //defined as a LED_BUILTIN = 19 on Artemis Processor Board, use this if you want to manually define the LED
//const byte STAT1 = LED_BUILTIN;
boolean STAT1_blink = HIGH;
#define Serial SerialUSB //Comment out if you are not using a native USB like the Atmega32U4 or SAMD21
#include "SparkFunBME280.h" // Click here to get the library: http://librarymanager/All#SparkFun_BME280
BME280 myBME280;
float RH = 0.00; // Variable to keep track of BME280 temperature compensation for the ENS160
int32_t RHint_1 = 0;
int32_t RHint_2 = 0;
float temperature = 0.00; // Variable to keep track of BME280 relative humidity compensation for the ENS160 float temp_C = 0.00;
float temp_C = 0.00; // Variable to keep track of BME280 relative humidity compensation for the ENS160 float temp_C = 0.00;
int32_t temp_Cint_1 = 0;
int32_t temp_Cint_2 = 0;
int32_t temp_Cint_3 = 0;
float temp_F = 0.00; // Variable to keep track of BME280 relative humidity compensation for the ENS160
int32_t temp_Fint_1 = 0;
int32_t temp_Fint_2 = 0;
int32_t temp_Fint_3 = 0;
float pressure = 0;
float altitude_Feet = 5280;
float altitude_Meters = 1609;
#include "SparkFun_ENS160.h" // Click here to get the library: http://librarymanager/All#SparkFun_ENS160
SparkFun_ENS160 myENS;
bool printedCompensation = false;
int ensStatus;
float CO2_value = 0.00; // Variable to keep track of ENS160 CO2
int32_t CO2_value_int_1 = 0;
int32_t CO2_value_int_2 = 0;
int32_t CO2_value_int_3 = 0;
int32_t VOCindex = 100; // Variable to keep track of ENS160 VOC index
int AQI = 1; //Variable to keep track of AQI
#include <SFE_MicroOLED.h> //Click here to get the library: http://librarymanager/All#SparkFun_Micro_OLED
#define PIN_RESET 7
#define DC_JUMPER 1
MicroOLED oled(PIN_RESET, DC_JUMPER); // I2C declaration
///////////////////////////////
// Display Mode Page Control //
///////////////////////////////
// This enum defines all of our display modes and their order.
enum t_displayModes {
DISPLAY_RH_TEMP,
DISPLAY_PRESSURE_ALTITUDE,
DISPLAY_ENS_STATUS,
DISPLAY_AQI,
DISPLAY_CO2,
DISPLAY_VOC_INDEX,
DISPLAY_CUBE
};
const int NUM_DISPLAY_MODES = 7; // Number of values defined in enum above
volatile int displayMode = NUM_DISPLAY_MODES - 1; // Keeps track of current display page
const unsigned long DISPLAY_UPDATE_RATE = 5000; // Cycle display every 5 seconds
unsigned long lastDisplayUpdate = 0; // Stores time of last display update
unsigned long lastLEDUpdate = 0; // Stores time of last LED update
unsigned long lastSensorUpdate = 0; // Stores time of last sensor update
unsigned long currentMillis = 0; // Stores time of last display update
//boolean activity = true; //used to keep track of movement or button press
//const unsigned long noActivityMillis = NUM_DISPLAY_MODES * (DISPLAY_UPDATE_RATE + 1000); //used to compare amount of time when no activity to turn of screen
//unsigned long lastActivityMillis = 0;
float percentage = 0; //store percent for progress bar
int progressWidth = 0; // Width of progress bar depends on the [% * (64 pixels wide)]
int progressY = 0; //location of the progress bar at the botton of the microOLED
int SCREEN_WIDTH = oled.getLCDWidth();
int SCREEN_HEIGHT = oled.getLCDHeight();
float d = 3;
float px[] = {
-d, d, d, -d, -d, d, d, -d
};
float py[] = {
-d, -d, d, d, -d, -d, d, d
};
float pz[] = {
-d, -d, -d, -d, d, d, d, d
};
float p2x[] = {
0, 0, 0, 0, 0, 0, 0, 0
};
float p2y[] = {
0, 0, 0, 0, 0, 0, 0, 0
};
float r[] = {
0, 0, 0
};
#define SHAPE_SIZE 600
// Define how fast the cube rotates. Smaller numbers are faster.
// This is the number of ms between draws.
//#define ROTATION_SPEED 0
void updateDisplay() {
switch (displayMode) {
case DISPLAY_RH_TEMP:
displayRH_TEMP();
break;
case DISPLAY_PRESSURE_ALTITUDE:
displayPRESSURE_ALTITUDE();
break;
case DISPLAY_ENS_STATUS:
displayENS_STATUS();
break;
case DISPLAY_AQI:
displayAQI();
break;
case DISPLAY_CO2:
displayCO2();
break;
case DISPLAY_VOC_INDEX:
displayVOC_INDEX();
break;
case DISPLAY_CUBE:
drawCube();
break;
}
}
void displayRH_TEMP() {
//64x48 size screen => [64px-30px for smallest font]/2 = 17px each side to place text in middle
oled.setFontType(0); // Smallest font
oled.setCursor(17, 0); // Set cursor to top-middle
oled.print(F("BME280")); // Print
oled.setFontType(1); // medium font
oled.setCursor(0, 8); // Set cursor to top-ish
oled.print(F(" C"));
oled.setCursor(0, 8); // Set cursor to top-ish
//oled.print(String(temp_C, 2)); // Print temp, assuming that it is within room temp in tens <= floats doesn't convert too well with the Artemis Processor Board
temp_Cint_1 = temp_C * 100;
temp_Cint_1 = temp_Cint_1 / 100;
oled.print(String(temp_Cint_1)); // Print temp, assuming that it is within room temp in tens
oled.print(".");
temp_Cint_2 = temp_C * 10;
temp_Cint_2 = temp_Cint_2 % 10;
oled.print(String(temp_Cint_2)); // Print temp, assuming that it is within room temp in tens
temp_Cint_3 = temp_C * 100;
temp_Cint_3 = temp_Cint_3 % 10;
oled.print(String(temp_Cint_3)); // Print temp, assuming that it is within room temp in tens
oled.setCursor(0, 21); // Set cursor to middle-ish
oled.print(F(" F"));
oled.setCursor(0, 21); // Set cursor to middle-ish
//oled.print(String(temp_F, 2));// Print temp, assuming that it is within room temp in tens <= floats doesn't convert too well with the Artemis Processor Board
temp_Fint_1 = temp_F * 100;
temp_Fint_1 = temp_Fint_1 / 100;
oled.print(String(temp_Fint_1)); // Print temp, assuming that it is within room temp in tens
oled.print(".");
temp_Fint_2 = temp_F * 10;
temp_Fint_2 = temp_Fint_2 % 10;
oled.print(String(temp_Fint_2)); // Print temp, assuming that it is within room temp in tens
temp_Fint_3 = temp_F * 100;
temp_Fint_3 = temp_Fint_3 % 10;
oled.print(String(temp_Fint_3)); // Print temp, assuming that it is within room temp in tens
oled.circle(50, 9, 1); //"degree" sign after output values
oled.circle(50, 22, 1); //"degree" sign after output values
oled.setCursor(0, 34); // Set cursor to bottom-ish
oled.print(F(" %RH"));
oled.setCursor(0, 34); // Set cursor to bottom-ish
//oled.print(String(RH, 1)); // Print humidity, assuming that it is within humidity in tens <= floats doesn't convert too well with the Artemis Processor Board
RHint_1 = RH * 100;
RHint_1 = RHint_1 / 100;
oled.print(String(RHint_1)); // Print humidity, assuming that it is within humidity in tens
oled.print(".");
RHint_2 = RH * 10;
RHint_2 = RHint_2 % 10;
oled.print(String(RHint_2)); // Print humidity, assuming that it is within humidity in tens
}
void displayPRESSURE_ALTITUDE() {
//64x48 size screen => [64px-30px for smallest font]/2 = 17px each side to place text in middle
oled.setFontType(0); // Smallest font
oled.setCursor(17, 0); // Set cursor to top-middle
oled.print(F("BME280")); // Print
oled.setCursor(0, 8); // Set cursor to middle-ish
oled.setFontType(0); // medium font
oled.print(String(pressure, 2) + "Pa"); // Print pressure, assuming that it is within pressure in tens
oled.setCursor(0, 16); // Set cursor to middle-ish
oled.print(String(altitude_Feet, 2) + "ft"); // Print altitude, assuming that it is within altitude in tens
oled.setCursor(0, 24); // Set cursor to middle-ish
oled.print(String(altitude_Meters, 2) + "m"); // Print altitude, assuming that it is within altitude in tens
}
void displayENS_STATUS() {
//64x48 size screen => [64px-30px for smallest font]/2 = 17px each side to place text in middle
oled.setFontType(0); // Smallest font
oled.setCursor(17, 0); // Set cursor to middle-ish
oled.print(F("ENS160")); // Print
oled.setFontType(1); // medium font
oled.setCursor(8, 8); // Set cursor to middle-ish
oled.print(F("Status"));
//Range: 0 to 4
oled.setFontType(0); // small font
oled.setCursor(29, 21); // Set cursor to middle-ish
oled.print(String(ensStatus)); // Print ENS160 Status in tens
oled.setFontType(0); // small font
if (ensStatus == 0) {
oled.setCursor(9, 29); // Set cursor to middle-ish
oled.print(F("Operating"));
oled.setCursor(27, 37); // Set cursor to middle-ish
oled.print(F("Ok"));
} else if (ensStatus == 1) {
oled.setCursor(14, 29); // Set cursor to middle-ish
oled.print(F("Warm-up"));
} else if (ensStatus == 2) {
oled.setCursor(14, 29); // Set cursor to middle-ish
oled.print(F("Initial"));
oled.setCursor(12, 37); // Set cursor to middle-ish
oled.print(F("Start-up"));
} else if (ensStatus == 3) {
oled.setCursor(12, 29); // Set cursor to middle-ish
oled.print(F("No Valid"));
oled.setCursor(17, 37); // Set cursor to middle-ish
oled.print(F("Output"));
}
}
void displayAQI() {
//64x48 size screen => [64px-30px for smallest font]/2 = 17px each side to place text in middle
oled.setFontType(0); // Smallest font
oled.setCursor(17, 0); // Set cursor to middle-ish
oled.print(F("ENS160")); // Print
oled.setFontType(1); // medium font
oled.setCursor(2, 8); // Set cursor to middle-ish
oled.print(F("AQI-UBA"));
//Range: 1 to 5
oled.setFontType(2); // medium font
oled.setCursor(26, 21); // Set cursor to middle-ish
oled.print(String(AQI)); // Print AQI in tens
oled.setFontType(0); // small font
if (AQI == 1) {
oled.setCursor(8, 38); // Set cursor to middle-ish
oled.print(F("Excellent"));
} else if (AQI == 2) {
oled.setCursor(22, 38); // Set cursor to middle-ish
oled.print(F("Good"));
} else if (AQI == 3) {
oled.setCursor(12, 38); // Set cursor to middle-ish
oled.print(F("Moderate"));
} else if (AQI == 4) {
oled.setCursor(22, 38); // Set cursor to middle-ish
oled.print(F("Poor"));
} else if (AQI == 5) {
oled.setCursor(8, 38); // Set cursor to middle-ish
oled.print(F("Unhealthy"));
}
}
void displayCO2() {
//64x48 size screen => [64px-30px for smallest font]/2 = 17px each side to place text in middle
oled.setFontType(0); // Smallest font
oled.setCursor(17, 0); // Set cursor to middle-ish
oled.print(F("ENS160")); // Print
oled.setFontType(1); // medium font
oled.setCursor(2, 8); // Set cursor to middle-ish
oled.print(F("eCO"));
oled.setFontType(0); // small font
oled.setCursor(27, 12); // Set cursor to middle-ish
oled.print(F("2"));
oled.setCursor(35, 10); // Set cursor to middle-ish
oled.print(F("[ppm]"));
//Range: 400 to 65,000 ppm
//Resolution: 1 ppm
CO2_value_int_1 = CO2_value * 100;
CO2_value_int_1 = CO2_value_int_1 / 100;
oled.setFontType(2); // medium font
if (CO2_value_int_1 < 10) {
oled.setCursor(26, 21); // Set cursor to middle-ish
} else if (CO2_value_int_1 >= 10 && CO2_value_int_1 < 100) {
oled.setCursor(21, 21); // Set cursor to middle-ish
} else if (CO2_value_int_1 >= 100 && CO2_value_int_1 < 1000) {
oled.setCursor(16, 21); // Set cursor to middle-ish
} else if (CO2_value_int_1 >= 1000 && CO2_value_int_1 < 10000) {
oled.setCursor(11, 21); // Set cursor to middle-ish
} else if (CO2_value_int_1 >= 10000) {
oled.setCursor(8, 21); // Set cursor to middle-ish
}
oled.print(String(CO2_value_int_1)); // Print CO2, assuming that it is within CO2 in tens
/*
//Code to convert tens and thousandths for other type of CO2 Sensors that have resolution, this is not necssary for the ENS160
oled.print(".");
CO2_value_int_2 = CO2_value * 10;
CO2_value_int_2 = CO2_value_int_2 % 10;
oled.print(String(CO2_value_int_2)); // Print temp, assuming that it is within CO2 in tenths
CO2_value_int_3 = CO2_value * 100;
CO2_value_int_3 = CO2_value_int_3 % 10;
oled.print(String(CO2_value_int_3)); // Print temp, assuming that it is within CO2 in thousandths
*/
}
void displayVOC_INDEX() {
//64x48 size screen => [64px-30px for smallest font]/2 = 17px each side to place text in middle
oled.setFontType(0); // Smallest font
oled.setCursor(17, 0); // Set cursor to top-left
oled.print(F("ENS160")); // Print
oled.setFontType(1); // Smallest font
oled.setCursor(0, 8); // Set cursor to middle-ish
oled.print(F("TVOC"));
oled.setFontType(0); // Smallest font
oled.setCursor(35, 10); // Set cursor to middle-ish
oled.print(F("[ppb]"));
// Range: 0-65,000 ppb
// Resolution: 1 ppb
oled.setFontType(2); // medium font
if (VOCindex < 10) {
oled.setCursor(26, 21); // Set cursor to middle-ish
} else if (VOCindex >= 10 && VOCindex < 100) {
oled.setCursor(21, 21); // Set cursor to middle-ish
} else if (VOCindex >= 100 && VOCindex < 1000) {
oled.setCursor(16, 21); // Set cursor to middle-ish
} else if (VOCindex >= 1000 && VOCindex < 10000) {
oled.setCursor(11, 21); // Set cursor to middle-ish
} else if (VOCindex >= 10000) {
oled.setCursor(8, 21); // Set cursor to middle-ish
}
oled.print(String(VOCindex)); // Print tVOC, assuming that it is within tVOC in tens
}
void drawCube() {
r[0] = r[0] + 10 * PI / 180.0; // Add a degree
r[1] = r[1] + 10 * PI / 180.0; // Add a degree
r[2] = r[2] + 10 * PI / 180.0; // Add a degree
if (r[0] >= 360.0 * PI / 180.0) r[0] = 0;
if (r[1] >= 360.0 * PI / 180.0) r[1] = 0;
if (r[2] >= 360.0 * PI / 180.0) r[2] = 0;
for (int i = 0; i < 8; i++) {
float px2 = px[i];
float py2 = cos(r[0]) * py[i] - sin(r[0]) * pz[i];
float pz2 = sin(r[0]) * py[i] + cos(r[0]) * pz[i];
float px3 = cos(r[1]) * px2 + sin(r[1]) * pz2;
float py3 = py2;
float pz3 = -sin(r[1]) * px2 + cos(r[1]) * pz2;
float ax = cos(r[2]) * px3 - sin(r[2]) * py3;
float ay = sin(r[2]) * px3 + cos(r[2]) * py3;
float az = pz3 - 150;
p2x[i] = SCREEN_WIDTH / 2 + ax * SHAPE_SIZE / az;
p2y[i] = SCREEN_HEIGHT / 2 + ay * SHAPE_SIZE / az;
}
for (int i = 0; i < 3; i++) {
oled.line(p2x[i], p2y[i], p2x[i + 1], p2y[i + 1]);
oled.line(p2x[i + 4], p2y[i + 4], p2x[i + 5], p2y[i + 5]);
oled.line(p2x[i], p2y[i], p2x[i + 4], p2y[i + 4]);
}
oled.line(p2x[3], p2y[3], p2x[0], p2y[0]);
oled.line(p2x[7], p2y[7], p2x[4], p2y[4]);
oled.line(p2x[3], p2y[3], p2x[7], p2y[7]);
}
// This function draws a line at the very bottom of the screen showing how long
// it'll be before the screen updates.
// Based on Jim's micro OLED code used in the Photon SIK KIT => [ https://github.com/sparkfun/Inventors_Kit_For_Photon_Experiments/blob/master/11-OLEDApps/Code/02-WeatherForecast/WeatherApp.ino ]
void displayProgressBar() {
// Use lastDisplayUpdate's time, the time Arduino has been running
// (since we do not have an RTC, Internet, or GPS), and the total time
// per page (DISPLAY_UPDATE_RATE) to calculate what portion
// of the display bar needs to be drawn.
percentage = (float)(currentMillis - lastDisplayUpdate) / (float)DISPLAY_UPDATE_RATE;
//for debugging progress bar
//Serial.println(currentMillis);
//Serial.println(lastDisplayUpdate);
//Serial.println(DISPLAY_UPDATE_RATE);
//Serial.println(percentage);
//Serial.println(oled.getLCDWidth());
// Mutliply that value by the total lcd width to get the pixel length of our line
progressWidth = percentage * oled.getLCDWidth();
// the y-position of our line should be at the very bottom of the screen:
progressY = oled.getLCDHeight() - 1;
// First, draw a blank line to clear any old lines out:
oled.line(0, progressY, oled.getLCDWidth(), progressY, BLACK, NORM);
// Next, draw our line:
oled.line(0, progressY, progressWidth, progressY);
//oled.display(); // Update the display, this is already called after we exit this function
}
void setup() {
Serial.begin(115200);
//while (!Serial) ; // Wait for Serial Monitor/Plotter to open for Processors with Native USB (i.e. SAMD51)
// initialize digital pin LED_BUILTIN as an output.
pinMode(LED_BUILTIN, OUTPUT);
Serial.println(F("Initializing Combined Example w/ ENS160 and BME280."));
Wire.begin();
//Wire.setClock(400000); //Increase I2C clock speed to 400kHz
if (!myENS.begin()) {
Serial.println("Did not begin.");
while (1)
;
}
if (myBME280.beginI2C() == false) //Begin communication over I2C
{
Serial.println("The sensor did not respond. Please check wiring.");
while (1)
; //Freeze
}
// Reset the indoor air quality sensor's settings.
if (myENS.setOperatingMode(SFE_ENS160_RESET))
Serial.println("Ready.");
delay(100);
// Device needs to be set to idle to apply any settings.
// myENS.setOperatingMode(SFE_ENS160_IDLE);
// Set to standard operation
// Others include SFE_ENS160_DEEP_SLEEP and SFE_ENS160_IDLE
myENS.setOperatingMode(SFE_ENS160_STANDARD);
// There are four values here:
// 0 - Operating ok: Standard Operation
// 1 - Warm-up: occurs for 3 minutes after power-on.
// 2 - Initial Start-up: Occurs for the first hour of operation.
// and only once in sensor's lifetime.
// 3 - No Valid Output
ensStatus = myENS.getFlags();
Serial.print("Gas Sensor Status Flag: ");
Serial.println(ensStatus);
oled.begin(); // Initialize the OLED
oled.clear(ALL); // Clear the display's internal memory
oled.display(); // Display what's in the buffer (splashscreen)
delay(1000); // Delay 1000 ms
oled.clear(PAGE); // Clear the buffer.
//Quick test to check how many characters can go across screen
//oled.clear(ALL); // Clear the display's internal memory
//oled.setCursor(0, 0); // Set cursor to top-left
//oled.setFontType(0); // Smallest font
//oled.print(F("123456789;")); // Print, max is 10 characters across, 5x7-pixel characters
//oled.display(); // Display what's in the buffer (splashscreen)
//delay(1000); // Delay 1000 ms
} //end setup()
void loop() {
//get time based on how long the Arduino has been running
currentMillis = millis();
if (currentMillis >= lastSensorUpdate + 1100) //read sensors after about every 1100 milliseconds
{
Serial.print("Time:");
Serial.println(currentMillis);
//==============================
//==========READ BME280=========
//==============================
RH = myBME280.readFloatHumidity(); // "toPercent" returns the percent humidity as a floating point number
Serial.print(F("% RH = "));
Serial.print(RH);
Serial.println(F("%"));
Serial.print(F("Temperature = "));
temp_F = myBME280.readTempF();
Serial.print(temp_F); // "toDegF" return the temperature as a floating point number in deg F
Serial.print(F("°F, "));
temperature = myBME280.readTempC(); // "toDegC" returns the temperature as a floating point number in deg C
temp_C = temperature;
Serial.print(temp_C);
Serial.println(F("°C"));
pressure = myBME280.readFloatPressure();
Serial.print(F("Pressure = "));
Serial.print(pressure, 2);
Serial.println(F("Pa"));
altitude_Feet = myBME280.readFloatAltitudeFeet();
Serial.print(F("Altitude = "));
Serial.print(altitude_Feet, 2);
Serial.println(F("ft"));
altitude_Meters = myBME280.readFloatAltitudeMeters();
Serial.print(F("Altitude = "));
Serial.print(altitude_Meters, 2);
Serial.println(F("meters"));
//==============================
//==========READ ENS160=========
//==============================
if (myENS.checkDataStatus()) {
if (printedCompensation == false) {
//set temperature and RH
myENS.setTempCompensationCelsius(temp_C);
myENS.setRHCompensationFloat(RH);
delay(500); //add small delay for ENS160 to process
Serial.println("---------------------------");
Serial.print("Compensation Relative Humidity (%): ");
Serial.println(myENS.getRH());
Serial.println("---------------------------");
Serial.print("Compensation Temperature (Celsius): ");
Serial.println(myENS.getTempCelsius());
Serial.println("---------------------------");
printedCompensation = true;
delay(500);
}
// There are four values here:
// 0 - Operating ok: Standard Operation
// 1 - Warm-up: occurs for 3 minutes after power-on.
// 2 - Initial Start-up: Occurs for the first hour of operation.
// and only once in sensor's lifetime.
// 3 - No Valid Output
ensStatus = myENS.getFlags();
Serial.print("Gas Sensor Status Flag: ");
Serial.println(ensStatus);
AQI = myENS.getAQI();
Serial.print("Air Quality Index (1-5) : ");
Serial.println(AQI);
VOCindex = myENS.getTVOC();
Serial.print("Total Volatile Organic Compounds: ");
Serial.print(VOCindex);
Serial.println("ppb");
CO2_value = myENS.getECO2();
Serial.print("CO2 concentration: ");
Serial.print(CO2_value, 2);
Serial.println("ppm");
Serial.println();
}
lastSensorUpdate = currentMillis;
}
// Another method of updating display:
// The display will cycle itself every DISPLAY_UPDATE_RATE seconds
if ((currentMillis >= (lastDisplayUpdate + DISPLAY_UPDATE_RATE + 1000))) {
// Increment displayMode, next time through a new page will be displayed:
displayMode = (displayMode + 1) % NUM_DISPLAY_MODES;
// Update lastDisplayTime, so we don't come back for DISPLAY_UPDATE_RATE seconds
lastDisplayUpdate = currentMillis;
}
// display
oled.clear(PAGE); // Clear the display
updateDisplay();
displayProgressBar(); // Draws a progress bar at the bottom of the screen
oled.display();
if (currentMillis >= lastLEDUpdate + 1000) {
STAT1_blink = !STAT1_blink;
digitalWrite(STAT1, STAT1_blink); //Blink stat LED
lastLEDUpdate = currentMillis;
}
//================================
//=========SPACE & DELAY==========
//================================
//delay is calculated using millis instead of using a delay() function
//Serial.println("");// Uncomment this line to add some space between readings for the Serial Monitor
} //end loop()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment