Initial commit: ESP32 NextPM sensor reader

Educational version with comprehensive comments for students.
- Reads PM1.0, PM2.5, and PM10 concentrations from NextPM sensor
- Uses UART serial communication with checksum validation
- Non-blocking timing with millis()
- Removed particle counts, kept only mass concentrations
- Extensively commented to help students understand serial protocols

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
PaulVua
2025-11-06 11:46:39 +01:00
commit 31127ff783
8 changed files with 533 additions and 0 deletions

91
CLAUDE.md Normal file
View File

@@ -0,0 +1,91 @@
# CLAUDE.md
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
## Project Overview
This is a PlatformIO-based ESP32 Arduino project for communicating with a NextPM (NPM) particulate matter sensor over serial connection. The project reads PM1, PM2.5, and PM10 measurements in both µg/m³ and particles per liter (pcs/L).
## Build and Development Commands
**Build the project:**
```bash
pio run
```
**Upload to ESP32:**
```bash
pio run --target upload
```
**Monitor serial output (115200 baud):**
```bash
pio device monitor
```
**Build and upload in one command:**
```bash
pio run --target upload && pio device monitor
```
**Clean build files:**
```bash
pio run --target clean
```
## Hardware Configuration
- **Board:** ESP32 dev board
- **Serial Configuration:**
- Debug serial: `Serial` (USB, 115200 baud)
- NPM serial: `Serial1` (UART1, 115200 baud, 8E1 parity)
- RX Pin: GPIO 39
- TX Pin: GPIO 32
## Architecture
### Serial Communication Protocol
The NextPM sensor uses a binary protocol with checksums. Communication follows a request-response pattern with specific message formats:
**Message Structure:**
- Header (2 bytes): Command identifier (e.g., `0x81 0x16`)
- State (1 byte): Device state bits
- Data (variable): Response payload
- Checksum (1 byte): Sum of all bytes mod 0x100 must equal 0
**State Machine Enums:**
The code uses multiple enums (`NPM_waiting_for_4`, `NPM_waiting_for_8`, `NPM_waiting_for_16`) to track parsing state for different response types (4, 8, or 16 bytes total).
### Key Functions
**Initialization (`powerOnTestNPM`):**
- Waits 15 seconds for sensor startup
- Queries sensor state
- Starts sensor if stopped
- Reads firmware version and temperature/humidity
**Measurement (`fetchSensorNPM_1min`):**
- Sends concentration command (1-minute averaged readings)
- Parses 16-byte response containing 6 values:
- N1, N2.5, N10 (particle counts as pcs/L)
- PM1, PM2.5, PM10 (mass concentrations as µg/m³ × 10)
- Validates checksum before accepting data
**Loop Behavior:**
- Reads sensor every 60 seconds (configurable via `interval` constant)
- Non-blocking timing using `millis()`
### File Organization
- `src/main.cpp`: Main application logic, NPM protocol implementation, sensor state machine
- `src/utils.h`: Protocol constants, enums, checksum validation prototypes
- `src/utils.cpp`: Utility functions for checksum validation and NPM command transmission
- `platformio.ini`: PlatformIO configuration for ESP32
## Important Notes
- The sensor requires a 3-second timeout for serial responses
- All particle concentration values from the sensor are scaled (PM values by 10, temperature/humidity by 100)
- The `nextpmconnected` flag prevents infinite loops if sensor disconnects
- Comments are in French in some sections of the code