---
title: Firmware
description: Flash FluidNC onto the control board — one command (`physiclaw flash`) or the manual browser flow — plus the config it loads.
---

PhysiClaw's hardware talks to the computer through the [FluidNC](https://github.com/bdring/FluidNC) firmware: the computer sends [G-code](https://en.wikipedia.org/wiki/G-code) (the GRBL protocol) to drive the motors and switch the solenoid, performing taps, swipes, and other gestures.

## Prerequisites

- [MKS DLC32 V2.1](https://github.com/makerbase-mks/mks-dlc32) control board.
- USB-B to USB-A data cable.
- 12 V 2 A power supply.
- Google Chrome (only for the manual option below).

You can flash FluidNC with a single command, or manually with FluidNC's web installer.

## Command-line flash (recommended)

Connect the board over USB (12 V power on, **stepper motors disconnected**), then run:

```bash
physiclaw flash
```

:::tip
If `physiclaw flash` succeeds, you can skip the steps below.
:::

## Manual flash

<Steps>

1. **Power up the board.** Connect **12 V** power, then connect **USB** to the computer.

2. **Open the installer.** Open the [FluidNC web installer](https://installer.fluidnc.com) in Chrome. The page shows two products — click **Continue** under **FluidNC**.

3. **Connect to the board.** Click **Connect**. A dialog lists available serial ports. Select **USB Serial** and click **Connect**.

4. **Go to Install.** The Home page appears. Click **Install** in the left sidebar.

5. **Select the firmware variant.** Pick the latest version from the dropdown. Three variants appear — select **`noradio`**.

6. **Select the installation type.** Select **fresh-install**.

7. **Confirm.** A confirmation dialog appears. Make sure **Installation speed** is **115200 baud**, then click **Install**.

8. **Wait.** A progress bar appears — wait until it completes.

9. **Installation complete.** A "Done" dialog confirms it. Click **Continue**.

10. **Open the File browser.** The Home page shows a red **"invalid configuration"** warning — this is because the board has firmware but no config yet. Click **File browser** in the left sidebar.

11. **Create the config file.** The File browser prompts you to create one. Click **Create config**; a dialog appears with `config.yaml` pre-filled as the filename. Click **OK**.

12. **Open the Source tab.** The editor opens on the **General** tab. Click the **Source** tab (rightmost).

13. **Paste the config.** Select all the existing text, delete it, and paste the **full contents** of [The config file](#the-config-file) below.

14. **Save.** Click **Save**.

15. **Go to Terminal.** Click **Terminal** in the left sidebar.

16. **Restart the board.** Click the red **Restart** button. The board reboots and prints the startup log.

17. **Verify.** Every message should be **green**, and the last line should read `<Idle|...>` — the firmware flashed and the config loaded successfully.

</Steps>

## The config file

The command-line flash installs this for you; for the manual flash, paste it in step 13. The FluidNC config:

```yaml
# FluidNC config — MKS DLC32 v2.1 — CoreXY + Solenoid
# Comments ONLY on their own lines (FluidNC YAML subset rule)
# Tune: steps_per_mm, max_travel_mm, acceleration, direction pins

board: MKS-DLC32 V2.1
name: PhysiClaw

# I2S bus — hardwired on DLC32 v2.1, do not change
i2so:
  bck_pin: gpio.16
  data_pin: gpio.21
  ws_pin: gpio.17

# I2S_STATIC only — I2S_STREAM causes drift on this board
stepping:
  engine: I2S_STATIC
  idle_ms: 250
  pulse_us: 4
  dir_delay_us: 1
  disable_delay_us: 0

kinematics:
  corexy:

axes:
  shared_stepper_disable_pin: I2SO.0

  x:
    # Tune: (motor_steps x microsteps) / mm_per_rev
    # e.g. 200 x 16 / 40mm (20T GT2) = 80
    steps_per_mm: 80.000
    max_rate_mm_per_min: 10000.000
    acceleration_mm_per_sec2: 1000.000
    # Set max_travel_mm to your actual X travel
    max_travel_mm: 200.000
    soft_limits: false

    motor0:
      hard_limits: false
      stepstick:
        step_pin: I2SO.1
        # Add :low after I2SO.2 if X runs backwards
        direction_pin: I2SO.2:low

  y:
    steps_per_mm: 80.000
    max_rate_mm_per_min: 10000.000
    acceleration_mm_per_sec2: 1000.000
    # Set max_travel_mm to your actual Y travel
    max_travel_mm: 200.000
    soft_limits: false

    motor0:
      hard_limits: false
      stepstick:
        step_pin: I2SO.5
        # Add :low after I2SO.6 if Y runs backwards
        direction_pin: I2SO.6:low

PWM:
  pwm_hz: 1000
  output_pin: gpio.32
  enable_pin: NO_PIN
  direction_pin: NO_PIN
  disable_with_s0: false
  s0_with_disable: true
  spinup_ms: 0
  spindown_ms: 0
  tool_num: 0
  speed_map: 0=0% 1000=100%
  off_on_alarm: true

start:
  must_home: false
```
