- Created comprehensive README.md with: - Project overview and features - Hardware requirements and wiring diagram - Installation and usage instructions - Detailed troubleshooting guide - Learning objectives for students - NextPM protocol reference - Updated CLAUDE.md to reflect: - Simplified educational implementation - Removal of particle counts - Current function structure - Educational focus and objectives 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
370 lines
11 KiB
Markdown
370 lines
11 KiB
Markdown
# ESP32 NextPM Sensor Reader
|
||
|
||
An educational ESP32 project for reading particulate matter (PM) concentrations from a NextPM sensor via UART serial communication. This simplified implementation is designed to help students understand serial communication protocols, binary data parsing, and sensor integration.
|
||
|
||
## 📋 Table of Contents
|
||
|
||
- [About Particulate Matter](#about-particulate-matter)
|
||
- [Features](#features)
|
||
- [Hardware Requirements](#hardware-requirements)
|
||
- [Wiring Connections](#wiring-connections)
|
||
- [Software Requirements](#software-requirements)
|
||
- [Installation](#installation)
|
||
- [Usage](#usage)
|
||
- [Understanding the Code](#understanding-the-code)
|
||
- [Expected Output](#expected-output)
|
||
- [Troubleshooting](#troubleshooting)
|
||
- [Learning Objectives](#learning-objectives)
|
||
- [License](#license)
|
||
|
||
## About Particulate Matter
|
||
|
||
Particulate Matter (PM) refers to tiny particles suspended in the air that can be harmful to human health. This project measures three types:
|
||
|
||
- **PM1.0**: Particles with diameter < 1.0 micrometers
|
||
- **PM2.5**: Particles with diameter < 2.5 micrometers (common air quality metric)
|
||
- **PM10**: Particles with diameter < 10 micrometers
|
||
|
||
Values are reported in **µg/m³** (micrograms per cubic meter).
|
||
|
||
## Features
|
||
|
||
- ✅ Reads PM1.0, PM2.5, and PM10 concentrations from NextPM sensor
|
||
- ✅ Uses UART serial communication with 8E1 parity
|
||
- ✅ Binary protocol with checksum validation
|
||
- ✅ Non-blocking timing pattern with `millis()`
|
||
- ✅ Extensively commented code for educational purposes
|
||
- ✅ Real-time data output to Serial Monitor
|
||
- ✅ Error handling and debugging support
|
||
|
||
## Hardware Requirements
|
||
|
||
| Component | Specification |
|
||
|-----------|--------------|
|
||
| **Microcontroller** | ESP32 development board |
|
||
| **Sensor** | NextPM (NPM) particulate matter sensor |
|
||
| **Connections** | UART (Serial) communication |
|
||
| **Power Supply** | USB (for ESP32) + sensor power supply |
|
||
|
||
## Wiring Connections
|
||
|
||
Connect the NextPM sensor to your ESP32 as follows:
|
||
|
||
| NextPM Sensor | ESP32 Board |
|
||
|---------------|-------------|
|
||
| TX (Transmit) | GPIO 39 (RX) |
|
||
| RX (Receive) | GPIO 32 (TX) |
|
||
| GND | GND |
|
||
| VCC | External power supply (check sensor voltage requirements) |
|
||
|
||
**Important Notes:**
|
||
- The NextPM sensor typically requires an external power supply (check your sensor's datasheet)
|
||
- ESP32 GPIO 39 is input-only (perfect for RX)
|
||
- Do not connect sensor VCC to ESP32 3.3V unless your sensor specifically supports it
|
||
|
||
### Connection Diagram
|
||
|
||
```
|
||
┌──────────────┐ ┌──────────────┐
|
||
│ │ │ │
|
||
│ NextPM │ │ ESP32 │
|
||
│ Sensor │ │ │
|
||
│ │ │ │
|
||
│ TX ──┼──────────────┼─→ GPIO 39 │
|
||
│ │ │ (RX) │
|
||
│ RX ←─┼──────────────┼── GPIO 32 │
|
||
│ │ │ (TX) │
|
||
│ │ │ │
|
||
│ GND ──┼──────────────┼── GND │
|
||
│ │ │ │
|
||
│ VCC ──┼─→ External │ │
|
||
│ │ Power │ │
|
||
└──────────────┘ └──────────────┘
|
||
```
|
||
|
||
## Software Requirements
|
||
|
||
- **PlatformIO** - Modern embedded development platform
|
||
- Recommended: Use PlatformIO IDE extension for VS Code
|
||
- Alternative: PlatformIO Core CLI
|
||
|
||
- **VS Code** (optional but recommended)
|
||
- Download from: https://code.visualstudio.com/
|
||
|
||
## Installation
|
||
|
||
### Step 1: Install PlatformIO
|
||
|
||
**Option A: VS Code Extension (Recommended)**
|
||
1. Open VS Code
|
||
2. Go to Extensions (Ctrl+Shift+X)
|
||
3. Search for "PlatformIO IDE"
|
||
4. Click Install
|
||
|
||
**Option B: Command Line**
|
||
```bash
|
||
pip install platformio
|
||
```
|
||
|
||
### Step 2: Clone the Repository
|
||
|
||
```bash
|
||
git clone http://gitea.aircarto.fr/PaulVua/esp32_NPM_only.git
|
||
cd esp32_NPM_only
|
||
```
|
||
|
||
### Step 3: Open in PlatformIO
|
||
|
||
**Using VS Code:**
|
||
1. Open the project folder in VS Code
|
||
2. PlatformIO will automatically detect the project
|
||
|
||
**Using CLI:**
|
||
```bash
|
||
pio project init
|
||
```
|
||
|
||
## Usage
|
||
|
||
### Building the Project
|
||
|
||
```bash
|
||
pio run
|
||
```
|
||
|
||
### Uploading to ESP32
|
||
|
||
1. Connect your ESP32 to your computer via USB
|
||
2. Upload the code:
|
||
|
||
```bash
|
||
pio run --target upload
|
||
```
|
||
|
||
### Monitoring Serial Output
|
||
|
||
View real-time sensor readings:
|
||
|
||
```bash
|
||
pio device monitor
|
||
```
|
||
|
||
Or combine upload and monitor:
|
||
|
||
```bash
|
||
pio run --target upload && pio device monitor
|
||
```
|
||
|
||
**Exit the monitor:** Press `Ctrl+C`
|
||
|
||
### Cleaning Build Files
|
||
|
||
```bash
|
||
pio run --target clean
|
||
```
|
||
|
||
## Understanding the Code
|
||
|
||
The code is organized into clear sections with extensive comments:
|
||
|
||
### Main Components
|
||
|
||
1. **Hardware Configuration** (`main.cpp:18-30`)
|
||
- Serial port definitions
|
||
- GPIO pin assignments
|
||
|
||
2. **Helper Functions** (`main.cpp:50-107`)
|
||
- `checksum_valid()`: Validates sensor messages
|
||
- `send_concentration_command()`: Sends read request to sensor
|
||
- `print_data()`: Debug output for troubleshooting
|
||
|
||
3. **Sensor Reading Function** (`main.cpp:109-242`)
|
||
- `read_concentration()`: 11-step process documented in detail
|
||
- Protocol parsing and data extraction
|
||
- Error handling with timeout protection
|
||
|
||
4. **Arduino Functions**
|
||
- `setup()`: One-time initialization (`main.cpp:244-286`)
|
||
- `loop()`: Non-blocking repeated execution (`main.cpp:288-318`)
|
||
|
||
### Key Concepts Demonstrated
|
||
|
||
- **Binary Serial Protocol**: Reading structured binary data
|
||
- **Checksum Validation**: Ensuring data integrity
|
||
- **Non-blocking Timing**: Using `millis()` instead of `delay()`
|
||
- **UART Communication**: 8E1 parity configuration
|
||
- **Error Handling**: Timeout protection and validation checks
|
||
- **Data Scaling**: Converting sensor's fixed-point integers to floats
|
||
|
||
## Expected Output
|
||
|
||
After uploading and opening the Serial Monitor, you should see:
|
||
|
||
```
|
||
=== NextPM Sensor Reader ===
|
||
Simplified version - Concentration readings only
|
||
Averaging: 60 seconds, Update: every 10 seconds
|
||
|
||
Waiting 15 seconds for sensor initialization...
|
||
Sensor ready. Starting measurements...
|
||
|
||
--- Reading NextPM Concentrations ---
|
||
|
||
=== Particulate Matter Concentrations ===
|
||
PM1.0: 12.3 µg/m³
|
||
PM2.5: 18.7 µg/m³
|
||
PM10: 24.5 µg/m³
|
||
======================================
|
||
```
|
||
|
||
Readings update every 10 seconds.
|
||
|
||
## Troubleshooting
|
||
|
||
### No sensor response
|
||
|
||
**Symptom:** `ERROR: No response from sensor`
|
||
|
||
**Solutions:**
|
||
1. Check wiring connections (TX/RX crossed correctly?)
|
||
2. Verify sensor has power
|
||
3. Wait for full 15-second initialization period
|
||
4. Check sensor is compatible with 115200 baud, 8E1 parity
|
||
|
||
### Invalid checksum errors
|
||
|
||
**Symptom:** `ERROR: Invalid checksum`
|
||
|
||
**Solutions:**
|
||
1. Check for electrical noise on signal wires
|
||
2. Verify correct parity setting (8E1)
|
||
3. Ensure ground connection between ESP32 and sensor
|
||
4. Try shorter wire lengths
|
||
|
||
### Header not found
|
||
|
||
**Symptom:** `ERROR: Header not found`
|
||
|
||
**Solutions:**
|
||
1. Sensor may not be responding correctly
|
||
2. Check baud rate matches (115200)
|
||
3. Verify sensor is in measurement mode
|
||
4. Power cycle the sensor
|
||
|
||
### Can't upload to ESP32
|
||
|
||
**Symptom:** Upload fails or port not found
|
||
|
||
**Solutions:**
|
||
1. Press and hold BOOT button on ESP32 during upload
|
||
2. Check USB cable (must support data, not just power)
|
||
3. Install USB drivers for your ESP32 board
|
||
4. Try a different USB port
|
||
|
||
## Learning Objectives
|
||
|
||
This project helps students learn:
|
||
|
||
### Communication Protocols
|
||
- Understanding binary serial communication
|
||
- Request-response patterns
|
||
- Header/state/data/checksum message structure
|
||
- Big-endian vs little-endian byte ordering
|
||
|
||
### Embedded Systems Concepts
|
||
- UART configuration (baud rate, parity, stop bits)
|
||
- GPIO pin assignment and usage
|
||
- Non-blocking vs blocking code patterns
|
||
- Timeout handling in real-time systems
|
||
|
||
### Data Processing
|
||
- Binary data parsing and extraction
|
||
- Checksum validation algorithms
|
||
- Fixed-point to floating-point conversion
|
||
- Byte manipulation with `word()` function
|
||
|
||
### Arduino/ESP32 Patterns
|
||
- Proper use of `setup()` and `loop()`
|
||
- Non-blocking timing with `millis()`
|
||
- Multiple serial ports (Serial vs Serial1)
|
||
- Error handling and debugging techniques
|
||
|
||
## Configuration
|
||
|
||
### Adjusting Read Interval
|
||
|
||
To change how often the sensor is read, modify the `interval` constant:
|
||
|
||
```cpp
|
||
const long interval = 10000; // Read every 10 seconds (in milliseconds)
|
||
```
|
||
|
||
### Changing GPIO Pins
|
||
|
||
To use different pins, modify these definitions:
|
||
|
||
```cpp
|
||
#define PM_SERIAL_RX 39 // Change RX pin
|
||
#define PM_SERIAL_TX 32 // Change TX pin
|
||
```
|
||
|
||
**Note:** GPIO 39 is input-only on ESP32, so it's ideal for RX.
|
||
|
||
## Project Structure
|
||
|
||
```
|
||
esp32_NPM_only/
|
||
├── src/
|
||
│ └── main.cpp # Main application with extensive comments
|
||
├── include/ # Header files (currently empty)
|
||
├── lib/ # Custom libraries (currently empty)
|
||
├── test/ # Unit tests (currently empty)
|
||
├── platformio.ini # PlatformIO configuration
|
||
├── CLAUDE.md # AI assistant guidance
|
||
└── README.md # This file
|
||
```
|
||
|
||
## NextPM Protocol Reference
|
||
|
||
### Concentration Request Command
|
||
|
||
| Byte | Value | Description |
|
||
|------|-------|-------------|
|
||
| 0 | 0x81 | Command prefix |
|
||
| 1 | 0x12 | Concentration request |
|
||
| 2 | 0x6D | Checksum |
|
||
|
||
### Concentration Response (16 bytes)
|
||
|
||
| Bytes | Description | Used? |
|
||
|-------|-------------|-------|
|
||
| 0-1 | Header (0x81 0x12) | ✅ For validation |
|
||
| 2 | State byte | ✅ Read but not parsed |
|
||
| 3-4 | N1.0 particle count | ❌ Not used |
|
||
| 5-6 | N2.5 particle count | ❌ Not used |
|
||
| 7-8 | N10 particle count | ❌ Not used |
|
||
| 9-10 | PM1.0 × 10 | ✅ Extracted |
|
||
| 11-12 | PM2.5 × 10 | ✅ Extracted |
|
||
| 13-14 | PM10 × 10 | ✅ Extracted |
|
||
| 15 | Checksum | ✅ Validated |
|
||
|
||
## Contributing
|
||
|
||
This is an educational project. Suggestions for improving code clarity and educational value are welcome!
|
||
|
||
## License
|
||
|
||
This project is provided for educational purposes.
|
||
|
||
## Acknowledgments
|
||
|
||
- NextPM sensor documentation
|
||
- ESP32 Arduino core community
|
||
- Students and educators using this project
|
||
|
||
---
|
||
|
||
**Questions or Issues?**
|
||
|
||
If you encounter problems or have questions about the code, please open an issue on the repository.
|