A high-precision, portable environmental monitor using an ESP8266, a Bosch BME680 sensor, and an integrated OLED display. This project leverages the official Bosch BSEC (Bosch Sensortec Environmental Cluster) software library to provide accurate Indoor Air Quality (IAQ) readings, alongside temperature, humidity, pressure, and altitude.
The device is designed for continuous operation with robust error handling, intelligent baseline management, and an always-on OLED display that continuously cycles through data screens.
- Bosch BSEC Integration: Utilizes Bosch's proprietary BSEC algorithm for reliable Indoor Air Quality (IAQ) index calculation (0β500 scale).
- Comprehensive Data: Measures Temperature, Humidity, Barometric Pressure, Gas Resistance (VOCs), and calculates Altitude.
- Data Persistence: Saves the BSEC calibration state to EEPROM every 4 hours, but only when the IAQ accuracy level is high (
iaqAccuracy==3). This minimizes flash wear and ensures stable calibration across power cycles.
- Variance-Aware IAQ Smoothing: Implements an adaptive smoothing algorithm on the Static IAQ value, providing a more stable and human-readable output.
- Self-Adapting Gas Baseline: Automatically adapts over time for long-term environmental stability.
- Transport-Aware Logic: Freezes baseline calibration when rapid environmental changes are detected (e.g., device movement).
- Altitude Filtering: Combines a median filter with an EMA for smooth and reliable altitude readings.
- Continuous Display Mode: OLED display remains active 24/7, cycling through three data screens:
- Screen 1 (5s): Temperature & Humidity
- Screen 2 (5s): Pressure & Altitude
- Screen 3 (5s): Gas Resistance, IAQ, Accuracy, Air Quality Status
- Incremental Refresh: Screen only updates when values change beyond thresholds, reducing flicker and CPU usage.
- Battery Optimized: Sensor reads every 30 seconds with intelligent power management for 24hr+ battery life.
- If temperature β₯ 45Β°C, device enters "HOT HOLD" mode.
- OLED shows a warning with a thermometer icon and the text Overheat, which shifts position every 60s to prevent burn-in.
- Normal operation resumes when temperature drops below 41Β°C.
- Error Recovery: Auto-retry mechanism for BSEC initialization with exponential backoff.
- Offline Operation: Continues to work without network, using last known QNH or default fallback.
- Serial Command Interface: Configure QNH, check status, and calibrate altitude via serial monitor.
- ESP8266 Board with Integrated OLED (0.96" SSD1306).
- Bosch BME680 Sensor (I2C).
- TP4056 for LiPo battery charging and management.
- LiPo Battery (e.g., 1500β2100 mAh).
- Power Switch for on/off control.
- Custom PCB & Enclosure for portability.
| Component | Pin / Address |
|---|---|
| I2C SDA (Data) | GPIO 14 |
| I2C SCL (Clock) | GPIO 12 |
| OLED I2C Address | 0x3C |
| BME680 I2C Address | 0x76 |
- Arduino IDE
- ESP8266 Board Package for Arduino IDE
- Libraries:
Wire.h(Built-in)EEPROM.h(Built-in)Adafruit GFX LibraryAdafruit SSD1306Bosch BSEC Software Library
If you encounter this compilation error:
section `.text1' will not fit in region `iram1_0_seg'
This is a memory configuration issue, not a code problem. The fix requires two settings changes:
- Tools β Flash Size β Change to
4M (3M SPIFFS) - Tools β MMU β Select
16KB cache + 48KB IRAM - Restart Arduino IDE
See FIX_IRAM_OVERFLOW_GUIDE.md for:
- Detailed step-by-step instructions
- VS Code / PlatformIO configuration
- Manual
platform.txtreplacement method - Troubleshooting and technical explanations
Included in this project: platform.txt (ready-to-use replacement file)
-
Install Arduino IDE & ESP8266 Core: Add
http://arduino.esp8266.com/stable/package_esp8266com_index.jsonto Board Manager URLs. -
Install Required Libraries via Library Manager:
- "Adafruit GFX Library"
- "Adafruit SSD1306"
- "BSEC Software Library"
-
Configure the Sketch:
// Optional: Edit configuration constants at top of sketch #define SENSOR_READ_INTERVAL_MS 30000UL // Sensor reading interval #define OLED_DATA_SCREEN_1_DURATION 5000UL // Screen 1 duration #define OLED_DATA_SCREEN_2_DURATION 5000UL // Screen 2 duration #define OLED_DATA_SCREEN_3_DURATION 5000UL // Screen 3 duration
-
Upload to ESP8266:
- Go to
Tools > Boardand select "NodeMCU 1.0 (ESP-12E Module)" - Tools > Flash Size β
4M (3M SPIFFS) - Tools > MMU β
16KB cache + 48KB IRAM - Connect your board and select the correct COM port
- Click "Upload"
- Go to
- Connect your Android phone to the device via USB-C OTG + data cable.
- Open Serial USB Terminal (or any compatible terminal app).
- Set baud rate to 115200, newline to CR+LF.
- Type:
(Adjust this to the latest QNH in your location. Check weather apps such as Breezy Weather for current atmospheric pressure)
QNH=1013.25
The device stores QNH in EEPROM and immediately recalculates altitude.
- Stand at a location with a verified elevation (e.g., summit, basecamp, map marker).
- Type:
(Adjust this according to the altitude of your location)
ALTREF=709
The device computes QNH from the current pressure and saves it permanently. Verify with:
ALT?
- At basecamp, perform one calibration (QNH or ALTREF).
- Recalibrate if the weather changes significantly.
- Precision Rule: Β±1 hPa β Β±8β9 m at mid-altitudes. Recalibrate whenever you change location or weather conditions vary.
The BSEC library provides an IAQ value on a scale from 0 to 500:
- 0 - 50: Excellent
- 51 - 100: Good
- 101 - 150: Lightly Polluted
- 151 - 200: Moderately Polluted
- 201 - 300: Heavily Polluted
- 301+: Severely Polluted
The device displays this scale as an "AQS" (Air Quality Status) string for easy interpretation. The Acc (Accuracy) value indicates the BSEC algorithm's confidence level (0=stabilizing, 1=low, 2=medium, 3=high). High accuracy is typically achieved after the device runs for a while.
Connect via serial monitor (115200 baud) and use:
| Command | Description | Example Response |
|---|---|---|
QNH=<hPa> |
Set sea-level pressure | OK QNH=1013.25 hPa |
QNH? |
Query current QNH value | QNH=1013.25 hPa |
ALT? |
Query current altitude | ALT=708.9 m |
PRESS? |
Query current pressure | P=933.10 hPa |
ALTREF=<m> |
Auto-calculate QNH from known altitude | OK QNH from ALTREF -> 1014.32 hPa |
STATUS |
Show system status | Mode:0 Therm:0 BSEC:Y IAQ:45.2(3) |
HELP |
Show all commands | CMD: QNH=<hPa>|QNH?|ALT?|... |
The OLED continuously cycles through 3 screens:
- Screen 1 (5s): Temperature & Humidity
- Screen 2 (5s): Pressure & Altitude
- Screen 3 (5s): Gas Resistance, IAQ, Accuracy, AQS
- Loops back to Screen 1 β Continuous monitoring mode
| IAQ Range | Air Quality |
|---|---|
| 0-50 | Excellent |
| 51-100 | Good |
| 101-150 | Light |
| 151-200 | Moderate |
| 201-300 | Unhealthy |
| 301+ | Hazardous |
The Acc value (0-3) shows BSEC algorithm confidence:
- 0: Stabilizing (first 5-30 minutes)
- 1: Low confidence
- 2: Medium confidence
- 3: High confidence (optimal)
- Continuous Mode: Display never turns off
- 3 screens cycle every 5 seconds each (15s total cycle)
- Conditional redraw: Only updates when values change beyond thresholds (reduces flicker)
| Battery Capacity | Estimated Runtime |
|---|---|
| 1500 mAh | ~24-30 hours |
| 2000 mAh | ~30-36 hours |
| 2100 mAh | ~32-40 hours |
Estimates based on continuous display mode with 30s sensor intervals
When temperature reaches 45Β°C:
- Display shows animated "Overheat" warning
- Contrast reduced to minimum (prevents OLED damage)
- Warning icon position changes every 60s (prevents burn-in)
- Normal operation resumes at 41Β°C
The device detects movement via rapid environmental changes:
- Freezes gas baseline calibration during transport
- Resumes calibration after 6 stable readings
- Prevents false VOC readings during relocation
IAQ display uses variance-adaptive filtering:
- Low variance (stable): Heavy smoothing (Ξ±=0.10) for stable reading
- High variance (changing): Light smoothing (Ξ±=0.45) for responsiveness
- Accuracy-based: Reduces smoothing when accuracy is low
- Formula: Based on the standard barometric equation. Real-world temperature deviations may cause small altitude offsets.
- Sensor Tolerance: BME680 pressure bias β Β±1 hPa β Β±8β9 m error.
- Weather Impact: QNH drifts naturally with weather; recalibrate as needed during extended outdoor sessions.
Symptoms:
section `.text1' will not fit in region `iram1_0_seg'
Compilation error: exit status 1
Solution: This is a memory configuration issue, NOT a code problem.
Quick Fix:
- Arduino IDE:
- Tools β Flash Size β Change to
4M (3M SPIFFS) - Tools β MMU β Select
16KB cache + 48KB IRAM - Restart Arduino IDE
- Tools β Flash Size β Change to
- VS Code:
- Edit
.vscode/arduino.json - Change
eesz=1M64βeesz=4M3M - Change
mmu=3232βmmu=4816 - Reload window
- Edit
Complete Guide: See FIX_IRAM_OVERFLOW_GUIDE.md for detailed instructions and manual platform.txt replacement method.
Symptoms: "Sensor Error" screen, "Retrying..."
Solutions:
- Check I2C wiring (GPIO14=SDA, GPIO12=SCL)
- Verify BME680 address (0x76 or 0x77)
- Check serial monitor for error messages
- Power cycle device
Cause: BSEC needs time to stabilize
Solution: Leave device running for 30 minutes - 24 hours for full calibration
Cause: Normal when values change frequently
Solution: Adjust thresholds (TH_T, TH_H, etc.) to reduce update frequency
Symptoms: Settings reset on reboot
Solution: Device auto-detects and repairs corrupted EEPROM
ESP8266Display-BME680.ino
βββ SECTION 1: Includes
βββ SECTION 2: Hardware Configuration
βββ SECTION 3: Application Configuration
βββ SECTION 4: Algorithm Parameters
βββ SECTION 5: EEPROM Memory Map
βββ SECTION 6: Type Definitions
βββ SECTION 7: Global State Variables
βββ SECTION 8: Utility Functions
βββ SECTION 9: OLED Display Functions
βββ SECTION 10: Display State Management
βββ SECTION 11: EEPROM Storage Management
βββ SECTION 12: BME680 & BSEC Sensor Functions
βββ SECTION 13: Thermal Protection
βββ SECTION 14: Error Recovery & Retry
βββ SECTION 15: Serial Command Interface
βββ SECTION 16: Setup & Main Loop
| File | Description |
|---|---|
ESP8266Display-BME680.ino |
Main Arduino sketch (v2.0) |
ESP8266Display-BME680.ino.backup |
Original v1.x backup |
platform.txt |
Fixed platform configuration for IRAM fix |
FIX_IRAM_OVERFLOW_GUIDE.md |
Complete IRAM overflow fix guide |
Fix RAM ESP8266.txt |
Original fix notes |
README.md |
This file - project documentation |
CHANGELOG.md |
Version history and changes |
MIGRATION.md |
Upgrade guide from v1.x to v2.0 |
- Flash: ~380 KB (varies with libraries)
- SRAM: ~42 KB
- EEPROM: 512 bytes (128 bytes used)
- Boot Time: ~2 seconds to first reading
- BSEC Stabilization: 5-30 minutes
- Sensor Read Cycle: 30 seconds
- Display Cycle: 15 seconds (3 screens, continuous loop)
- Fork repository
- Create feature branch
- Follow existing code structure and documentation style
- Test with actual hardware
- Submit PR with detailed description
This project is provided as-is for educational and personal use.
BSEC library is subject to Bosch Software License Agreement.
- Bosch Sensortec for BSEC library
- Adafruit for display libraries
- ESP8266 community for excellent core support
- Issues: Open GitHub issue
- Questions: Use GitHub Discussions
- Documentation: See comments in source code and
FIX_IRAM_OVERFLOW_GUIDE.md
Version: 2.0.0
Last Updated: 2026-04-11
Author: rifqi