Initial release v1.1.0 — ESP32 automated telescope flat panel
Firmware (Arduino Nano ESP32 / PlatformIO): - Native ASCOM Alpaca CoverCalibrator REST API on port 11111 - Alnitak serial protocol on USB at 9600 baud (simultaneous with WiFi) - MG995 servo cover mechanism with non-blocking state machine (D9) - LED brightness PWM via IRLZ44N MOSFET, LEDC channel 0 (D3) - 12V dew heater PWM via IRLZ44N MOSFET, LEDC channel 1 (D5) - mDNS + UDP Alpaca discovery, WiFi watchdog reconnect - SERIAL_DEBUG flag to silence debug output in USB-only mode INDI driver (C++ / libcurl / nlohmann-json): - WiFi mode: HTTP Alpaca via libcurl - USB mode: Alnitak serial via POSIX termios - LightBoxInterface + DustCapInterface + dew heater number property Python controller (PyQt6): - Dark-themed desktop app for direct manual control - AlpacaBackend (requests) + AlnitakBackend (pyserial) - PollWorker QThread; cover, brightness, dew heater panels - QSettings persistence; auto serial port discovery Docs: - system-diagram.svg, wiring-diagram.svg (browser-renderable SVG) - BUILD_NOTES.md with BOM, LM2596 calibration, power-on checklist - WIRING.md quick-reference, README.md, CHANGELOG.md
This commit is contained in:
commit
c32f00a2be
15 changed files with 3653 additions and 0 deletions
275
README.md
Normal file
275
README.md
Normal file
|
|
@ -0,0 +1,275 @@
|
|||
# ESP32 FlatPanel
|
||||
|
||||
An open-source automated telescope flat-field panel built around the **Arduino Nano ESP32**.
|
||||
Controls LED brightness, a motorised cover, and a dew heater — all accessible from ASCOM, INDI, and a standalone desktop application.
|
||||
|
||||
---
|
||||
|
||||
## Features
|
||||
|
||||
| Feature | Detail |
|
||||
|---------|--------|
|
||||
| **LED brightness** | 8-bit PWM (0–255) via logic-level MOSFET |
|
||||
| **Motorised cover** | MG995 servo rotates panel in/out of the telescope light path |
|
||||
| **Dew heater** | 12V resistive element, 0–100% PWM — keeps the diffuser clear |
|
||||
| **WiFi mode** | Native ASCOM Alpaca REST API on port 11111; auto-discovered via mDNS and UDP broadcast |
|
||||
| **USB mode** | Alnitak serial protocol at 9600 baud — plug-and-play with N.I.N.A., SGPro, APT and `indi_flipflat` |
|
||||
| **Both simultaneously** | WiFi and USB are active at the same time in a single firmware build |
|
||||
| **ASCOM** | Use ASCOM Remote (free, official) — no custom COM driver required |
|
||||
| **INDI** | Custom `indi_esp32_flatpanel` driver with WiFi and USB connection modes |
|
||||
| **Desktop app** | Dark-themed PyQt6 controller for direct manual operation |
|
||||
|
||||
---
|
||||
|
||||
## Repository layout
|
||||
|
||||
```
|
||||
flatpanel/
|
||||
├── firmware/ ESP32 firmware (PlatformIO / Arduino)
|
||||
│ ├── platformio.ini
|
||||
│ └── src/
|
||||
│ ├── config.h ← edit this first
|
||||
│ └── main.cpp
|
||||
├── indi-driver/ INDI driver (C++, Linux)
|
||||
│ ├── CMakeLists.txt
|
||||
│ ├── indi_esp32_flatpanel.h
|
||||
│ ├── indi_esp32_flatpanel.cpp
|
||||
│ └── indi_esp32_flatpanel.xml
|
||||
├── controller/ Python desktop controller (all platforms)
|
||||
│ ├── flatpanel_controller.py
|
||||
│ └── requirements.txt
|
||||
├── docs/
|
||||
│ ├── system-diagram.svg Block diagram — open in any browser
|
||||
│ ├── wiring-diagram.svg Colour-coded wiring — open in any browser
|
||||
│ └── BUILD_NOTES.md Step-by-step assembly guide
|
||||
├── WIRING.md Quick-reference wiring + BOM
|
||||
├── README.md This file
|
||||
└── CHANGELOG.md
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Hardware required
|
||||
|
||||
| Component | Role | Pin |
|
||||
|-----------|------|-----|
|
||||
| Arduino Nano ESP32 | Main controller | — |
|
||||
| MG995 servo | Cover open/close | D9 |
|
||||
| IRLZ44N MOSFET × 2 | LED brightness + dew heater | D3, D5 |
|
||||
| LM2596 buck module | 12V → 5V for ESP32 + servo | — |
|
||||
| 12V PSU ≥ 4A | Powers everything | — |
|
||||
| White LED strip 12V (Ra ≥ 90) | Flat-field illumination | — |
|
||||
| Frosted acrylic 3mm | Light diffuser | — |
|
||||
| Dew heater element 12V ~24Ω | Anti-dew resistive heater | — |
|
||||
| 100Ω resistor × 2 | MOSFET gate series | — |
|
||||
| 10kΩ resistor × 2 | MOSFET gate pull-down | — |
|
||||
|
||||
See [docs/BUILD_NOTES.md](docs/BUILD_NOTES.md) for the full BOM, dew heater sizing table, and step-by-step assembly instructions.
|
||||
See [docs/wiring-diagram.svg](docs/wiring-diagram.svg) for the colour-coded wiring diagram.
|
||||
|
||||
---
|
||||
|
||||
## Quick-start
|
||||
|
||||
### 1 Configure the firmware
|
||||
|
||||
Edit `firmware/src/config.h`:
|
||||
|
||||
```cpp
|
||||
#define WIFI_SSID "your_network"
|
||||
#define WIFI_PASSWORD "your_password"
|
||||
|
||||
// Tune to your mechanical stops after assembly:
|
||||
#define SERVO_CLOSED 0 // panel in flat position
|
||||
#define SERVO_OPEN 90 // panel clear of telescope
|
||||
|
||||
// Set false when using USB/Alnitak mode to keep the serial line clean:
|
||||
#define SERIAL_DEBUG true
|
||||
```
|
||||
|
||||
### 2 Flash
|
||||
|
||||
```bash
|
||||
cd flatpanel
|
||||
pio run -t upload # PlatformIO CLI
|
||||
# or use the PlatformIO IDE extension in VS Code
|
||||
```
|
||||
|
||||
### 3 Verify
|
||||
|
||||
Open a serial monitor at **9600 baud**.
|
||||
You should see the ESP32's IP address printed on boot.
|
||||
Browse to:
|
||||
|
||||
```
|
||||
http://esp32-flatpanel.local:11111/management/v1/configureddevices
|
||||
```
|
||||
|
||||
Expected response contains `"DeviceType":"CoverCalibrator"`.
|
||||
|
||||
---
|
||||
|
||||
## Connection modes
|
||||
|
||||
### WiFi — ASCOM Alpaca (no driver needed)
|
||||
|
||||
The ESP32 **is** an Alpaca server. Use **ASCOM Remote** as the bridge to ASCOM COM:
|
||||
|
||||
1. Install [ASCOM Platform 6.6+](https://ascom-standards.org/Downloads/Index.htm) and [ASCOM Remote](https://github.com/ASCOMInitiative/ASCOM.Remote/releases).
|
||||
2. In ASCOM Remote, add a **CoverCalibrator** device → host `esp32-flatpanel.local`, port `11111`, device `0`.
|
||||
3. In N.I.N.A. / SGPro / APT, choose **ASCOM CoverCalibrator** and select the ASCOM Remote device.
|
||||
|
||||
The ESP32 is also discovered automatically by software that supports Alpaca UDP discovery (N.I.N.A. 3+, Cartes du Ciel).
|
||||
|
||||
### WiFi — INDI
|
||||
|
||||
```bash
|
||||
# Build and install the custom driver (once)
|
||||
cd flatpanel/indi-driver
|
||||
cmake -B build -DCMAKE_INSTALL_PREFIX=/usr
|
||||
cmake --build build -j$(nproc)
|
||||
sudo cmake --install build
|
||||
|
||||
# Start (KStars/Ekos loads it automatically after install)
|
||||
indiserver indi_esp32_flatpanel
|
||||
```
|
||||
|
||||
In Ekos: select **ESP32 FlatPanel**, set Connection Mode to **WiFi / Alpaca**, enter the host and port.
|
||||
|
||||
### USB — Alnitak (plug-and-play)
|
||||
|
||||
Set `SERIAL_DEBUG false` in `config.h` and reflash. Then connect via USB-C.
|
||||
|
||||
The firmware speaks the standard Alnitak protocol so existing software works without any driver:
|
||||
|
||||
| Software | Built-in support |
|
||||
|----------|-----------------|
|
||||
| N.I.N.A. | ✅ Alnitak / Flip-Flat |
|
||||
| Sequence Generator Pro | ✅ Alnitak |
|
||||
| Astro Photography Tool | ✅ Alnitak |
|
||||
| INDI (`indi_flipflat`) | ✅ ships with INDI |
|
||||
| Our INDI driver | ✅ USB mode in Connection tab |
|
||||
|
||||
> **Dew heater via USB:** The standard Alnitak protocol has no dew heater concept.
|
||||
> Our INDI driver and the Python controller use custom extension commands `>T` (set) / `>U` (get) that are silently ignored by other software.
|
||||
|
||||
### Desktop controller app
|
||||
|
||||
Works in both WiFi and USB mode. Dark-themed for night use.
|
||||
|
||||
```bash
|
||||
pip install PyQt6 requests pyserial
|
||||
python flatpanel/controller/flatpanel_controller.py
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Alpaca API reference
|
||||
|
||||
Base URL: `http://<host>:11111/api/v1/covercalibrator/0/`
|
||||
|
||||
| Method | Endpoint | Parameters | Description |
|
||||
|--------|----------|-----------|-------------|
|
||||
| GET | `coverstate` | — | 2=Open, 3=Closed, 4=Moving |
|
||||
| GET | `calibratorstate` | — | 1=Off, 3=Ready |
|
||||
| GET | `brightness` | — | Current brightness 0–255 |
|
||||
| GET | `maxbrightness` | — | Always 255 |
|
||||
| GET | `dewheater` | — | Current dew heater 0–100% *(custom)* |
|
||||
| PUT | `opencover` | — | Rotate panel out of light path |
|
||||
| PUT | `closecover` | — | Rotate panel into flat position |
|
||||
| PUT | `haltcover` | — | Stop cover movement |
|
||||
| PUT | `calibratoron` | `Brightness=N` | Turn on LED at brightness N |
|
||||
| PUT | `calibratoroff` | — | Turn off LED |
|
||||
| PUT | `dewheater` | `Percentage=N` | Set dew heater 0–100% *(custom)* |
|
||||
| PUT | `action` | `Action=SetDewHeater`<br>`Parameters=N` | Alpaca-standard alternative to PUT dewheater |
|
||||
| PUT | `action` | `Action=GetDewHeater` | Returns current dew % as string Value |
|
||||
|
||||
Management endpoints: `/management/apiversions`, `/management/v1/description`, `/management/v1/configureddevices`
|
||||
|
||||
---
|
||||
|
||||
## Alnitak serial protocol reference
|
||||
|
||||
Port: USB-C at 9600 baud, 8N1.
|
||||
Command format: `>CXXX\r` · Response format: `*CDDVVV\r` (DD = device type 19).
|
||||
|
||||
| Cmd | Description | Example |
|
||||
|-----|-------------|---------|
|
||||
| `>P000` | Ping | `*P19000` |
|
||||
| `>S000` | State (motor + light) | `*S19` + motor(1) + light(0) + `00` |
|
||||
| `>B128` | Set brightness 0–255 | `*B19128` |
|
||||
| `>J000` | Get brightness | `*J19128` |
|
||||
| `>L000` | Light on (keep current brightness) | `*L19000` |
|
||||
| `>D000` | Light off | `*D19000` |
|
||||
| `>O000` | Open cover | `*O19000` |
|
||||
| `>C000` | Close cover | `*C19000` |
|
||||
| `>H000` | Halt cover | `*H19000` |
|
||||
| `>T050` | **Set dew heater 50%** *(custom)* | `*T19050` |
|
||||
| `>U000` | **Get dew heater %** *(custom)* | `*U19050` |
|
||||
|
||||
Motor state in `>S000` response: `0`=unknown/moving · `1`=closed · `2`=open
|
||||
Light state: `0`=off · `1`=on
|
||||
|
||||
---
|
||||
|
||||
## Pin assignments
|
||||
|
||||
| D-pin | GPIO | Function | Config define |
|
||||
|-------|------|----------|---------------|
|
||||
| D9 | — | MG995 servo signal | `SERVO_PIN` |
|
||||
| D3 | — | LED MOSFET gate | `LED_PWM_PIN` |
|
||||
| D5 | — | Dew heater MOSFET gate | `DEW_HEATER_PIN` |
|
||||
|
||||
All pins use the Arduino Nano ESP32 D-number scheme.
|
||||
LEDC channel 0 → LED · channel 1 → dew heater.
|
||||
|
||||
---
|
||||
|
||||
## Building the INDI driver
|
||||
|
||||
**Dependencies:** `libindi-dev`, `libcurl4-openssl-dev`, `nlohmann-json3-dev`, `cmake`
|
||||
|
||||
```bash
|
||||
sudo apt install libindi-dev libcurl4-openssl-dev nlohmann-json3-dev cmake build-essential
|
||||
|
||||
cd flatpanel/indi-driver
|
||||
cmake -B build -DCMAKE_INSTALL_PREFIX=/usr
|
||||
cmake --build build -j$(nproc)
|
||||
sudo cmake --install build
|
||||
```
|
||||
|
||||
If `nlohmann-json3-dev` is unavailable, CMake will fetch it automatically via `FetchContent`.
|
||||
|
||||
---
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
| Symptom | Fix |
|
||||
|---------|-----|
|
||||
| No boot message on Serial | Check VIN wiring; try USB-C direct to PC (bypasses LM2596) |
|
||||
| Servo twitches constantly | LM2596 sagging; re-measure 5V under servo load |
|
||||
| LED stays on at 0% | Missing 10kΩ gate pull-down on MOSFET-A |
|
||||
| Alnitak commands ignored | Set `SERIAL_DEBUG false`, reflash |
|
||||
| `Connection refused` on port 11111 | ESP32 not yet connected to WiFi; check credentials |
|
||||
| Dew heater not warming | Verify MOSFET-B drain voltage ≈ 0V when active; check element resistance |
|
||||
| Python app import error | `pip install PyQt6 requests pyserial` |
|
||||
| INDI build fails | `sudo apt install libindi-dev` |
|
||||
|
||||
---
|
||||
|
||||
## Diagrams
|
||||
|
||||
| File | Description |
|
||||
|------|-------------|
|
||||
| [docs/system-diagram.svg](docs/system-diagram.svg) | Architecture block diagram |
|
||||
| [docs/wiring-diagram.svg](docs/wiring-diagram.svg) | Colour-coded wiring diagram |
|
||||
|
||||
Open either file in a web browser — no additional software needed.
|
||||
|
||||
---
|
||||
|
||||
## Licence
|
||||
|
||||
Released under the **MIT Licence** — see `LICENCE` file.
|
||||
ASCOM and Alpaca are trademarks of the ASCOM Initiative.
|
||||
INDI is maintained by the INDI developers at indilib.org.
|
||||
Loading…
Add table
Add a link
Reference in a new issue