Last active
August 23, 2023 05:50
-
-
Save bboyho/7a9b6badab4d0f2726f21984df80a6b2 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/****************************************************************************** | |
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