The setup of the limit switches in FluidNC is very flexible. This allows it to be both feature rich and allows for very low input pin count. It supports basic axes as well as ganged axes with or without squaring. Some keys are under the homing: group for the axis and some are under the motor<0 or 1>: group.
An IO pin can only be used once. You can use parallel or series wiring for multiple switches, but you can never assign the input to more than one item in your config file.
You can place limit switches at either or both the positive or negative ends of travel. The positive end of travel is the end you move towards when the axis location is increasing. If you move from X0 to X10, you are moving in the positive direction.
Typically the negative end of the X axis is on the left side and the positive end is on the right side. The positive end of the Z axis is the top.
You can assign switches to the ends with these key words.
limit_neg_pin:
limit_pos_pin:
limit_all_pin:
The limit_all_pin:
is used when a switch will be placed at both ends, but wired to one input pin. These switches would be wired in series or parallel depending on the swithc type. If an limit_all_pin:
is triggered, FluidNC will not know which end was touch. This is OK for all scenarios except if a switch is triggered before homing. If does not know which way to move to clear the switch. You must manaully clear the switch before homine.
Typically you can use...
Typically you do not use an all switch with other switches.
Each axis is inpdependant and you can choose the best arrangement for that axis.
These features control whether you can move the axis past its endpoints. You can use neither, either or both of these features.
Hard limits use switches to stop the motion when you activate a limit switch. Ideally you have switches at both ends. If it hits a switch motion is immediately stopped, an alarm is given and accurate position is assumed to be lost. You must rehome. Since this feature is controlled by switches this is defined at the same level as the switches. Hard limits alarms will not occur during homing.
Soft limits are determined by the range of motion. If you send a command that would send it beyond the range it blocks that command. It does a safe stop and position is not lost. You should home the machine, so the machine accurately knows where it is. The soft limit range of each axis is shown in the startup messages. These values are in machine coordinates, not work coordinates. Most gcode uses work coordinates. If you are getting unexpected soft limit errors, check your work offsets.
[MSG:INFO: Axis X (0.000,300.000)]
You can view the real time switch status in a test mode by sending the $limits
command. The status of the switches will be displayed on the serial console. Activate switches and you should see it in the reporting. It uses lower case for motor0 and upper case for motor1. If you activate a limit_all_pin: switch, it will report report for a positive and negative end. Send !
to exit this mode and return to normal control mode.
The best way to test the switches is to slowly push and release each switch individually. Watch the status being displayed. Be sure to give time for each update of of the display. You should see a change in the status when you push and release each switch.
It will look like this:
$limits
Homing Axes: xyz
Limit Axes: xyz
PosLimitPins NegLimitPins Probe
: x x
: x X
Here is one with explanations added:
$limits (The command to start the reporting)
Homing Axes: xyz (Your config file has a homing section for motors x,y, & z)
Limit Axes: xyz (Axes x,y, & z have limit switch pins defined in the config file)
PosLimitPins NegLimitPins Probe (A header for the reporting below it)
: (No switches are currently active)
: x x (motor0 has a positive x and negative x switch active. Could be an all switch)
: x X (motor0 and motor1 [upper case] have positive switches active)
: (No switches active)
: P (Probe Switch is active)
! (The command to stop the recording)
Axis squaring uses 2 homing switches to make sure the axis is squared during homing. It requires 2 motors and a separate switch input for each side. If it sees this in the config file, squaring will be used. This enables a stress free method. This means no side will move without the other if it does not have to. If your axis starts out square, it will never be pulled out of square (stressed) during the squaring.
The above method assumes your switches are mounted squarely. That is definitely the ideal setup. If this is not the case, you can use pulloff_mm: settings in the config file to compensate for this. This is the amount the motor reverses after touching the switch. By using different values for each motor, you can compensate for misaligned switches.
It is very important that you do not mix up the switches and motors. Motor0 must activate its switches and Motor1 must activate its switches or you will get crashes.
It is recommended that you set stepping/idle_ms: 255. This will prevent to the motors from disabling in the idle state. Machines that need squaring tend to go out of square when the motors disable.
You can place a switch at each end of the axis and wire them both to the same input. You would wire them is series for and N.C. setup or in parallel for a N.O. setup. You would define the input as a limit_all_pin:
.
This has one disadvantage with homing. If a limit switch is touching before homing, FluidNC will do a small move away from the switch to deactive it and then attempt to home. With a
limit_all_pin:
, FluidNC does not know which end is touching, so it does not know what direction to move to clear the switch. If it moves the wrong way, it could damage something. You must manually move the axis to clear the switch before homing.
x:
motor0:
limit_neg_pin: gpio:2
x:
motor0:
limit_neg_pin: gpio:2
limit_pos_pin: gpio:2
x:
motor0:
limit_neg: gpio:2
motor1:
limit_neg: gpio:3
x:
motor0:
limit_neg_pin: gpio:2
limit_pos_pin: gpio:3
motor1:
limit_neg_pin: gpio:4
limit_pos_pin: gpio:5
x:
motor0:
limit_all_pin: gpio:2
motor1:
limit_neg_pin: gpio:4
limit_pos_pin: gpio:5
This is supported, but the axis will not auto square during homing. The switch can be placed on either the motor0 or motor1 side.
You can use N.O. or N.C. switches. Both will require a pulling resistor for the open state. The closed state has lower impedance because the open state uses a resistor to set the voltage and the closed state is a direct connection. This means N.C. is less likely to falsely trigger due to noise during normal operation.
You can get additional feedback by showing the debug messages. This give information for each phase of the homing cycle. If you are requesting suppport for homing problems, please provide this information.
$Message/Level=Debug
ok
$HX
[MSG:DBG: Homing Cycle X]
[MSG:DBG: Homing nextPhase FastApproach]
[MSG:DBG: Starting from 50.000,80.000,50.000]
[MSG:DBG: Planned move to -115.002,80.000,50.000 @ 800.000]
[MSG:DBG: X Neg Limit 1]
[MSG:DBG: Homing limited X]
[MSG:DBG: Homing nextPhase Pulloff0]
[MSG:DBG: Starting from 36.042,80.000,50.000]
[MSG:DBG: Planned move to 39.042,80.000,50.000 @ 600.000]
[MSG:DBG: CycleStop Pulloff0]
[MSG:INFO: ALARM: Homing Fail Pulloff]
You can also see debug information if you manually activate the switches.
[MSG:DBG: X Neg Limit 1]
[MSG:DBG: Limit switch tripped for X motor 0]
[MSG:DBG: X Neg Limit 0]
If you get strange behavior, you might need pull up or pull down resistors. External ones in the 3k-10k range work well. You can also apply ESP32 ones to many pins in firmware with the :pu or :pd pin attribute. It is a good practice to put these in your config file even if you have external ones, so people reading your file will know.
If the switches are reporting backwards from what you want, you need to change the active state attribute of the switch (:low vs :high). If you don't have an active state attribute, it assumes :high
Before debugging any homing direction issues, make sure the directions are working with normal moves and jogs.
Homing direction is determined by config values like axes/<axis>/homing/positive_direction:
If that value is true, you must have a limit_pos_pin:
defined for at least motor0.
If you get an error like this, it means the homing switch is active and did not deactivate when the machine tried to back off it. This could mean the switch is stuck in the active state, the machine did not pull off far enough or the machine is not actually moving when pulling off.
With this issue the machine will try to pull away from the machine regardless if it is touching the switch. If you are using a limit_all_pin
you will get an ambiguous limit switch alarm.
[MSG:INFO: ALARM: Homing Fail Pulloff]
ALARM:8
If you have more than one axis on a homing cycle, like X and Y, both axes will stop when the first axis touches, then the untouched axis will continue until it touches the switch.