Add FSESC 4.20 Plus hardware reference wiki page
Complete documentation of Flipsky Dual FSESC 4.20 Plus: - Full STM32F405 pin mapping from hw_410.h - All connectors and headers identified - ADC, voltage/current sensing, NTC formulas - Operating limits (firmware-enforced) - BMI160 IMU wiring problem documented (UART != I2C) - Pin conflict/multiplexing reference table - CAN bus setup (CANable 2.0, python-can) - VESC Tool access (VNC, vesc-cli.py) - Current config state and lessons learned
parent
571c5ec4a3
commit
b9be8cbebc
314
FSESC-4.20-Plus.md
Normal file
314
FSESC-4.20-Plus.md
Normal file
@ -0,0 +1,314 @@
|
|||||||
|
# FSESC 4.20 Plus — Hardware Reference
|
||||||
|
|
||||||
|
## Overview
|
||||||
|
|
||||||
|
| Parameter | Value |
|
||||||
|
|-----------|-------|
|
||||||
|
| **Model** | Flipsky Dual FSESC 4.20 Plus |
|
||||||
|
| **Hardware Version** | HW 410 (VESC 4.20) |
|
||||||
|
| **Firmware** | VESC FW 6.6 (vedderb/bldc) |
|
||||||
|
| **MCU** | STM32F405RGT6 (×2, one per ESC) |
|
||||||
|
| **Voltage Range** | 8V–60V (3–13S LiPo) |
|
||||||
|
| **Current (per ESC)** | 50A continuous, 150A burst |
|
||||||
|
| **Current (dual total)** | 100A continuous, 300A burst |
|
||||||
|
| **BEC Output** | 5V @ 1.5A |
|
||||||
|
| **CAN Bus** | Between both ESCs (internal), external header |
|
||||||
|
| **Our CAN IDs** | 61 (USB-connected ESC), 79 (secondary) |
|
||||||
|
| **USB** | STM32 Virtual COM Port → `/dev/ttyACM1` on Orin |
|
||||||
|
| **Firmware source** | `hwconf/other/vesc4/hw_410.h` in vedderb/bldc |
|
||||||
|
|
||||||
|
## Role in SaltyLab
|
||||||
|
|
||||||
|
As of 2026-03-12, the VESC replaced the MAMBA F722S flight controller + hoverboard ESC entirely. The VESC now handles:
|
||||||
|
- **Motor control** — FOC for both hub motors
|
||||||
|
- **Balance PID** — via VESC balance app (internal)
|
||||||
|
- **CAN communication** — with Orin via CANable 2.0
|
||||||
|
|
||||||
|
Architecture: `Orin ↔ CAN ↔ VESC (balance + motors)`
|
||||||
|
|
||||||
|
## STM32F405 Pin Mapping (from hw_410.h)
|
||||||
|
|
||||||
|
### UART (USART6)
|
||||||
|
| Pin | GPIO | Function |
|
||||||
|
|-----|------|----------|
|
||||||
|
| TX | PC6 | USART6 TX |
|
||||||
|
| RX | PC7 | USART6 RX |
|
||||||
|
|
||||||
|
**Header:** "UART" / "Header 6" on PCB — the JST header labeled TX/RX.
|
||||||
|
|
||||||
|
**⚠️ This is NOT I2C.** UART and I2C are on completely different pins.
|
||||||
|
|
||||||
|
### I2C (I2C2) — External IMU
|
||||||
|
| Pin | GPIO | Function |
|
||||||
|
|-----|------|----------|
|
||||||
|
| SCL | PB10 | I2C2 SCL |
|
||||||
|
| SDA | PB11 | I2C2 SDA |
|
||||||
|
|
||||||
|
**⚠️ CRITICAL:** PB10/PB11 are **NOT** on the UART header. They share GPIO port B with hall sensor pins but are DIFFERENT pins (PB10/PB11 vs PB6/PB7).
|
||||||
|
|
||||||
|
**Note:** PB10/PB11 are also USART3 TX/RX (alternate function). On the original VESC 4.12 design, these go to the "COMM" header. On the Flipsky 4.20 Plus, **their physical location needs to be traced on the PCB** — they may be on the COMM port, an unpopulated header, or not broken out at all.
|
||||||
|
|
||||||
|
### Hall Sensor / Encoder
|
||||||
|
| Pin | GPIO | Function |
|
||||||
|
|-----|------|----------|
|
||||||
|
| H1 | PB6 | Hall sensor 1 / Encoder A |
|
||||||
|
| H2 | PB7 | Hall sensor 2 / Encoder B |
|
||||||
|
| H3 | PC11 | Hall sensor 3 / Encoder Z |
|
||||||
|
|
||||||
|
**Header:** 6-pin JST "HALL" / "SENSOR" connector (H1, H2, H3, 5V, Temp, GND).
|
||||||
|
|
||||||
|
**Note:** These are NOT the I2C pins despite being in port B.
|
||||||
|
|
||||||
|
### SPI (SPI1)
|
||||||
|
| Pin | GPIO | Function |
|
||||||
|
|-----|------|----------|
|
||||||
|
| NSS | PA4 | SPI1 NSS (chip select) |
|
||||||
|
| SCK | PA5 | SPI1 SCK |
|
||||||
|
| MISO | PA6 | SPI1 MISO |
|
||||||
|
| MOSI | PA7 | SPI1 MOSI |
|
||||||
|
|
||||||
|
Used for DRV8302/DRV8301 gate driver communication (internal, not user-accessible).
|
||||||
|
|
||||||
|
### PPM / Servo Input (ICU)
|
||||||
|
| Pin | GPIO | Function |
|
||||||
|
|-----|------|----------|
|
||||||
|
| PPM | PB5 | TIM3_CH2 — servo/PPM input capture |
|
||||||
|
|
||||||
|
**Header:** Combined with UART header on "Header 6" (typically: VCC, GND, PPM, RX, TX).
|
||||||
|
|
||||||
|
### LEDs
|
||||||
|
| Pin | GPIO | Function |
|
||||||
|
|-----|------|----------|
|
||||||
|
| Green | PC4 | Status LED (active high) |
|
||||||
|
| Red | PC5 | Fault LED (active high) |
|
||||||
|
|
||||||
|
### Control Signals
|
||||||
|
| Pin | GPIO | Function |
|
||||||
|
|-----|------|----------|
|
||||||
|
| Gate Enable | PC10 | DRV gate driver enable (active high) |
|
||||||
|
| DC Cal | PB12 | DC offset calibration |
|
||||||
|
| DRV Fault | PC12 | DRV fault detect (active low) |
|
||||||
|
|
||||||
|
### ADC Channels
|
||||||
|
| ADC Index | Channel | GPIO | Function |
|
||||||
|
|-----------|---------|------|----------|
|
||||||
|
| 0 | IN0 | PA0 | Phase C sense (SENS3) |
|
||||||
|
| 1 | IN1 | PA1 | Phase B sense (SENS2) |
|
||||||
|
| 2 | IN2 | PA2 | Phase A sense (SENS1) |
|
||||||
|
| 3 | IN8 | PB0 | Motor current 2 |
|
||||||
|
| 4 | IN9 | PB1 | Motor current 1 |
|
||||||
|
| 5 | IN3 | PA3 | MOSFET temperature (NTC) |
|
||||||
|
| 7 | IN6 | PA6 | ADC_EXT2 |
|
||||||
|
| 8 | IN12 | PC2 | Input voltage (Vin) |
|
||||||
|
| 10 | IN5 | PA5 | ADC_EXT |
|
||||||
|
| 11 | IN3 | PA3 | Motor temperature (NTC) |
|
||||||
|
|
||||||
|
### Voltage / Current Sensing
|
||||||
|
| Parameter | Value |
|
||||||
|
|-----------|-------|
|
||||||
|
| Vref | 3.3V |
|
||||||
|
| Vin divider R1 | 39kΩ |
|
||||||
|
| Vin divider R2 | 2.2kΩ |
|
||||||
|
| Vin ratio | 18.73:1 |
|
||||||
|
| Current shunt | 0.001Ω |
|
||||||
|
| Current amp gain | 10× |
|
||||||
|
| Max measurable Vin | ~57V |
|
||||||
|
|
||||||
|
Formula: `Vin = (ADC_raw / 4095) × 3.3V × (39000 + 2200) / 2200`
|
||||||
|
|
||||||
|
### NTC Temperature Sensing
|
||||||
|
- **FET thermistor:** 10kΩ NTC, β=3434, pullup to 3.3V
|
||||||
|
- **Motor thermistor:** 10kΩ NTC (low-side), β configurable
|
||||||
|
- Formula: `R = (4095 × 10000) / ADC_val - 10000` → `T = 1 / (ln(R/10000)/3434 + 1/298.15) - 273.15`
|
||||||
|
|
||||||
|
### Operating Limits (firmware-enforced)
|
||||||
|
| Limit | Min | Max |
|
||||||
|
|-------|-----|-----|
|
||||||
|
| Motor current | -100A | 100A |
|
||||||
|
| Battery current | -100A | 100A |
|
||||||
|
| Absolute current | 0A | 150A |
|
||||||
|
| Input voltage | 6V | 57V |
|
||||||
|
| ERPM | -200,000 | 200,000 |
|
||||||
|
| Duty min | 0% | 10% |
|
||||||
|
| Duty max | 0% | 95% |
|
||||||
|
| FET temp | -40°C | 110°C |
|
||||||
|
|
||||||
|
## Physical Connectors (Flipsky FSESC 4.20 Plus)
|
||||||
|
|
||||||
|
```
|
||||||
|
┌─────────────────────────────────────────────┐
|
||||||
|
│ FSESC 4.20 Plus (Top View) │
|
||||||
|
│ │
|
||||||
|
│ ┌──────┐ ┌──────┐ │
|
||||||
|
│ │ ESC 1│ │ ESC 2│ (each has own STM32) │
|
||||||
|
│ │CAN 61│ │CAN 79│ │
|
||||||
|
│ └──┬───┘ └──┬───┘ │
|
||||||
|
│ │ CAN bus │ │
|
||||||
|
│ └────┬─────┘ │
|
||||||
|
│ │ │
|
||||||
|
│ Headers (edge of board): │
|
||||||
|
│ ┌─────┐ ┌─────┐ ┌──────┐ ┌─────┐ ┌──────┐ │
|
||||||
|
│ │MOTOR│ │MOTOR│ │HALL×2│ │UART │ │BATT │ │
|
||||||
|
│ │ 1 │ │ 2 │ │ │ │+PPM │ │ XT60 │ │
|
||||||
|
│ └─────┘ └─────┘ └──────┘ └─────┘ └──────┘ │
|
||||||
|
│ │
|
||||||
|
│ Also: USB-C, CAN header, anti-spark switch │
|
||||||
|
└─────────────────────────────────────────────┘
|
||||||
|
```
|
||||||
|
|
||||||
|
### Connector List
|
||||||
|
| Connector | Type | Pins | Notes |
|
||||||
|
|-----------|------|------|-------|
|
||||||
|
| **Motor 1** | 3-phase | A, B, C | Thick gauge wires to hub motor |
|
||||||
|
| **Motor 2** | 3-phase | A, B, C | Thick gauge wires to hub motor |
|
||||||
|
| **Battery** | XT60 | +, − | Main power input (with anti-spark) |
|
||||||
|
| **USB** | USB-C or Micro-B | Data + 5V | Config via VESC Tool |
|
||||||
|
| **HALL 1** | 6-pin JST | H1(PB6), H2(PB7), H3(PC11), 5V, Temp, GND | Motor 1 hall/encoder |
|
||||||
|
| **HALL 2** | 6-pin JST | Same pinout | Motor 2 hall/encoder |
|
||||||
|
| **UART/PPM** | JST | PPM(PB5), TX(PC6), RX(PC7), 5V, GND | **NOT I2C!** |
|
||||||
|
| **CAN** | 2-pin JST | CANH, CANL | External CAN bus (to CANable 2.0) |
|
||||||
|
| **COMM** | 4-pin JST (if present) | **Possibly PB10/PB11** | Needs PCB tracing — see I2C section |
|
||||||
|
|
||||||
|
## BMI160 IMU Wiring
|
||||||
|
|
||||||
|
### ❌ What DOESN'T Work
|
||||||
|
Wiring BMI160 to the **UART header** (TX=PC6, RX=PC7). These are USART6 pins — completely different GPIOs from the I2C2 peripheral (PB10/PB11). No amount of firmware config will make UART pins do I2C on this chip.
|
||||||
|
|
||||||
|
### ✅ What's Needed
|
||||||
|
BMI160 must connect to **PB10 (SCL) and PB11 (SDA)** — the I2C2 bus. Options:
|
||||||
|
|
||||||
|
1. **COMM header** — On original VESC 4.12, PB10/PB11 are brought out to a COMM connector. Flipsky may or may not have this. We tried "Header 11" which might be COMM — got zeros, but BMI160 chip may be dead or wrong orientation.
|
||||||
|
|
||||||
|
2. **Solder directly to STM32** — PB10 = pin 69, PB11 = pin 70 on LQFP64 package. Tiny but doable with fine solder and a magnifier.
|
||||||
|
|
||||||
|
3. **Run IMU from Orin instead** — Wire BMI160 to Orin GPIO I2C (Pin 3=SDA, Pin 5=SCL on J12 header), read IMU data on Orin, feed orientation to VESC over CAN. VESC balance app can accept external IMU data over CAN.
|
||||||
|
|
||||||
|
### BMI160 I2C Wiring (once correct pins found)
|
||||||
|
| BMI160 Pin | VESC Pin | Notes |
|
||||||
|
|------------|----------|-------|
|
||||||
|
| VCC/VIN | 3.3V or 5V | Breakout has onboard 3.3V regulator |
|
||||||
|
| GND | GND | Common ground |
|
||||||
|
| SCL | PB10 (I2C2 SCL) | **NOT PC6!** |
|
||||||
|
| SDA | PB11 (I2C2 SDA) | **NOT PC7!** |
|
||||||
|
| SA0/AD0 | GND | Sets I2C address to 0x68 (VESC default) |
|
||||||
|
|
||||||
|
### Diagnostic: Test BMI160 on Orin First
|
||||||
|
Before fighting with VESC pins, verify the chip is alive:
|
||||||
|
```bash
|
||||||
|
# Wire BMI160 to Orin J12: Pin 3 (SDA), Pin 5 (SCL), Pin 1 (3.3V), Pin 6 (GND)
|
||||||
|
sudo i2cdetect -y -r 1
|
||||||
|
# Should show 0x68 (or 0x69 if SA0 is high)
|
||||||
|
```
|
||||||
|
|
||||||
|
## VESC Tool Access
|
||||||
|
|
||||||
|
| Method | Details |
|
||||||
|
|--------|---------|
|
||||||
|
| **Direct USB** | Plug USB into laptop, open VESC Tool |
|
||||||
|
| **VNC on Orin** | `ssh seb@192.168.86.158`, VNC at `:5901` (pw: `vesc`) |
|
||||||
|
| **vesc-cli.py** | `/home/seb/vesc-cli.py` — status, scan, spin, stop, term, imu, balance |
|
||||||
|
| **VESC Tool path** | `/usr/local/bin/vesc_tool` (built from source, arm64 Qt5) |
|
||||||
|
|
||||||
|
### vesc-cli.py Quick Reference
|
||||||
|
```bash
|
||||||
|
# Status of USB-connected VESC
|
||||||
|
python3 vesc-cli.py status
|
||||||
|
|
||||||
|
# Scan CAN bus for all VESCs
|
||||||
|
python3 vesc-cli.py scan
|
||||||
|
|
||||||
|
# Spin motor at 5% duty for 2 seconds
|
||||||
|
python3 vesc-cli.py spin 5 -t 2
|
||||||
|
|
||||||
|
# Spin CAN-connected motor (ID 79)
|
||||||
|
python3 vesc-cli.py -c 79 spin 5 -t 2
|
||||||
|
|
||||||
|
# Stop motor
|
||||||
|
python3 vesc-cli.py stop
|
||||||
|
|
||||||
|
# Send terminal command
|
||||||
|
python3 vesc-cli.py term faults
|
||||||
|
|
||||||
|
# IMU info
|
||||||
|
python3 vesc-cli.py imu
|
||||||
|
```
|
||||||
|
|
||||||
|
## CAN Bus Setup (Orin ↔ VESC)
|
||||||
|
|
||||||
|
| Component | Details |
|
||||||
|
|-----------|---------|
|
||||||
|
| **Adapter** | CANable 2.0 (USB-to-CAN) |
|
||||||
|
| **Orin device** | `/dev/ttyACM0` |
|
||||||
|
| **Mode** | slcan (via python-can — kernel lacks gs_usb/slcan modules on Tegra) |
|
||||||
|
| **Bitrate** | 500kbps (VESC default) |
|
||||||
|
| **CAN IDs** | ESC 1 = 61, ESC 2 = 79 |
|
||||||
|
|
||||||
|
### python-can Usage
|
||||||
|
```python
|
||||||
|
import can
|
||||||
|
bus = can.Bus(interface='slcan', channel='/dev/ttyACM0', bitrate=500000)
|
||||||
|
for msg in bus:
|
||||||
|
print(f"ID: {msg.arbitration_id:#x} Data: {msg.data.hex()}")
|
||||||
|
```
|
||||||
|
|
||||||
|
## VESC Configuration (Current State)
|
||||||
|
|
||||||
|
| Setting | Value | Notes |
|
||||||
|
|---------|-------|-------|
|
||||||
|
| app_to_use | 1 (PPM) | Changed from 3 (PPM_UART) to free UART pins |
|
||||||
|
| IMU type | 4 (BMI160) | Set but not working — wrong wiring (see above) |
|
||||||
|
| permanent_uart | 1 | Stubbornly stays enabled — GUI change doesn't persist |
|
||||||
|
| Motor detection | Done | Via VESC Tool GUI (2026-03-12) |
|
||||||
|
| Battery voltage | 32.8V | Measured 2026-03-12 |
|
||||||
|
|
||||||
|
## Pin Conflict / Multiplexing Reference
|
||||||
|
|
||||||
|
This table clarifies which STM32F405 pins serve which function — the #1 source of wiring confusion:
|
||||||
|
|
||||||
|
| GPIO | Primary (HW 410) | Alternate Functions | Header |
|
||||||
|
|------|-------------------|---------------------|--------|
|
||||||
|
| PA0 | Phase C sense (ADC) | USART2_CTS, TIM2_CH1 | Internal |
|
||||||
|
| PA1 | Phase B sense (ADC) | USART2_RTS, TIM2_CH2 | Internal |
|
||||||
|
| PA2 | Phase A sense (ADC) | USART2_TX, TIM2_CH3 | Internal |
|
||||||
|
| PA3 | FET temp (ADC) | USART2_RX, TIM2_CH4 | Internal |
|
||||||
|
| PA4 | SPI1 NSS (DRV) | — | Internal |
|
||||||
|
| PA5 | SPI1 SCK (DRV) | ADC_EXT | Internal |
|
||||||
|
| PA6 | SPI1 MISO (DRV) | ADC_EXT2 | Internal |
|
||||||
|
| PA7 | SPI1 MOSI (DRV) | — | Internal |
|
||||||
|
| PB0 | Motor current 2 (ADC) | — | Internal |
|
||||||
|
| PB1 | Motor current 1 (ADC) | — | Internal |
|
||||||
|
| PB5 | PPM input (TIM3_CH2) | — | UART/PPM header |
|
||||||
|
| **PB6** | **Hall 1** | USART1_TX, TIM4_CH1 | **HALL header** |
|
||||||
|
| **PB7** | **Hall 2** | USART1_RX, TIM4_CH2 | **HALL header** |
|
||||||
|
| **PB10** | **I2C2 SCL** | USART3_TX, TIM2_CH3 | **COMM header?** |
|
||||||
|
| **PB11** | **I2C2 SDA** | USART3_RX, TIM2_CH4 | **COMM header?** |
|
||||||
|
| PB12 | DC calibration | — | Internal |
|
||||||
|
| PC2 | Vin sense (ADC) | — | Internal |
|
||||||
|
| PC4 | LED green | — | On-board |
|
||||||
|
| PC5 | LED red | — | On-board |
|
||||||
|
| **PC6** | **USART6 TX** | TIM3_CH1 | **UART header** |
|
||||||
|
| **PC7** | **USART6 RX** | TIM3_CH2 | **UART header** |
|
||||||
|
| PC10 | Gate enable | — | Internal |
|
||||||
|
| PC11 | Hall 3 | EXTI | HALL header |
|
||||||
|
| PC12 | DRV fault | — | Internal |
|
||||||
|
|
||||||
|
**Key takeaway:** PB10/PB11 (I2C/COMM) and PC6/PC7 (UART) are on completely different pins and headers. Connecting an I2C device to the UART header will never work on HW 410.
|
||||||
|
|
||||||
|
## Lessons Learned
|
||||||
|
|
||||||
|
1. **UART ≠ I2C on HW 410.** The UART header (PC6/PC7) and I2C bus (PB10/PB11) use completely different GPIO pins. Always check `hw_xxx.h` before wiring.
|
||||||
|
|
||||||
|
2. **VESC 4.x vs VESC 6+ differences.** On VESC 6+ boards, the COMM header often multiplexes TX/SCL and RX/SDA on the same pins. On VESC 4.x (HW 410), UART and I2C are physically separate peripherals on separate pins.
|
||||||
|
|
||||||
|
3. **Verify pin accessibility before buying peripherals.** We ordered the BMI160 for VESC use without confirming that PB10/PB11 are broken out on the Flipsky board.
|
||||||
|
|
||||||
|
4. **`permanent_uart_enabled` is persistent.** Changing it in VESC Tool GUI doesn't stick — may need terminal command or direct config binary write.
|
||||||
|
|
||||||
|
5. **Each ESC has its own STM32.** The dual board is two independent VESCs connected by CAN. Config changes to one don't affect the other.
|
||||||
|
|
||||||
|
## References
|
||||||
|
|
||||||
|
- **VESC firmware source:** [vedderb/bldc](https://github.com/vedderb/bldc) — `hwconf/other/vesc4/hw_410.h`
|
||||||
|
- **External IMU wiring (VESC 6):** [pev.dev/t/external-imu-wiring/294](https://pev.dev/t/external-imu-wiring/294)
|
||||||
|
- **BMI160 for VESC balance:** [spintend.com](https://spintend.com/products/bmi-160-module-for-diy-balanced-board-with-vesc)
|
||||||
|
- **VESC project:** [vesc-project.com](https://vesc-project.com)
|
||||||
Loading…
x
Reference in New Issue
Block a user