# 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