Remora 1.1.0 + BTT Octopus – jog overshoot and joint following error

More
16 Dec 2025 19:15 #340207 by Chad
Hi,I have been fighting with Remora on a Raspberry Pi for about 3 months now and I am running out of ideas, so I’m asking for some help.Hardware / versions
  • Raspberry Pi: (model + RAM ).
  • BTT Octopus: (exact version, e.g. v1.1, STM32F446).
  • LinuxCNC: version from the official RPi image.
  • Remora: 1.1.0 – STM32 firmware for the Octopus from the 1.1.0 release, LinuxCNC component compiled from 
    remora-1.1.0/LinuxCNC/Components/Remora/remora.c
    .
Why I switched from SKROn SKR 1.4 with Remora 0.1.0 I constantly get “bad SPI payload” and E‑STOP, even after improving the wiring (short cable, ground every second wire, shielded cable, common GND). In that old Remora version there are no 
SPI_clk_div
 / 
PRU_base_freq
 parameters, so I cannot slow down the SPI clock from the LinuxCNC side.Because of that I moved to a BTT Octopus with Remora 1.1.0, which gives me 
SPI_clk_div
 and 
PRU_base_freq
 so I can reduce SPI speed.What happens on the Octopus
  • SPI now looks stable: when I run the heater/wire only (no axis motion) I don’t get any “bad SPI payload” at all.
  • I load the component like this:
loadrt remora SPI_clk_div=128 PRU_base_freq=40000
(Values can be changed, this is just what I’m testing now.)
  • The motors move, in the correct direction, but I have two problems:
  1. Jog incremental overshoot
    In incremental jog (for example 1 mm or 10 mm) when I press the jog “+” button and release it, the axis moves noticeably more than the requested increment.
    It looks like Remora/stepgen continues to output steps for a short time after LinuxCNC has stopped the move.
  2. Joint following error after a few cm of travel
    With conservative parameters (see JOINT_0 below) the axis can travel a few centimetres and then I get a joint following error.
    With SKR + Remora 0.1.0, using the same HAL/INI values for SCALE, acceleration, max velocity and FERROR, I never had following errors – only the “bad SPI payload” issue.
Current 
[JOINT_0]
 section in my INI
[JOINT_0] TYPE = LINEAR HOME = 0 HOME_OFFSET = -10 MIN_LIMIT = -0.001 MAX_LIMIT = 450 MAX_VELOCITY = 10 MAX_ACCELERATION = 200 STEPGEN_MAXACCEL = 300 SCALE = (current value – was 50 originally) FERROR = 50 MIN_FERROR = 20 HOME_SEARCH_VEL = -1.5 HOME_LATCH_VEL = -0.5 HOME_IGNORE_LIMITS = YES HOME_SEQUENCE = 0
Relevant HAL fragment (Octopus / Remora connection)
loadrt remora SPI_clk_div=128 PRU_base_freq=40000 # add remora and motion functions to threads addf remora.read servo-thread addf motion-command-handler servo-thread addf motion-controller servo-thread addf remora.update-freq servo-thread addf remora.write servo-thread # --- Joint 0 (X) --- setp remora.joint.0.scale [JOINT_0]SCALE setp remora.joint.0.maxaccel [JOINT_0]STEPGEN_MAXACCEL net xpos-cmd <= joint.0.motor-pos-cmd => remora.joint.0.pos-cmd net xpos-fb <= remora.joint.0.pos-fb => joint.0.motor-pos-fb net j0enable <= joint.0.amp-enable-out => remora.joint.0.enable
(If anything in this mapping looks obviously wrong, please point it out.)What I have already tried
  • Reduced 
    MAX_VELOCITY
    MAX_ACCELERATION
     and 
    STEPGEN_MAXACCEL
     a lot and increased 
    FERROR
    /
    MIN_FERROR
    . This delays the following error but does not remove it.
  • Tried to tune 
    SCALE
     using G‑code (G91 / G0 X100 and measuring real travel). Even with reasonable SCALE values I still see overshoot in incremental jog: the axis moves clearly more than the selected increment.
  • On SKR 1.4 with old Remora 0.1.0, with the same mechanical setup and same SCALE / accel / maxvel / FERROR, jogging and running G‑code worked fine (no following errors, no overshoot). The only issue there is the fixed, too‑fast SPI that causes “bad SPI payload”.
