1
FSESC 4.20 Plus
Salty edited this page 2026-03-13 17:20:09 -04:00
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.

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 8V60V (313S 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 - 10000T = 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:

# 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

# 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

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