# How to Migrate Firmware Between Different PCB Versions in the DIY Sim Racing FFB Pedal

> Learn how to migrate firmware between different PCB versions for your DIY Sim Racing FFB Pedal. Easily update your hardware using download mode and PlatformIO.

- Repository: [chrgri/diy-sim-racing-ffb-pedal](https://github.com/chrgri/diy-sim-racing-ffb-pedal)
- Tags: migration-guide
- Published: 2026-02-27

---

**Migrating firmware between PCB versions requires putting the ESP32-S3 into download mode, building the binary for the specific target PCB using the correct PlatformIO environment, and flashing via the OTA folder or SimHub UI.**

The ChrGri DIY-Sim-Racing-FFB-Pedal project supports multiple hardware revisions including V5 and V6 variants with different wireless capabilities. Since each PCB version uses distinct pin mappings and peripheral configurations, you must migrate firmware between different PCB versions using specific build environments and flashing procedures to ensure hardware compatibility.

## Step 1: Enable Download Mode on the ESP32-S3

Before flashing new firmware, the ESP32-S3 must reboot into the OTA bootloader.

- In the SimHub plugin UI, click **"Enable Download Mode"**.
- This triggers the `btn_Bridge_boot_restart_Click` handler defined in [`SimHubPlugin/UICallback/btnCallbacks.cs`](https://github.com/chrgri/diy-sim-racing-ffb-pedal/blob/main/SimHubPlugin/UICallback/btnCallbacks.cs).
- The handler calls `bridge.boot_restart()`, which forces the ESP32-S3 to reboot into the OTA bootloader mode (`[0xFF,0xFF,0xFF]`).

The ESP32-S3 can only accept a new binary when running the bootloader, making this step mandatory for every migration.

## Step 2: Build Firmware for the Target PCB Version

Each PCB revision requires a specific PlatformIO build environment that defines the correct pin-out and feature flags.

The environment definitions live in [`ESP32/platformio.ini`](https://github.com/chrgri/diy-sim-racing-ffb-pedal/blob/main/ESP32/platformio.ini). Available environments include:

- `esp32s3usbotg_pcbV5` – PCB V5 with ESP-Now enabled
- `esp32s3usbotg_pcbV5_without_espnow` – PCB V5 without wireless
- `esp32s3usbotg_pcbV6` – PCB V6 with ESP-Now enabled
- `esp32s3usbotg_pcbV6_without_espnow` – PCB V6 without wireless

Build the firmware for your specific target:

```bash

# For PCB V5

pio run -e esp32s3usbotg_pcbV5

# For PCB V6 without ESP-Now

pio run -e esp32s3usbotg_pcbV6_without_espnow

```

The build generates `firmware.bin`, `bootloader.bin`, and `partitions.bin` in `ESP32/.pio/build/<environment>/`.

## Step 3: Flash the Binary to the Hardware

After building, deploy the binary using either local file copy or over-the-air (OTA) flashing via SimHub.

### Local Flashing via OTA Folder

Use the provided batch script to copy binaries to the correct OTA directory:

```cmd
cd OTA
copy_to_OTA_folder_ControlBoard.bat

```

The script `OTA/copy_to_OTA_folder_ControlBoard.bat` automatically selects the correct sub-folder based on the PlatformIO environment name (e.g., `esp32s3usbotg_pcbV5` or `esp32s3usbotg_pcbV6_without_espnow`).

### Over-the-Air Flashing via SimHub

Alternatively, use the SimHub OTA interface:

1. Open SimHub → **System Settings → OTA**.
2. Select the channel matching your target PCB revision (defined in `SystemSetting_OTA.xaml` via radio buttons `OTAChannel_Sel_1`, `OTAChannel_Sel_2`, etc.).
3. Click **"Enable OTA"**.

SimHub reads [`OTA/TestBuild/json/Version_ControlBoard.json`](https://github.com/chrgri/diy-sim-racing-ffb-pedal/blob/main/OTA/TestBuild/json/Version_ControlBoard.json) to locate the correct binary URL for the selected PCB version, then transmits the firmware to the bridge via the serial link.

## Verifying the Migration

After flashing, confirm the firmware version matches the target PCB:

- The bridge reports its version via `Bridge_firmware_version_u8`, defined in [`BridgeFirmware/src/Main.cpp`](https://github.com/chrgri/diy-sim-racing-ffb-pedal/blob/main/BridgeFirmware/src/Main.cpp).
- The SimHub plugin reads this value in [`payloadBridgeState.cs`](https://github.com/chrgri/diy-sim-racing-ffb-pedal/blob/main/payloadBridgeState.cs) and displays it in the UI.

If the version string matches your target environment (e.g., showing V5 or V6 specific identifiers), the migration succeeded.

## Summary

- **Enable Download Mode** using the SimHub UI button (`btn_Bridge_boot_restart_Click` in [`SimHubPlugin/UICallback/btnCallbacks.cs`](https://github.com/chrgri/diy-sim-racing-ffb-pedal/blob/main/SimHubPlugin/UICallback/btnCallbacks.cs)) to reboot the ESP32-S3 into the OTA bootloader.
- **Select the correct PlatformIO environment** in [`ESP32/platformio.ini`](https://github.com/chrgri/diy-sim-racing-ffb-pedal/blob/main/ESP32/platformio.ini) (e.g., `esp32s3usbotg_pcbV5` or `esp32s3usbotg_pcbV6_without_espnow`) to match your target PCB's pin-out and features.
- **Flash the binary** using `OTA/copy_to_OTA_folder_ControlBoard.bat` for local deployment or the SimHub OTA tab for over-the-air updates, referencing [`OTA/TestBuild/json/Version_ControlBoard.json`](https://github.com/chrgri/diy-sim-racing-ffb-pedal/blob/main/OTA/TestBuild/json/Version_ControlBoard.json) for version mapping.
- **Verify** the installation by checking the `Bridge_firmware_version_u8` field reported in the SimHub plugin.

## Frequently Asked Questions

### Can I use the same firmware binary for V5 and V6 PCBs?

No. Each PCB revision uses distinct pin mappings and peripheral configurations defined in separate PlatformIO environments within [`ESP32/platformio.ini`](https://github.com/chrgri/diy-sim-racing-ffb-pedal/blob/main/ESP32/platformio.ini). Flashing a V5 binary on a V6 PCB (or vice versa) will result in non-functional hardware because the firmware will attempt to control incorrect GPIO pins.

### What happens if I flash the wrong PCB version firmware?

The ESP32-S3 will likely boot, but the pedal will not function correctly because the firmware references pin definitions that do not match the physical PCB layout. If this occurs, simply repeat the migration process: enable download mode via the **"Enable Download Mode"** button in SimHub, build the correct binary for your actual PCB version, and re-flash.

### Do I need to enable download mode for every firmware update?

Yes. The ESP32-S3 must be in bootloader mode to accept new firmware binaries. The `btn_Bridge_boot_restart_Click` handler in [`SimHubPlugin/UICallback/btnCallbacks.cs`](https://github.com/chrgri/diy-sim-racing-ffb-pedal/blob/main/SimHubPlugin/UICallback/btnCallbacks.cs) triggers the `bridge.boot_restart()` command, which forces the MCU into the OTA bootloader state. This step is mandatory whether you are migrating between PCB versions or updating to a newer release of the same version.

### How do I know which PCB version I have?

Check the physical silkscreen labeling on your PCB, which typically indicates "V5" or "V6". Additionally, after flashing any firmware, you can verify the active configuration by examining the `Bridge_firmware_version_u8` field in the SimHub plugin UI, which reports the firmware identity defined in [`BridgeFirmware/src/Main.cpp`](https://github.com/chrgri/diy-sim-racing-ffb-pedal/blob/main/BridgeFirmware/src/Main.cpp). If the version string matches a specific PCB environment (e.g., containing "V5" or "V6" identifiers), you have confirmed the hardware revision.