Questions
  1. Is this kind of jog overshoot in incremental mode a known configuration issue with Remora 1.1.0 + Octopus (for example related to PRU_base_freq, servo thread period, or some Remora parameter), or is it more likely that I have a clear mistake in my HAL/INI?
  2. What SPI / PRU settings do people successfully use on a BTT Octopus with Remora 1.x? Is 
    SPI_clk_div=128
     and 
    PRU_base_freq=40000
     reasonable, or should I change these?
  3. Does anyone have a working LinuxCNC config (INI/HAL) for Remora 1.1.0 + Octopus in plain step/dir mode and would be willing to share the relevant 
    loadrt remora
     line and joint settings?
  4. Are there any STM32/Octopus‑specific considerations in Remora (different expectations for SCALE, FERROR, etc.) when migrating from an LPC/SKR setup?
My main goals are:
  • to get rid of the jog overshoot in incremental mode,
  • to choose sane parameters so joint following error does not appear every few centimetres at reasonable speeds.
Any hints, working examples, or “known good” values for an Octopus setup would be very much appreciated.

my octopus config.txt:
{
  "Board": "BIGTREETECH OCTOPUS",
  "Modules": [
    { "Thread": "Servo", "Type": "Reset Pin", "Comment": "Reset pin", "Pin": "PC_15" },
    { "Thread": "Base", "Type": "SPI", "Comment": "SPI interface to Raspberry Pi", "CS Pin": "PA_4" },

    { "Thread": "Base", "Type": "Stepgen", "Comment": "X - Joint 0 stepgen", "Joint Number": 0, "Step Pin": "PF_13", "Direction Pin": "PF_12", "Enable Pin": "PF_14" },
    { "Thread": "Base", "Type": "Stepgen", "Comment": "Y - Joint 1 stepgen", "Joint Number": 1, "Step Pin": "PG_0", "Direction Pin": "PG_1", "Enable Pin": "PF_15" },
    { "Thread": "Base", "Type": "Stepgen", "Comment": "U - Joint 2 stepgen", "Joint Number": 2, "Step Pin": "PF_11", "Direction Pin": "PG_3", "Enable Pin": "PG_5" },
    { "Thread": "Base", "Type": "Stepgen", "Comment": "V - Joint 3 stepgen", "Joint Number": 3, "Step Pin": "PG_4", "Direction Pin": "PC_1", "Enable Pin": "PA_0" },
    { "Thread": "Base", "Type": "Stepgen", "Comment": "B - Joint 4 stepgen", "Joint Number": 4, "Step Pin": "PF_9", "Direction Pin": "PF_10", "Enable Pin": "PG_2" },


{
    "Thread": "Servo",
    "Type": "Digital Pin",
            "Comment":                      "X limit",
            "Pin":                          "PG_6",
            "Mode":                         "Input",
            "Data Bit":                     0
    },



{
    "Thread": "Servo",
    "Type": "Digital Pin",
            "Comment":                      "Y limit",
            "Pin":                          "PG_9",
            "Mode":                         "Input",
            "Data Bit":                     1
    },

{
    "Thread": "Servo",
    "Type": "Digital Pin",
            "Comment":                      "U limit",
            "Pin":                          "PG_10",
            "Mode":                         "Input",
            "Data Bit":                     2
    },
{
    "Thread": "Servo",
    "Type": "Digital Pin",
            "Comment":                      "V limit",
            "Pin":                          "PG_11",
            "Mode":                         "Input",
            "Data Bit":                     3
    },

{
    "Thread": "Servo",
    "Type": "Digital Pin",
            "Comment":                      "B limit",
            "Pin":                          "PG_12",
            "Mode":                         "Input",
            "Data Bit":                     4
    },

 
 {
    "Thread": "Servo",
    "Type": "PWM",
            "Comment":                      "PWM for heating",
            "SP[i]":                        5,
            "PWM Pin":                      "PA_1",
            "PWM Max":                      256,
            "Hardware PWM":                 "True",
            "Variable Freq":                "True",
            "Period SP[i]":                  1,
            "Period us":                    500
    }
  ]
}


