From a44accafeeb2b71f158d94f80d17cefe52401381 Mon Sep 17 00:00:00 2001 From: SV-Zanshin Date: Wed, 27 May 2020 13:15:33 +0200 Subject: [PATCH 01/49] Update SDLoggerSPIDemo.ino --- examples/SDLoggerSPIDemo/SDLoggerSPIDemo.ino | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/SDLoggerSPIDemo/SDLoggerSPIDemo.ino b/examples/SDLoggerSPIDemo/SDLoggerSPIDemo.ino index 679e4ab..86219fe 100644 --- a/examples/SDLoggerSPIDemo/SDLoggerSPIDemo.ino +++ b/examples/SDLoggerSPIDemo/SDLoggerSPIDemo.ino @@ -70,7 +70,7 @@ Version | Date | Developer | Comments ** Declare all program constants ** *******************************************************************************************************************/ const uint8_t BME_680_SPI_CS_PIN = SS; ///< Use the standard SS pin for the BME680 -const uint8_t SD_CARD_SPI_CS_PIN = 24; ///< Use Pin A6 for the SD Card +const uint8_t SD_CARD_SPI_CS_PIN = 24; ///< Use Pin A6/D4 for the SD Card const uint32_t SERIAL_SPEED = 115200; ///< Set the baud rate for Serial I/O const uint8_t NUMBER_READINGS = 10; ///< Number of readings to average const uint32_t LONG_DELAY = 10000; ///< Long delay in milliseconds - 10 seconds From 056791d99b1af27b40e933727aabfc92f7a26884 Mon Sep 17 00:00:00 2001 From: Zanshin Date: Wed, 27 May 2020 13:35:28 +0200 Subject: [PATCH 02/49] Update SDLoggerSPIDemo.ino --- examples/SDLoggerSPIDemo/SDLoggerSPIDemo.ino | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/SDLoggerSPIDemo/SDLoggerSPIDemo.ino b/examples/SDLoggerSPIDemo/SDLoggerSPIDemo.ino index 86219fe..8b66cfe 100644 --- a/examples/SDLoggerSPIDemo/SDLoggerSPIDemo.ino +++ b/examples/SDLoggerSPIDemo/SDLoggerSPIDemo.ino @@ -28,7 +28,7 @@ This example program was designed as a simple data logger which defaults to meas Once either the temperature, pressure or humidity changes at a rate above that set in the constants TEMPERATURE_TRIP, PRESSURE_TRIP or HUMIDITY_TRIP then the measurement rate is sped up to read every second and to read more accurately. This was intended as a data logger inside a refrigerator or freezer, where most of the time there are constant -values but when the door is opened or the anti-icing cycle kicks in then readings need to be done more often. +values but when the door is opened or the defrosting cycle kicks in then readings need to be done more often. This example program initializes the BME680 to use SPI for communications. The library does not using floating point numbers to save on memory space and computation time. The values for Temperature, Pressure and Humidity are From 27dd60f73ff09e3f8f8b6b509430532dcd01d25c Mon Sep 17 00:00:00 2001 From: Zanshin Date: Wed, 27 May 2020 13:36:10 +0200 Subject: [PATCH 03/49] Check signature on commit --- examples/SDLoggerSPIDemo/SDLoggerSPIDemo.ino | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/SDLoggerSPIDemo/SDLoggerSPIDemo.ino b/examples/SDLoggerSPIDemo/SDLoggerSPIDemo.ino index 8b66cfe..e9e4c7e 100644 --- a/examples/SDLoggerSPIDemo/SDLoggerSPIDemo.ino +++ b/examples/SDLoggerSPIDemo/SDLoggerSPIDemo.ino @@ -63,7 +63,7 @@ Version | Date | Developer | Comments 1.0.0b | 2020-05-22 | https://github.com/SV-Zanshin | Cloned from original SPIDemo program and modified */ #include "Zanshin_BME680.h" // Include the BME680 Sensor library -#include // Include the SPI standard library (it is also included in the BME680 library) +#include // Include the SPI standard library (also included in the BME680 library) #include // Include the SD Card standard library /******************************************************************************************************************* From 2843e6d35ddde46e907181ce0bae7793ddc1b895 Mon Sep 17 00:00:00 2001 From: Zanshin Date: Wed, 27 May 2020 13:44:15 +0200 Subject: [PATCH 04/49] Checking GPG --- examples/SDLoggerSPIDemo/SDLoggerSPIDemo.ino | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/examples/SDLoggerSPIDemo/SDLoggerSPIDemo.ino b/examples/SDLoggerSPIDemo/SDLoggerSPIDemo.ino index e9e4c7e..0ab6e0c 100644 --- a/examples/SDLoggerSPIDemo/SDLoggerSPIDemo.ino +++ b/examples/SDLoggerSPIDemo/SDLoggerSPIDemo.ino @@ -145,10 +145,10 @@ void setup() and then control goes to the main "loop()" method, from which control never returns @return void */ - digitalWrite(SD_CARD_SPI_CS_PIN, HIGH); // Write a high value to it in order to deselect device - digitalWrite(BME_680_SPI_CS_PIN, HIGH); // Write a high value to it in order to deselect device pinMode(BME_680_SPI_CS_PIN, OUTPUT); // Declare the Chip-Select pin for the BME680 as output pinMode(SD_CARD_SPI_CS_PIN, OUTPUT); // Declare the Chip-Select pin for the SD Card as output + digitalWrite(SD_CARD_SPI_CS_PIN, HIGH); // Write a high value to it in order to deselect device + digitalWrite(BME_680_SPI_CS_PIN, HIGH); // Write a high value to it in order to deselect device Serial.begin(SERIAL_SPEED); // Start serial port at Baud rate #ifdef __AVR_ATmega32U4__ // If this is a 32U4 processor, delay(3000); // then wait 3 seconds to initialize USB port From a31a7eb1376286b7abe339941c0a84ae0e65c494 Mon Sep 17 00:00:00 2001 From: Zanshin Date: Wed, 27 May 2020 13:47:19 +0200 Subject: [PATCH 05/49] Test commit for checking GPG key --- examples/SDLoggerSPIDemo/SDLoggerSPIDemo.ino | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/examples/SDLoggerSPIDemo/SDLoggerSPIDemo.ino b/examples/SDLoggerSPIDemo/SDLoggerSPIDemo.ino index 0ab6e0c..090104e 100644 --- a/examples/SDLoggerSPIDemo/SDLoggerSPIDemo.ino +++ b/examples/SDLoggerSPIDemo/SDLoggerSPIDemo.ino @@ -200,7 +200,8 @@ void loop() */ if (loopCounter % 25 == 0) // Header every 25 loops { // - Serial.print(F("\nLoop Temp\xC2\xB0\x43 Humid% Press hPa Avg Tmp Avg Hum Avg hPa\n==== ====== ====== ========= ======= ====== =========\n")); // Show header plus unicode "°C" symbol + Serial.print(F("\nLoop Temp\xC2\xB0\x43 Humid% Press hPa Avg Tmp Avg Hum Avg hPa\n" + "==== ====== ====== ========= ======= ====== =========\n")); // Show header plus unicode "°C" symbol } // if-then time to show headers // idx = (idx+1) % NUMBER_READINGS; // increment and clamp BME680.getSensorData(data[idx].temperature, data[idx].humidity, // Read once at beginning From 65e89d3396e85328f56784f62eb19e133d8ff5db Mon Sep 17 00:00:00 2001 From: Zanshin Date: Thu, 28 May 2020 13:26:31 +0200 Subject: [PATCH 06/49] commented out serial on SDLoggerSPIDemo program, test upload to Travis-CI for other platforms --- examples/SDLoggerSPIDemo/SDLoggerSPIDemo.ino | 21 +++++++++++++++++--- 1 file changed, 18 insertions(+), 3 deletions(-) diff --git a/examples/SDLoggerSPIDemo/SDLoggerSPIDemo.ino b/examples/SDLoggerSPIDemo/SDLoggerSPIDemo.ino index 090104e..e7d48c7 100644 --- a/examples/SDLoggerSPIDemo/SDLoggerSPIDemo.ino +++ b/examples/SDLoggerSPIDemo/SDLoggerSPIDemo.ino @@ -66,11 +66,24 @@ Version | Date | Developer | Comments #include // Include the SPI standard library (also included in the BME680 library) #include // Include the SD Card standard library +//#define SERIAL_ATTACHED // When commented out then no output is done to the serial port +#ifndef SERIAL_ATTACHED +// disable Serial output +#define Serial SomeOtherwiseUnusedName +static class { +public: + void begin(...) {} + void print(...) {} + void println(...) {} +} Serial; +#endif + /******************************************************************************************************************* ** Declare all program constants ** *******************************************************************************************************************/ const uint8_t BME_680_SPI_CS_PIN = SS; ///< Use the standard SS pin for the BME680 const uint8_t SD_CARD_SPI_CS_PIN = 24; ///< Use Pin A6/D4 for the SD Card +const uint8_t LED_PIN = LED_BUILTIN; ///< Built-in LED pin const uint32_t SERIAL_SPEED = 115200; ///< Set the baud rate for Serial I/O const uint8_t NUMBER_READINGS = 10; ///< Number of readings to average const uint32_t LONG_DELAY = 10000; ///< Long delay in milliseconds - 10 seconds @@ -147,10 +160,12 @@ void setup() */ pinMode(BME_680_SPI_CS_PIN, OUTPUT); // Declare the Chip-Select pin for the BME680 as output pinMode(SD_CARD_SPI_CS_PIN, OUTPUT); // Declare the Chip-Select pin for the SD Card as output + pinMode(LED_PIN, OUTPUT); // Declare the builtin LED to be an output digitalWrite(SD_CARD_SPI_CS_PIN, HIGH); // Write a high value to it in order to deselect device digitalWrite(BME_680_SPI_CS_PIN, HIGH); // Write a high value to it in order to deselect device + digitalWrite(LED_PIN, LOW); // Turn off the LED Serial.begin(SERIAL_SPEED); // Start serial port at Baud rate - #ifdef __AVR_ATmega32U4__ // If this is a 32U4 processor, + #ifdef __AVR_ATmega32U4__ // If this is a 32U4 processor, delay(3000); // then wait 3 seconds to initialize USB port #endif Serial.print(F("Starting SDLoggerSPIDemo example program for BME680\n- Initializing BME680 sensor\n")); @@ -200,8 +215,8 @@ void loop() */ if (loopCounter % 25 == 0) // Header every 25 loops { // - Serial.print(F("\nLoop Temp\xC2\xB0\x43 Humid% Press hPa Avg Tmp Avg Hum Avg hPa\n" - "==== ====== ====== ========= ======= ====== =========\n")); // Show header plus unicode "°C" symbol + Serial.print(F("\nLoop Temp\xC2\xB0\x43 Humid% Press hPa Avg Tmp Avg Hum Avg hPa\n" // Show header plus the + "==== ====== ====== ========= ======= ====== =========\n")); // unicode "°C" symbol } // if-then time to show headers // idx = (idx+1) % NUMBER_READINGS; // increment and clamp BME680.getSensorData(data[idx].temperature, data[idx].humidity, // Read once at beginning From 9e17fe7502c5e6384ffa54338e530ec4da5bad14 Mon Sep 17 00:00:00 2001 From: Arnd Date: Fri, 29 May 2020 14:56:12 +0200 Subject: [PATCH 07/49] Update README.md --- .github/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/README.md b/.github/README.md index 257a84b..7e31a66 100644 --- a/.github/README.md +++ b/.github/README.md @@ -1,4 +1,4 @@ -# BME680 library
[![Build Status](https://travis-ci.org/SV-Zanshin/BME680.svg?branch=master)](https://travis-ci.org/SV-Zanshin/BME680) [![DOI](https://zenodo.org/badge/139349456.svg)](https://zenodo.org/badge/latestdoi/139349456) [![arduino-library-badge](https://www.ardu-badge.com/badge/BME680.svg?)](https://www.ardu-badge.com/BME680) +# BME680 library
[![Build Status](https://travis-ci.org/SV-Zanshin/BME680.svg?branch=master)](https://travis-ci.org/SV-Zanshin/BME680) [![arduino-library-badge](https://www.ardu-badge.com/badge/BME680.svg?)](https://www.ardu-badge.com/BME680) [![DOI](https://zenodo.org/badge/139349456.svg)](https://zenodo.org/badge/latestdoi/139349456) *Arduino* library for using the [Bosch BME680](https://www.bosch-sensortec.com/bst/products/all_products/bme680) sensor which senses temperature, humidity and pressure. The BME680 is a tiny package and no hobbyist is going to be breadboarding this sensor directly, so one will be part of a breakout board. Here are some breakout board examples: | Supplier | Image | Instructions | Comments | From 18a440c7b5054dcfc5bccf6ab8fef2b6973a950f Mon Sep 17 00:00:00 2001 From: Zanshin Date: Sun, 31 May 2020 13:41:03 +0200 Subject: [PATCH 08/49] Initial Commit of ESP32FeatherWiFiDemo program --- examples/ESP32FeatherWiFiDemo/.due.test.skip | 0 .../ESP32FeatherWiFiDemo/.esp8266.test.skip | 0 .../ESP32FeatherWiFiDemo/.leonardo.test.skip | 0 examples/ESP32FeatherWiFiDemo/.m4.test.skip | 0 .../ESP32FeatherWiFiDemo/.mega2560.test.skip | 0 examples/ESP32FeatherWiFiDemo/.uno.test.skip | 0 examples/ESP32FeatherWiFiDemo/.zero.test.skip | 0 .../ESP32FeatherWiFiDemo/Authentication.h | 3 + .../ESP32FeatherWiFiDemo.ino | 258 ++++++++++++++++++ .../ESP32FeatherWiFiDemo/WebPageContents.h | 157 +++++++++++ examples/SDLoggerSPIDemo/SDLoggerSPIDemo.ino | 22 +- 11 files changed, 436 insertions(+), 4 deletions(-) create mode 100644 examples/ESP32FeatherWiFiDemo/.due.test.skip create mode 100644 examples/ESP32FeatherWiFiDemo/.esp8266.test.skip create mode 100644 examples/ESP32FeatherWiFiDemo/.leonardo.test.skip create mode 100644 examples/ESP32FeatherWiFiDemo/.m4.test.skip create mode 100644 examples/ESP32FeatherWiFiDemo/.mega2560.test.skip create mode 100644 examples/ESP32FeatherWiFiDemo/.uno.test.skip create mode 100644 examples/ESP32FeatherWiFiDemo/.zero.test.skip create mode 100644 examples/ESP32FeatherWiFiDemo/Authentication.h create mode 100644 examples/ESP32FeatherWiFiDemo/ESP32FeatherWiFiDemo.ino create mode 100644 examples/ESP32FeatherWiFiDemo/WebPageContents.h diff --git a/examples/ESP32FeatherWiFiDemo/.due.test.skip b/examples/ESP32FeatherWiFiDemo/.due.test.skip new file mode 100644 index 0000000..e69de29 diff --git a/examples/ESP32FeatherWiFiDemo/.esp8266.test.skip b/examples/ESP32FeatherWiFiDemo/.esp8266.test.skip new file mode 100644 index 0000000..e69de29 diff --git a/examples/ESP32FeatherWiFiDemo/.leonardo.test.skip b/examples/ESP32FeatherWiFiDemo/.leonardo.test.skip new file mode 100644 index 0000000..e69de29 diff --git a/examples/ESP32FeatherWiFiDemo/.m4.test.skip b/examples/ESP32FeatherWiFiDemo/.m4.test.skip new file mode 100644 index 0000000..e69de29 diff --git a/examples/ESP32FeatherWiFiDemo/.mega2560.test.skip b/examples/ESP32FeatherWiFiDemo/.mega2560.test.skip new file mode 100644 index 0000000..e69de29 diff --git a/examples/ESP32FeatherWiFiDemo/.uno.test.skip b/examples/ESP32FeatherWiFiDemo/.uno.test.skip new file mode 100644 index 0000000..e69de29 diff --git a/examples/ESP32FeatherWiFiDemo/.zero.test.skip b/examples/ESP32FeatherWiFiDemo/.zero.test.skip new file mode 100644 index 0000000..e69de29 diff --git a/examples/ESP32FeatherWiFiDemo/Authentication.h b/examples/ESP32FeatherWiFiDemo/Authentication.h new file mode 100644 index 0000000..9f5c9ae --- /dev/null +++ b/examples/ESP32FeatherWiFiDemo/Authentication.h @@ -0,0 +1,3 @@ +#pragma once +const char* WIFI_SSID = "YourNetworkNameGoesHere"; ///< Network to connect to +const char* WIFI_PASSWORD = "EnterPasswordHere"; ///< Network authentication code diff --git a/examples/ESP32FeatherWiFiDemo/ESP32FeatherWiFiDemo.ino b/examples/ESP32FeatherWiFiDemo/ESP32FeatherWiFiDemo.ino new file mode 100644 index 0000000..7ed8e28 --- /dev/null +++ b/examples/ESP32FeatherWiFiDemo/ESP32FeatherWiFiDemo.ino @@ -0,0 +1,258 @@ +/*! @file ESP32FeatherWiFiDemo.ino + +@section ESP32FeatherWiFiDemo_intro_section Description + +Example program for using an Arduino ESP32 based system (this sketch was developed and tested on a ESP32 Huzzah32 +Feather board from https://www.adafruit.com/product/3405) along with a BME680 connected via I2C to monitor the +temperature, pressure and humidity and report the values in a dynamic chart on a web page hosted by the ESP32 +and connected to a local network. + +Prior to compiling the program, the contents of the include file "Authentication.h" need to be updated to reflect +the local WiFi network to use and the corresponding authentication code. + +Once started, the IP-Address is set by the WiFi router and displayed on the serial output of the ESP32, this IP +address should then be entered as the URL in a web browser of a computer attached to the same network and the +data should be presented there, updated every 5 seconds. + +The Bosch BME680 sensor measures temperature, pressure, humidity and air quality and is described at +https://www.bosch-sensortec.com/bst/products/all_products/BME680. The datasheet is available from Bosch at +https://ae-bst.resource.bosch.com/media/_tech/media/datasheets/BST-BME680_DS001-11.pdf \n\n + +The most recent version of the BME680 library is available at https://github.com/SV-Zanshin/BME680 and the +documentation of the library as well as example programs are described in the project's wiki pages located at +https://github.com/SV-Zanshin/BME680/wiki. \n\n + +The BME680 is an extremely small physical package that is so tiny as to be impossible to solder at home, hence it +will be used as part of a third-party breakout board. There are several such boards available at this time, for +example \n +Company | Link +------- | ---------- +Sparkfun | https://www.sparkfun.com/products/14570 +BlueDot | https://www.bluedot.space/sensor-boards/bme680/ +Adafruit | https://learn.adafruit.com/adafruit-BME680-humidity-barometric-pressure-temperature-sensor-breakout \n\n + +Bosch supplies sample software that runs on various platforms, including the Arduino family; this can be downloaed +at https://github.com/BoschSensortec/BSEC-Arduino-library . This software is part of the Bosch "BSEC" (Bosch +Sensortec Environmental Cluster) framework and somewhat bulky and unwieldy for typical Arduino applications, hence +the choice to make a more compact and rather less abstract library. + +The pressure reading needs to be adjusted for altitude to get the adjusted pressure reading. There are numerous +sources on the internet for formulae converting from standard sea-level pressure to altitude, see the data sheet +for the BME180 on page 16 of http://www.adafruit.com/datasheets/BST-BMP180-DS000-09.pdf. Rather than put a +floating-point function in the library which may not be used but which would use space, an example altitude +computation function has been added to this example program to show how it might be done. + +@section ESP32FeatherWiFiDemolicense License + +This program is free software: you can redistribute it and/or modify it under the terms of the GNU General +Public License as published by the Free Software Foundation, either version 3 of the License, or (at your +option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY +WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. You should have received a copy of the GNU General Public License +along with this program. If not, see . + +@section ESP32FeatherWiFiDemoauthor Author + +Written by Arnd\@SV-Zanshin + +@section ESP32FeatherWiFiDemoversions Changelog + +Version | Date | Developer | Comments +------- | ---------- | ----------------------------- | ------------------------------------------- +1.0.0b | 2020-05-30 | https://github.com/SV-Zanshin | Initial coding +*/ + +#if !defined(ESP32) + #error This example program is designed specifically for the ESP32 platform and might not work on other platforms +#endif + +/******************************************************************************************************************* +** Declare all include files required ** +*******************************************************************************************************************/ +#include ///< Include the SPI standard library +#include ///< Include the SD Card standard library +#include ///< ESP32 WiFi Library +#include ///< WiFi Client library +#include ///< WiFi Web Server library +#include "WebPageContents.h" ///< Include external HTML and JavaScript definitions +#include "Authentication.h" ///< Contains the network SSID and authentication code +#include "Zanshin_BME680.h" ///< The BME680 sensor library + +/******************************************************************************************************************* +** Declare all program constants ** +*******************************************************************************************************************/ +const uint32_t SERIAL_SPEED = 115200; ///< Set the baud rate for Serial I/O +const uint8_t POWER_PIN = A13; ///< Supply voltage through a divider +const uint8_t LED_PIN = 13; ///< This pin is the on-board red LED +const uint8_t SD_CARD_SPI_CS_PIN = 21; ///< Use Pin 21 (general GPIO) on the ESP32 for chip select +const uint8_t SD_CARD_SPI_CD_PIN = A5; ///< Use Pin A5 (general GPIO) on the ESP32 for carrier detect +const char* FILE_NAME = "/BME_680.csv"; ///< Filename on SD-Card +const uint32_t SD_LOG_INTERVAL = 1000; ///< Milliseconds between measurements to SD-Card +const uint8_t SD_FLUSH_INTERVAL = 60; ///< do a "flush" after this number of writes + +/******************************************************************************************************************* +** Declare all program macros ** +*******************************************************************************************************************/ +#define VOLTAGE (analogRead(POWER_PIN)/4095.0*3.3*2*1.1) ///< Macro for floating point voltage +/******************************************************************************************************************* +** Declare all global variables ** +*******************************************************************************************************************/ +WebServer server(80); ///< Instantiate a web server on port 80 +BME680_Class BME680; ///< Create an instance of the BME680 class +File dataFile; ///< Class for a SD-Card file +int32_t temperature; ///< BME680 temperature value +int32_t humidity; ///< BME680 humidity value +int32_t pressure; ///< BME680 pressure value +int32_t gas; ///< BME680 gas resistance value +int32_t start_pressure; ///< Initial pressure reading +bool sd_card_present = false; ///< Switch set when SD-Card detected +String jsonData; ///< JSON data string +uint16_t loopCounter = 0; ///< Counter for number of write operations since startup +uint32_t next_log_millis; ///< Millis() value for next SD-Card measurement + +void setup() +{ + pinMode(SD_CARD_SPI_CS_PIN, OUTPUT); // Declare the Chip-Select pin for the SD Card as output + pinMode(SD_CARD_SPI_CD_PIN, INPUT_PULLUP); // Declare the Carrier detect pin for the SD Card as input + digitalWrite(SD_CARD_SPI_CS_PIN, HIGH); // Write a high value to it in order to deselect device + pinMode(LED_PIN, OUTPUT); // make the LED an output pin + Serial.begin(115200); + Serial.print(F("Starting ESP32FeatherWiFiDemo example program for BME680\n")); + /********************** + ** Initialize BME680 ** + **********************/ + Serial.print(F("- Initializing BME680 sensor\n")); + while (!BME680.begin(I2C_STANDARD_MODE)) // Start BME680 using I2C, use first device found + { + Serial.print(F("- Unable to find BME680. Trying again in 5 seconds.\n")); + delay(5000); + } // of loop until device is located + Serial.print(F("- Setting 16x oversampling for all sensors\n")); + BME680.setOversampling(TemperatureSensor, Oversample16); // Use enumerated type values to set value + BME680.setOversampling(HumiditySensor, Oversample16); // Use enumerated type values to set value + BME680.setOversampling(PressureSensor, Oversample16); // Use enumerated type values to set value + Serial.print(F("- Setting IIR filter to a value of 4 samples\n")); + BME680.setIIRFilter(IIR4); // Use enumerated type values + Serial.print(F("- Turning off gas measurements\n")); + BME680.setGas(0, 0); // Setting either to 0 turns off gas measurement + BME680.getSensorData(temperature, humidity, start_pressure, gas); // Get most recent readings + /*************************************************************** + ** Initialize SD-Card for logging, if not found then continue ** + ***************************************************************/ + Serial.print(F("- Checking to see if SD Card connected\n")); + if (!digitalRead(SD_CARD_SPI_CD_PIN)) + { + sd_card_present = false; // if pin is high then no card inserted + } + else + { + uint8_t loopCounter = 10; ///< countdown to 0 to detect car + while (--loopCounter && !SD.begin(SD_CARD_SPI_CS_PIN)) // Try to start card using SPI + { + Serial.print(F("- Unable to find SD Card. Trying again in 5 seconds.\n")); + for (uint8_t i = 0; i < 50; i++) + { + digitalWrite(LED_PIN, !digitalRead(LED_PIN)); + delay(100); + } // loop to toggle LED light 10 times + } // of loop until device is located + if (loopCounter) sd_card_present = true; + } // if-then card is inserted + if (!sd_card_present) + { + Serial.print(F("- No SD-Card detected, continuing\n")); + } + else + { + Serial.print(F("- SD-Card Initialized\n")); + dataFile = SD.open(FILE_NAME, FILE_WRITE); // Open the logfile for writing and position to end-of-file + if (!dataFile) + { + Serial.print(F("Unable to open file \"")); + Serial.print(FILE_NAME); + Serial.print(F("\" on SD-Card. Error. Skipping SD writes.")); + sd_card_present = false; // turn off card + } + else + { + Serial.print(F("- File \"")); + Serial.print(FILE_NAME); + Serial.print(F("\" successfully opened. Appending data.\n")); + dataFile.print("Counter,Seconds,SupplyVoltage,Temperature,Humidity,Pressure\n"); + } // if-then-else the file could be opened + } // if-then-else SD-Card located + /********************************************** + ** Connect to the specified wireless network ** + **********************************************/ + Serial.print(F("- Connecting to Wireless network \"")); + Serial.print(WIFI_SSID); + Serial.print(F("\".")); + WiFi.begin(WIFI_SSID, WIFI_PASSWORD); // Connect to the specified WiFi router + while (WiFi.status() != WL_CONNECTED) // Loop until the connection is established + { + delay(1000); // wait one second before trying again + Serial.print("."); + } // for-next connection not established + WiFi.setHostname("BME680"); // Give our device a name + // Show connection data + Serial.print("\n- Open browser to IP address \""); + Serial.print(WiFi.localIP()); + Serial.print("\"\n- or to \"http://BME680\" to view data.\n"); + server.on("/", handleRoot); // Routine for root page call + server.on("/readADC", handleADC); // Page called by AJAX + server.begin(); //Start server + Serial.println("HTTP server started"); +} // of method "setup()" + +void handleRoot() +{ + //=============================================================== + // This routine is executed when you open its IP in browser + //=============================================================== + String s = MAIN_page; //Read HTML contents + server.send(200, "text/html", s); //Send web page +} // of method "handleRoot()" + +void handleADC() +{ + server.send(200, "text/plain", jsonData); // Send JSON to client ajax request +} + +void loop() +{ + server.handleClient(); // Handle client requests + if (millis() > next_log_millis) + { + next_log_millis = millis() + SD_LOG_INTERVAL; // set next timer + getSensorData(); // get the BME680 data + } // if-then time to get a measurement +} // of method "loop()" + +void getSensorData() +{ + Serial.print("."); + digitalWrite(LED_PIN, !digitalRead(LED_PIN)); // Toggle LED each loop + BME680.getSensorData(temperature, humidity, pressure, gas); // Get the most recent readings from the BME680 + if (sd_card_present) // Log data to the SD-Card, if present + { + dataFile.print(++loopCounter); + dataFile.print(","); + dataFile.print(millis() / 1000); + dataFile.print(","); + dataFile.print(VOLTAGE); + dataFile.print(","); + dataFile.print(temperature / 100.0, 2); + dataFile.print(","); + dataFile.print(humidity / 1000.0, 2); + dataFile.print(","); + dataFile.println(pressure / 100.0, 2); + if (loopCounter % SD_FLUSH_INTERVAL == 0) + { + dataFile.flush(); + Serial.print("\nFlushed data to SD-Card\n"); + } // flush the buffer + } // if-then SD card is present + jsonData = "{\"SupplyVoltage\":\"" + String(VOLTAGE) + "\", \"Temperature\":\"" + + String(temperature / 100.0) + "\", \"Humidity\":\"" + String(humidity / 1000.0) + + "\", \"Pressure\":\"" + String((start_pressure - pressure) / 100.0) + "\"}"; +} // of method "getSensorData()" diff --git a/examples/ESP32FeatherWiFiDemo/WebPageContents.h b/examples/ESP32FeatherWiFiDemo/WebPageContents.h new file mode 100644 index 0000000..60896e3 --- /dev/null +++ b/examples/ESP32FeatherWiFiDemo/WebPageContents.h @@ -0,0 +1,157 @@ +const char MAIN_page[] PROGMEM = R"=====( + + + + ESP32 Feather BME680 WiFi Program + + + + +
Zanshin Logo Zanshin
+
+ +
+
+ + +
TimeSupply VoltageTemperature °CRelative Humidity %Pressure Pa
+
+
+
+ + + + + + + + Untitled Document + +)====="; \ No newline at end of file diff --git a/examples/SDLoggerSPIDemo/SDLoggerSPIDemo.ino b/examples/SDLoggerSPIDemo/SDLoggerSPIDemo.ino index e7d48c7..fbec078 100644 --- a/examples/SDLoggerSPIDemo/SDLoggerSPIDemo.ino +++ b/examples/SDLoggerSPIDemo/SDLoggerSPIDemo.ino @@ -163,7 +163,7 @@ void setup() pinMode(LED_PIN, OUTPUT); // Declare the builtin LED to be an output digitalWrite(SD_CARD_SPI_CS_PIN, HIGH); // Write a high value to it in order to deselect device digitalWrite(BME_680_SPI_CS_PIN, HIGH); // Write a high value to it in order to deselect device - digitalWrite(LED_PIN, LOW); // Turn off the LED + digitalWrite(LED_PIN, HIGH); // Turn on the LED Serial.begin(SERIAL_SPEED); // Start serial port at Baud rate #ifdef __AVR_ATmega32U4__ // If this is a 32U4 processor, delay(3000); // then wait 3 seconds to initialize USB port @@ -172,7 +172,11 @@ void setup() while (!BME680.begin(BME_680_SPI_CS_PIN)) // Start BME680 using hardware SPI protocol { Serial.print(F("- Unable to find BME680. Trying again in 5 seconds.\n")); - delay(5000); + for (uint8_t i = 0; i < 50; i++) + { + digitalWrite(LED_PIN, !digitalRead(LED_PIN)); + delay(100); + } // loop to toggle LED light 10 times } // of loop until device is located normalMode(); BME680.getSensorData(data[idx].temperature, data[idx].humidity, data[idx].pressure, unused_gas); @@ -182,7 +186,11 @@ void setup() while (!SD.begin(SD_CARD_SPI_CS_PIN)) // Start card using hardware SPI protocol { Serial.print(F("- Unable to find SD Card. Trying again in 5 seconds.\n")); - delay(5000); + for (uint8_t i = 0; i < 50; i++) + { + digitalWrite(LED_PIN, !digitalRead(LED_PIN)); + delay(100); + } // loop to toggle LED light 10 times } // of loop until device is located Serial.print(F("- SD-Card Initialized\n")); dataFile = SD.open(FILE_NAME, FILE_WRITE); // Open the logfile for writing and position to end-of-file @@ -203,6 +211,7 @@ void setup() data[i].humidity = data[0].humidity; data[i].pressure = data[0].pressure; } // of for-next each array element + digitalWrite(LED_PIN, LOW); // turn off LED } // of method setup() void loop() { @@ -286,6 +295,11 @@ void loop() (uint8_t)(data[idx].pressure % 100)); dataFile.print(buf); - if (idx == 0) dataFile.flush(); // force a SD write every cycle + if (idx == 0) + { + digitalWrite(LED_PIN, HIGH); // turn on LED + dataFile.flush(); // force a SD write every cycle + digitalWrite(LED_PIN, LOW); // turn off LED + } // if-then time to flush buffer to SD-Card delay(delayTime); // Wait appropriate amount of time } // of method loop() \ No newline at end of file From 671f2ddb2313e0aeb484fdbfc38d64217cc37792 Mon Sep 17 00:00:00 2001 From: Arnd Date: Sun, 31 May 2020 13:45:22 +0200 Subject: [PATCH 09/49] Created file to ignore this header The header contains sensitive information, so is skipped on commits --- examples/ESP32FeatherWiFiDemo/.gitignore | 10 ++++++++++ 1 file changed, 10 insertions(+) create mode 100644 examples/ESP32FeatherWiFiDemo/.gitignore diff --git a/examples/ESP32FeatherWiFiDemo/.gitignore b/examples/ESP32FeatherWiFiDemo/.gitignore new file mode 100644 index 0000000..265fb85 --- /dev/null +++ b/examples/ESP32FeatherWiFiDemo/.gitignore @@ -0,0 +1,10 @@ +######################################################################## +# This file defines which file types are to be ignroed and skipped by # +# git so that they are not transferred and committed. # +# # +# Date Author Comments # +# ========== ============================= =========================== # +# 2020-05-31 https://github.com/SV-Zanshin Ignore for authentication # +# # +######################################################################## +Authentication.h From 1ab28fd2aba116f415d70b677b3c170790359dce Mon Sep 17 00:00:00 2001 From: Arnd Date: Sun, 31 May 2020 13:51:04 +0200 Subject: [PATCH 10/49] Added ignore for Authentication.h File can contain sensitive information, don't commit --- .gitignore | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/.gitignore b/.gitignore index fb86e28..57ef430 100644 --- a/.gitignore +++ b/.gitignore @@ -1,9 +1,10 @@ ######################################################################## -# This file defines which file types are to be ignroed and skipped by # +# This file defines which file types are to be ignored and skipped by # # git so that they are not transferred and committed. # # # # Date Author Comments # # ========== ============================= =========================== # +# 2020-05-31 https://github.com/SV-Zanshin Ignore for Authentication # # 2019-02-02 https://github.com/SV-Zanshin Ignores for Doxygen # # 2018-09-22 https://github.com/SV-Zanshin Ignores for MS VS 2017 # # 2018-06-24 https://github.com/SV-Zanshin Changed file # @@ -94,3 +95,7 @@ Release ######################################################################## html +######################################################################## +# Files that contain sensitive information # +######################################################################## +Authentication.h From f1b5e19789992ff35062ed7d1e1047298789e794 Mon Sep 17 00:00:00 2001 From: Zanshin Date: Sun, 31 May 2020 13:53:18 +0200 Subject: [PATCH 11/49] Corrected Data --- examples/ESP32FeatherWiFiDemo/.gitignore | 10 ---------- examples/ESP32FeatherWiFiDemo/Authentication.h | 5 +++-- 2 files changed, 3 insertions(+), 12 deletions(-) delete mode 100644 examples/ESP32FeatherWiFiDemo/.gitignore diff --git a/examples/ESP32FeatherWiFiDemo/.gitignore b/examples/ESP32FeatherWiFiDemo/.gitignore deleted file mode 100644 index 265fb85..0000000 --- a/examples/ESP32FeatherWiFiDemo/.gitignore +++ /dev/null @@ -1,10 +0,0 @@ -######################################################################## -# This file defines which file types are to be ignroed and skipped by # -# git so that they are not transferred and committed. # -# # -# Date Author Comments # -# ========== ============================= =========================== # -# 2020-05-31 https://github.com/SV-Zanshin Ignore for authentication # -# # -######################################################################## -Authentication.h diff --git a/examples/ESP32FeatherWiFiDemo/Authentication.h b/examples/ESP32FeatherWiFiDemo/Authentication.h index 9f5c9ae..d0a24a8 100644 --- a/examples/ESP32FeatherWiFiDemo/Authentication.h +++ b/examples/ESP32FeatherWiFiDemo/Authentication.h @@ -1,3 +1,4 @@ #pragma once -const char* WIFI_SSID = "YourNetworkNameGoesHere"; ///< Network to connect to -const char* WIFI_PASSWORD = "EnterPasswordHere"; ///< Network authentication code +const char* WIFI_SSID = "Zanshin"; ///< Network to connect to +const char* WIFI_PASSWORD = "TANSTAAFl1!"; ///< Network authentication code + From 9262f9823aa8e060a5c12179d96787a450a69b6b Mon Sep 17 00:00:00 2001 From: Zanshin Date: Sun, 31 May 2020 13:59:42 +0200 Subject: [PATCH 12/49] Update Authentication.h --- examples/ESP32FeatherWiFiDemo/Authentication.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/examples/ESP32FeatherWiFiDemo/Authentication.h b/examples/ESP32FeatherWiFiDemo/Authentication.h index d0a24a8..3e188fd 100644 --- a/examples/ESP32FeatherWiFiDemo/Authentication.h +++ b/examples/ESP32FeatherWiFiDemo/Authentication.h @@ -1,4 +1,4 @@ #pragma once -const char* WIFI_SSID = "Zanshin"; ///< Network to connect to -const char* WIFI_PASSWORD = "TANSTAAFl1!"; ///< Network authentication code +const char* WIFI_SSID = "YourNetworkNameGoesHere"; ///< Network to connect to +const char* WIFI_PASSWORD = "EnterPasswordHere"; ///< Network authentication code From f702a242bfb602c61d33aa150e18e6c67fc12a9e Mon Sep 17 00:00:00 2001 From: Zanshin Date: Mon, 1 Jun 2020 14:04:10 +0200 Subject: [PATCH 13/49] Initial commit of ESP32FeatherWiFiDemo.ino Initial program commit. Functioning prototype, but need to see what Travis CI has to say about it. --- .gitignore | 6 +- .../ESP32FeatherWiFiDemo/Authentication.h | 4 - .../ESP32FeatherWiFiDemo.ino | 198 +++++++++++------- .../ESP32FeatherWiFiDemo/WebPageContents.h | 54 ++--- 4 files changed, 149 insertions(+), 113 deletions(-) delete mode 100644 examples/ESP32FeatherWiFiDemo/Authentication.h diff --git a/.gitignore b/.gitignore index 57ef430..3356502 100644 --- a/.gitignore +++ b/.gitignore @@ -4,6 +4,7 @@ # # # Date Author Comments # # ========== ============================= =========================== # +# 2020-06-01 https://github.com/SV-Zanshin Removed ignore again # # 2020-05-31 https://github.com/SV-Zanshin Ignore for Authentication # # 2019-02-02 https://github.com/SV-Zanshin Ignores for Doxygen # # 2018-09-22 https://github.com/SV-Zanshin Ignores for MS VS 2017 # @@ -94,8 +95,3 @@ Release # Files and directories from Doxygen # ######################################################################## html - -######################################################################## -# Files that contain sensitive information # -######################################################################## -Authentication.h diff --git a/examples/ESP32FeatherWiFiDemo/Authentication.h b/examples/ESP32FeatherWiFiDemo/Authentication.h deleted file mode 100644 index 3e188fd..0000000 --- a/examples/ESP32FeatherWiFiDemo/Authentication.h +++ /dev/null @@ -1,4 +0,0 @@ -#pragma once -const char* WIFI_SSID = "YourNetworkNameGoesHere"; ///< Network to connect to -const char* WIFI_PASSWORD = "EnterPasswordHere"; ///< Network authentication code - diff --git a/examples/ESP32FeatherWiFiDemo/ESP32FeatherWiFiDemo.ino b/examples/ESP32FeatherWiFiDemo/ESP32FeatherWiFiDemo.ino index 7ed8e28..581854a 100644 --- a/examples/ESP32FeatherWiFiDemo/ESP32FeatherWiFiDemo.ino +++ b/examples/ESP32FeatherWiFiDemo/ESP32FeatherWiFiDemo.ino @@ -69,31 +69,29 @@ Version | Date | Developer | Comments /******************************************************************************************************************* ** Declare all include files required ** *******************************************************************************************************************/ -#include ///< Include the SPI standard library -#include ///< Include the SD Card standard library -#include ///< ESP32 WiFi Library -#include ///< WiFi Client library -#include ///< WiFi Web Server library -#include "WebPageContents.h" ///< Include external HTML and JavaScript definitions -#include "Authentication.h" ///< Contains the network SSID and authentication code -#include "Zanshin_BME680.h" ///< The BME680 sensor library +#include ///< Include the SPI standard library +#include ///< Include the SD Card standard library +#include ///< ESP32 WiFi Library +#include ///< WiFi Client library +#include ///< WiFi Web Server library +#include "WebPageContents.h" ///< Include external HTML and JavaScript definitions +#include "Zanshin_BME680.h" ///< The BME680 sensor library /******************************************************************************************************************* ** Declare all program constants ** *******************************************************************************************************************/ -const uint32_t SERIAL_SPEED = 115200; ///< Set the baud rate for Serial I/O -const uint8_t POWER_PIN = A13; ///< Supply voltage through a divider -const uint8_t LED_PIN = 13; ///< This pin is the on-board red LED -const uint8_t SD_CARD_SPI_CS_PIN = 21; ///< Use Pin 21 (general GPIO) on the ESP32 for chip select -const uint8_t SD_CARD_SPI_CD_PIN = A5; ///< Use Pin A5 (general GPIO) on the ESP32 for carrier detect -const char* FILE_NAME = "/BME_680.csv"; ///< Filename on SD-Card -const uint32_t SD_LOG_INTERVAL = 1000; ///< Milliseconds between measurements to SD-Card -const uint8_t SD_FLUSH_INTERVAL = 60; ///< do a "flush" after this number of writes - -/******************************************************************************************************************* -** Declare all program macros ** -*******************************************************************************************************************/ -#define VOLTAGE (analogRead(POWER_PIN)/4095.0*3.3*2*1.1) ///< Macro for floating point voltage +const char* FILE_NAME = "/BME_680.csv"; ///< Filename on SD-Card +const char* HOSTNAME = "BME680"; ///< Give the device a name +const char* WIFI_SSID = "Zanshin"; ///< Network SSID for connection +const char* WIFI_PASSWORD = "TANSTAAFl1!"; ///< Network authentication code +const uint32_t SERIAL_SPEED = 115200; ///< Set the baud rate for Serial I/O +const uint8_t POWER_PIN = A13; ///< Supply voltage through a divider +const uint8_t LED_PIN = 13; ///< This pin is the on-board red LED +const uint8_t SD_CARD_SPI_CS_PIN = 21; ///< Use Pin 21 (general GPIO) on the ESP32 for chip select +const uint8_t SD_CARD_SPI_CD_PIN = A5; ///< Use Pin A5 (general GPIO) on the ESP32 for carrier detect +const uint32_t SD_LOG_INTERVAL = 1000; ///< Milliseconds between measurements to SD-Card +const uint8_t SD_FLUSH_INTERVAL = 60; ///< do a "flush" after this number of writes +const float SEA_LEVEL_PRESSURE = 1013.25; ///< Standard atmosphere sea level pressure /******************************************************************************************************************* ** Declare all global variables ** *******************************************************************************************************************/ @@ -108,48 +106,63 @@ int32_t start_pressure; ///< Initial pressure readi bool sd_card_present = false; ///< Switch set when SD-Card detected String jsonData; ///< JSON data string uint16_t loopCounter = 0; ///< Counter for number of write operations since startup -uint32_t next_log_millis; ///< Millis() value for next SD-Card measurement + +/******************************************************************************************************************* +** Macro that returns the floating point voltage. The formula is the analog value of POWER_PIN. Since this goes ** +** through a voltage divider the value is multiplied by 2. The register is 12-bit (0-4095) so we divide by 4095 ** +** and then by the 3.3V reference voltage and, finally, by the ADC reference voltage of 1.1V. The formula is: ** +** analogRead(POWER_PIN) / 4095.0 * 3.3v * 2 * 1.1v) ** +*******************************************************************************************************************/ +#define VOLTAGE ( analogRead(POWER_PIN) / 4095.0 * 3.3 * 2 * 1.1) void setup() { - pinMode(SD_CARD_SPI_CS_PIN, OUTPUT); // Declare the Chip-Select pin for the SD Card as output - pinMode(SD_CARD_SPI_CD_PIN, INPUT_PULLUP); // Declare the Carrier detect pin for the SD Card as input - digitalWrite(SD_CARD_SPI_CS_PIN, HIGH); // Write a high value to it in order to deselect device - pinMode(LED_PIN, OUTPUT); // make the LED an output pin - Serial.begin(115200); - Serial.print(F("Starting ESP32FeatherWiFiDemo example program for BME680\n")); + /*! + @brief Arduino method called once at startup to initialize the system + @details This is an Arduino IDE method which is called first upon boot or restart. It is only called one time + and then control goes to the main "loop()" method, from which control never returns. The BME680, then + the SD-Card (if present, if not present then it is ignored), then the Wi-Fi connection are initialized + and configured here. + @return void + */ + pinMode(SD_CARD_SPI_CS_PIN, OUTPUT); // Declare the Chip-Select pin for the SD Card as output + pinMode(SD_CARD_SPI_CD_PIN, INPUT_PULLUP); // Declare the Carrier detect pin for the SD Card as input + digitalWrite(SD_CARD_SPI_CS_PIN, HIGH); // Write a high value to it in order to deselect device + pinMode(LED_PIN, OUTPUT); // make the on-board LED an output pin so we can change it + Serial.begin(SERIAL_SPEED); // Start the Serial port with the specified speed + Serial.print("Starting ESP32FeatherWiFiDemo example program for BME680\n"); /********************** ** Initialize BME680 ** **********************/ - Serial.print(F("- Initializing BME680 sensor\n")); - while (!BME680.begin(I2C_STANDARD_MODE)) // Start BME680 using I2C, use first device found + Serial.print("- Initializing BME680 sensor\n"); + while (!BME680.begin(I2C_STANDARD_MODE)) // Start BME680 using I2C, use first device found { - Serial.print(F("- Unable to find BME680. Trying again in 5 seconds.\n")); + Serial.print("- Unable to find BME680. Trying again in 5 seconds.\n"); delay(5000); } // of loop until device is located - Serial.print(F("- Setting 16x oversampling for all sensors\n")); - BME680.setOversampling(TemperatureSensor, Oversample16); // Use enumerated type values to set value - BME680.setOversampling(HumiditySensor, Oversample16); // Use enumerated type values to set value - BME680.setOversampling(PressureSensor, Oversample16); // Use enumerated type values to set value - Serial.print(F("- Setting IIR filter to a value of 4 samples\n")); + Serial.print("- Setting 16x oversampling for all sensors\n"); + BME680.setOversampling(TemperatureSensor, Oversample16); // Use enumerated type values to set value + BME680.setOversampling(HumiditySensor, Oversample16); // Use enumerated type values to set value + BME680.setOversampling(PressureSensor, Oversample16); // Use enumerated type values to set value + Serial.print("- Setting IIR filter to a value of 4 samples\n"); BME680.setIIRFilter(IIR4); // Use enumerated type values - Serial.print(F("- Turning off gas measurements\n")); - BME680.setGas(0, 0); // Setting either to 0 turns off gas measurement + Serial.print("- Turning off gas measurements\n"); + BME680.setGas(0, 0); // Setting either to 0 turns off gas measurement BME680.getSensorData(temperature, humidity, start_pressure, gas); // Get most recent readings /*************************************************************** ** Initialize SD-Card for logging, if not found then continue ** ***************************************************************/ - Serial.print(F("- Checking to see if SD Card connected\n")); + Serial.print("- Checking to see if SD Card connected\n"); if (!digitalRead(SD_CARD_SPI_CD_PIN)) { - sd_card_present = false; // if pin is high then no card inserted + sd_card_present = false; // if pin is high then no card inserted } else { - uint8_t loopCounter = 10; ///< countdown to 0 to detect car - while (--loopCounter && !SD.begin(SD_CARD_SPI_CS_PIN)) // Try to start card using SPI + uint8_t loopCounter = 10; ///< countdown to 0 to detect car + while (--loopCounter && !SD.begin(SD_CARD_SPI_CS_PIN)) // Try to start card using SPI { - Serial.print(F("- Unable to find SD Card. Trying again in 5 seconds.\n")); + Serial.print("- Unable to find SD Card. Trying again in 5 seconds.\n"); for (uint8_t i = 0; i < 50; i++) { digitalWrite(LED_PIN, !digitalRead(LED_PIN)); @@ -160,83 +173,104 @@ void setup() } // if-then card is inserted if (!sd_card_present) { - Serial.print(F("- No SD-Card detected, continuing\n")); + Serial.print("- No SD-Card detected, continuing\n"); } else { - Serial.print(F("- SD-Card Initialized\n")); + Serial.print("- SD-Card Initialized\n"); dataFile = SD.open(FILE_NAME, FILE_WRITE); // Open the logfile for writing and position to end-of-file if (!dataFile) { - Serial.print(F("Unable to open file \"")); + Serial.print("Unable to open file \""); Serial.print(FILE_NAME); - Serial.print(F("\" on SD-Card. Error. Skipping SD writes.")); + Serial.print("\" on SD-Card. Error. Skipping SD writes."); sd_card_present = false; // turn off card } else { - Serial.print(F("- File \"")); + Serial.print("- File \""); Serial.print(FILE_NAME); - Serial.print(F("\" successfully opened. Appending data.\n")); - dataFile.print("Counter,Seconds,SupplyVoltage,Temperature,Humidity,Pressure\n"); + Serial.print("\" successfully opened. Appending data.\n"); + dataFile.print("Seconds,SupplyVoltage,Temperature,Humidity,Altitude\n"); } // if-then-else the file could be opened } // if-then-else SD-Card located /********************************************** ** Connect to the specified wireless network ** **********************************************/ - Serial.print(F("- Connecting to Wireless network \"")); + Serial.print("- Connecting to Wireless network \""); Serial.print(WIFI_SSID); - Serial.print(F("\".")); + Serial.print("\"."); WiFi.begin(WIFI_SSID, WIFI_PASSWORD); // Connect to the specified WiFi router while (WiFi.status() != WL_CONNECTED) // Loop until the connection is established { delay(1000); // wait one second before trying again Serial.print("."); } // for-next connection not established - WiFi.setHostname("BME680"); // Give our device a name + WiFi.setHostname(HOSTNAME); // Give our device a name // Show connection data Serial.print("\n- Open browser to IP address \""); Serial.print(WiFi.localIP()); Serial.print("\"\n- or to \"http://BME680\" to view data.\n"); - server.on("/", handleRoot); // Routine for root page call - server.on("/readADC", handleADC); // Page called by AJAX - server.begin(); //Start server - Serial.println("HTTP server started"); -} // of method "setup()" + server.on("/", handleRoot); // Routine for root page call + server.on("/readADC", handleADC); // Page called by AJAX + server.begin(); // Start server + Serial.print("HTTP server started\n"); + digitalWrite(LED_PIN, false); // Turn the LED off +} // of method "setup()" void handleRoot() { - //=============================================================== - // This routine is executed when you open its IP in browser - //=============================================================== - String s = MAIN_page; //Read HTML contents - server.send(200, "text/html", s); //Send web page + /*! + @brief Called when a request is sent from a browser client + @details When the ESP32 gets an IP address and that address is entered in a browser then this ISR get called to + handle that request. The response is to send the HTML page which is contained in the variable "MAIN_page" + which is set in the "WebPageContents.h" include file + @return void + */ + String s = MAIN_page; // Read HTML contents into a string + server.send(200, "text/html", s); // Send the string as HTML to the requester } // of method "handleRoot()" - void handleADC() { - server.send(200, "text/plain", jsonData); // Send JSON to client ajax request -} - + /*! + @brief Called when a "readADC"" request is sent from a browser client + @details When the browser client sends a GET request for a "readADC" this ISR is called, which then returns + the current value in the jsonData string, which is continuously updated in the main loop + @return void + */ + server.send(200, "text/plain", jsonData); // Send JSON to client ajax request +} // of method "handleADC()" void loop() { - server.handleClient(); // Handle client requests - if (millis() > next_log_millis) - { - next_log_millis = millis() + SD_LOG_INTERVAL; // set next timer + /*! + @brief Arduino method for the main program loop + @details This is the main program for the Arduino IDE, it is an infinite loop and keeps on repeating. + The timed measurements from the BME680 are handled here, while the actual web page serving and + responses are handled by the 2 ISRs - "handleADC()" and "handleRoot()". + @return void + */ + static uint32_t next_log_millis; ///< Millis() value for next SD-Card measurement time + server.handleClient(); // Handle client requests + if (millis() > next_log_millis) // if time to get another measurement from the BME680 + { // + next_log_millis = millis() + SD_LOG_INTERVAL; // set next time to get a reading getSensorData(); // get the BME680 data } // if-then time to get a measurement } // of method "loop()" - void getSensorData() { - Serial.print("."); - digitalWrite(LED_PIN, !digitalRead(LED_PIN)); // Toggle LED each loop + /*! + @brief Function to read the BME680 data and optionally write it to the SD-Card + @details The BME680 data is read in and if an SD-Card is present the values are written to it. The "jsonData" + string is also put together here so that a client request can immediately send the current data. This + is done because the frequency with which the data is written to the SD-Card is higher than that of the + web page refresh. + @return void + */ BME680.getSensorData(temperature, humidity, pressure, gas); // Get the most recent readings from the BME680 + float altitude = 44330.0 * (1.0 - pow(((float)pressure/100) / SEA_LEVEL_PRESSURE, 0.1903)); if (sd_card_present) // Log data to the SD-Card, if present { - dataFile.print(++loopCounter); - dataFile.print(","); dataFile.print(millis() / 1000); dataFile.print(","); dataFile.print(VOLTAGE); @@ -245,14 +279,18 @@ void getSensorData() dataFile.print(","); dataFile.print(humidity / 1000.0, 2); dataFile.print(","); - dataFile.println(pressure / 100.0, 2); - if (loopCounter % SD_FLUSH_INTERVAL == 0) + dataFile.print(altitude, 2); + dataFile.print("\n"); + + if (++loopCounter % SD_FLUSH_INTERVAL == 0) { + digitalWrite(LED_PIN, !digitalRead(LED_PIN)); // Toggle LED before flushing buffer dataFile.flush(); - Serial.print("\nFlushed data to SD-Card\n"); + digitalWrite(LED_PIN, !digitalRead(LED_PIN)); // Toggle LED after flushing is complete + Serial.print("Flushed data to SD-Card\n"); } // flush the buffer } // if-then SD card is present jsonData = "{\"SupplyVoltage\":\"" + String(VOLTAGE) + "\", \"Temperature\":\"" + String(temperature / 100.0) + "\", \"Humidity\":\"" + String(humidity / 1000.0) + - "\", \"Pressure\":\"" + String((start_pressure - pressure) / 100.0) + "\"}"; + "\", \"Altitude\":\"" + String(altitude) + "\"}"; } // of method "getSensorData()" diff --git a/examples/ESP32FeatherWiFiDemo/WebPageContents.h b/examples/ESP32FeatherWiFiDemo/WebPageContents.h index 60896e3..6629269 100644 --- a/examples/ESP32FeatherWiFiDemo/WebPageContents.h +++ b/examples/ESP32FeatherWiFiDemo/WebPageContents.h @@ -1,8 +1,17 @@ +/*! + This character string "MAIN_page" is loaded into program memory and contains the web page that is served when a + browser calls up the site. It uses the javascript from https://www.chartjs.org to generate a page with a dynamic + chart and lists the data in tabular form underneath as well. + + Since this is used for demonstration purposes it has been kept basic and simple. + +*/ + const char MAIN_page[] PROGMEM = R"=====( - ESP32 Feather BME680 WiFi Program + ESP32FeatherWiFiDemo - BME680 demononstration program