diff --git a/.github/README.md b/.github/README.md
index 7d82650..f3c8828 100644
--- a/.github/README.md
+++ b/.github/README.md
@@ -1,4 +1,4 @@
-# BME680 library
[![License: GPL v3](https://zanduino.github.io/Badges/GPLv3-blue.svg)](https://www.gnu.org/licenses/gpl-3.0) [![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) [![Doxygen](https://zanduino.github.io/Badges/Doxygen-Badge.svg)](https://sv-zanshin.github.io/BME680/html/index.html) [![Wiki](https://zanduino.github.io/Badges/Documentation-Badge.svg)](https://github.com/SV-Zanshin/BME680/wiki)
+# BME680 library
[![License: GPL v3](https://zanduino.github.io/Badges/GPLv3-blue.svg)](https://www.gnu.org/licenses/gpl-3.0) [![Build Status](https://travis-ci.com/SV-Zanshin/BME680.svg?branch=master)](https://travis-ci.com/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) [![Doxygen](https://zanduino.github.io/Badges/Doxygen-Badge.svg)](https://sv-zanshin.github.io/BME680/html/index.html) [![Wiki](https://zanduino.github.io/Badges/Documentation-Badge.svg)](https://github.com/SV-Zanshin/BME680/wiki)
*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:
diff --git a/Doxyfile b/Doxyfile
new file mode 100644
index 0000000..6f694b4
--- /dev/null
+++ b/Doxyfile
@@ -0,0 +1,294 @@
+######################################################################################################
+## Doxygen control file for Version 1.8.16 ##
+## ##
+## Date Developer Comments ##
+## ========== ============================= ======================================================= ##
+## 2020-09-27 https://github.com/SV-Zanshin Updated version to 1.0.10 ##
+## 2020-06-25 https://github.com/SV-Zanshin Updated version to 1.0.9 ##
+## 2020-06-25 https://github.com/SV-Zanshin Updated version to 1.0.8 ##
+## 2020-06-08 https://github.com/SV-Zanshin Updated version to 1.0.7 ##
+## 2020-06-01 https://github.com/SV-Zanshin Added "PREDEFINED = DOXYGEN_SHOULD_SKIP_THIS" ##
+## 2020-05-23 https://github.com/SV-Zanshin Removed e-mail addresses from file and updated version ##
+## 2020-05-21 https://github.com/SV-Zanshin Updated "PROJECT_NUMBER" value to 1.0.5 ##
+## 2020-05-17 https://github.com/SV-Zanshin Updated "PROJECT_NUMBER" value to 1.0.4 ##
+## 2020-05-10 https://github.com/SV-Zanshin Removed all comments in order to compact this file ##
+## ##
+######################################################################################################
+DOXYFILE_ENCODING = UTF-8
+PROJECT_NAME = BME680
+PROJECT_NUMBER = "Version 1.0.10"
+PROJECT_BRIEF = "Arduino Library for the Bosch BME680 Temperature, Humidity, Pressure and Gas sensor"
+PROJECT_LOGO =
+OUTPUT_DIRECTORY =
+CREATE_SUBDIRS = NO
+ALLOW_UNICODE_NAMES = NO
+OUTPUT_LANGUAGE = English
+BRIEF_MEMBER_DESC = YES
+REPEAT_BRIEF = YES
+ABBREVIATE_BRIEF = "The $name class" \
+ "The $name widget" \
+ "The $name file" \
+ is \
+ provides \
+ specifies \
+ contains \
+ represents \
+ a \
+ an \
+ the
+ALWAYS_DETAILED_SEC = NO
+INLINE_INHERITED_MEMB = NO
+FULL_PATH_NAMES = YES
+STRIP_FROM_PATH =
+STRIP_FROM_INC_PATH =
+SHORT_NAMES = NO
+JAVADOC_AUTOBRIEF = NO
+QT_AUTOBRIEF = NO
+MULTILINE_CPP_IS_BRIEF = NO
+INHERIT_DOCS = YES
+SEPARATE_MEMBER_PAGES = NO
+TAB_SIZE = 2
+ALIASES =
+TCL_SUBST =
+OPTIMIZE_OUTPUT_FOR_C = NO
+OPTIMIZE_OUTPUT_JAVA = NO
+OPTIMIZE_FOR_FORTRAN = NO
+OPTIMIZE_OUTPUT_VHDL = NO
+EXTENSION_MAPPING = ino=c
+MARKDOWN_SUPPORT = YES
+TOC_INCLUDE_HEADINGS = 0
+AUTOLINK_SUPPORT = YES
+BUILTIN_STL_SUPPORT = NO
+CPP_CLI_SUPPORT = NO
+SIP_SUPPORT = NO
+IDL_PROPERTY_SUPPORT = YES
+DISTRIBUTE_GROUP_DOC = NO
+GROUP_NESTED_COMPOUNDS = NO
+SUBGROUPING = YES
+INLINE_GROUPED_CLASSES = NO
+INLINE_SIMPLE_STRUCTS = NO
+TYPEDEF_HIDES_STRUCT = NO
+LOOKUP_CACHE_SIZE = 0
+EXTRACT_ALL = NO
+EXTRACT_PRIVATE = NO
+EXTRACT_PACKAGE = NO
+EXTRACT_STATIC = NO
+EXTRACT_LOCAL_CLASSES = YES
+EXTRACT_LOCAL_METHODS = NO
+EXTRACT_ANON_NSPACES = NO
+HIDE_UNDOC_MEMBERS = NO
+HIDE_UNDOC_CLASSES = NO
+HIDE_FRIEND_COMPOUNDS = NO
+HIDE_IN_BODY_DOCS = NO
+INTERNAL_DOCS = NO
+CASE_SENSE_NAMES = NO
+HIDE_SCOPE_NAMES = NO
+HIDE_COMPOUND_REFERENCE= NO
+SHOW_INCLUDE_FILES = YES
+SHOW_GROUPED_MEMB_INC = NO
+FORCE_LOCAL_INCLUDES = NO
+INLINE_INFO = YES
+SORT_MEMBER_DOCS = YES
+SORT_BRIEF_DOCS = NO
+SORT_MEMBERS_CTORS_1ST = NO
+SORT_GROUP_NAMES = NO
+SORT_BY_SCOPE_NAME = NO
+STRICT_PROTO_MATCHING = NO
+GENERATE_TODOLIST = YES
+GENERATE_TESTLIST = YES
+GENERATE_BUGLIST = YES
+GENERATE_DEPRECATEDLIST= YES
+ENABLED_SECTIONS =
+MAX_INITIALIZER_LINES = 30
+SHOW_USED_FILES = YES
+SHOW_FILES = YES
+SHOW_NAMESPACES = YES
+FILE_VERSION_FILTER =
+LAYOUT_FILE =
+CITE_BIB_FILES =
+QUIET = YES
+WARNINGS = YES
+WARN_IF_UNDOCUMENTED = YES
+WARN_IF_DOC_ERROR = YES
+WARN_NO_PARAMDOC = NO
+WARN_AS_ERROR = NO
+WARN_FORMAT = "$file:$line: $text"
+WARN_LOGFILE =
+INPUT = src examples
+INPUT_ENCODING = UTF-8
+FILE_PATTERNS = *.ino \
+ *.c \
+ *.cpp \
+ *.h
+RECURSIVE = YES
+EXCLUDE =
+EXCLUDE_SYMLINKS = NO
+EXCLUDE_PATTERNS =
+EXCLUDE_SYMBOLS =
+EXAMPLE_PATH =
+EXAMPLE_PATTERNS = *
+EXAMPLE_RECURSIVE = NO
+IMAGE_PATH =
+INPUT_FILTER =
+FILTER_PATTERNS =
+FILTER_SOURCE_FILES = NO
+FILTER_SOURCE_PATTERNS =
+USE_MDFILE_AS_MAINPAGE =
+SOURCE_BROWSER = NO
+INLINE_SOURCES = NO
+STRIP_CODE_COMMENTS = YES
+REFERENCED_BY_RELATION = NO
+REFERENCES_RELATION = NO
+REFERENCES_LINK_SOURCE = YES
+SOURCE_TOOLTIPS = YES
+USE_HTAGS = NO
+VERBATIM_HEADERS = YES
+CLANG_ASSISTED_PARSING = NO
+CLANG_OPTIONS =
+ALPHABETICAL_INDEX = YES
+COLS_IN_ALPHA_INDEX = 5
+IGNORE_PREFIX =
+GENERATE_HTML = YES
+HTML_OUTPUT = html
+HTML_FILE_EXTENSION = .html
+HTML_HEADER =
+HTML_FOOTER =
+HTML_STYLESHEET =
+HTML_EXTRA_STYLESHEET =
+HTML_EXTRA_FILES =
+HTML_COLORSTYLE_HUE = 220
+HTML_COLORSTYLE_SAT = 100
+HTML_COLORSTYLE_GAMMA = 80
+HTML_TIMESTAMP = NO
+HTML_DYNAMIC_SECTIONS = NO
+HTML_INDEX_NUM_ENTRIES = 100
+GENERATE_DOCSET = NO
+DOCSET_FEEDNAME = "Doxygen generated docs"
+DOCSET_BUNDLE_ID = org.doxygen.Project
+DOCSET_PUBLISHER_ID = org.doxygen.Publisher
+DOCSET_PUBLISHER_NAME = Publisher
+GENERATE_HTMLHELP = NO
+CHM_FILE =
+HHC_LOCATION =
+GENERATE_CHI = NO
+CHM_INDEX_ENCODING =
+BINARY_TOC = NO
+TOC_EXPAND = NO
+GENERATE_QHP = NO
+QCH_FILE =
+QHP_NAMESPACE = org.doxygen.Project
+QHP_VIRTUAL_FOLDER = doc
+QHP_CUST_FILTER_NAME =
+QHP_CUST_FILTER_ATTRS =
+QHP_SECT_FILTER_ATTRS =
+QHG_LOCATION =
+GENERATE_ECLIPSEHELP = NO
+ECLIPSE_DOC_ID = org.doxygen.Project
+DISABLE_INDEX = NO
+GENERATE_TREEVIEW = YES
+ENUM_VALUES_PER_LINE = 4
+TREEVIEW_WIDTH = 250
+EXT_LINKS_IN_WINDOW = NO
+FORMULA_FONTSIZE = 10
+FORMULA_TRANSPARENT = YES
+USE_MATHJAX = NO
+MATHJAX_FORMAT = HTML-CSS
+MATHJAX_RELPATH = http://cdn.mathjax.org/mathjax/latest
+MATHJAX_EXTENSIONS =
+MATHJAX_CODEFILE =
+SEARCHENGINE = YES
+SERVER_BASED_SEARCH = NO
+EXTERNAL_SEARCH = NO
+SEARCHENGINE_URL =
+SEARCHDATA_FILE = searchdata.xml
+EXTERNAL_SEARCH_ID =
+EXTRA_SEARCH_MAPPINGS =
+GENERATE_LATEX = NO
+LATEX_OUTPUT = latex
+LATEX_CMD_NAME = latex
+COMPACT_LATEX = NO
+PAPER_TYPE = a4
+EXTRA_PACKAGES =
+LATEX_HEADER =
+LATEX_FOOTER =
+LATEX_EXTRA_STYLESHEET =
+LATEX_EXTRA_FILES =
+PDF_HYPERLINKS = YES
+USE_PDFLATEX = YES
+LATEX_BATCHMODE = NO
+LATEX_HIDE_INDICES = NO
+LATEX_SOURCE_CODE = NO
+LATEX_BIB_STYLE = plain
+LATEX_TIMESTAMP = NO
+GENERATE_RTF = NO
+RTF_OUTPUT = rtf
+COMPACT_RTF = NO
+RTF_HYPERLINKS = NO
+RTF_STYLESHEET_FILE =
+RTF_EXTENSIONS_FILE =
+RTF_SOURCE_CODE = NO
+GENERATE_MAN = NO
+MAN_OUTPUT = man
+MAN_EXTENSION = .3
+MAN_SUBDIR =
+MAN_LINKS = NO
+GENERATE_XML = NO
+XML_OUTPUT = xml
+XML_PROGRAMLISTING = YES
+GENERATE_DOCBOOK = NO
+DOCBOOK_OUTPUT = docbook
+DOCBOOK_PROGRAMLISTING = NO
+GENERATE_AUTOGEN_DEF = NO
+GENERATE_PERLMOD = NO
+PERLMOD_LATEX = NO
+PERLMOD_PRETTY = YES
+PERLMOD_MAKEVAR_PREFIX =
+ENABLE_PREPROCESSING = YES
+MACRO_EXPANSION = NO
+EXPAND_ONLY_PREDEF = NO
+SEARCH_INCLUDES = YES
+INCLUDE_PATH =
+INCLUDE_FILE_PATTERNS =
+PREDEFINED = DOXYGEN_SHOULD_SKIP_THIS
+EXPAND_AS_DEFINED =
+SKIP_FUNCTION_MACROS = YES
+TAGFILES =
+GENERATE_TAGFILE =
+ALLEXTERNALS = NO
+EXTERNAL_GROUPS = YES
+EXTERNAL_PAGES = YES
+CLASS_DIAGRAMS = YES
+DIA_PATH =
+HIDE_UNDOC_RELATIONS = YES
+HAVE_DOT = NO
+DOT_NUM_THREADS = 0
+DOT_FONTNAME = Helvetica
+DOT_FONTSIZE = 10
+DOT_FONTPATH =
+CLASS_GRAPH = YES
+COLLABORATION_GRAPH = YES
+GROUP_GRAPHS = YES
+UML_LOOK = NO
+UML_LIMIT_NUM_FIELDS = 10
+TEMPLATE_RELATIONS = NO
+INCLUDE_GRAPH = YES
+INCLUDED_BY_GRAPH = YES
+CALL_GRAPH = NO
+CALLER_GRAPH = NO
+GRAPHICAL_HIERARCHY = YES
+DIRECTORY_GRAPH = YES
+DOT_IMAGE_FORMAT = png
+INTERACTIVE_SVG = NO
+DOT_PATH =
+DOTFILE_DIRS =
+MSCFILE_DIRS =
+DIAFILE_DIRS =
+PLANTUML_JAR_PATH =
+PLANTUML_CFG_FILE =
+PLANTUML_INCLUDE_PATH =
+DOT_GRAPH_MAX_NODES = 50
+MAX_DOT_GRAPH_DEPTH = 0
+DOT_TRANSPARENT = NO
+DOT_MULTI_TARGETS = NO
+GENERATE_LEGEND = YES
+DOT_CLEANUP = YES
diff --git a/examples/I2CDemo/I2CDemo.ino b/examples/I2CDemo/I2CDemo.ino
index 9bd276e..a31e45d 100644
--- a/examples/I2CDemo/I2CDemo.ino
+++ b/examples/I2CDemo/I2CDemo.ino
@@ -59,17 +59,17 @@ Written by Arnd\@SV-Zanshin
Version | Date | Developer | Comments
------- | ---------- | ---------- | ---------------------------------------------------------------
-1.0.3 | 2020-07-04 | SV-Zanshin | Issue #25 - implement clang-formatting
-1.0.2 | 2020-05-09 | SV-Zanshin | Issue #8 - clean up comments and code
-1.0.1 | 2019-01-30 | SV-Zanshin | Removed old comments
-1.0.1 | 2019-01-26 | SV-Zanshin | Issue #3 - convert documentation to Doxygen
-1.0.0b | 2018-06-30 | SV-Zanshin | Cloned from original BME280 program
+1.0.3 | 2020-07-04 | SV-Zanshin | Issue #25 implement clang-formatting
+1.0.2 | 2020-05-09 | SV-Zanshin | Issue #8 clean up comments and code
+1.0.1 | 2019-01-30 | SV-Zanshin | Removed old comments
+1.0.1 | 2019-01-26 | SV-Zanshin | Issue #3 convert documentation to Doxygen
+1.0.0b | 2018-06-30 | SV-Zanshin | Cloned from original BME280 program
*/
#include "Zanshin_BME680.h" // Include the BME680 Sensor library
/**************************************************************************************************
** Declare all program constants **
**************************************************************************************************/
-const uint32_t SERIAL_SPEED = 115200; ///< Set the baud rate for Serial I/O
+const uint32_t SERIAL_SPEED{115200}; ///< Set the baud rate for Serial I/O
/**************************************************************************************************
** Declare global variables and instantiate classes **
@@ -107,7 +107,7 @@ void setup() {
#endif
Serial.print(F("Starting I2CDemo example program for BME680\n"));
Serial.print(F("- Initializing BME680 sensor\n"));
- while (!BME680.begin(I2C_STANDARD_MODE)) { // Start BME680 using I2C, use first device found
+ 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
@@ -136,21 +136,23 @@ void loop() {
if (loopCounter % 25 == 0) { // Show header @25 loops
Serial.print(F("\nLoop Temp\xC2\xB0\x43 Humid% Press hPa Alt m Air m"));
Serial.print(F("\xE2\x84\xA6\n==== ====== ====== ========= ======= ======\n")); // "°C" symbol
- } // if-then time to show headers
- BME680.getSensorData(temp, humidity, pressure, gas); // Get readings
- sprintf(buf, "%4d %3d.%02d", ++loopCounter % 9999, // Clamp to 9999,
- (int8_t)(temp / 100), (uint8_t)(temp % 100)); // Temp in decidegrees
- Serial.print(buf);
- sprintf(buf, "%3d.%03d", (int8_t)(humidity / 1000),
- (uint16_t)(humidity % 1000)); // Humidity milli-pct
- Serial.print(buf);
- sprintf(buf, "%7d.%02d", (int16_t)(pressure / 100),
- (uint8_t)(pressure % 100)); // Pressure Pascals
- Serial.print(buf);
- alt = altitude(pressure); // temp altitude
- sprintf(buf, "%5d.%02d", (int16_t)(alt), ((uint8_t)(alt * 100) % 100)); // Altitude meters
- Serial.print(buf);
- sprintf(buf, "%4d.%02d\n", (int16_t)(gas / 100), (uint8_t)(gas % 100)); // Resistance milliohms
- Serial.print(buf);
- delay(10000); // Wait 10s
+ } // if-then time to show headers
+ BME680.getSensorData(temp, humidity, pressure, gas); // Get readings
+ if (loopCounter++ != 0) { // Ignore first reading, might be incorrect
+ sprintf(buf, "%4d %3d.%02d", (loopCounter - 1) % 9999, // Clamp to 9999,
+ (int8_t)(temp / 100), (uint8_t)(temp % 100)); // Temp in decidegrees
+ Serial.print(buf);
+ sprintf(buf, "%3d.%03d", (int8_t)(humidity / 1000),
+ (uint16_t)(humidity % 1000)); // Humidity milli-pct
+ Serial.print(buf);
+ sprintf(buf, "%7d.%02d", (int16_t)(pressure / 100),
+ (uint8_t)(pressure % 100)); // Pressure Pascals
+ Serial.print(buf);
+ alt = altitude(pressure); // temp altitude
+ sprintf(buf, "%5d.%02d", (int16_t)(alt), ((uint8_t)(alt * 100) % 100)); // Altitude meters
+ Serial.print(buf);
+ sprintf(buf, "%4d.%02d\n", (int16_t)(gas / 100), (uint8_t)(gas % 100)); // Resistance milliohms
+ Serial.print(buf);
+ delay(10000); // Wait 10s
+ } // of ignore first reading
} // of method loop()
diff --git a/examples/README.md b/examples/README.md
index c63af3f..ac03ca8 100644
--- a/examples/README.md
+++ b/examples/README.md
@@ -1,4 +1,4 @@
-# Example programs for the BME680 library
[![License: GPL v3](https://zanduino.github.io/Badges/GPLv3-blue.svg)](https://www.gnu.org/licenses/gpl-3.0) [![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) [![Doxygen](https://zanduino.github.io/Badges/Doxygen-Badge.svg)](https://sv-zanshin.github.io/BME680/html/index.html) [![Wiki](https://zanduino.github.io/Badges/Documentation-Badge.svg)](https://github.com/SV-Zanshin/BME680/wiki)
+# Example programs for the BME680 library
[![License: GPL v3](https://zanduino.github.io/Badges/GPLv3-blue.svg)](https://www.gnu.org/licenses/gpl-3.0) [![Build Status](https://travis-ci.com/SV-Zanshin/BME680.svg?branch=master)](https://travis-ci.com/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) [![Doxygen](https://zanduino.github.io/Badges/Doxygen-Badge.svg)](https://sv-zanshin.github.io/BME680/html/index.html) [![Wiki](https://zanduino.github.io/Badges/Documentation-Badge.svg)](https://github.com/SV-Zanshin/BME680/wiki)
Various example programs illustrating the use of the *Arduino* BME680 library are included in this directory and sub-directories.
diff --git a/keywords.txt b/keywords.txt
index eeddb26..15e2451 100644
--- a/keywords.txt
+++ b/keywords.txt
@@ -2,11 +2,12 @@
## Syntax Coloring Map for library. The values below MUST be separated by a single "TAB", otherwise ##
## the file will not be parsed correctly. ##
## ##
-## Date Developer Comments ##
-## ========== ============================= ======================================================= ##
-## 2020-06-25 https://github.com/SV-Zanshin Added "getI2CAddress" to list ##
-## 2020-05-23 https://github.com/SV-Zanshin Updated values, added versioning comments ##
-## 2018-06-14 https://github.com/SV-Zanshin Fixed multiple tab errors ##
+## Date Developer Comments ##
+## ========== ========== ========================================================================== ##
+## 2020-12-03 SV-Zanshin Added "measuring()" and "triggerMeasurement()" ##
+## 2020-06-25 SV-Zanshin Added "getI2CAddress" to list ##
+## 2020-05-23 SV-Zanshin Updated values, added versioning comments ##
+## 2018-06-14 SV-Zanshin Fixed multiple tab errors ##
## ##
######################################################################################################
@@ -26,6 +27,8 @@ getSensorData KEYWORD2
getI2CAddress KEYWORD2
waitForReadings KEYWORD2
reset KEYWORD2
+measuring KEYWORD2
+triggerMeasurement KEYWORD2
######################################################################################################
## Constants (LITERAL1) ##
diff --git a/library.properties b/library.properties
index 6feab5d..9c38095 100644
--- a/library.properties
+++ b/library.properties
@@ -1,5 +1,5 @@
name=BME680
-version=1.0.9
+version=1.0.10
author=https://github.com/SV-Zanshin
maintainer=https://github.com/SV-Zanshin
sentence=Arduino library to access and control the Bosch BME680 sensor and get temperature, humidity, pressure and gas readings.
diff --git a/src/README.md b/src/README.md
index 205199d..23ef892 100644
--- a/src/README.md
+++ b/src/README.md
@@ -1,4 +1,4 @@
-# BME680 library Header and Source files
[![License: GPL v3](https://zanduino.github.io/Badges/GPLv3-blue.svg)](https://www.gnu.org/licenses/gpl-3.0) [![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) [![Doxygen](https://zanduino.github.io/Badges/Doxygen-Badge.svg)](https://sv-zanshin.github.io/BME680/html/index.html) [![Wiki](https://zanduino.github.io/Badges/Documentation-Badge.svg)](https://github.com/SV-Zanshin/BME680/wiki)
+# BME680 library Header and Source files
[![License: GPL v3](https://zanduino.github.io/Badges/GPLv3-blue.svg)](https://www.gnu.org/licenses/gpl-3.0) [![Build Status](https://travis-ci.com/SV-Zanshin/BME680.svg?branch=master)](https://travis-ci.com/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) [![Doxygen](https://zanduino.github.io/Badges/Doxygen-Badge.svg)](https://sv-zanshin.github.io/BME680/html/index.html) [![Wiki](https://zanduino.github.io/Badges/Documentation-Badge.svg)](https://github.com/SV-Zanshin/BME680/wiki)
This directory contains the two files that define the [Bosch BME680](https://www.bosch-sensortec.com/bst/products/all_products/bme680) *Arduino* library.
The "Zanshin_BME680.h" is the library header file, and the program code is contained in the "Zanshin_BME680.cpp" file.
diff --git a/src/Zanshin_BME680.cpp b/src/Zanshin_BME680.cpp
index fdffae5..2426644 100644
--- a/src/Zanshin_BME680.cpp
+++ b/src/Zanshin_BME680.cpp
@@ -7,6 +7,78 @@
#include "Zanshin_BME680.h" // Include the library header definition
+/***************************************************************************************************
+** Declare class-internal and not publically visible constants **
+***************************************************************************************************/
+const uint8_t BME680_STATUS_REGISTER{0x1D}; ///< Device status register
+const uint8_t BME680_GAS_HEATER_REGISTER0{0x5A}; ///< Heater Register 0 address
+const uint8_t BME680_GAS_DURATION_REGISTER0{0x64}; ///< Heater Register 0 address
+const uint8_t BME680_CONTROL_GAS_REGISTER1{0x70}; ///< Gas control register on/off
+const uint8_t BME680_CONTROL_GAS_REGISTER2{0x71}; ///< Gas control register settings
+const uint8_t BME680_CONTROL_HUMIDITY_REGISTER{0x72}; ///< Humidity control register
+const uint8_t BME680_SPI_REGISTER{0x73}; ///< Status register for SPI memory
+const uint8_t BME680_CONTROL_MEASURE_REGISTER{0x74}; ///< Temp, Pressure control register
+const uint8_t BME680_CONFIG_REGISTER{0x75}; ///< Configuration register
+const uint8_t BME680_CHIPID_REGISTER{0xD0}; ///< Chip-Id register
+const uint8_t BME680_SOFTRESET_REGISTER{0xE0}; ///< Reset when 0xB6 is written here
+const uint8_t BME680_CHIPID{0x61}; ///< Hard-coded value 0x61 for BME680
+const uint8_t BME680_RESET_CODE{0xB6}; ///< Reset when this put in reset reg
+const uint8_t BME680_MEASURING_BIT_POSITION{5}; ///< Bit position for measuring flag
+const uint8_t BME680_I2C_MIN_ADDRESS{0x76}; ///< Minimum possible address for BME680
+const uint8_t BME680_I2C_MAX_ADDRESS{0x77}; ///< Minimum possible address for BME680
+const uint8_t BME680_SPI_MEM_PAGE_POSITION{4}; ///< Bit position for memory page value
+const uint8_t BME680_HUMIDITY_MASK{0xF8}; ///< Mask is binary B11111000
+const uint8_t BME680_PRESSURE_MASK{0xE3}; ///< Mask is binary B11100011
+const uint8_t BME680_TEMPERATURE_MASK{0x1F}; ///< Mask is binary B00011111
+/***************************************************************************************************
+** Declare the constants used for calibration **
+***************************************************************************************************/
+const uint8_t BME680_COEFF_SIZE1{25}; ///< First array with coefficients
+const uint8_t BME680_COEFF_SIZE2{16}; ///< Second array with coefficients
+const uint8_t BME680_COEFF_START_ADDRESS1{0x89}; ///< start address for array 1
+const uint8_t BME680_COEFF_START_ADDRESS2{0xE1}; ///< start address for array 2
+const uint8_t BME680_HUM_REG_SHIFT_VAL{4}; ///< Ambient humidity shift value
+const uint8_t BME680_BIT_H1_DATA_MSK{0x0F}; ///< Mask for humidity
+const uint8_t BME680_T2_LSB_REG{1}; ///< Register for temperature calibration
+const uint8_t BME680_T2_MSB_REG{2}; ///< Register for temperature calibration
+const uint8_t BME680_T3_REG{3}; ///< Register for temperature calibration
+const uint8_t BME680_P1_LSB_REG{5}; ///< Register for pressure calibration
+const uint8_t BME680_P1_MSB_REG{6}; ///< Register for pressure calibration
+const uint8_t BME680_P2_LSB_REG{7}; ///< Register for pressure calibration
+const uint8_t BME680_P2_MSB_REG{8}; ///< Register for pressure calibration
+const uint8_t BME680_P3_REG{9}; ///< Register for pressure calibration
+const uint8_t BME680_P4_LSB_REG{11}; ///< Register for pressure calibration
+const uint8_t BME680_P4_MSB_REG{12}; ///< Register for pressure calibration
+const uint8_t BME680_P5_LSB_REG{13}; ///< Register for pressure calibration
+const uint8_t BME680_P5_MSB_REG{14}; ///< Register for pressure calibration
+const uint8_t BME680_P7_REG{15}; ///< Register for pressure calibration
+const uint8_t BME680_P6_REG{16}; ///< Register for pressure calibration
+const uint8_t BME680_P8_LSB_REG{19}; ///< Register for pressure calibration
+const uint8_t BME680_P8_MSB_REG{20}; ///< Register for pressure calibration
+const uint8_t BME680_P9_LSB_REG{21}; ///< Register for pressure calibration
+const uint8_t BME680_P9_MSB_REG{22}; ///< Register for pressure calibration
+const uint8_t BME680_P10_REG{23}; ///< Register for pressure calibration
+const uint8_t BME680_H2_MSB_REG{0}; ///< Register for humidity calibration
+const uint8_t BME680_H2_LSB_REG{1}; ///< Register for humidity calibration
+const uint8_t BME680_H1_LSB_REG{1}; ///< Register for humidity calibration
+const uint8_t BME680_H1_MSB_REG{2}; ///< Register for humidity calibration
+const uint8_t BME680_H3_REG{3}; ///< Register for humidity calibration
+const uint8_t BME680_H4_REG{4}; ///< Register for humidity calibration
+const uint8_t BME680_H5_REG{5}; ///< Register for humidity calibration
+const uint8_t BME680_H6_REG{6}; ///< Register for humidity calibration
+const uint8_t BME680_H7_REG{7}; ///< Register for humidity calibration
+const uint8_t BME680_T1_LSB_REG{8}; ///< Register for gas calibration
+const uint8_t BME680_T1_MSB_REG{9}; ///< Register for gas calibration
+const uint8_t BME680_GH2_LSB_REG{10}; ///< Register for gas calibration
+const uint8_t BME680_GH2_MSB_REG{11}; ///< Register for gas calibration
+const uint8_t BME680_GH1_REG{12}; ///< Register for gas calibration
+const uint8_t BME680_GH3_REG{13}; ///< Register for gas calibration
+const uint8_t BME680_ADDR_RES_HEAT_RANGE_ADDR{0x02}; ///< Register for gas calibration
+const uint8_t BME680_RHRANGE_MSK{0x30}; ///< Register for gas calibration
+const uint8_t BME680_ADDR_RES_HEAT_VAL_ADDR{0x00}; ///< Register for gas calibration
+const uint8_t BME680_ADDR_RANGE_SW_ERR_ADDR{0x04}; ///< Register for gas calibration
+const uint8_t BME680_RSERROR_MSK{0xF0}; ///< Register for gas calibration
+
BME680_Class::BME680_Class() {
/*!
* @brief Class constructor
@@ -133,9 +205,9 @@ bool BME680_Class::commonInitialization() {
else
return false;
} // of method commonInitialization
-uint8_t BME680_Class::readByte(const uint8_t addr) {
+uint8_t BME680_Class::readByte(const uint8_t addr) const {
/*!
- @brief Read a single byte from the give address
+ @brief Read a single byte from the given address
@details interlude function to the "getData()" function. This is called so that the return value
is the byte of data that has just been read rather than the number of bytes read
returned by "getData()"
@@ -198,10 +270,12 @@ void BME680_Class::getCalibration() {
/**********************************
** Humidity related coefficients **
**********************************/
- _H1 = (uint16_t)(((uint16_t)coeff_arr2[BME680_H1_MSB_REG] << BME680_HUM_REG_SHIFT_VAL) |
- (coeff_arr2[BME680_H1_LSB_REG] & BME680_BIT_H1_DATA_MSK));
- _H2 = (uint16_t)(((uint16_t)coeff_arr2[BME680_H2_MSB_REG] << BME680_HUM_REG_SHIFT_VAL) |
- ((coeff_arr2[BME680_H2_LSB_REG]) >> BME680_HUM_REG_SHIFT_VAL));
+ _H1 = (uint16_t)(
+ ((uint16_t)coeff_arr2[BME680_H1_MSB_REG] << BME680_HUM_REG_SHIFT_VAL) |
+ ((coeff_arr2[BME680_H1_LSB_REG] >> BME680_HUM_REG_SHIFT_VAL) & BME680_BIT_H1_DATA_MSK));
+ _H2 = (uint16_t)(
+ ((uint16_t)coeff_arr2[BME680_H2_MSB_REG] << BME680_HUM_REG_SHIFT_VAL) |
+ ((coeff_arr2[BME680_H2_LSB_REG] >> BME680_HUM_REG_SHIFT_VAL) & BME680_BIT_H1_DATA_MSK));
_H3 = (int8_t)coeff_arr2[BME680_H3_REG];
_H4 = (int8_t)coeff_arr2[BME680_H4_REG];
_H5 = (int8_t)coeff_arr2[BME680_H5_REG];
@@ -221,7 +295,7 @@ void BME680_Class::getCalibration() {
getData(BME680_ADDR_RANGE_SW_ERR_ADDR, temp_var);
_rng_sw_err = ((int8_t)temp_var & (int8_t)BME680_RSERROR_MSK) / 16;
} // of method getCalibration()
-uint8_t BME680_Class::setOversampling(const uint8_t sensor, const uint8_t sampling) {
+uint8_t BME680_Class::setOversampling(const uint8_t sensor, const uint8_t sampling) const {
/*!
@brief sets the oversampling mode for the sensor
@details See enumerated "sensorTypes" for a list of values. Set to a valid oversampling rate as
@@ -284,7 +358,7 @@ uint8_t BME680_Class::setOversampling(const uint8_t sensor, const uint8_t sampli
} // of switch the sensor type
return (returnValue); // Otherwise return current value
} // of method setOversampling()
-uint8_t BME680_Class::setIIRFilter(const uint8_t iirFilterSetting) {
+uint8_t BME680_Class::setIIRFilter(const uint8_t iirFilterSetting) const {
/*!
@brief Set or return the current IIR filter setting
@details When called with no parameters returns the current IIR Filter setting, otherwise
@@ -320,7 +394,7 @@ uint8_t BME680_Class::getSensorData(int32_t& temp, int32_t& hum, int32_t& press,
gas = _Gas; // Copy global variables to parameters
return (status); // Nonzero if gas is invalid or unstable
} // of method getSensorData()
-uint8_t BME680_Class::getI2CAddress() {
+uint8_t BME680_Class::getI2CAddress() const {
/*!
@brief Returns the I2C address of the BME680
return I2C Address from private variables
@@ -355,15 +429,15 @@ uint8_t BME680_Class::readSensors(const bool waitSwitch) {
uint16_t adc_hum, adc_gas_res; // Raw ADC humidity and gas
if (waitSwitch) waitForReadings(); // Doesn't return until the readings are finished
getData(BME680_STATUS_REGISTER, buff); // read all 15 bytes in one go
- adc_pres = (uint32_t)(((uint32_t)buff[2] * 4096) | ((uint32_t)buff[3] * 16) |
- ((uint32_t)buff[4] / 16)); // put the 3 bytes of Pressure
- adc_temp = (uint32_t)(((uint32_t)buff[5] * 4096) | ((uint32_t)buff[6] * 16) |
- ((uint32_t)buff[7] / 16)); // put the 3 bytes of Temperature
+ adc_pres = (uint32_t)(((uint32_t)buff[2] << 12) | ((uint32_t)buff[3] << 4) |
+ ((uint32_t)buff[4] >> 4)); // put the 3 bytes of Pressure
+ adc_temp = (uint32_t)(((uint32_t)buff[5] << 12) | ((uint32_t)buff[6] << 4) |
+ ((uint32_t)buff[7] >> 4)); // put the 3 bytes of Temperature
adc_hum =
- (uint16_t)(((uint32_t)buff[8] * 256) | (uint32_t)buff[9]); // put the 2 bytes of Humidity
+ (uint16_t)(((uint32_t)buff[8] << 8) | (uint32_t)buff[9]); // put the 2 bytes of Humidity
adc_gas_res =
- (uint16_t)((uint32_t)buff[13] * 4 | (((uint32_t)buff[14]) / 64)); // put the 2 bytes of Gas
- gas_range = buff[14] & 0X0F; // Retrieve the range
+ (uint16_t)((uint32_t)buff[13] << 2 | (((uint32_t)buff[14]) >> 6)); // put the 2 bytes of Gas
+ gas_range = buff[14] & 0X0F; // Retrieve the range
//*******************************//
// First compute the temperature //
//*******************************//
@@ -401,7 +475,7 @@ uint8_t BME680_Class::readSensors(const bool waitSwitch) {
// Compute the humidity //
//**********************//
temp_scaled = (((int32_t)_tfine * 5) + 128) >> 8;
- var1 = (int32_t)(adc_hum - ((int32_t)((int32_t)_H1 * 16))) -
+ var1 = (int32_t)(adc_hum - ((int32_t)((int32_t)_H1 << 4))) -
(((temp_scaled * (int32_t)_H3) / ((int32_t)100)) >> 1);
var2 =
((int32_t)_H2 *
@@ -427,20 +501,17 @@ uint8_t BME680_Class::readSensors(const bool waitSwitch) {
uvar2 = (((int64_t)((int64_t)adc_gas_res << 15) - (int64_t)(16777216)) + var1);
var3 = (((int64_t)lookupTable2[gas_range] * (int64_t)var1) >> 9);
_Gas = (uint32_t)((var3 + ((int64_t)uvar2 >> 1)) / (int64_t)uvar2);
- uint8_t workRegister = readByte(BME680_CONTROL_MEASURE_REGISTER); // Read the control measure
- putData(BME680_CONTROL_MEASURE_REGISTER,
- (uint8_t)(workRegister | 1)); // Trigger start of next measurement
- return (buff[14] & 0X30); // Return nonzero if gas or heat stabilization is invalid
+ triggerMeasurement(); // trigger the next measurement
+ return (buff[14] & 0X30); // Return nonzero if gas or heat stabilization is invalid
} // of method readSensors()
-void BME680_Class::waitForReadings() {
+void BME680_Class::waitForReadings() const {
/*!
@brief Only returns once a measurement on the BME680 has completed
*/
- while ((readByte(BME680_STATUS_REGISTER) & // Loop until the "measuring" bit
- _BV(BME680_MEASURING_BIT_POSITION)) != 0)
- ; // is cleared by BME680
+ while (measuring()) {
+ } // loop until any active measurment is complete
} // of method waitForReadings
-bool BME680_Class::setGas(uint16_t GasTemp, uint16_t GasMillis) {
+bool BME680_Class::setGas(uint16_t GasTemp, uint16_t GasMillis) const {
/*!
* @brief sets the gas measurement target temperature and heating time
* param[in] GasTemp Target temperature in Celsius
@@ -462,7 +533,8 @@ bool BME680_Class::setGas(uint16_t GasTemp, uint16_t GasMillis) {
GasTemp = 200;
else if (GasTemp > 400)
GasTemp = 400; // Clamp temperature to min/max
- var1 = (((int32_t)(_Temperature / 100) * _H3) / 1000) * 256;
+
+ var1 = (((int32_t)(_Temperature / 100) * _H3) / 1000) << 8;
var2 = (_G1 + 784) * (((((_G2 + 154009) * GasTemp * 5) / 100) + 3276800) / 10); // Issue #26
var3 = var1 + (var2 / 2);
var4 = (var3 / (_res_heat_range + 4));
@@ -476,7 +548,7 @@ bool BME680_Class::setGas(uint16_t GasTemp, uint16_t GasMillis) {
durval = 0xff; // Max duration
else {
while (GasMillis > 0x3F) {
- GasMillis = GasMillis / 4;
+ GasMillis = GasMillis >> 2;
factor += 1;
} // of while loop
durval = (uint8_t)(GasMillis + (factor * 64));
@@ -487,3 +559,22 @@ bool BME680_Class::setGas(uint16_t GasTemp, uint16_t GasMillis) {
} // of if-then-else turn gas measurements on or off
return true;
} // of method setGas()
+bool BME680_Class::measuring() const {
+ /*!
+ * @brief Returns whether the BME680 is currently measuring
+ * return "true" if a measurement is active, otherwise "false"
+ */
+ bool result(false);
+ if ((readByte(BME680_STATUS_REGISTER) & _BV(BME680_MEASURING_BIT_POSITION)) != 0) {
+ result = true;
+ } // if-then device is currently measuring
+ return result;
+} // of method "measuring()"
+void BME680_Class::triggerMeasurement() const {
+ /*!
+ * @brief Trigger a new measurement on the BME680
+ */
+ uint8_t workRegister = readByte(BME680_CONTROL_MEASURE_REGISTER); // Read the control measure
+ putData(BME680_CONTROL_MEASURE_REGISTER,
+ (uint8_t)(workRegister | 1)); // Trigger start of next measurement
+} // of method "triggerMeasurement()"
diff --git a/src/Zanshin_BME680.h b/src/Zanshin_BME680.h
index 0645391..883cd71 100644
--- a/src/Zanshin_BME680.h
+++ b/src/Zanshin_BME680.h
@@ -1,3 +1,4 @@
+// clang-format off
/*! @file Zanshin_BME680.h
@mainpage Arduino Library to access and control a Bosch BME680 Environmental Sensor
@@ -55,27 +56,32 @@ Written by Arnd, https://github.com/SV-Zanshin
Version | Date | Developer | Comments
------- | ---------- | ---------- | ---------------------------------------------------------------
-1.0.9 | 2020-09-27 | SV-Zanshin | Issue #26 - added return status for getSensorData
-1.0.9 | 2020-09-27 | SV-Zanshin | Issue #26 - Corrected computation of gas heater resistance value
-1.0.9 | 2020-06-28 | SV-Zanshin | Issue #25 - Reformat according to standard c++ style
-1.0.8 | 2020-06-20 | SV-Zanshin | Issue #22 - added "getI2CAddress()" function
-1.0.6 | 2020-05-25 | SV-Zanshin | Issue #17 - return value for "setOversampling()"
-1.0.6 | 2020-05-25 | SV-Zanshin | Issue #16 - I2C "reset()" when using 2 devices
-1.0.6 | 2020-05-25 | SV-Zanshin | General formatting of comments and spell-checking
-1.0.6 | 2020-05-24 | SV-Zanshin | Issue #14 - Humidity sometimes 100% despite turning on
-1.0.6 | 2020-05-24 | SV-Zanshin | Issue #15 - Pressure & Temperature oversampling switched
-1.0.5 | 2020-05-21 | SV-Zanshin | Issue #12 - First call to getSensorData() returns invalid data
-1.0.4 | 2020-05-14 | SV-Zanshin | Issue #9 - Allow 2 devices when using I2C
-1.0.4 | 2020-05-14 | SV-Zanshin | Issue #9 - Allow 2 devices when using I2C
-1.0.3 | 2020-05-09 | SV-Zanshin | Issue #5 - Adjust readings. Subsequently removed code again
-1.0.3 | 2020-05-09 | SV-Zanshin | Issue #8 - clean up comments and code
-1.0.2 | 2019-01-26 | SV-Zanshin | Issue #3 - Converted documentation to doxygen style
-1.0.1 | 2018-07-22 | SV-Zanshin | Corrected I2C datatypes
-1.0.1 | 2018-07-03 | SV-Zanshin | Issue #1 - Added waitForReading and param to getSensorData()
-1.0.0 | 2018-07-02 | SV-Zanshin | Added guard code against multiple I2C constants defs
-1.0.0 | 2018-07-01 | SV-Zanshin | Added and tested I2C, SPI and soft-SPI connections
-1.0.0a | 2018-06-30 | SV-Zanshin | Cloned from BME280 library and started recoding
+1.0.10 | 2020-12-03 | SV-Zanshin | Issue #34 Enhancements from Alain2019 - added measurement functionality
+1.0.10 | 2020-12-02 | SV-Zanshin | Issue #33 Optimize library code for size, performance, initializers
+1.0.10 | 2020-10-19 | Alain2019 | Issue #32 Change division to bit shifts for clarity
+1.0.10 | 2020-10-10 | Alain2019 | Issue #31 Incorrect computation of _H1 and _H2
+1.0.9 | 2020-09-27 | SV-Zanshin | Issue #26 added return status for getSensorData
+1.0.9 | 2020-09-27 | SV-Zanshin | Issue #26 Corrected computation of gas heater resistance value
+1.0.9 | 2020-06-28 | SV-Zanshin | Issue #25 Reformat according to standard c++ style
+1.0.8 | 2020-06-20 | SV-Zanshin | Issue #22 added "getI2CAddress()" function
+1.0.6 | 2020-05-25 | SV-Zanshin | Issue #17 return value for "setOversampling()"
+1.0.6 | 2020-05-25 | SV-Zanshin | Issue #16 I2C "reset()" when using 2 devices
+1.0.6 | 2020-05-25 | SV-Zanshin | General formatting of comments and spell-checking
+1.0.6 | 2020-05-24 | SV-Zanshin | Issue #14 Humidity sometimes 100% despite turning on
+1.0.6 | 2020-05-24 | SV-Zanshin | Issue #15 Pressure & Temperature oversampling switched
+1.0.5 | 2020-05-21 | SV-Zanshin | Issue #12 First call to getSensorData() returns invalid data
+1.0.4 | 2020-05-14 | SV-Zanshin | Issue #9 Allow 2 devices when using I2C
+1.0.4 | 2020-05-14 | SV-Zanshin | Issue #9 Allow 2 devices when using I2C
+1.0.3 | 2020-05-09 | SV-Zanshin | Issue #5 Adjust readings. Subsequently removed code again
+1.0.3 | 2020-05-09 | SV-Zanshin | Issue #8 clean up comments and code
+1.0.2 | 2019-01-26 | SV-Zanshin | Issue #3 Converted documentation to doxygen style
+1.0.1 | 2018-07-22 | SV-Zanshin | Corrected I2C datatypes
+1.0.1 | 2018-07-03 | SV-Zanshin | Issue #1 Added waitForReading and param to getSensorData()
+1.0.0 | 2018-07-02 | SV-Zanshin | Added guard code against multiple I2C constants defs
+1.0.0 | 2018-07-01 | SV-Zanshin | Added and tested I2C, SPI and soft-SPI connections
+1.0.0a | 2018-06-30 | SV-Zanshin | Cloned from BME280 library and started recoding
*/
+// clang-format on
#include // Standard SPI library
#include // Standard I2C "Wire" library
@@ -83,94 +89,25 @@ Version | Date | Developer | Comments
#ifndef BME680_h
#define BME680_h ///< Guard code definition for the header
-#define CONCAT_BYTES(msb, lsb) \
- (((uint16_t)msb << 8) | (uint16_t)lsb) ///< Inline to combine msb and lsb bytes
+#define CONCAT_BYTES(msb, lsb) (((uint16_t)msb << 8) | (uint16_t)lsb) ///< combine msb & lsb bytes
#ifndef _BV
-#define _BV(bit) (1 << (bit)) ///< Sometimes this macro isn't pre-defined
+#define _BV(bit) (1 << (bit)) ///< This macro isn't pre-defined on all platforms
#endif
-/**************************************************************************************************
-** Declare constants used in the class **
-**************************************************************************************************/
-#ifndef I2C_MODES // If the I2C_Modes haven't been declared yet
-#define I2C_MODES ///< Guard code definition for the I2C modes
-const uint32_t I2C_STANDARD_MODE = 100000; ///< Default normal I2C 100KHz speed
-const uint32_t I2C_FAST_MODE = 400000; ///< Fast mode
-const uint32_t I2C_FAST_MODE_PLUS = 1000000; ///< Really fast mode
-const uint32_t I2C_HIGH_SPEED_MODE = 3400000; ///< Turbo mode
+/***************************************************************************************************
+** Declare publically visible constants used in the class **
+***************************************************************************************************/
+#ifndef I2C_MODES // If the I2C_Modes haven't been declared yet
+#define I2C_MODES ///< Guard code definition for the I2C modes
+const uint32_t I2C_STANDARD_MODE{100000}; ///< Default normal I2C 100KHz speed
+const uint32_t I2C_FAST_MODE{400000}; ///< Fast mode
+const uint32_t I2C_FAST_MODE_PLUS{1000000}; ///< Really fast mode
+const uint32_t I2C_HIGH_SPEED_MODE{3400000}; ///< Turbo mode
#endif
-const uint32_t SPI_HERZ = 500000; ///< SPI speed in Hz
-const uint8_t BME680_STATUS_REGISTER = 0x1D; ///< Device status register
-const uint8_t BME680_GAS_HEATER_REGISTER0 = 0x5A; ///< Heater Register 0 address
-const uint8_t BME680_GAS_DURATION_REGISTER0 = 0x64; ///< Heater Register 0 address
-const uint8_t BME680_CONTROL_GAS_REGISTER1 = 0x70; ///< Gas control register on/off
-const uint8_t BME680_CONTROL_GAS_REGISTER2 = 0x71; ///< Gas control register settings
-const uint8_t BME680_CONTROL_HUMIDITY_REGISTER = 0x72; ///< Humidity control register
-const uint8_t BME680_SPI_REGISTER = 0x73; ///< Status register for SPI memory
-const uint8_t BME680_CONTROL_MEASURE_REGISTER = 0x74; ///< Temp, Pressure control register
-const uint8_t BME680_CONFIG_REGISTER = 0x75; ///< Configuration register
-const uint8_t BME680_CHIPID_REGISTER = 0xD0; ///< Chip-Id register
-const uint8_t BME680_SOFTRESET_REGISTER = 0xE0; ///< Reset when 0xB6 is written here
-const uint8_t BME680_CHIPID = 0x61; ///< Hard-coded value 0x61 for BME680
-const uint8_t BME680_RESET_CODE = 0xB6; ///< Reset when this put in reset reg
-const uint8_t BME680_MEASURING_BIT_POSITION = 5; ///< Bit position for measuring flag
-const uint8_t BME680_I2C_MIN_ADDRESS = 0x76; ///< Minimum possible address for BME680
-const uint8_t BME680_I2C_MAX_ADDRESS = 0x77; ///< Minimum possible address for BME680
-const uint8_t BME680_SPI_MEM_PAGE_POSITION = 4; ///< Bit position for the memory page value
-const uint8_t BME680_HUMIDITY_MASK = 0xF8; ///< Mask is binary B11111000
-const uint8_t BME680_PRESSURE_MASK = 0xE3; ///< Mask is binary B11100011
-const uint8_t BME680_TEMPERATURE_MASK = 0x1F; ///< Mask is binary B00011111
-/**************************************************************************************************
-** Declare the constants used for calibration **
-**************************************************************************************************/
-const uint8_t BME680_COEFF_SIZE1 = 25; ///< First array with coefficients
-const uint8_t BME680_COEFF_SIZE2 = 16; ///< Second array with coefficients
-const uint8_t BME680_COEFF_START_ADDRESS1 = 0x89; ///< start address for array 1
-const uint8_t BME680_COEFF_START_ADDRESS2 = 0xE1; ///< start address for array 2
-const uint8_t BME680_HUM_REG_SHIFT_VAL = 4; ///< Ambient humidity shift value
-const uint8_t BME680_BIT_H1_DATA_MSK = 0x0F; ///< Mask for humidity
-const uint8_t BME680_T2_LSB_REG = 1; ///< Register for temperature calibration
-const uint8_t BME680_T2_MSB_REG = 2; ///< Register for temperature calibration
-const uint8_t BME680_T3_REG = 3; ///< Register for temperature calibration
-const uint8_t BME680_P1_LSB_REG = 5; ///< Register for pressure calibration
-const uint8_t BME680_P1_MSB_REG = 6; ///< Register for pressure calibration
-const uint8_t BME680_P2_LSB_REG = 7; ///< Register for pressure calibration
-const uint8_t BME680_P2_MSB_REG = 8; ///< Register for pressure calibration
-const uint8_t BME680_P3_REG = 9; ///< Register for pressure calibration
-const uint8_t BME680_P4_LSB_REG = 11; ///< Register for pressure calibration
-const uint8_t BME680_P4_MSB_REG = 12; ///< Register for pressure calibration
-const uint8_t BME680_P5_LSB_REG = 13; ///< Register for pressure calibration
-const uint8_t BME680_P5_MSB_REG = 14; ///< Register for pressure calibration
-const uint8_t BME680_P7_REG = 15; ///< Register for pressure calibration
-const uint8_t BME680_P6_REG = 16; ///< Register for pressure calibration
-const uint8_t BME680_P8_LSB_REG = 19; ///< Register for pressure calibration
-const uint8_t BME680_P8_MSB_REG = 20; ///< Register for pressure calibration
-const uint8_t BME680_P9_LSB_REG = 21; ///< Register for pressure calibration
-const uint8_t BME680_P9_MSB_REG = 22; ///< Register for pressure calibration
-const uint8_t BME680_P10_REG = 23; ///< Register for pressure calibration
-const uint8_t BME680_H2_MSB_REG = 0; ///< Register for humidity calibration
-const uint8_t BME680_H2_LSB_REG = 1; ///< Register for humidity calibration
-const uint8_t BME680_H1_LSB_REG = 1; ///< Register for humidity calibration
-const uint8_t BME680_H1_MSB_REG = 2; ///< Register for humidity calibration
-const uint8_t BME680_H3_REG = 3; ///< Register for humidity calibration
-const uint8_t BME680_H4_REG = 4; ///< Register for humidity calibration
-const uint8_t BME680_H5_REG = 5; ///< Register for humidity calibration
-const uint8_t BME680_H6_REG = 6; ///< Register for humidity calibration
-const uint8_t BME680_H7_REG = 7; ///< Register for humidity calibration
-const uint8_t BME680_T1_LSB_REG = 8; ///< Register for gas calibration
-const uint8_t BME680_T1_MSB_REG = 9; ///< Register for gas calibration
-const uint8_t BME680_GH2_LSB_REG = 10; ///< Register for gas calibration
-const uint8_t BME680_GH2_MSB_REG = 11; ///< Register for gas calibration
-const uint8_t BME680_GH1_REG = 12; ///< Register for gas calibration
-const uint8_t BME680_GH3_REG = 13; ///< Register for gas calibration
-const uint8_t BME680_ADDR_RES_HEAT_RANGE_ADDR = 0x02; ///< Register for gas calibration
-const uint8_t BME680_RHRANGE_MSK = 0x30; ///< Register for gas calibration
-const uint8_t BME680_ADDR_RES_HEAT_VAL_ADDR = 0x00; ///< Register for gas calibration
-const uint8_t BME680_ADDR_RANGE_SW_ERR_ADDR = 0x04; ///< Register for gas calibration
-const uint8_t BME680_RSERROR_MSK = 0xF0; ///< Register for gas calibration
+const uint32_t SPI_HERZ{500000}; ///< SPI speed in Hz
-/**************************************************************************************************
-** Declare enumerated types used in the class **
-**************************************************************************************************/
+/***************************************************************************************************
+** Declare enumerated types used in the class **
+***************************************************************************************************/
/*! @brief Enumerate the sensor type */
enum sensorTypes { TemperatureSensor, HumiditySensor, PressureSensor, GasSensor, UnknownSensor };
/*! @brief Enumerate the Oversampling types */
@@ -197,29 +134,30 @@ class BME680_Class {
bool begin(); // Start using I2C Communications
bool begin(const uint32_t i2cSpeed); // I2C with a non-default speed
bool begin(const uint8_t chipSelect); // Start using either I2C or HW-SPI
- bool begin(const uint32_t i2cSpeed,
- const uint8_t i2cAddress); // Explicitly set speed and I2C Addr.
- bool begin(const uint8_t chipSelect, const uint8_t mosi, // Start using software SPI
+ bool begin(const uint32_t i2cSpeed, const uint8_t i2cAddress); // Set speed and I2C Addr.
+ bool begin(const uint8_t chipSelect, const uint8_t mosi, // Start using software SPI
const uint8_t miso, const uint8_t sck);
- uint8_t setOversampling(const uint8_t sensor, // Set enum sensorType Oversampling
- const uint8_t sampling = UINT8_MAX); // and return current value
- bool setGas(uint16_t GasTemp, uint16_t GasMillis); // Gas heating temperature and time
- uint8_t setIIRFilter(const uint8_t iirFilterSetting = UINT8_MAX); // Set IIR Filter
- uint8_t getSensorData(int32_t &temp, int32_t &hum, // get most recent readings
- int32_t &press, int32_t &gas, //
- const bool waitSwitch = true); //
- uint8_t getI2CAddress(); // Return the I2C Address of the BME680
- void reset(); // Reset the BME680
- private: //
- bool commonInitialization(); ///< Common initialization code
- uint8_t readByte(const uint8_t addr); ///< Read byte from register address
- uint8_t readSensors(const bool waitSwitch); ///< read the registers in one burst
- void waitForReadings(); ///< Wait for readings to finish
- void getCalibration(); ///< Load calibration from registers
- uint8_t _I2CAddress = 0; ///< Default is I2C address is unknown
- uint16_t _I2CSpeed = 0; ///< Default is I2C speed is unknown
- uint8_t _cs, _sck, _mosi, _miso; ///< Hardware and software SPI pins
- uint8_t _H6, _P10, _res_heat_range; ///< unsigned configuration vars
+ uint8_t setOversampling(const uint8_t sensor, // Set enum sensorType Oversampling
+ const uint8_t sampling = UINT8_MAX) const; // and return current value
+ bool setGas(uint16_t GasTemp, uint16_t GasMillis) const; // Gas heating temperature and time
+ uint8_t setIIRFilter(const uint8_t iirFilterSetting = UINT8_MAX) const; // Set IIR Filter
+ uint8_t getSensorData(int32_t &temp, int32_t &hum, // get most recent readings
+ int32_t &press, int32_t &gas, //
+ const bool waitSwitch = true); //
+ uint8_t getI2CAddress() const; // Return the I2C Address of the BME680
+ void reset(); // Reset the BME680
+ bool measuring() const; ///< true if currently measuring
+ void triggerMeasurement() const; ///< trigger a measurement
+ private: //
+ bool commonInitialization(); ///< Common initialization code
+ uint8_t readByte(const uint8_t addr) const; ///< Read byte from register address
+ uint8_t readSensors(const bool waitSwitch); ///< read the registers in one burst
+ void waitForReadings() const; ///< Wait for readings to finish
+ void getCalibration(); ///< Load calibration from registers
+ uint8_t _I2CAddress = 0; ///< Default is I2C address is unknown
+ uint16_t _I2CSpeed = 0; ///< Default is I2C speed is unknown
+ uint8_t _cs, _sck, _mosi, _miso; ///< Hardware and software SPI pins
+ uint8_t _H6, _P10, _res_heat_range; ///< unsigned configuration vars
int8_t _H3, _H4, _H5, _H7, _G1, _G3, _T3, _P3, _P6, _P7, _res_heat,
_rng_sw_err; ///< signed configuration vars
uint16_t _H1, _H2, _T1, _P1; ///< unsigned 16bit configuration vars
@@ -240,7 +178,7 @@ class BME680_Class {
the getData(). The "putData()" is called directly in the code.
*/
template
- uint8_t &getData(const uint8_t addr, T &value) {
+ uint8_t &getData(const uint8_t addr, T &value) const {
/*!
@brief Template for reading from I2C or SPI using any data type
@details As a template it can support compile-time data type definitions
@@ -300,7 +238,7 @@ class BME680_Class {
return (structSize);
} // of method getData()
template
- uint8_t &putData(const uint8_t addr, const T &value) {
+ uint8_t &putData(const uint8_t addr, const T &value) const {
/*!
@brief Template for writing to I2C or SPI using any data type
@details As a template it can support compile-time data type definitions