my .ini file:
[EMC]
MACHINE = Remora-XYUV
DEBUG = 0
VERSION = 1.1

[DISPLAY]
DISPLAY = axis
EDITOR = gedit
FOAM = 1
GEOMETRY = XY;UV
POSITION_OFFSET = RELATIVE
POSITION_FEEDBACK = ACTUAL
ARCDIVISION = 64
GRIDS = 10mm 20mm 50mm 100mm
MAX_FEED_OVERRIDE = 1.2
MIN_SPINDLE_OVERRIDE = 0.5
MAX_SPINDLE_OVERRIDE = 1.2
DEFAULT_LINEAR_VELOCITY = 2.50
MIN_LINEAR_VELOCITY = 0
MAX_LINEAR_VELOCITY = 25.00
DEFAULT_ANGULAR_VELOCITY = 36.00
MIN_ANGULAR_VELOCITY = 0
MAX_ANGULAR_VELOCITY = 45.00
INTRO_GRAPHIC = linuxcnc.gif
INTRO_TIME = 5
PROGRAM_PREFIX = ~/linuxcnc/nc_files
OPEN_FILE = ./foam.ngc
INCREMENTS = 5mm 1mm .5mm .1mm .05mm .01mm .005mm

[KINS]
JOINTS = 5
KINEMATICS = trivkins coordinates=XYUVB

[FILTER]
PROGRAM_EXTENSION = .py Python Script
py = python

[TASK]
TASK = milltask
CYCLE_TIME = 0.010

[RS274NGC]
PARAMETER_FILE = linuxcnc.var

[EMCMOT]
EMCMOT = motmod
COMM_TIMEOUT = 1.0
COMM_WAIT = 0.010
BASE_PERIOD = 100000
SERVO_PERIOD = 1000000

[HAL]
HALFILE = remora-xyuvb.hal
POSTGUI_HALFILE = postgui_call_list.hal

[TRAJ]
AXES = 5
COORDINATES = X Y U V B
LINEAR_UNITS = mm
ANGULAR_UNITS = degree
DEFAULT_LINEAR_VELOCITY = 2.50
MAX_LINEAR_VELOCITY = 25.00
NO_FORCE_HOMING = 1

[EMCIO]
EMCIO = io
CYCLE_TIME = 0.100
TOOL_TABLE = tool.tbl
EXTERNAL_OUTPUT_0 = motion.analog-out-00

[AXIS_X]
MAX_VELOCITY = 23.75
MAX_ACCELERATION = 750.0
MIN_LIMIT = 10
MAX_LIMIT = 450

[JOINT_0]
TYPE = LINEAR
HOME = 0
HOME_OFFSET = -10
MIN_LIMIT = -0.001
MAX_LIMIT = 450
MAX_VELOCITY = 23.75
MAX_ACCELERATION = 750.0
STEPGEN_MAXACCEL = 937.5
SCALE = 50
FERROR = 1
MIN_FERROR = .25
HOME_OFFSET = 0.000
HOME_SEARCH_VEL = -1.5
HOME_LATCH_VEL = -0.5
HOME_IGNORE_LIMITS = YES
HOME_SEQUENCE = 0

[AXIS_Y]
MAX_VELOCITY = 23.75
MAX_ACCELERATION = 750.0
MIN_LIMIT = -0.001
MAX_LIMIT = 200.0

