Before you start be sure your startup messages are free of all errors and warnings. See the troubleshooting guide for help with that.
Start with very conservative values in the config file - slow speeds and large pulloff distances. Once everything is working, you can fine tune the values.
Set homing_runs:
to 2 (the default). This will move to activate the switch at a seek speed, move back a little and then move to activate it again at a feed speed.
axes:
homing_runs: 2
Under each axis, make sure max_travel_mm
is accurate. If it is less than the actual length, the axis might not travel far enough to reach the switch.
x:
max_travel_mm: 1000.000000
Set the values for homing. Everything can be tuned later, but the important one to get right at this time is positive_direction:
. If you are homing in the positive direction for the axis, set it to true.
axes:
x:
homing:
cycle: 1
allow_single_axis: true
positive_direction: false
mpos_mm: 0.000000
feed_mm_per_min: 700.000000
seek_mm_per_min: 1000.000000
settle_ms: 250
seek_scaler: 1.100000
feed_scaler: 1.100000
Assign the pins for each motor. There is more info here. If you are in doubt about the high: or :low
attribute, don't worry. Later in the flowchart this will be verified. Set pull_off_mm
to at least 3 to be sure it pulls off of the switch after activating it far enough to deactivate the switch.
axes:
x:
motor0:
limit_neg_pin: gpio.35:high
limit_pos_pin: NO_PIN
limit_all_pin: NO_PIN
hard_limits: false
pulloff_mm: 3.000000
You can place limit switches at either the positive or negative ends of travel, or at both ends. 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. Positive Y is typically away from you. Positive Z is the top.
You can assign switches to the ends with these key words. They are assigned at the motor level in the config file, because an axis with 2 motors will need switches separately defined for each motor. Use NO_PIN for a switch that is not present.
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 swith type. If a limit_all_pin:
is triggered, FluidNC will not know which end was activated. This will work normally for all scenarios except if a switch is triggered before homing. It does not know which way to move to clear the switch. You must manaully clear the switch before homing.
Typically you can use...
You do not use an all switch with other switches.
Each motor is inpdependant and you can choose the best arrangement for that motor.
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.
N.C. switch wiring is also more fail safe. A broken circuit will typically indicate the active state.
Axis squaring uses a switch on each motor to square the axis 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. 2 separate switches enables a stress free method. 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 best to set stepping/idle_ms: 255. This will prevent the motors from disabling in the idle state. Machines that need squaring tend to go out of square when the motors disable.
This is supported, but the axis will not auto square during homing. The switch can be placed on either the motor0 or motor1 side.
After an axis homes, its machine position is set to the mpos_mm:
value. Typically if you home in positive_direction: false
you would set mpos_mm: 0
. If you home in positive_direction: true
, you would set mpos_mm:
to the length of travel. If your max_travel_mm:
were 1000, in both these cases your range would be 0 to 1000.
axes:
x:
homing:
mpos_mm: 0.000
You are free to set the value to any number. This would allow you to set a range in positive or negative space. There is more detail on this wiki page.
We use the term "active" to mean the state of the switch when the limit is reached regardless if you use a normally open, normally closed, normally logic high or low, etc.
Set the messaging level to debug with $Message/Level=Debug
. This will show a lot of extra information. 1 means active and 0 mean inactive.
Manually activate each switch while watching the console output. Each switch should display in the console when active. If you have any axes with 2 motors make sure both motor switches display when active and are associated with the correct motor0 or motor1.
$Message/Level=Debug
ok
[MSG:DBG: X Neg Limit 1]
[MSG:DBG: Limit switch tripped for X motor 0]
[MSG:DBG: X Neg Limit 0]
[MSG:DBG: X Neg Limit 1]
[MSG:DBG: Limit switch tripped for X motor 0]
[MSG:DBG: X Neg Limit 0]
[MSG:DBG: Y Pos Limit 1]
[MSG:DBG: Limit switch tripped for Y motor 0]
[MSG:DBG: Y Pos Limit 0]
[MSG:DBG: Z Pos Limit 1]
[MSG:DBG: Limit switch tripped for Z motor 0]
[MSG:DBG: Z Pos Limit 0]
$Message/Level=Info
ok
Remeber to return the message level to info with $Message/Level=Info
after you are done setting up the machine. Too much debugging information can slow down the system and possibly result in motion problems.
This could be a configuration, wiring or hardware problem. Try using a voltmeter on the signal pin to see if the state is actually changing.
If a switch reports active when not touched and inactive when touched, then you should invert the :low
or :high
(the default) attribute
When testing, have a planned way to stop the machine if something unexpected happens. Be ready to stop the machine by cutting power or resetting FluidNC.
Double check that no switches are active before starting homing.
Check the positive_direction:
value.
If it moves the pulloff_mm:
distance in the wrong direction and causes an Alarm 8 (Homing Fail Pulloff) the switch was probably active when you homed, but the move did not clear the switch. The switch appears to be stuck in the active state.
max_travel_mm
if the value is long enough.A common problem is that the switches are on the incorrect motors. The Motor0 side moves into the switch for Motor1. It then disables the wrong motor for the autosquaring and the other motor continues, but can never move to its switch. Double check the switches in this step or try swapping the pins in the config file.
FluidNC cannot pull off an active limit switch if it does not know which end is active. There are 2 cases for this.
limit_all_pin:
FluidNC does not know which end to pull off.limit_neg_pin:
and the limit_pos_pin:
are active FluidNC does not know which end to pull off.You must clear the switch with a jog or manual move.
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. External pullups are more reliable than internal ones because the internal pullups in an ESP32 are of too high a value for good noise immunity.
Hard limits uses switches to limit motion. If a moving axis hits a switch and hard limits are on, the motion will immediately stop and issue an alarm.
Soft limits use the machine range to limit motion. If you try to move outside the range it will reject the commend and issue an alarm. The range of each axis is shown in the startup messages.
[MSG:INFO: Axis Y (0.000,1000.000)]]
Soft limits only work correctly after the axis has been homed, because it needs to know the current position to determine if the move will go outside the range of motion. If you try to jog to a point outside the range of travel, it will just jog to the end.
If you can, prefer soft limits over hard limits. Soft limits prevent problems before they occur.