Skip to content

AD5X IFS Serial Protocol

GhostTypes edited this page Sep 1, 2026 · 7 revisions

AD5X IFS Serial Protocol

Overview

The Intelligent Filament Station (IFS) on the AD5X talks to the main printer controller over a dedicated UART. This document describes the hardware interface and the complete command protocol. It covers IFS firmware 3.0.1, 3.0.6, and 3.0.7.

Hardware Interface

Property Value
Device /dev/ttyS4
Baud Rate 115200
Data Bits 8
Parity None
Stop Bits 1
Flow Control None

Wire Conventions

Opcode echo: Every reply starts with F<n> ok. and repeats the request opcode. Match a reply to its request by this prefix. Discard a stale or unsolicited line instead of parsing it as the latest answer.

Line framing: End every command with CR LF. The module acts on a line only after it receives CR or LF. A line that grows past 94 characters ends without a terminator. Do not rely on this. A semicolon starts a comment. The module ignores all text after a semicolon on the same line.

Send each command in one write: The module collects bytes that arrive in one burst. It drops a burst that holds only one or two bytes. Write the full command, the space, and CR LF with one call.

Host write pattern: The stock host writes the command, one space, and CR LF in a single write. It then waits 100 ms before it listens. It waits up to 2 s for the reply. The trailing space has no meaning. A driver does not need it.

Stray bytes: Extra bytes that arrive inside a command burst cause no harm. The module scans the line for the opcode letter and parameter letters. It ignores any other byte. No firmware version needs a trailing 0xFF byte. A lone byte sent after CR LF is dropped, because it forms a burst of one byte.

Reply framing: A reply carries no terminator. No CR and no LF appears in the reply. The reply ends when the module goes quiet. Do not read until a newline. Read until the port is silent. The first byte arrives about 105 ms after the command.

F21 is the only multi-line reply: It sends three lines with CR LF between them: the F21 ok. line, then the silk: line, then the stall: line. Read the whole reply. A one-line read leaves two lines in the buffer. They then answer the next two requests.

One reader only: The reply has no terminator, so two readers on the port corrupt each other quietly. Route every command and every poll through one reader.

Command Reference

F10 — Feed Filament

Feed filament from a slot toward the nozzle. The IFS reports the channel as feeding.

Format: F10 C<slot> L<length> S<speed>

Parameter Description
C<slot> Slot number (1–4)
L<length> Feed length in mm
S<speed> Feed speed in mm/min

Example: F10 C2 L20 S600 → F10 ok. FFS channel 2 feeding.

The IFS sets FFS_state to 10, 21, 32, or 43 for slots 1 to 4. The state then changes as the feed advances. A status query right after the command can show 22 for slot 2.

Replies:

Reply Condition
F10 ok. FFS channel <n> feeding. The feed started
F10 ok. FFS not ready. FFS_state is not 5
F10 ok. FFS channel not exist. The slot number is not 1–4
F10 ok. No channel selected. The command has no C parameter

Precondition, IFS 3.0.6: FFS_state must equal 5. If it does not, the IFS refuses the command. A driver can use this refusal as a free precondition check.

IFS 3.0.7: F10 runs even when no channel is clamped. Do not rely on the refusal as a safety check.

Host usage: The FourToOne panel sends F10 C<slot> L1000 S<speed>. It clamps the slot with F24 first, then polls F13 field 3 until it equals 5. It waits 1 second between polls.

F11 — Exit Filament

Move filament out of the station. This command is the reverse of F10. The IFS reports the channel as exiting.

Format: F11 C<slot> L<length> S<speed>

The parameters match F10. The IFS negates the length value, so the motor runs in reverse.

Example: F11 C2 L20 S600 → F11 ok. FFS channel 2 exiting.

The IFS sets FFS_state to 14, 25, 36, or 47 for slots 1 to 4. The replies match the F10 set, with exiting in place of feeding.

Note: The IFS accepts only the C, L, and S parameters for F11. Do not send a color code.

Load Operation Flow (host):

  1. Send F11 C<slot> L<length> S<speed>
  2. Poll F13 to monitor progress
  3. If field 3 returns 0x7F → send F15 to continue
  4. Wait for field 3 = 5 (complete)
  5. Check filament sensor
  6. Send F112 to stop the IFS motors

Unload Operation Flow (host):

  1. Send F11 C<slot> L<length> S<speed>
  2. Send M400 (wait for motion buffer clear)
  3. Poll F13 to monitor progress
  4. If field 3 returns 0x7F → send F15 to continue
  5. Wait for field 3 = 5 (complete)
  6. Verify the slot bit is clear in F13 field 5 (silk_state)

F112 — Halt Movement

Stop all IFS motor movement at once. The command also sets FFS_state to 5 (idle). It stops a feed or an exit in progress.