[JOINT_1]
TYPE = LINEAR
HOME = 0
HOME_OFFSET = -10
MIN_LIMIT = -0.001
MAX_LIMIT = 200.0
MAX_VELOCITY = 23.75
MAX_ACCELERATION = 750.0
STEPGEN_MAXACCEL = 937.5
SCALE = -50
FERROR = 1
MIN_FERROR = .25
HOME_OFFSET = 0.000
HOME_SEARCH_VEL = -1.5
HOME_LATCH_VEL = -0.5
HOME_IGNORE_LIMITS = YES
HOME_SEQUENCE = 1

[AXIS_U]
MAX_VELOCITY = 23.75
MAX_ACCELERATION = 750.0
MIN_LIMIT = 10
MAX_LIMIT = 450

[JOINT_2]
TYPE = LINEAR
HOME = 0
HOME_OFFSET = -10
MIN_LIMIT = -0.001
MAX_LIMIT = 450
MAX_VELOCITY = 23.75
MAX_ACCELERATION = 750.0
STEPGEN_MAXACCEL = 937.5
SCALE = -50
FERROR = 1
MIN_FERROR = .25
HOME_OFFSET = 0.000
HOME_SEARCH_VEL = -1.5
HOME_LATCH_VEL = -0.5
HOME_IGNORE_LIMITS = YES
HOME_SEQUENCE = 0

[AXIS_V]
MAX_VELOCITY = 23.75
MAX_ACCELERATION = 750.0
MIN_LIMIT = -0.001
MAX_LIMIT = 200.0

[JOINT_3]
TYPE = LINEAR
HOME = 0
HOME_OFFSET = -10
MIN_LIMIT = -0.001
MAX_LIMIT = 200.0
MAX_VELOCITY = 23.75
MAX_ACCELERATION = 750.0
STEPGEN_MAXACCEL = 937.5
SCALE = -50
FERROR = 1
MIN_FERROR = .25
HOME_OFFSET = 0.000
HOME_SEARCH_VEL = -1.5
HOME_LATCH_VEL = -0.5
HOME_IGNORE_LIMITS = YES
HOME_SEQUENCE = 1

[AXIS_B]
MAX_VELOCITY = 23.75
MAX_ACCELERATION = 750.0
MIN_LIMIT = -0.001
MAX_LIMIT = 200.0

[JOINT_4]
TYPE = LINEAR
HOME = 0
HOME_OFFSET = 1
MIN_LIMIT = -0.001
MAX_LIMIT = 200.0
MAX_VELOCITY = 23.75
# MAX_ACCELERATION = 750.0
MAX_ACCELERATION = 500.0
# STEPGEN_MAXACCEL = 937.5
STEPGEN_MAXACCEL = 537.5
SCALE = 50
FERROR = 1
MIN_FERROR = .25
HOME_OFFSET = 0.000
HOME_SEARCH_VEL = 1
HOME_LATCH_VEL = 0.1
HOME_IGNORE_LIMITS = YES
HOME_SEQUENCE = 2

my .hal file:
# --- load the realtime components
loadrt [KINS]KINEMATICS
loadrt [EMCMOT]EMCMOT base_period_nsec=[EMCMOT]BASE_PERIOD servo_period_nsec=[EMCMOT]SERVO_PERIOD num_joints=5

loadrt remora

# --- estop loopback, SPI comms enable and feedback
net user-enable-out      <= iocontrol.0.user-enable-out        => remora.SPI-enable
net user-request-enable  <= iocontrol.0.user-request-enable    => remora.SPI-reset
net remora-status        <= remora.SPI-status                  => iocontrol.0.emc-enable-in

# --- add the remora and motion functions to threads
addf remora.read servo-thread
addf motion-command-handler servo-thread
addf motion-controller servo-thread
addf remora.update-freq servo-thread
addf remora.write servo-thread

# ------- Joint 0 (X / Tower 1) -------
setp remora.joint.0.scale         [JOINT_0]SCALE
setp remora.joint.0.maxaccel      [JOINT_0]STEPGEN_MAXACCEL

