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

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, 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:

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:

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 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 at lines 32–38:

// 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, 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 at lines 66–68, the slider values update the configuration structure:

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:

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.
  • preloadForce and maxForce are configured through the SimHub Force Range slider and stored in 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. 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 or 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.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →