sirens/AGENTS.md

214 lines
5.7 KiB
Markdown
Raw Permalink Normal View History

# AGENTS.md - Sirens Project
## Project Overview
This is an Arduino/ESP32 embedded systems project for controlling sirens. The codebase consists of multiple Arduino sketches (.ino files) for different hardware components.
## Directory Structure
```
sirens/
├── src/
│ ├── siren_remote_control_esp32_v2/ # Remote control unit
│ │ └── siren_remote_control_esp32_v2.ino
│ ├── siren_controller_esp32_simple_station_v2_multi/ # Station controller
│ │ └── siren_controller_esp32_simple_station_v2_multi.ino
│ └── B_G431B_ESC1_motor_controller/ # SimpleFOC motor controller
│ └── B_G431B_ESC1_motor_controller.ino
├── v1/ # Version 1 designs
├── designs/ # CAD files (OpenSCAD, STL)
└── AGENTS.md # This file
```
## Build Commands
### Current State
- **No command-line build system configured** - Uses Arduino IDE
- Upload via Arduino IDE or PlatformIO (recommended for future)
### Future: PlatformIO Migration (TODO)
```bash
# Once PlatformIO is configured:
pio run # Build all projects
pio run -e <environment> # Build specific environment
pio run -t upload # Upload to device
pio device monitor # Monitor serial output
```
### Running a Single Test
- **No unit tests exist** - Embedded projects typically test via hardware
- For now, manual testing on physical hardware is required
## Libraries
The project uses the following Arduino/ESP32 libraries:
| Library | Purpose |
|---------|---------|
| WiFi | ESP32 WiFi connectivity |
| Wire | I2C communication |
| SSD1306Ascii / SSD1306AsciiWire | OLED display (128x64) |
| ArduinoOSCWiFi | OSC protocol over WiFi |
| AiEsp32RotaryEncoder | Rotary encoder input |
| arduino-timer | Timer/async operations |
| Preferences | ESP32 NVS storage |
| SimpleFOC | Motor control (B-G431B-ESC1) |
| SimpleFOCDrivers | SimpleFOC driver utilities |
## Code Style Guidelines
### General Conventions
- **Language**: C++ (Arduino framework)
- **File extension**: `.ino` (Arduino sketch)
- **Naming**: camelCase for variables and functions
- **Constants**: UPPER_SNAKE_CASE with `const` or `#define`
### Arduino Sketch Structure
```cpp
// 1. Includes
#include "WiFi.h"
#include <Wire.h>
#include <SSD1306Ascii.h>
// 2. Global constants
const int sirenCount = 4;
const char* ssid = "sirening";
// 3. Global variables
int menuSelect = 0;
// 4. Function prototypes (if needed)
void setupEncoderButton(AiEsp32RotaryEncoder& eb, char* val);
// 5. setup() - runs once at boot
void setup() {
Serial.begin(115200);
// initialization code...
}
// 6. loop() - runs continuously
void loop() {
// main logic...
}
```
### Functions
- Keep functions focused and reasonably sized (<100 lines)
- Use descriptive names: `updateFreq()`, `killAll()`, `setupOSC()`
- Group related functions together
- Use helper functions to reduce duplication in loop()
### Types
- Use explicit types: `int`, `float`, `bool`, `unsigned long`
- Prefer `const` for values that won't change
- Use `float` for floating-point values (no `double` on ESP32)
### Error Handling
- Return early on errors:
```cpp
if(!currentSense.init()){
Serial.println("Current sense init failed.");
return;
}
```
- Use Serial for debugging output with descriptive messages
- Validate input ranges before use:
```cpp
if (input < 500.0 && input >= 0.0) {
updateFreq(input);
}
```
### Interrupt Service Routines (ISR)
- Mark ISRs with `IRAM_ATTR` on ESP32:
```cpp
void IRAM_ATTR readFreqEncoderISR() {
encoderButton1.readEncoder_ISR();
}
```
- Keep ISRs minimal - only do essential work
### Display/UI Code
- Use helper functions for display updates:
```cpp
void updateDisplayValue(String string) {
oled.set2X();
oled.setCursor(12, 5);
oled.print(string);
oled.clearToEOL();
}
```
### OSC Communication
- Use lambda callbacks for OSC subscriptions:
```cpp
OscWiFi.subscribe(settings_port, "/freq", [](const OscMessage& m) {
float input = m.arg<float>(0);
// handle message...
});
```
### Preferences (NVS)
- Open with explicit mode:
```cpp
prefs.begin("prefs", RO_MODE); // false = read/write, true = read only
prefs.putUInt("ports", ports);
prefs.getUInt("ports");
prefs.end();
```
### Serial Communication
- Use `Serial.begin(115200)` for debug output
- Use `HardwareSerial` for additional UARTs:
```cpp
HardwareSerial freqSerial(1);
freqSerial.begin(115200, SERIAL_8N1, 18, 19);
```
### Comments
- Use TODO comments for future work:
```cpp
//TODO: These should be bound to a publication of the frequency directly from the siren
```
- Comment out disabled code with explanation
- Keep comments brief and purposeful
### Formatting
- Use 2-space indentation (Arduino default)
- Opening brace on same line
- Space after keywords: `if (` not `if(`
## Future Improvements
1. **Add PlatformIO**: Create `platformio.ini` for command-line builds
2. **Add unit tests**: Use PlatformIO unit testing for non-hardware logic
3. **Consolidate common code**: Extract shared utilities into a common library
4. **Add CI/CD**: GitHub Actions for build verification
5. **Document hardware**: Add wiring diagrams and pinouts
## Hardware Targets
- **ESP32** (WiFi + BLE)
- **B-G431B-ESC1** motor controller (SimpleFOC compatible)
- **OLED Display**: SSD1306 128x64 I2C
- **Rotary Encoder**: AiEsp32RotaryEncoder
## Development Notes
- Serial monitor uses 115200 baud
- WiFi AP: `sirening` / `alarm_11735`
- OSC ports: 54000 (settings), 54001 (state)
- Motor control uses FOC (Field-Oriented Control) via SimpleFOC