Format: F112

Replies:

IFS firmware Reply Meaning
3.0.6 F112 ok. The halt always runs
3.0.7 F112 ok. yes. The halt ran, FFS_state is now 5
3.0.7 F112 ok. error. A driver error is pending, the halt did not run

The IFS error latch:

The IFS keeps an internal error latch. No wire command can read, set, or clear it. The latch marks a motor driver error.

If a driver fails, the IFS stops all motors and resets both drivers. It sets FFS_state to 1 and sets the latch. The state machine then walks through states 1 to 4. At state 4, it reads the latch. If the latch is set, it sets FFS_state to 0x7F and clears the latch in the same step. This walk takes less than one second. The first visible sign is FFS_state 0x7F in the F13 reply. The latch is already clear at that point.

F15 stops the TMC motion and sets FFS_state to 5. It does not touch the latch.

Firmware 3.0.6 and 3.0.7 handle the latch in the same way. Only F112 differs. On 3.0.6, F112 always halts. On 3.0.7, F112 halts only when the latch is clear. If the latch is set, it replies F112 ok. error. and does not halt. The error routine has already stopped the motors.

If this happens, poll F13. If FFS_state is 0x7F, send F15. Send F112 again if needed.

The reply selection is not yet verified on hardware. Match the F112 ok prefix, not the full string. A driver that matches the exact 3.0.6 reply fails on 3.0.7.

Usage: The printer sends F112 when an error occurs during a load or an unload. The FourToOne panel also sends it from a debug button. This command does not finalize a load. It has no link to F13 field 3 = 5.

F13 — Query IFS Status

Returns the complete IFS state. This is the primary polling command.

Format: F13

Wire Reply:

F13 ok. FFS_state: <d> silk_state: <d> chan: <d> ffs_channels_insert: <d> stall_state: <d> jinsi_GCONF: <8 hex digits> qiehuan_GCONF: <8 hex digits>

Fields:

Field Meaning
FFS_state State machine state. See the status codes below
silk_state Filament presence bitmask (bits 0–3 = slots 1–4)
chan Active channel
ffs_channels_insert Pending thread request per slot. The module sets a bit when filament enters the slot. F23 clears the bit of that slot
stall_state Odometer movement bitmask (bits 0–3 = slots 1–4). A set bit means the roller of that slot turns
jinsi_GCONF TMC GCONF register of the feed driver, 4 bytes hex
qiehuan_GCONF TMC GCONF register of the switch driver, 4 bytes hex

Field Indexes: Split the reply on spaces and colons to get numbered sections. Use this mapping:

Section Field
3 FFS_state
5 silk_state
7 chan
9 ffs_channels_insert
11 stall_state

FFS_state — Status Codes:

Code Meaning
5 Idle, or the last operation is complete
0x7F (127) The operation needs F15 to continue
0x7E (126) Error state

silk_state — Filament Presence Bitmask:

Bit Slot
0 Slot 1
1 Slot 2
2 Slot 3
3 Slot 4

stall_state — Stall Detection:

The module checks each odometer roller about 20 times per second. It sets the bit of a slot when its roller turns. It clears the bit when the roller stays static. If the bit of the active slot stays 0 during a print, a stall counter grows on the host. After 200 consecutive reads with no movement, error E0109 fires and the print pauses.

Polling Intervals:

State Interval
Idle 200 ms
Printing 1000 ms
IFS offline 1000 ms (with retry)

Special: F13 bypasses the IFS online check. Send it even when the IFS status flag is false.

F15 — Return to Idle

Force the IFS back to the idle state. The command stops the TMC motion and sets FFS_state to 5.

Format: F15

The IFS ignores any text after the opcode. The stock host sends F15, F15 C, and F15 L1500 S<speed> at different call sites. All three have the same effect.

Recovery use: Send F15 when F13 field 3 returns 0x7F. The IFS returns to idle. Then resend the command that failed (F11, F24, or F39).

F19 — IFS Version/Probe (Heartbeat)

Query IFS firmware version and verify the module is alive.

Format: F19

Response: ok ... version:<version_string>

Special Properties:

  • Bypasses IFS online check (like F13)
  • Used after firmware update to verify new firmware is running
  • Retried up to 3 times after firmware update

F23 — Clear Channel Status

Clear the insert flag of a channel. The flag marks a lane that waits to be threaded. Send F23 after the lane is threaded. F112 and F39 do not clear the flag.

Format: F23 C<slotId>

Parameter Description
C<slotId> Channel number (1–4)

Typically called after load/unload operations, followed by F39 (release channel).

F24 — Clamp Channel

Clamp the filament of a slot. Send this command before a feed, an exit, or a slot change.

Format: F24 C<slot>

Example: F24 C2 → F24 ok. chan 2. — FFS_state 7.

