- C++ 99.6%
- Lua 0.4%
| config | ||
| include | ||
| src | ||
| .gitignore | ||
| README.md | ||
| xmake.lua | ||
BME680 C++ Project
A comprehensive C++ application for the BME680 environmental sensor, providing temperature, pressure, humidity, and gas resistance readings with air quality calculation, data logging, and multiple CLI display modes.
Features
- Sensor Reading: Read all four sensor values (Temperature, Pressure, Humidity, Gas Resistance)
- Air Quality Calculation: Indoor air quality estimation based on Bosch's algorithm
- Data Logging: CSV and JSON logging with automatic file rotation
- Multiple Display Modes: Basic, Full, Air Quality, Minimal, Graphic, Raw, JSON, CSV
- Real-time Dashboard: Colorized CLI output with progress bars and gauges
- Configurable: All parameters configurable via command-line or config file
- Thread-safe: Multi-threaded reading with proper synchronization
Requirements
Hardware
- Raspberry Pi (or any Linux system with I2C support)
- BME680 environmental sensor module
- I2C connection cables
Software
- C++17 compiler (GCC 8+, Clang 7+)
- CMake 3.10+
- libi2c-dev
- pthread library
Quick Start
1. Setup
Run the setup script to install dependencies and build the project:
chmod +x setup.sh
./setup.sh
This will:
- Install required packages
- Enable I2C interface
- Update git submodules
- Build the project
2. Connect Sensor
Connect the BME680 to your Raspberry Pi:
| BME680 Pin | Raspberry Pi Pin | GPIO | Description |
|---|---|---|---|
| VIN | 3.3V (Pin 1) | - | Power |
| GND | GND (Pin 6) | - | Ground |
| SDA | GPIO 2 (Pin 3) | 2 | I2C Data |
| SCL | GPIO 3 (Pin 5) | 3 | I2C Clock |
3. Verify Connection
Check that your sensor is detected:
sudo i2cdetect -y 1
You should see device at address 0x76 or 0x77.
4. Run Application
./build/bme680_cli
Usage
Command-Line Options
./build/bme680_cli [OPTIONS]
Display Options
| Option | Description |
|---|---|
-m, --mode MODE |
Display mode: basic, full, air_quality, minimal, graphic, raw, json, csv |
-c, --color |
Enable colored output (default: true) |
--no-color |
Disable colored output |
-t, --timestamp BOOL |
Show/hide timestamp |
-u, --units BOOL |
Show/hide units |
-p, --precision N |
Number of decimal places (default: 2) |
--date-format FORMAT |
Date format string (strftime format) |
Sensor Options
| Option | Description |
|---|---|
-a, --address ADDR |
I2C address in hex (0x76 or 0x77, default: 0x76) |
-b, --bus N |
I2C bus number (default: 1) |
-v, --verbose |
Enable verbose output |
-d, --debug |
Enable debug output |
Logging Options
| Option | Description |
|---|---|
-l, --log |
Enable data logging |
--log-dir DIR |
Log directory (default: logs/) |
--log-prefix PREFIX |
Log file prefix (default: bme680_) |
--log-format FORMAT |
Log format: csv, json, binary (default: csv) |
--log-rotation TYPE |
Rotation type: none, daily, hourly, size_limit (default: daily) |
--log-max-size BYTES |
Maximum file size before rotation (default: 10MB) |
Air Quality Options
| Option | Description |
|---|---|
--humidity-baseline N |
Humidity baseline percentage (default: 40.0) |
--humidity-weighting N |
Humidity weighting factor (0.0-1.0, default: 0.25) |
--air-quality BOOL |
Enable/disable air quality calculation (default: true) |
Operation Options
| Option | Description |
|---|---|
--continuous BOOL |
Run in continuous mode (default: true) |
-n, --num-readings N |
Number of readings to take (0 = continuous) |
--help, -h |
Show help message |
--version |
Show version information |
Examples
Basic Reading
./build/bme680_cli
Full Display Mode
./build/bme680_cli --mode full
JSON Output
./build/bme680_cli --mode json
With Data Logging
./build/bme680_cli --log --log-format csv --log-dir ./data
Specific I2C Address
./build/bme680_cli --address 0x77 --bus 1
Single Reading
./build/bme680_cli --continuous false
Custom Display
./build/bme680_cli --mode graphic --no-color --precision 1
Display Modes
BASIC (default)
Shows temperature, pressure, humidity, and gas resistance on separate lines.
FULL
Shows all sensor values plus additional metadata.
AIR_QUALITY
Focuses on air quality score with humidity and gas contributions.
MINIMAL
Single-line compact display with all values.
GRAPHIC
Visual representation with progress bars and gauges.
RAW
Shows raw ADC values before compensation.
JSON
Outputs data in JSON format (useful for pipelines).
CSV
Outputs data in CSV format (useful for logging).
Configuration File
The application can be configured using config/config.ini. Command-line arguments override configuration file settings.
[Sensor]
i2c_address = 0x76
i2c_bus = 1
temp_oversampling = 2x
pres_oversampling = 4x
hum_oversampling = 1x
filter = 3
[Display]
display_mode = basic
use_colors = true
show_timestamp = true
show_units = true
decimal_places = 2
[Logging]
enable_logging = false
log_directory = logs/
log_prefix = bme680_
log_format = csv
log_rotation = daily
log_max_size = 10485760
[AirQuality]
humidity_baseline = 40.0
humidity_weighting = 0.25
calculate_air_quality = true
Building
Prerequisites
Install build dependencies:
sudo apt update
sudo apt install -y build-essential cmake git libi2c-dev i2c-tools
CMake Build
mkdir -p build
cd build
cmake -DCMAKE_BUILD_TYPE=Release ..
make -j$(nproc)
Makefile Build (Alternative)
make clean all
Project Structure
bme680-cpp/
├── include/
│ ├── bme680/ # Low-level sensor interface
│ │ ├── BME680Config.hpp # Constants and enums
│ │ ├── BME680Data.hpp # Data structures
│ │ └── BME680Sensor.hpp # Sensor driver interface
│ ├── core/ # Core functionality
│ │ ├── SensorReader.hpp # High-level reader
│ │ ├── DataLogger.hpp # Data logging
│ │ └── AirQuality.hpp # Air quality calculation
│ ├── cli/ # CLI interface
│ │ ├── CLIHandler.hpp # Command-line parsing
│ │ └── DisplayFormater.hpp # Output formatting
│ ├── mqtt/ # MQTT publishing (NEW)
│ │ ├── MQTTConfig.hpp # MQTT configuration
│ │ └── MQTTClient.hpp # MQTT client wrapper
│ └── utils/ # Utilities
│ ├── RingBuffer.hpp # Circular buffer
│ ├── Timer.hpp # Timing utilities
│ └── TypeUtils.hpp # Type conversions
├── src/ # Implementations
│ ├── bme680/
│ ├── core/
│ ├── cli/
│ ├── mqtt/ # MQTT publishing (NEW)
│ │ ├── MQTTClient.cpp # MQTT client implementation
│ │ └── mqtt_main.cpp # MQTT executable entry point
│ ├── utils/
│ ├── main.cpp # CLI executable entry point
│ └── ...
├── third_party/bme680/ # Bosch driver (git submodule)
├── config/
│ └── config.ini # Default configuration
├── tests/ # Unit tests
├── CMakeLists.txt
├── Makefile
├── setup.sh
└── README.md
Air Quality Algorithm
The air quality calculation is based on Bosch's indoor air quality example. It combines relative humidity and gas resistance measurements to produce a score from 0-100%:
- Humidity Score: Based on distance from the optimal humidity baseline (typically 40%)
- Gas Score: Based on distance from the gas resistance baseline
- Combined Score: Weighted average of humidity and gas scores
- Category: The final score is categorized into quality levels
Quality Categories:
- 80-100%: Excellent
- 60-79%: Good
- 40-59%: Fair
- 20-39%: Poor
- 0-19%: Very Poor
Troubleshooting
I2C Permission Denied
If you get permission errors when accessing the I2C device:
# Add user to i2c group
sudo usermod -aG i2c $USER
# Log out and log back in, or run:
newgrp i2c
Sensor Not Detected
- Verify wiring (SDA, SCL, VCC, GND)
- Check I2C address with
sudo i2cdetect -y 1 - Try the alternative address (0x76 or 0x77)
- Verify sensor power (3.3V)
Build Errors
- Ensure all dependencies are installed
- Clean build directory:
rm -rf build CMakeCache.txt CMakeFiles/ - Re-run cmake:
cmake -DCMAKE_BUILD_TYPE=Release .
Hardware Notes
I2C Pull-up Resistors
The BME680 module typically has built-in pull-up resistors on SDA and SCL. If your module doesn't have them, you'll need to add 4.7kOhm resistors between SDA/SCL and 3.3V.
Multiple Sensors
You can connect multiple BME680 sensors by:
- Using different I2C addresses (change the ADDR pin on the module)
- Connecting to different I2C buses (if available)
- Using an I2C multiplexer
API Reference
SensorReader
The SensorReader class is the main interface for reading sensor data:
#include "core/SensorReader.hpp"
bme680::core::SensorReader reader;
// Initialize
if (reader.initialize()) {
// Start continuous reading with callback
reader.setDataCallback([](const bme680::SensorReading& r) {
std::cout << "Temp: " << r.temperature << " °C\n";
});
reader.start();
// ... use data ...
reader.stop();
}
DataLogger
#include "core/DataLogger.hpp"
bme680::core::LogConfig config;
config.format = bme680::core::LogFormat::CSV;
config.directory = "./logs/";
bme680::core::DataLogger logger(config);
logger.open();
// Log a reading
bme680::SensorReading reading;
logger.log(reading);
logger.close();
Contributing
- Fork the repository
- Create a feature branch (
git checkout -b feature/your-feature) - Commit your changes (
git commit -am 'Add some feature') - Push to the branch (
git push origin feature/your-feature) - Create a new Pull Request
License
This project is provided for educational and development purposes.
🌐 BME680 MQTT Publisher
An MQTT client that reads BME680 sensor data and publishes it to an MQTT broker for integration with home automation systems, dashboards, or IoT platforms.
🚀 Quick Start
# Build the MQTT executable
mkdir -p build && cd build
cmake ..
make bme680_mqtt
# Start Mosquitto broker (if not already running)
sudo systemctl start mosquitto
# Run the MQTT publisher
./bme680_mqtt -b localhost -t sensors/room
# Subscribe to the topic in another terminal
mosquitto_sub -t "sensors/room" -v
📡 Usage
# Basic usage with default settings
./bme680_mqtt
# Connect to a remote broker
./bme680_mqtt --broker mqtt.example.com --port 1883
# With authentication
./bme680_mqtt -b mqtt.example.com -u username -p password -t sensors/bme680
# With TLS/SSL encryption
./bme680_mqtt --broker mqtt.example.com --tls --ca-file /etc/mosquitto/ca_certificates/ca.crt
# Custom topic and I2C settings
./bme680_mqtt -b localhost -t home/livingroom/sensor --i2c-address 0x76 --interval 500
# Publish to separate topics
./bme680_mqtt --separate-topics -t sensors/bme680
# Verbose output for debugging
./bme680_mqtt -v
⚙️ Command Line Options
MQTT Options
| Option | Description | Default |
|---|---|---|
--broker, -b HOST |
MQTT broker hostname/IP address | localhost |
--port, -P PORT |
MQTT broker port number | 1883 |
--client-id ID |
MQTT client identifier | bme680_sensor |
--topic, -t TOPIC |
Base topic for publishing | sensors/bme680 |
--username, -u USER |
MQTT username for authentication | (none) |
--password, -p PASS |
MQTT password for authentication | (none) |
--qos QOS |
Quality of Service level (0, 1, 2) | 1 |
--retain |
Retain last message on broker | false |
--tls |
Enable TLS/SSL encryption | false |
--ca-file FILE |
CA certificate file for TLS | (none) |
--cert-file FILE |
Client certificate file for TLS | (none) |
--key-file FILE |
Client private key file for TLS | (none) |
--separate-topics |
Publish to individual subtopics | false |
Sensor Options
| Option | Description | Default |
|---|---|---|
--i2c-address ADDR |
BME680 I2C address (0x76 or 0x77) | 0x77 |
--i2c-bus BUS |
I2C bus number | 1 |
--interval MS |
Reading interval in milliseconds | 1000 |
--no-gas |
Disable gas sensor measurements | false |
--no-aq |
Disable air quality calculation | false |
General Options
| Option | Description | Default |
|---|---|---|
--verbose, -v |
Enable verbose output | false |
--help, -h |
Display help message | - |
--version |
Display version information | - |
📊 MQTT Message Format
All messages are published in JSON format. The message structure includes sensor readings and optionally air quality data.
Full Sensor Data with Air Quality (default)
{
"timestamp": "2026-06-20T15:30:00.123Z",
"sensor": {
"temperature": 29.45,
"pressure": 1001.31,
"humidity": 36.68,
"gas_resistance": 97970.0
},
"air_quality": {
"score": 97.9,
"category": "Excellent"
}
}
Sensor Data Only (when --no-aq is used)
{
"timestamp": "2026-06-20T15:30:00.123Z",
"sensor": {
"temperature": 29.45,
"pressure": 1001.31,
"humidity": 36.68,
"gas_resistance": 97970.0
}
}
🔄 Features
- Automatic Reconnection: Automatically reconnects if the broker connection is lost
- QoS Support: Configurable Quality of Service levels (0, 1, or 2)
- Message Retention: Option to retain the last message on the broker
- TLS/SSL Security: Encrypted connections with certificate verification
- Authentication: Username/password authentication support
- Flexible Topics: Single topic or multiple subtopics for each sensor value
References
- BME680 Datasheet
- Bosch BME68x SensorAPI
- BME680 Python Library
- Eclipse Mosquitto
- MQTT v3.1.1 Specification
Version
Current version: 1.0.0