Skip to content
Main site

Flashing the control boards

The Raspberry Pi is not the only computer in the G1. Three microcontrollers sit underneath it, each with its own firmware in its own flash memory, and none of them can be reached by writing an SD card.


The panel box holds two Ginger boards and one BigTreeTech board. The two Ginger ones are named on the assembly drawings as Ginger.Extruder and Ginger.Feeding — and the answer to the obvious question is yes:

OctopusGinger.ExtruderGinger.Feeding
Klipper calls it[mcu] — the main one[mcu extruder_board]nothing — Klipper does not know it exists
BoardBigTreeTech Octopus Pro v1.1Ginger PCB + Arduino NanoGinger PCB + Arduino Nano
MCUSTM32H723ATmega328PATmega328P
Firmwareklipper4pelletklipper4pellet, AVR buildG1-AutoFeedingnot Klipper
DrivesMotion, all four NTC thermistors, bed heater output3 zone heater relays (and the 220 V through them), probe servo, part fan, feeder switch, buzzerVacuum relay, hopper level probe, buzzer, LED
WherePanel boxPanel boxPanel box
Link to the PiUSB (USB_2)USB (USB_1)None
Flashed fromThe Pi, over SSHThe Pi, over SSHA computer, over the Nano’s own USB

How to tell the two Klipper MCUs apart in printer.cfg: the Octopus reports as usb-Klipper_stm32h723xx_…, the extruder_board as usb-1a86_…1a86 is the CH340 USB-serial chip on the Nano, not Klipper’s own identifier.

This is the point that catches people out.

Machine → Update Manager updates the Raspberry Pi. It does not flash any board. Pressing UPDATE on the klipper row replaces the Klipper host software on the Pi. The binaries on the Octopus and the extruder_board are untouched, and so is the feeder board, which the Pi cannot even see.

Nor does flashing the SD card. A brand-new card boots and talks to boards still running whatever they were flashed with — see G1OS installation.

That separation is normally invisible, because Ginger’s Klipper version deliberately trails upstream and does not change often. It becomes visible in exactly one way: a host Klipper update that crosses a protocol change, after which Klipper refuses to start and says the MCU firmware is out of date.


SituationWhich boardWhy
You have just updated the softwareOctopusRequired. The update moves the host and leaves the board behind, and the two are meant to match. Flashing is the second half of the update, not a repair — see Updating the printer
Klipper will not start and reports the MCU protocol / version does not match the hostThe board named in the errorThe host moved; the board did not
A board has been physically replaced with a blank oneThe replacementNew silicon, no firmware
The vacuum cycle timing or alarm behaviour must changeFeeder boardThose constants are compiled into the sketch — there is no setting for them anywhere in Mainsail
Ginger support asks you toAs instructed

Everything else — including a board that disappears from STATUS, intermittent dropouts, or a zone that stops heating — is a wiring, USB or configuration problem. Reflashing will not fix it and costs you a working board if it goes wrong.


The procedures below are Ginger’s own — the same steps used when a machine is built: the panel box assembly manual (SA27 §18, and the newer Panelbox §06), the flashing document OP10.5, and the internal electronics notes for how the Octopus is written.

The page is v0 until someone has followed it on a real machine end to end.

Extruder board (extruder_board) — Arduino Nano, Klipper

Section titled “Extruder board (extruder_board) — Arduino Nano, Klipper”

Built and flashed on the Raspberry Pi itself, over SSH. No cable moves and the box does not need opening: the Nano is written down the same USB link Klipper normally uses.

Building it on the printer is not just convenient — it is what makes the firmware match. The binary is compiled from the same klipper checkout the host is running, so the two versions agree by construction.

