209 lines
11 KiB
Markdown
209 lines
11 KiB
Markdown
# ChronoDisplay
|
|
|
|
An ESP32-based display panel for the **FX Archery Chronograph (v1)** that provides a real-time, always-on ePaper display of shot data via Bluetooth Low Energy (BLE). Compatible with airguns and archery applications.
|
|
|
|
## Overview
|
|
|
|
ChronoDisplay connects wirelessly to the [FX Archery Chronograph](https://fx-archery.com) via BLE, receives speed readings in real time, and displays comprehensive shot statistics on a 7.5" monochrome ePaper screen. It runs entirely on an ESP32 — no PC or phone required.
|
|
|
|
### Key Features
|
|
|
|
- **Live BLE Connection** — Automatically scans for, connects to, and maintains a link with the FX Chronograph
|
|
- **Real-Time E-Paper Display** — Always-on, sunlight-readable display showing:
|
|
- Latest shot velocity (FPS) and energy (FPE)
|
|
- Running shot count, average / min / max FPS
|
|
- Spread and standard deviation
|
|
- Profile info (gun name, power level, projectile type/caliber/weight)
|
|
- Last 32 shot history
|
|
- Real-time clock (EST timezone)
|
|
- Connection status indicator
|
|
- **Built-in Web Server** — Configure everything from any browser on your WiFi network
|
|
- Gun profiles (Bow/Airsoft, CO2 Pistol, Air Pistol, Air Gun UK, FAC)
|
|
- Projectile profiles (pellets & slugs with caliber and weight)
|
|
- Export all readings as CSV
|
|
- Reset readings, format storage, toggle test mode
|
|
- Accessible at `http://esp32.local` (mDNS) or the device's IP
|
|
- **Persistent Storage** — Gun and projectile profiles saved to LittleFS filesystem
|
|
- **Test Mode** — Generate simulated readings for display debugging
|
|
|
|
## Hardware
|
|
|
|
| Component | Specification |
|
|
|---|---|
|
|
| Microcontroller | ESP32 |
|
|
| Display | 7.5" Monochrome ePaper (UC8179 chipset, Screen Combo board ID: 502) |
|
|
| BLE Library | [NimBLEDevice](https://github.com/h2zero/NimBLE-Arduino) |
|
|
| Display Library | [TFT_eSPI](https://github.com/Bodmer/TFT_eSPI) |
|
|
| Filesystem | LittleFS |
|
|
|
|
### Pin / Board Configuration
|
|
|
|
The board type is defined in `driver.h`:
|
|
|
|
```cpp
|
|
#define BOARD_SCREEN_COMBO 502
|
|
#define USE_XIAO_EPAPER_DRIVER_BOARD
|
|
```
|
|
|
|
Ensure your `User_Setup_Select.h` (from TFT_eSPI) is configured for the **XIAO ePaper driver board** with a 7.5" UC8179 display.
|
|
|
|
## Architecture
|
|
|
|
```
|
|
┌──────────────┐ BLE ┌──────────────────┐ WiFi ┌──────────────┐
|
|
│ FX Chrono │ ◄──────────► │ ESP32 │ ◄──────────► │ Browser │
|
|
│ (v1) │ (speed │ │ (web UI) │ │
|
|
│ │ data) │ ┌──────────────┐│ │ 192.168.x.x │
|
|
│ │ │ │ ChronoBLE ││ │ esp32.local │
|
|
│ │ │ ├──────────────┤│ │ │
|
|
│ │ │ │ Display │ │ │ │
|
|
│ │ │ ├──────────────┤│ │ │
|
|
│ │ │ │ WebServer │ │ │ │
|
|
│ │ │ ├──────────────┤│ │ │
|
|
│ │ │ │ FileMgr │ │ │ │
|
|
│ │ │ └──────────────┘│ │ │
|
|
└──────────────┘ └──────────────────┘ └──────────────┘
|
|
```
|
|
|
|
### Core Modules
|
|
|
|
| Module | File(s) | Purpose |
|
|
|---|---|---|
|
|
| **Main** | `ChronoDisplay.ino` | Arduino setup/loop, orchestrates all subsystems |
|
|
| **BLE Client** | `ChronoBLE.h/.cpp` | NimBLE connection to FX Chronograph, reads speed notifications |
|
|
| **Display** | `Display.h/.cpp` | E-Paper rendering of all data fields |
|
|
| **Web Server** | `ChronoWebServer.h/.cpp` | HTTP server with embedded HTML/JS UI |
|
|
| **File Manager** | `FileManager.h/.cpp` | Persistent profile storage on LittleFS |
|
|
| **Reading Manager** | `ChronoReadingManager.h/.cpp` | Singleton that tracks all readings, profiles, and stats |
|
|
| **Profiles** | `GunProfile.h/.cpp`, `ProjectileProfile.h/.cpp`, `ChronoProfile.h/.cpp` | Gun and projectile profile data models |
|
|
| **Reading** | `ChronoReading.h/.cpp` | Individual shot reading (FPS + FPE + profile) |
|
|
|
|
## BLE Details
|
|
|
|
### FX Chronograph BLE Characteristics
|
|
|
|
The device uses a custom GATT service with the following UUIDs:
|
|
|
|
| Description | UUID |
|
|
|---|---|
|
|
| Device Info Service | `0000180A-0000-1000-8000-00805F9B34FB` |
|
|
| Chronograph Service | `00001623-88EC-688C-644B-3FA706C0BB75` |
|
|
| **Speed Characteristic** (notify) | `00001624-88EC-688C-644B-3FA706C0BB75` |
|
|
| Profile Setting Low | `00001626-88EC-688C-644B-3FA706C0BB75` |
|
|
| Battery Level | `00001627-88EC-688C-644B-3FA706C0BB75` |
|
|
| Profile Setting High | `00001628-88EC-688C-644B-3FA706C0BB75` |
|
|
|
|
Speed data is received as a 2-byte big-endian value and converted to FPS by multiplying by `0.0475111859`.
|
|
|
|
### Connection Flow
|
|
|
|
1. Start BLE scan for devices advertising the Device Info Service UUID
|
|
2. When target found, connect using cached or new BLE client
|
|
3. Subscribe to the speed characteristic for notifications
|
|
4. Write low/high speed profile bytes to configure range
|
|
5. On disconnect, return to scan state and repeat
|
|
|
|
## Web Interface
|
|
|
|
Connect to the device's WiFi network (or existing network — SSID and password are set in `ChronoWebServer.cpp`), then open:
|
|
|
|
- **mDNS**: `http://esp32.local`
|
|
- **Direct IP**: `http://<ESP32-IP>`
|
|
|
|
### Available Pages & Endpoints
|
|
|
|
| Route | Method | Purpose |
|
|
|---|---|---|
|
|
| `/` | GET | Main dashboard — select gun & projectile profiles, control panel |
|
|
| `/gunprofile` | GET | Form to add a new gun profile |
|
|
| `/gunprofile/add` | POST | Create a gun profile (name + type) |
|
|
| `/gunprofile/set` | POST | Activate a gun profile |
|
|
| `/gunprofile/remove` | POST | Delete a gun profile |
|
|
| `/projectileprofile` | GET | Form to add a projectile profile |
|
|
| `/projectileprofile/add` | POST | Create a projectile profile (name, type, caliber, weight) |
|
|
| `/projectileprofile/set` | POST | Activate a projectile profile |
|
|
| `/projectileprofile/remove` | POST | Delete a projectile profile |
|
|
| `/export` | GET | Download all readings as `data.csv` |
|
|
| `/reset` | GET | Clear all readings (shot count, stats) |
|
|
| `/format` | GET | Format LittleFS — erase all stored profiles |
|
|
| `/testmode` | GET | Toggle test mode (simulated readings every 5s) |
|
|
|
|
### Gun Profile Types
|
|
|
|
| Type | Description |
|
|
|---|---|
|
|
| 0 | Bow / Airsoft |
|
|
| 1 | CO2 Pistol |
|
|
| 2 | Air Pistol |
|
|
| 3 | Air Gun UK |
|
|
| 4 | FAC (French) |
|
|
|
|
### Display Layout
|
|
|
|
```
|
|
┌──────────────────────────────────────────────────────────────────────────────────────────┐
|
|
│ 14:56 EST ┌─────────────────────────────────┐ │
|
|
│ [Time] │ Profile: │ │
|
|
│ │ "My Rifle" [1] │ │
|
|
│ Latest Shot │ .22 Pellet │ │
|
|
│ ┌────────────────────┐ │ Cal: 6.35 │ │
|
|
│ │ │ │ Pellet 0.58g │ │
|
|
│ │ 905 fps │ └─────────────────────────────────┘ │
|
|
│ └────────────────────┘ (Right Panel) │
|
|
│ │ │ │
|
|
│ ┌─────────┐┌─────────┐┌─────────┐ ┌──────────────────────────────────────────┐ │ │
|
|
│ │Avg: 902│ │Count: 12│ │Spread: 5│ │Last Shots: │ │ │
|
|
│ └─────────┘└─────────┘└─────────┘ │ 12) 905 / 18.2 11) 904 / 18.2 ... │ │ │
|
|
│ ┌─────────┐┌─────────┐┌─────────┐ └──────────────────────────────────────────┘ │ │
|
|
│ │Low: 897│ │High: 907│ │SD: 3.2 │ │ │
|
|
│ └─────────┘└─────────┘└─────────┘ │ │
|
|
│ │ │
|
|
│ FPE: 18.2 │ │
|
|
└──────────────────────────────────────────────────────────────────────────────────────────┘
|
|
```
|
|
|
|
## Development
|
|
|
|
### Prerequisites
|
|
|
|
- [Arduino IDE](https://www.arduino.cc/en/software) or [PlatformIO](https://platformio.org/)
|
|
- ESP32 board support package
|
|
- [TFT_eSPI](https://github.com/Bodmer/TFT_eSPI) library — configure `User_Setup_Select.h` for your display
|
|
- [NimBLE-Arduino](https://github.com/h2zero/NimBLE-Arduino) library
|
|
|
|
### TFT_eSPI Configuration
|
|
|
|
In your TFT_eSPI `User_Setup_Select.h`, uncomment the XIAO ePaper 7.5" setup. The board constant used is `BOARD_SCREEN_COMBO 502` with `USE_XIAO_EPAPER_DRIVER_BOARD`.
|
|
|
|
### WiFi Configuration
|
|
|
|
Edit the SSID and password in `ChronoWebServer.cpp`:
|
|
|
|
```cpp
|
|
const char *ssid = "your-network";
|
|
const char *password = "your-password";
|
|
```
|
|
|
|
### Build & Upload
|
|
|
|
1. Configure libraries and board in Arduino IDE / PlatformIO
|
|
2. Set board to your ESP32 variant
|
|
3. Flash via USB
|
|
|
|
## Project Status
|
|
|
|
Initial development. The project compiles and runs with the following functionality:
|
|
|
|
- ✅ BLE connection to FX Chronograph v1
|
|
- ✅ Live ePaper display of shot data
|
|
- ✅ Web-based gun & projectile profile management
|
|
- ✅ CSV export of readings
|
|
- ✅ Persistent profile storage
|
|
- ✅ Test mode for display debugging
|
|
- ⏳ OTA firmware updates (Update.h included but not implemented)
|
|
- ⏳ Time synchronization via NTP (currently hardcoded)
|
|
|
|
## License
|
|
|
|
[Add your license here]
|