Find a file
Michael Winter 0fbf33b756 Restructure project with OpenSCAD redesign and v1 legacy code
- Move legacy FreeCAD files to v1/
- Add OpenSCAD programmatic CAD designs
- Add README and AGENTS.md documentation
- Add .gitignore
- Update firmware to v2 architecture
2026-03-29 14:24:42 +02:00
designs Restructure project with OpenSCAD redesign and v1 legacy code 2026-03-29 14:24:42 +02:00
src Restructure project with OpenSCAD redesign and v1 legacy code 2026-03-29 14:24:42 +02:00
v1 Restructure project with OpenSCAD redesign and v1 legacy code 2026-03-29 14:24:42 +02:00
.gitignore Restructure project with OpenSCAD redesign and v1 legacy code 2026-03-29 14:24:42 +02:00
AGENTS.md Restructure project with OpenSCAD redesign and v1 legacy code 2026-03-29 14:24:42 +02:00
README.md Restructure project with OpenSCAD redesign and v1 legacy code 2026-03-29 14:24:42 +02:00

Tunable Sirens

A programmable, tunable siren system using BLDC motors with FOC (Field-Oriented Control).

Overview

This project implements a tunable siren where the frequency is controlled remotely via OSC (Open Sound Control) messages over WiFi. The system uses a DJI 2212 920KV BLDC motor driven by a B-G431B-ESC1 controller running SimpleFOC. Multiple stations can be controlled independently or simultaneously.

Hardware

Component Part
Motor DJI 2212 920KV BLDC
Motor Controller STMicroelectronics B-G431B-ESC1
Processors ESP32 WROOM (one per station, one for remote)
Display SSD1306 128x64 OLED (on both remote and station)
Input AiEsp32 Rotary Encoder (on both remote and station)

Architecture

                                    ┌──────────────────────┐
                                    │   Remote Control     │
                                    │   (ESP32 + OLED)     │
 ┌─────────────────┐   OSC (WiFi)   │  192.168.4.200      │
 │  External OSC  │ ───────────────┤  Port: 54001        │
 │  (Any client)  │                │  - Acts as WiFi AP  │
 └─────────────────┘                │  - Routes to stations│
                                   └──────────┬───────────┘
                                              │ OSC forward
                                              │ (optional path)
                                              ▼
   ┌────────────────┐         ┌────────────────┐
   │ Station 1      │         │ Station N      │
   │ 192.168.4.201  │   ...   │ 192.168.4.20X  │
   │ Port: 54000    │         │ Port: 54000    │
   └───────┬────────┘         └────────┬────────┘
           │                           │
           │         ┌─────────────────┴─────────┐
           └────────►│  B-G431B-ESC1             │
                     │  SimpleFOC                 │
                     │  DJI 2212 920KV BLDC      │
                     └────────────────────────────┘

Communication Modes

1. Via Remote Control (Router Mode)

The remote control acts as a WiFi access point and forwards OSC messages to stations. This allows controlling multiple sirens from a single entry point.

  • Remote IP: 192.168.4.200
  • Port: 54001 (receives commands)

2. Direct to Station

Send OSC messages directly to each station's IP address:

  • Station 1: 192.168.4.201:54000
  • Station 2: 192.168.4.202:54000
  • And so on...

WiFi Setup

  • SSID: sirening
  • Password: alarm_11735
  • IP Range: 192.168.4.200 (remote) + 201-208 (stations)

OSC Protocol

Messages

Address Arguments Description
/freq motorIndex, frequency Set frequency in Hz (0-500)
/kill Stop siren (set frequency to 0)
/state motorIndex, frequency Station reports current state

Example (Python)

from pythonosc import osc_message_builder
from pythonosc.udp_client import SimpleUDPClient

client = SimpleUDPClient("192.168.4.201", 54000)

# Set frequency to 100Hz for motor 1
msg = osc_message_builder.OscMessageBuilder(address="/freq")
msg.add_arg(1)        # motorIndex (1-indexed)
msg.add_arg(100.0)    # frequency in Hz
client.send(msg.build())

# Kill/stop the siren
msg = osc_message_builder.OscMessageBuilder(address="/kill")
client.send(msg.build())

Station Response

The station reports its state back on port 54001:

# Incoming message: /state motorIndex frequency
# Example: /state 1 100.0

Local Controls

Both the remote control and station controllers have a local interface:

Rotary Encoder

Action Function
Rotate Change frequency (or navigate menus)
Press Select siren / confirm selection
Double-press (remote) Kill all sirens

OLED Display

  • Shows current frequency
  • Shows selected siren number
  • Shows connection status (WiFi)

Directory Structure

sirens/
├── README.md              # This file
├── AGENTS.md              # Developer notes for AI agents
├── src/                   # Current firmware (v2)
│   ├── siren_remote_control_esp32_v2/      # Remote control unit
│   ├── siren_controller_esp32_*/           # Station controller
│   └── B_G431B_ESC1_motor_controller/      # Motor controller (SimpleFOC)
├── v1/                    # Legacy hardware and firmware
│   ├── src/               # Old versions of controller code
│   └── designs/          # Legacy CAD files (FreeCAD)
├── designs/               # Current CAD files
│   ├── openscad/          # OpenSCAD source files
│   │   ├── siren_redesign.scad   # Main siren design
│   │   └── box_snap.scad         # Controller box
│   ├── stl/              # 3D print files
│   └── 3mf/              # 3MF print files

CAD Files

  • Main siren: designs/openscad/siren_redesign.scad
  • Controller box: designs/openscad/box_snap.scad
  • STL files: designs/stl/

Building & Flashing

Uses Arduino framework. For development, PlatformIO is recommended for command-line builds.

See AGENTS.md for details on libraries and coding conventions.

Version History

Version Description
v1 Legacy system (FreeCAD)
v2 (current) Programmatic CAD design (OpenSCAD), improved code structure