# CLAUDE.md This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository. ## Project Overview This is a **simplified, educational** 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 mass concentration measurements in µg/m³. **Educational Focus:** - Extensively commented code to help students understand serial communication protocols - Simplified implementation focusing only on PM concentration readings (particle counts removed) - Clear step-by-step documentation of the sensor communication process - Non-blocking timing pattern demonstration ## 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: **Message Structure (16 bytes total):** - Header (2 bytes): `0x81 0x12` (concentration response identifier) - State (1 byte): Device state bits - Data (12 bytes): 6 values × 2 bytes each - Bytes 0-5: N1, N2.5, N10 particle counts (not used in this simplified version) - Bytes 6-11: PM1, PM2.5, PM10 mass concentrations - Checksum (1 byte): Sum of all bytes mod 0x100 must equal 0 ### Key Functions **`checksum_valid()`** - Validates 16-byte messages using checksum algorithm - Returns true if sum of all bytes modulo 256 equals 0 **`send_concentration_command()`** - Sends 3-byte command sequence: `{0x81, 0x12, 0x6D}` - Requests 1-minute averaged concentration readings **`read_concentration()`** - Main sensor reading function with 11 documented steps - Sends command, waits for response (3-second timeout) - Validates header and checksum - Extracts PM1, PM2.5, PM10 values from data bytes - Converts scaled values (÷10) to actual µg/m³ - Displays results on serial monitor **`setup()`** - Initializes USB serial (115200 baud) for debugging - Initializes sensor serial (115200 baud, 8E1 parity) - Waits 15 seconds for sensor power-up **`loop()`** - Non-blocking timing implementation using `millis()` - Reads sensor every 10 seconds (configurable via `interval`) - Demonstrates proper Arduino timing patterns ### File Organization - `src/main.cpp`: Complete application in single file with extensive educational comments - `platformio.ini`: PlatformIO configuration for ESP32 - `CLAUDE.md`: Developer guidance for AI assistance - `README.md`: User documentation and getting started guide ## Important Notes - The sensor requires a 3-second timeout for serial responses - PM values from the sensor are scaled by 10 (e.g., 25.3 µg/m³ sent as 253) - The 15-second startup delay is critical - sensor won't respond if queried too early - All comments are in English for educational purposes - Code emphasizes readability and learning over performance optimization