net xpos-cmd      <= joint.0.motor-pos-cmd  => remora.joint.0.pos-cmd  
net j0pos-fb      <= remora.joint.0.pos-fb  => joint.0.motor-pos-fb
net j0enable      <= joint.0.amp-enable-out => remora.joint.0.enable
net X-stop        remora.input.0          => joint.0.home-sw-in joint.0.neg-lim-sw-in joint.0.pos-lim-sw-in

# ------- Joint 1 (Y / Tower 1) -------
setp remora.joint.1.scale         [JOINT_1]SCALE
setp remora.joint.1.maxaccel      [JOINT_1]STEPGEN_MAXACCEL

net ypos-cmd      <= joint.1.motor-pos-cmd  => remora.joint.1.pos-cmd
net j1pos-fb      <= remora.joint.1.pos-fb  => joint.1.motor-pos-fb 
net j1enable      <= joint.1.amp-enable-out => remora.joint.1.enable
net Y-min         remora.input.1            => joint.1.home-sw-in joint.1.neg-lim-sw-in joint.1.pos-lim-sw-in

# ------- Joint 2 (U / Tower 2) -------
setp remora.joint.2.scale         [JOINT_2]SCALE
setp remora.joint.2.maxaccel      [JOINT_2]STEPGEN_MAXACCEL

net upos-cmd      <= joint.2.motor-pos-cmd  => remora.joint.2.pos-cmd
net j2pos-fb      <= remora.joint.2.pos-fb  => joint.2.motor-pos-fb
net j2enable      <= joint.2.amp-enable-out => remora.joint.2.enable
net U-min         remora.input.2            => joint.2.home-sw-in joint.2.neg-lim-sw-in joint.2.pos-lim-sw-in

# ------- Joint 3 (V / Tower 2) -------
setp remora.joint.3.scale         [JOINT_3]SCALE
setp remora.joint.3.maxaccel      [JOINT_3]STEPGEN_MAXACCEL

net vpos-cmd      <= joint.3.motor-pos-cmd  => remora.joint.3.pos-cmd
net j3pos-fb      <= remora.joint.3.pos-fb  => joint.3.motor-pos-fb
net j3enable      <= joint.3.amp-enable-out => remora.joint.3.enable
net V-min         remora.input.3            => joint.3.home-sw-in joint.3.neg-lim-sw-in joint.3.pos-lim-sw-in

# ------- Joint 4 (B / Rotary Table) -------
setp remora.joint.4.scale         [JOINT_4]SCALE
setp remora.joint.4.maxaccel      [JOINT_4]STEPGEN_MAXACCEL

net bpos-cmd      <= joint.4.motor-pos-cmd  => remora.joint.4.pos-cmd
net j4pos-fb      <= remora.joint.4.pos-fb  => joint.4.motor-pos-fb
net j4enable      <= joint.4.amp-enable-out => remora.joint.4.enable
net B-min         remora.input.4            => joint.4.home-sw-in joint.4.neg-lim-sw-in joint.4.pos-lim-sw-in

net heat_pwm motion.analog-out-00 => remora.SP.5

Please Log in or Create an account to join the conversation.

  • tommylight
  • tommylight's Avatar
  • Away
  • Moderator
  • Moderator
More
16 Dec 2025 23:38 #340218 by tommylight
Moved to " Computers and Hardware".
Thank you.
The following user(s) said Thank You: Chad

Please Log in or Create an account to join the conversation.

More
17 Dec 2025 20:23 #340253 by Cena
Are you using a MOSFET to heat the wire from the SKR? If so, I suggest reducing the PWM duty cycle and seeing what happens. First of all, try connecting the resistance wire directly to the power supply — reminder: this might help — and check whether the “Bad SPI Payload” messages still occur. You may also want to consider powering the resistance wire from a completely separate power source.

Please Log in or Create an account to join the conversation.

Time to create page: 0.059 seconds
Powered by Kunena Forum