The awkward part is that Raspberry Pi OS Bookworm dropped the AVR toolchain, so it has to be pulled from the older Buster archive first.

  1. Add the Buster archive. In /etc/apt/sources.list:

    deb http://raspbian.raspberrypi.org/raspbian/ buster main contrib non-free rpi
  2. Pin the AVR packages to it, in /etc/apt/preferences.d/avr-buster:

    Package: avr-libc avrdude binutils-avr gcc-avr
    Pin: release n=buster
    Pin-Priority: 1001

    Pinning matters: without it apt takes the Bookworm versions and the build fails. If apt complains about a missing key, add it with sudo apt-key adv --keyserver keyserver.ubuntu.com --recv-keys [KEY]

  3. Install the toolchain:

    Terminal window
    sudo apt update
    sudo apt install avr-libc avrdude binutils-avr gcc-avr
  4. Clear any previous build. menuconfig keeps your last answers in .config, and the Octopus build uses the same directory — so without this you can silently rebuild with the wrong micro-controller or the wrong options:

    Terminal window
    cd klipper
    make clean
    rm -f .config
  5. Configure the build:

    Terminal window
    make menuconfig

    Select atmega328p as the micro-controller. Under the advanced options, the set that matters is:

    [*] Support micro-controller based ADC (analog to digital)
    [ ] Support communicating with external chips via SPI bus
    [ ] Support communicating with external chips via I2C bus
    [*] Support hardware PWM (pulse width modulation)
    [*] Support GPIO based button reading
    [ ] Support Trinamic stepper motor driver UART communication
    [ ] Support 'neopixel' type LED control
    [ ] Support measuring fan tachometer GPIO pins

    Save and exit.

  6. Compile:

    Terminal window
    make
  7. Find the board:

    Terminal window
    ls /dev/serial/by-id/

    The Nano is the usb-1a86_… entry. The usb-Klipper_stm32h723xx_… one is the Octopus — writing to that path will not end well

  8. Flash it, with that path in place of [path]:

    Terminal window
    avrdude -C /etc/avrdude.conf -v -V -p atmega328p -carduino -P [path] -b115200 -D -U flash:w:out/klipper.elf.hex:i
  9. Verify. The board keeps the same USB serial ID, so printer.cfg needs no editing. Do a firmware restart, then in the console:

    STATUS

    extruder_board must show as connected, with no Unknown command line anywhere in the message. Then toggle FEEDER in the Extrude menu — if the feeder switch responds, buttons.c is in the build and the job is done

Feeder board (Ginger.Feeding) — Arduino Nano, G1-AutoFeeding

Section titled “Feeder board (Ginger.Feeding) — Arduino Nano, G1-AutoFeeding”

Not Klipper, not part of any Klipper update, and not reachable from the Raspberry Pi — there is no USB cable between them. It is flashed from a computer plugged into that Nano’s own USB port, which means opening the panel box.

The repository ships the exact board settings it was built with, in .vscode/arduino.json:

SettingValue
Boardarduino:avr:nano
ProcessorATmega328P (Old Bootloader)cpu=atmega328old, i.e. 57600 baud
SketchG1-AutoFeeding.ino

Open the sketch in the Arduino IDE, pick Arduino Nano with the ATmega328P (Old Bootloader) processor, select the port and upload. It uses no libraries, so it compiles as it stands.

Its whole behaviour is five pins and a handful of constants at the top of the file:

PinConstantRole
D2relayPinSwitches the vacuum pump
D3ledPinLit while the vacuum runs
D4sensorPinCapacitive level probe in the hopper
D9feederPinThe FEEDER enable, arriving from Ginger.Extruder over GCOM
D12buzzerPinAlarm

Changing the feeding timings means editing those constants and re-uploading — there is no way to change them from Mainsail, from the display or from printer.cfg, which is the practical reason this board is ever flashed at all. The timings themselves are in the auto feeding firmware.

The Octopus is not written over its USB link. It is flashed from its own microSD slot: you put firmware.bin on a card, power the board, and the bootloader takes it. Nothing is sent from the Raspberry Pi.

  1. Get the firmware. Download Ginger’s build — this is the binary used in production, so you do not have to compile anything:

    firmware.bin — Ginger’s build of 9 September 2026, 44,660 bytes

    SHA-256 faef9001c45bc68969589a7145114a4925ef534d43eae46708add4ec7fed88c0, if you want to check what you downloaded is what was published. The Klipper version is not readable from the file; the board reports it after flashing, and that is the copy to trust

    Keep the name exactly as it downloads. The bootloader looks for firmware.bin and ignores anything else

    Or build it yourself

    On the Pi over SSH, in klipper, run make menuconfig with the options fixed by the board — they are stated in Ginger’s own board config (config/generic-bigtreetech-octopus-pro-v1.1.cfg):

    • Enable low-level configuration options
    • Micro-controller: STMicroelectronics STM32, model STM32H723
    • Bootloader offset: 128KiB bootloader
    • Clock reference: 25 MHz crystal

    Save, exit, then make. Rename the resulting out/klipper.bin to firmware.bin.

    Prefer the download unless you have a reason not to: a hand-built binary is the one thing here nobody can check for you afterwards.

  2. Put it on the card. Format a microSD FAT32 and copy firmware.bin across on its own — one file, nothing else

  3. Insert and power. Ease the cable loom aside, put the card in the slot, and power the printer for a few seconds. The bootloader reads the card and writes the firmware

  4. Check the card. Power off, remove it and look at it on your computer. firmware.bin should be gone — renamed, typically to FIRMWARE.CUR. That is the confirmation it was flashed; if the file is still sitting there untouched, nothing happened

  5. Verify on the machine. Power up and run STATUS in the console: mcu should be connected and the version mismatch error gone

The card was never read. In order of likelihood: not FAT32, more than one file on it, the card is too large or too new for the bootloader, or the board has no bootloader.

For that last case — a new or bricked board — the same mechanism installs one: put bootloader.hex on a blank card (Ginger’s dedicated SD carries a .bat that restores it automatically), power the board about 10 seconds, then check the file has disappeared. Then write the firmware as above.