multi-functional-controller/README.md

177 lines
10 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# Multi-Functional Controller (MFC)
[![ESP-IDF](https://img.shields.io/badge/ESP--IDF-v5.x-E7352C?style=for-the-badge&logo=espressif&logoColor=white)](https://github.com/espressif/esp-idf)
[![Target MCU](https://img.shields.io/badge/MCU-ESP32--S3--N16R8-red?style=for-the-badge&logo=espressif)](https://www.espressif.com/en/products/socs/esp32-s3)
[![KiCad](https://img.shields.io/badge/EDA-KiCad%2010-314CB0?style=for-the-badge&logo=kicad&logoColor=white)](https://www.kicad.org/)
[![Language](https://img.shields.io/badge/Firmware-C99%20%2F%20C%2B%2B-00599C?style=for-the-badge&logo=c)](https://en.wikipedia.org/wiki/C_(programming_language))
[![RTOS](https://img.shields.io/badge/OS-FreeRTOS-008080?style=for-the-badge)](https://www.freertos.org/)
[![Status](https://img.shields.io/badge/Status-Active%20Prototype-success?style=for-the-badge)](#roadmap--milestones)
A custom, high-performance handheld remote controller engineered from scratch for dual-role applications: **long-range, low-latency RC vehicle control** and **USB/Bluetooth HID gaming**.
Built around the **ESP32-S3-N16R8 (Xtensa® 32-bit LX7 dual-core @ 240 MHz)**, this project bridges hardware and software engineering—combining analog/Hall-effect sensing on `ADC1`, 2.4 GHz nRF24L01+ RF telemetry, hardware pulse-counted (`pulse_cnt`) rotary inputs, and a shared high-speed `SPI2_HOST` (FSPI) bus driving both the 1.3" SH1106 OLED display and radio transceiver without bus collisions.
---
## Prototype Showcase
<p align="center">
<img src="images/TOP_VIEW.png" alt="Multi-Functional Controller Top View" width="700">
<br>
<em><b>Figure 1:</b> Top assembly layout — ESP32-S3-N16R8 module, analog joystick, quadrature rotary encoder, 1.3" SH1106 SPI OLED display, and nRF24L01+ RF transceiver.</em>
</p>
<p align="center">
<img src="images/SIDE_VIEW_WITH_ANTENNA.png" alt="Multi-Functional Controller Profile & RF Antenna" width="700">
<br>
<em><b>Figure 2:</b> Ergonomic profile — 2.4 GHz external dipole antenna connected to the nRF24L01+ transceiver, rotary dial, and dual USB-C ports.</em>
</p>
<p align="center">
<img src="images/BOTTOM_VIEW.png" alt="Multi-Functional Controller Perfboard Soldering" width="700">
<br>
<em><b>Figure 3:</b> Underbody point-to-point bus routing — 6×9 cm perfboard with dedicated decoupled power rails (100 µF smoothing capacitor across nRF24L01+ VCC/GND) and direct FSPI signal lines.</em>
</p>
---
## Key Hardware & Firmware Architecture
- **Microcontroller Core:** Espressif **ESP32-S3-N16R8** (16 MB Quad SPI Flash, 8 MB Octal PSRAM) running FreeRTOS.
- **Collision-Free Shared FSPI (`SPI2_HOST`) Bus:**
- Shares `MOSI` (`GPIO 11`), `MISO` (`GPIO 13`), and `SCK` (`GPIO 12`) between the **1.3" SH1106 OLED** (10 MHz clock) and the **nRF24L01+ 2.4 GHz Transceiver** (1 MHz clock) via independent hardware Chip Select lines (`GPIO 10` and `GPIO 14`).
- **Bare-Metal 5×8 OLED Graphics Engine & Multi-Screen UI State Machine:**
- Direct register-level driver for the 1.3" SH1106 controller (handling the 132×64 internal RAM 2-pixel column offset) with a complete 5×8 bitmap font table (`A–Z`, `0–9`, `<`, `>`, `[`, `]`, `(`, `)`, `/`, `-`, `:`, `.`).
- **4 Interactive Screens:**
1. `DRIVE VEHICLE`: Real-time One-Shot `ADC1` joystick acquisition (`VRx` / `VRy`) and live 2.4 GHz packet broadcasting (`rc_packet_t`).
2. `RADIO CONFIG`: Verifies physical nRF24L01+ SPI link (`SETUP_AW` register `0x03`) and tunes `RF_CH` (register `0x05`) live across channels `0–125` (`2.400–2.525 GHz`) using the rotary dial.
3. `CALIBRATE`: Live raw `ADC1` readout (`0–4095`) with one-click neutral center-point capture.
4. `SYSTEM INFO`: Displays target silicon (`ESP32-S3`) and real-time free RTOS heap memory (`esp_get_free_heap_size()`).
- **Hardware Quadrature Rotary Decoder (`pulse_cnt`):**
- Uses the ESP32-S3 hardware Pulse Counter peripheral on `GPIO 15` (`CLK`) and `GPIO 16` (`DT`) with a `1000 ns` hardware glitch filter and full 4× quadrature edge/level state decoding, paired with a `300 ms` debounced push-switch (`GPIO 17`).
- **Wi-Fi-Safe Analog Joystick Acquisition (`ADC1`):**
- Routes `VRx` (`GPIO 4`, `ADC1_CH3`) and `VRy` (`GPIO 5`, `ADC1_CH4`) with `12 dB` attenuation (`0–3.3V` full-scale) on `ADC_UNIT_1` to avoid `ADC2` Wi-Fi/RF arbitration conflicts.
- **Power Subsystem:**
- Dual parallel 18650 Li-ion cells delivering **4800 mAh** combined capacity.
- 100 µF low-ESR electrolytic bulk decoupling capacitor suppressing nRF24L01+ TX current spikes.
---
## GPIO Pinout & Peripheral Mapping (ESP32-S3 Hardware Specification)
The physical controller uses a shared high-speed **SPI2_HOST** (FSPI) bus for both the 1.3" SH1106 OLED and the nRF24L01+ RF transceiver, alongside dedicated `ADC1` channels and hardware pulse-counter inputs:
| Peripheral / Signal | GPIO | Hardware Interface | Description |
| :--- | :---: | :--- | :--- |
| **SPI Bus: MOSI** | `GPIO 11` | SPI Master Output (`SPI2_HOST`) | Shared data line for nRF24L01+ and OLED (`SDA` / `D1`) |
| **SPI Bus: MISO** | `GPIO 13` | SPI Master Input (`SPI2_HOST`) | Data line from nRF24L01+ radio module |
| **SPI Bus: SCK (Clock)** | `GPIO 12` | SPI Master Clock (`SPI2_HOST`) | Shared clock line for nRF24L01+ and OLED (`CLK` / `D0`) |
| **nRF24L01+ Chip Select (CS)** | `GPIO 14` | SPI Device Select | Dedicated radio bus enable |
| **nRF24L01+ Chip Enable (CE)** | `GPIO 21` | Digital Output | Radio TX/RX power state activation line |
| **OLED Chip Select (CS)** | `GPIO 10` | SPI Device Select | Display SPI bus enable |
| **OLED Data/Command (DC)** | `GPIO 9` | Digital Output | 1.3" OLED command vs. data selection |
| **OLED Reset (RES)** | `GPIO 8` | Digital Output | Hardware display reset line |
| **Joystick VRx (X-Axis)** | `GPIO 4` | `ADC1` Channel 3 (`12 dB` Atten) | Analog X-axis potentiometer input (`0–3.3V` safe) |
| **Joystick VRy (Y-Axis)** | `GPIO 5` | `ADC1` Channel 4 (`12 dB` Atten) | Analog Y-axis potentiometer input (`0–3.3V` safe) |
| **Rotary Encoder CLK** | `GPIO 15` | ESP-IDF `pulse_cnt` Unit | Quadrature channel A (hardware edge counter) |
| **Rotary Encoder DT** | `GPIO 16` | ESP-IDF `pulse_cnt` Unit | Quadrature channel B (direction sensing) |
| **Rotary Encoder Switch (SW)**| `GPIO 17` | Digital Input (`PULLUP`) | Push-button (menu enter/select mode) |
### Silicon Multiplexing Notes (ESP32-S3-N16R8 vs. Classic ESP32)
1. **Octal PSRAM & Flash Reservation (`GPIO 26 – GPIO 37`):** On the **ESP32-S3-N16R8** (8 MB Octal PSRAM), `GPIO 26` through `GPIO 37` are wired internally to the Octal SPI Flash/PSRAM bus. Accessing `GPIO 26, 27, 32, 33` triggers an immediate *Guru Meditation Error / Cache Disabled Panic* on boot.
2. **Unbonded Silicon Pins (`GPIO 22 – GPIO 25`):** `GPIO 22, 23, 24, 25` do not exist on the ESP32-S3 pin multiplexing matrix.
3. **FSPI (`SPI2_HOST`) Default Matrix:** Uses native ESP32-S3 FSPI pins (`GPIO 10, 11, 12, 13`) for zero-penalty IOMUX/GPIO matrix routing rather than legacy 2016 ESP32 VSPI defaults (`GPIO 5, 18, 23`).
---
## Repository Structure
```text
multi-functional-controller/
├── firmware/ # ESP-IDF C99 Firmware Project (ESP32-S3)
│ ├── CMakeLists.txt # Top-level CMake project configuration
│ ├── sdkconfig # ESP32-S3 target configuration
│ └── main/
│ ├── CMakeLists.txt # Component registration
│ └── mmcontroller.c # Master firmware: Shared SPI2, SH1106 5x8 UI, nRF24L01+, PCNT, ADC1
├── hardware/ # KiCad 10 Electronic Design Automation (EDA)
│ ├── mfc-1.kicad_pro # KiCad project file
│ ├── mfc-1.kicad_sch # Complete schematic design & component symbols
│ └── mfc-1.kicad_pcb # Board layout & routing rules
├── images/ # High-resolution prototype photography
│ ├── TOP_VIEW.png # Front control surface overview
│ ├── SIDE_VIEW_WITH_ANTENNA.png # RF antenna and profile perspective
│ └── BOTTOM_VIEW.png # Perfboard underside bus wiring
├── .gitignore # Clean repository filter (builds, caches, local configs)
├── LICENSE # MIT License
└── README.md # Master engineering documentation
```
---
## Getting Started: Building the Firmware
### Prerequisites
- [ESP-IDF v5.1+](https://docs.espressif.com/projects/esp-idf/en/latest/esp32s3/get-started/) installed and exported into your environment:
```bash
. $HOME/esp/esp-idf/export.sh
```
### Build & Flash
1. Navigate to the firmware directory:
```bash
cd firmware
```
2. Set target to ESP32-S3:
```bash
idf.py set-target esp32s3
```
3. Compile the firmware:
```bash
idf.py build
```
4. Flash to the controller and open serial monitoring:
```bash
idf.py -p /dev/ttyACM0 flash monitor
```
---
## Hardware CAD & Schematic Editing
The electronic schematic is developed in **KiCad 10**:
1. Open the project:
```bash
kicad hardware/mfc-1.kicad_pro
```
2. Inspect or modify the schematic in `eeschema` (`hardware/mfc-1.kicad_sch`).
3. To generate vector schematics for documentation or web publication:
- Select **File $\rightarrow$ Plot $\rightarrow$ SVG** or **PDF**.
---
## Roadmap & Milestones
- [x] Initial hardware breadboard and perfboard prototype (6×9 cm assembly).
- [x] Shared `SPI2_HOST` bus driving both 1.3" SH1106 OLED and nRF24L01+ without bus collisions.
- [x] Full 5×8 bare-metal font renderer (`A–Z`, `0–9`, and UI punctuation/symbols).
- [x] Hardware pulse-counter (`pulse_cnt`) quadrature decoder with 1000 ns glitch filter & 300 ms debounced state machine.
- [x] Live nRF24L01+ SPI register verification (`0x03`) and channel tuning (`0–125`) with `ADC1` joystick packet transmission.
- [ ] Custom multi-layer printed circuit board (PCB) design in KiCad.
- [ ] 3D-printable ergonomic handheld enclosure (PETG / Resin).
- [ ] Bidirectional ACK-payload telemetry from target RC vehicle.
- [ ] Native USB Gamepad HID descriptor integration on ESP32-S3 USB-OTG port.
---
## Author & Project Notebook
- **Author:** [Ertunç Özbay](https://github.com/ertunc-ozbay)
- **Personal Workshop & Portfolio:** [ertuncozbay.dev](https://ertuncozbay.dev)
- **Project Detail Page:** [ertuncozbay.dev/projects/multi-functional-controller.html](https://ertuncozbay.dev/projects/multi-functional-controller.html)
- **License:** [MIT License](LICENSE)