Replies:

Reply Condition
F24 ok. chan <n>. The clamp ran
F24 ok. FFS channel not exist. The slot number is not 1–4
F24 ok. No channel selected. The command has no C parameter

Operation Flow:

  1. Send F24 C<slot>
  2. Poll F13 field 3:
    • 5 → complete, exit
    • 0x7F → send F15 C, re-send F24 C<slot>, reset retry counter
    • 0x7E → error, exit
    • Retry count > 20 → timeout, exit
  3. Otherwise: increment retry, wait 1 s

F37 — Enter Firmware Update Mode

Puts the IFS module into bootloader mode for firmware flashing.

Format: F37

Firmware Update Sequence:

  1. Send F37 to enter bootloader
  2. Close serial port
  3. Execute: /usr/prog/PROGRAM/control/IFSCommand /usr/prog/PROGRAM/control/ifs.hex /dev/ttyS4
  4. Sleep 5 seconds
  5. Reopen serial port
  6. Send F19 (up to 3 retries) to verify IFS is alive
  7. Parse version from response

Recovery: If you send F37 by accident, run the IFS firmware update from the printer screen. The update restores normal operation.

F39 — Release Channel

Release the clamp of a slot. The command does not clear the insert flag. Send F23 for that.

Format: F39 C<slot>

Example: F39 C2 → F39 ok. FFS channel 2 release. — FFS_state 23 for slot 2.

The IFS sets FFS_state to 12, 23, 34, or 45 for slots 1 to 4.

Operation Flow: Same poll flow as F24, with a maximum of 10 retries.

Typical Sequence:

F11 C<slot> L<length> S<speed>   → Load filament
[poll F13 until done]
F23 C<slot>                      → Clear channel status
F39 C<slot>                      → Release channel
[poll F13 until done]

F44 — Query TMC DRV_STATUS

Query the TMC stepper motor driver status register from the IFS module. Diagnostic command shown in Status screen UI.

Format: F44

Response: ok DRV_STATUS:<hex_value>

Only sent when the IFS present flag is true. The firmware displays the raw hex value without parsing individual bits.

F45 — Query TMC GSTAT

Query the TMC stepper motor general status register (GSTAT). Reports over-temperature, short-to-ground, and driver error flags.

Format: F45

Response: ok GSTAT:<hex_value>

Only sent when the IFS present flag is true. The firmware displays the raw hex value without parsing individual bits.

Note on TMC registers: DRV_STATUS and GSTAT are standard Trinamic TMC stepper driver registers (likely TMC2209 or similar). The IFS firmware returns the raw register values — refer to the TMC2209 datasheet for bit-level definitions of these registers.

Diagnostic and Debug Commands

F20 — Ping

Replies only. The command changes nothing on the IFS.

Format: F20

Reply: F20 ok.

Use this command as a keepalive or a safe probe.

F12 — Read Filament Sensor Flags

Format: F12

Reply: F12 ok. <d> <d> <d> <d>

Returns the raw filament sensor flag of each slot. Value 1 means the slot sensor detects filament. F13 builds silk_state from these four flags. The reply lists slot 4 first and slot 1 last.

F14 — Read Odometer Movement Flags

Format: F14

Reply: F14 ok. stall: <d> <d> <d> <d>

Returns one movement flag per slot. Value 1 means the odometer roller of that slot turns. Value 0 means the roller is static. F13 builds stall_state from these four flags. The label stall is inverted. Value 1 means normal movement.

F21 — Read Raw Sensor Values

Format: F21

Reply: F21 ok. silk: <d> <d> <d> <d> stall: <d> <d> <d> <d>

Returns the averaged raw analog reading of each sensor, from 0 to 4095. The first four values are the filament presence sensors. The last four values are the second sensor group. These are live readings, not counters. They update about 20 times per second.

F22 — Read Insert Flags

Format: F22

Reply: F22 ok. ffs_channels_insert: <d>

Returns the insert flags of the channels as one value. This is the same value as section 9 of the F13 reply.

F42 — Set Motor Current

Set the run current of a stepper motor driver. The IFS has two motors. Motor 1 feeds filament. Motor 2 turns the channel selector.

Format: F42 T<motor> I<value>

Parameter Description
T<motor> Motor number. 1 = feeder, 2 = selector
I<value> Run current scale, 0–31. The IFS clamps the value to this range

Reply: F42 ok.stepper_motor: <d> stepper_motor_irun: <d>

The reply echoes the motor and the applied value.

What the value means: The value scales the current that the driver sends to the motor. A higher value gives more torque. It also gives more heat. A value that is too low makes the motor skip steps. A value that is too high overheats the motor and the driver.

