- 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>
11 KiB
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
- Features
- Hardware Requirements
- Wiring Connections
- Software Requirements
- Installation
- Usage
- Understanding the Code
- Expected Output
- Troubleshooting
- Learning Objectives
- 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)
- Open VS Code
- Go to Extensions (Ctrl+Shift+X)
- Search for "PlatformIO IDE"
- Click Install
Option B: Command Line
pip install platformio
Step 2: Clone the Repository
git clone http://gitea.aircarto.fr/PaulVua/esp32_NPM_only.git
cd esp32_NPM_only
Step 3: Open in PlatformIO
Using VS Code:
- Open the project folder in VS Code
- PlatformIO will automatically detect the project
Using CLI:
pio project init
Usage
Building the Project
pio run
Uploading to ESP32
- Connect your ESP32 to your computer via USB
- Upload the code:
pio run --target upload
Monitoring Serial Output
View real-time sensor readings:
pio device monitor
Or combine upload and monitor:
pio run --target upload && pio device monitor
Exit the monitor: Press Ctrl+C
Cleaning Build Files
pio run --target clean
Understanding the Code
The code is organized into clear sections with extensive comments:
Main Components
-
Hardware Configuration (
main.cpp:18-30)- Serial port definitions
- GPIO pin assignments
-
Helper Functions (
main.cpp:50-107)checksum_valid(): Validates sensor messagessend_concentration_command(): Sends read request to sensorprint_data(): Debug output for troubleshooting
-
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
-
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 ofdelay() - 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:
- Check wiring connections (TX/RX crossed correctly?)
- Verify sensor has power
- Wait for full 15-second initialization period
- Check sensor is compatible with 115200 baud, 8E1 parity
Invalid checksum errors
Symptom: ERROR: Invalid checksum
Solutions:
- Check for electrical noise on signal wires
- Verify correct parity setting (8E1)
- Ensure ground connection between ESP32 and sensor
- Try shorter wire lengths
Header not found
Symptom: ERROR: Header not found
Solutions:
- Sensor may not be responding correctly
- Check baud rate matches (115200)
- Verify sensor is in measurement mode
- Power cycle the sensor
Can't upload to ESP32
Symptom: Upload fails or port not found
Solutions:
- Press and hold BOOT button on ESP32 during upload
- Check USB cable (must support data, not just power)
- Install USB drivers for your ESP32 board
- 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()andloop() - 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:
const long interval = 10000; // Read every 10 seconds (in milliseconds)
Changing GPIO Pins
To use different pins, modify these definitions:
#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.