Merge branch 'readme-add' into 'main'
Add comprehensive README.md with project overview, architecture, and documentation See merge request airguns/chronodisplay!1
This commit is contained in:
@@ -0,0 +1,208 @@
|
||||
# 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]
|
||||
Reference in New Issue
Block a user