Cautions:

  • Send this command only when the IFS is idle. A current change during a move can lose steps.
  • Raise the value in small steps. Test a feed after each change.
  • The stock host does not send F42. The default value is not yet measured on hardware. Read the current value before you change it, and note the original.

Reply parsing note: The reply has no space after ok.. Match the F42 ok prefix, then read the two numbers.

F43 — Reset Motor Drivers

Initialize both stepper motor drivers again.

Format: F43

Reply: F43 ok.

F18 and F30 — Factory Motion Test Commands

F18 forces the module state machine to its re-home state. The module then runs the motor re-home sequence. It replies F18 ok with no period.

F30 D<position> moves the slot selector motor to an absolute position. The module stores the number and steps the selector motor until it reaches that position. It replies F30 ok.

Both commands are factory test tools. They move motors without the normal guards. Do not send them from a driver.

TMC Register Queries

All commands take no parameters. Each returns one raw register value in hex.

Command Register Driver
F41, F50 GCONF 1
F44, F53 DRV_STATUS 1
F45, F51 GSTAT 1
F52 CHOPCONF 1
F54 PWMCONF 1
F60 GCONF 2
F61 GSTAT 2
F62 CHOPCONF 2
F63 DRV_STATUS 2
F64 PWMCONF 2

F40 returns the stall counters: F40 ok.stall count: C1: <d> C2: <d> C3: <d> C4: <d>.

Commands F16, F17, F25–F29, F31–F36, F38, F46–F49, F55–F59, and F65–F111 return no reply. Send only the commands in this document.

Command Summary

Command Purpose Parameters Polls F13
F10 Feed filament (toward nozzle) C<slot> L<length> S<speed> Yes
F11 Exit filament (reverse) C<slot> L<length> S<speed> Yes
F12 Read filament sensor flags (none) No
F112 Halt movement (none) No
F13 Query IFS status (none) N/A
F14 Read odometer movement flags (none) No
F15 Return to idle (none; extra text ignored) No
F18 Force motor re-home (test) (none) No
F19 IFS version/probe (none) No
F20 Ping (none) No
F21 Read raw sensor values (none) No
F22 Read insert flags (none) No
F23 Clear channel status C<slot> (1–4) No
F24 Clamp channel C<slot> Yes (max 20)
F30 Move slot selector to position (test) D<position> No
F37 Enter firmware update mode (none) No
F39 Release channel C<slot> Yes (max 10)
F40 Read stall counters (none) No
F42 Set motor current T<motor> I<value> No
F43 Reset motor drivers (none) No
F41, F44, F45, F50–F54 TMC register query, driver 1 (none) No
F60–F64 TMC register query, driver 2 (none) No

IFS Firmware Version Differences

Topic IFS 3.0.1 IFS 3.0.6 IFS 3.0.7
F112 reply F112 ok. F112 ok. F112 ok. yes. or F112 ok. error.
F10 or F11 on an empty lane Refused with FFS not ready. Refused with FFS not ready. Runs with no channel clamped
F19 version string version: 3.0.1 version: 3.0.6 version: 3.0.7
F54, F64 PWMCONF query Not present Present Present
Serial framing Same as 3.0.6 CR LF lines, burst of 3 bytes minimum Same as 3.0.6

Drivers that depend on the 3.0.6 refusal lose that safety net on 3.0.7. Check the lane state with F13 before you send F10 or F11.

Error Codes

Code Description Trigger
E0100 Channel 1 feeding timeout Slot 1 load timeout
E0101 Channel 2 feeding timeout Slot 2 load timeout
E0102 Channel 3 feeding timeout Slot 3 load timeout
E0103 Channel 4 feeding timeout Slot 4 load timeout
E0104 Channel 1 retracting timeout Slot 1 unload timeout
E0105 Channel 2 retracting timeout Slot 2 unload timeout
E0106 Channel 3 retracting timeout Slot 3 unload timeout
E0107 Channel 4 retracting timeout Slot 4 unload timeout
E0108 Failed to feed filament to extruder Filament sensor timeout
E0109 IFS odometer roller not moving Stall count > 200
E0114 IFS homing error fourInOneLoadFristStep returns 10

Channel Change Sequence

The core filament swap routine (changeChannel) during multi-material printing:

  1. M400 — Wait for all moves to complete
  2. Save current state (crash recovery)
  3. M114 — Get current position
  4. Move nozzle to purge position
  5. doLoadAndUnload() — Physical filament swap (unload old, load new via F11)
  6. Calculate flush volume via getFlushVol()
  7. Run cleanFilamentBox() 1–2 times (2× if flush volume > 400)
  8. Set fan speed: SET_FAN_SPEED FAN=fanM106 SPEED=<value>
  9. Move nozzle back to print position
  10. G92 E0 — Reset extruder position
  11. SDCARD_CLEAR_REFUELLING — Clear refuelling flag

Clone this wiki locally