# DIY Sim-Racing FFB Pedal Calibration Procedures and Force Range Configuration Guide

> Master DIY Sim-Racing FFB pedal calibration with SimHub. Learn to auto-zero pedals and configure preload and max force for optimal control and adjustable force ranges up to 200kg.

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

---

**Enable Step-Loss Recov in the SimHub plugin, fully release the pedal to its mechanical stop to trigger automatic zeroing via `correctPos()`, and configure the **preloadForce** and **maxForce** values (0–50 kg for basic builds or 0–200 kg for high-power builds) using the Force Range slider.**

The `chrgri/diy-sim-racing-ffb-pedal` repository implements a dual-layer calibration system that combines automatic firmware-level position correction with SimHub plugin-based force range limits. Proper execution of these **pedal calibration procedures and force range configuration** steps ensures accurate force feedback response and prevents mechanical drift during operation.

## Automatic Calibration via Step-Loss Compensation

The firmware running on the ESP32 automatically detects when the pedal reaches its mechanical minimum position and recalibrates the stepper motor's zero point. This **step-loss compensation** routine is controlled by the `stepLossFunctionFlags_u8` bitmask and executes in the main control loop.

### Detecting the Minimum Position

In [`Firmware_for_V3/PedalFirmware/src/Main.cpp`](https://github.com/chrgri/diy-sim-racing-ffb-pedal/blob/main/Firmware_for_V3/PedalFirmware/src/Main.cpp), the firmware continuously monitors the pedal state through the main loop. When `stepper->isAtMinPos()` returns true, indicating the pedal has reached its physical hard stop, the system initiates the calibration sequence at lines 1419–1422:

```cpp
if (stepper->isAtMinPos()) { 
    stepper->configSteplossRecovAndCrashDetection(
        dap_config_pedalUpdateTask_st.payLoadPedalConfig_.stepLossFunctionFlags_u8
    );
}

```

This check determines whether automatic recovery is enabled before proceeding with position correction.

### Re-Zeroing the Stepper Position

Upon detecting the minimum position, the firmware immediately calls `correctPos()` at lines 1426–1427 to reset the internal step counter to zero:

```cpp
stepper->correctPos();

```

This function compensates for any step loss that occurred during operation and establishes the absolute zero reference point for all subsequent force calculations. The same logic exists in [`ESP32/src/Main.cpp`](https://github.com/chrgri/diy-sim-racing-ffb-pedal/blob/main/ESP32/src/Main.cpp) at lines 2058–2061 for ESP32-specific builds.

### Enabling the Calibration Flag

For the automatic calibration to execute, **bit 0** of `stepLossFunctionFlags_u8` must be set to 1. This corresponds to the **"Step-Loss Recov"** checkbox in the SimHub plugin's General Settings tab. The UI handles this toggle in [`SimHubPlugin/UIFunction/GeneralSetting_PedalSetting.xaml.cs`](https://github.com/chrgri/diy-sim-racing-ffb-pedal/blob/main/SimHubPlugin/UIFunction/GeneralSetting_PedalSetting.xaml.cs) at lines 32–38:

```csharp
// Enable auto-recalibration
tmp.payloadPedalConfig_.stepLossFunctionFlags_u8 |= (1 << 0);

// Disable auto-recalibration
tmp.payloadPedalConfig_.stepLossFunctionFlags_u8 = (byte)(tmp & ~(1 << 0));

```

When enabled, the firmware executes the calibration routine every time the pedal returns to its mechanical minimum.

## Configuring the Force Range

The pedal's force output boundaries are defined by two parameters stored in the `payloadPedalConfig` structure: **preloadForce** (minimum resting force) and **maxForce** (maximum output limit). These values are transmitted from the SimHub plugin to the firmware and enforced by the control algorithm.

### Understanding Force Parameters

According to [`SimHubPlugin/VariablesStruct/payloadPedalConfig.cs`](https://github.com/chrgri/diy-sim-racing-ffb-pedal/blob/main/SimHubPlugin/VariablesStruct/payloadPedalConfig.cs), the critical fields are:

- `maxForce` (line 21): Defines the upper force limit in kilograms.
- `preloadForce` (line 22): Defines the minimum force applied when the pedal is at rest.

These values determine the operating range of the stepper motor and directly affect the pedal's resistance characteristics.

### Setting Values via the SimHub Interface

The **Force Range** slider in the Curve Tab UI maps directly to these configuration fields. In [`SimHubPlugin/UIFunction/CurveTab_PedalForceTravel_Modified.xaml.cs`](https://github.com/chrgri/diy-sim-racing-ffb-pedal/blob/main/SimHubPlugin/UIFunction/CurveTab_PedalForceTravel_Modified.xaml.cs) at lines 66–68, the slider values update the configuration structure:

```csharp
if (control.Rangeslider_force_range != null) 
    control.Rangeslider_force_range.UpperValue = control.dap_config_st.payloadPedalConfig_.maxForce;
    
if (control.Rangeslider_force_range != null) 
    control.Rangeslider_force_range.LowerValue = control.dap_config_st.payloadPedalConfig_.preloadForce;

```

Adjust the **Upper** slider to set `maxForce` and the **Lower** slider to set `preloadForce`. These changes propagate to the firmware on the next configuration update cycle.

### Pedal Type Force Limits

The UI enforces hardware-specific force limits based on the selected pedal type (`Settings.table_selected`). Basic pedals (type 0) support up to **50 kg**, while high-power pedals (type 1) support up to **200 kg**, as implemented at lines 11–16:

```csharp
if (Settings != null)
{
    if (Settings.table_selected != 1)   // Basic pedal
        Rangeslider_force_range.Maximum = 50;
    else                               // High-power pedal
        Rangeslider_force_range.Maximum = 200;
}

```

This validation prevents users from requesting force levels that exceed the mechanical capabilities of their specific build.

## Complete Calibration Workflow

Execute the following sequence to properly calibrate your pedal and configure force limits:

1. Enable automatic calibration by opening the SimHub plugin, navigating to General Settings, and checking **"Step-Loss Recov"**. This sets bit 0 of `stepLossFunctionFlags_u8`.

2. Configure force boundaries in the Curve Settings tab by adjusting the Force Range slider. Set the lower value to your desired **preloadForce** (e.g., 2 kg for light resting pressure) and the upper value to your **maxForce** (e.g., 120 kg for high-power setups).

3. Perform physical calibration by powering on the pedal and allowing the firmware to start. Fully release the pedal so it returns to the mechanical hard stop. The firmware detects this position via `isAtMinPos()` and executes `correctPos()` to zero the stepper count.

4. Verify success by monitoring the serial console output. A successful calibration shows the step count resetting to zero and no step-loss errors when the pedal is at rest.

## Summary

- **Enable Step-Loss Recov** in the SimHub General Settings to allow automatic calibration via `stepLossFunctionFlags_u8` bit 0.
- **Force range limits** are enforced by pedal type: 0–50 kg for basic builds and 0–200 kg for high-power builds.
- **Physical calibration** requires fully releasing the pedal to its mechanical stop, triggering `isAtMinPos()` and `correctPos()` in [`Firmware_for_V3/PedalFirmware/src/Main.cpp`](https://github.com/chrgri/diy-sim-racing-ffb-pedal/blob/main/Firmware_for_V3/PedalFirmware/src/Main.cpp).
- **preloadForce** and **maxForce** are configured through the SimHub Force Range slider and stored in [`payloadPedalConfig.cs`](https://github.com/chrgri/diy-sim-racing-ffb-pedal/blob/main/payloadPedalConfig.cs).

## Frequently Asked Questions

### How do I verify that automatic calibration is working?

After powering on the pedal, fully release it to the mechanical stop and monitor the serial console. If `stepLossFunctionFlags_u8` bit 0 is enabled, you should observe the firmware detecting the minimum position via `stepper->isAtMinPos()` and executing `stepper->correctPos()` to reset the position counter to zero.

### What is the difference between preloadForce and maxForce?

**preloadForce** defines the minimum force the pedal applies when at rest, creating initial resistance before you press. **maxForce** sets the absolute ceiling for force output during full depression. Both values are stored in the `payloadPedalConfig` structure and transmitted to the ESP32 firmware to bound the stepper motor's torque output.

### Why can't I set the maximum force above 50 kg?

The SimHub plugin restricts the slider maximum based on your selected pedal type in `Settings.table_selected`. If your build uses the basic pedal configuration (type 0), the UI limits `maxForce` to 50 kg as defined in [`CurveTab_PedalForceTravel_Modified.xaml.cs`](https://github.com/chrgri/diy-sim-racing-ffb-pedal/blob/main/CurveTab_PedalForceTravel_Modified.xaml.cs). Switch to the high-power pedal type (type 1) to unlock the 200 kg limit.

### Do I need to recalibrate after firmware updates?

Yes. After flashing new firmware to [`Firmware_for_V3/PedalFirmware/src/Main.cpp`](https://github.com/chrgri/diy-sim-racing-ffb-pedal/blob/main/Firmware_for_V3/PedalFirmware/src/Main.cpp) or [`ESP32/src/Main.cpp`](https://github.com/chrgri/diy-sim-racing-ffb-pedal/blob/main/ESP32/src/Main.cpp), or after manually moving the pedal mechanism during maintenance, perform the physical calibration procedure by fully releasing the pedal to ensure the stepper's zero reference remains accurate.