klipper update

This commit is contained in:
Rainboooom
2023-06-15 11:41:08 +08:00
parent 845d13acb1
commit dffff1ae35
1921 changed files with 1625400 additions and 0 deletions

403
docs/API_Server.md Normal file
View File

@@ -0,0 +1,403 @@
# API server
This document describes Klipper's Application Programmer Interface
(API). This interface enables external applications to query and
control the Klipper host software.
## Enabling the API socket
In order to use the API server, the klippy.py host software must be
started with the `-a` parameter. For example:
```
~/klippy-env/bin/python ~/klipper/klippy/klippy.py ~/printer.cfg -a /tmp/klippy_uds -l /tmp/klippy.log
```
This causes the host software to create a Unix Domain Socket. A client
can then open a connection on that socket and send commands to
Klipper.
See the [Moonraker](https://github.com/Arksine/moonraker) project for
a popular tool that can forward HTTP requests to Klipper's API Server
Unix Domain Socket.
## Request format
Messages sent and received on the socket are JSON encoded strings
terminated by an ASCII 0x03 character:
```
<json_object_1><0x03><json_object_2><0x03>...
```
Klipper contains a `scripts/whconsole.py` tool that can perform the
above message framing. For example:
```
~/klipper/scripts/whconsole.py /tmp/klippy_uds
```
This tool can read a series of JSON commands from stdin, send them to
Klipper, and report the results. The tool expects each JSON command to
be on a single line, and it will automatically append the 0x03
terminator when transmitting a request. (The Klipper API server does
not have a newline requirement.)
## API Protocol
The command protocol used on the communication socket is inspired by
[json-rpc](https://www.jsonrpc.org/).
A request might look like:
`{"id": 123, "method": "info", "params": {}}`
and a response might look like:
`{"id": 123, "result": {"state_message": "Printer is ready",
"klipper_path": "/home/pi/klipper", "config_file":
"/home/pi/printer.cfg", "software_version": "v0.8.0-823-g883b1cb6",
"hostname": "octopi", "cpu_info": "4 core ARMv7 Processor rev 4
(v7l)", "state": "ready", "python_path":
"/home/pi/klippy-env/bin/python", "log_file": "/tmp/klippy.log"}}`
Each request must be a JSON dictionary. (This document uses the Python
term "dictionary" to describe a "JSON object" - a mapping of key/value
pairs contained within `{}`.)
The request dictionary must contain a "method" parameter that is the
string name of an available Klipper "endpoint".
The request dictionary may contain a "params" parameter which must be
of a dictionary type. The "params" provide additional parameter
information to the Klipper "endpoint" handling the request. Its
content is specific to the "endpoint".
The request dictionary may contain an "id" parameter which may be of
any JSON type. If "id" is present then Klipper will respond to the
request with a response message containing that "id". If "id" is
omitted (or set to a JSON "null" value) then Klipper will not provide
any response to the request. A response message is a JSON dictionary
containing "id" and "result". The "result" is always a dictionary -
its contents are specific to the "endpoint" handling the request.
If the processing of a request results in an error, then the response
message will contain an "error" field instead of a "result" field. For
example, the request:
`{"id": 123, "method": "gcode/script", "params": {"script": "G1
X200"}}`
might result in an error response such as:
`{"id": 123, "error": {"message": "Must home axis
first: 200.000 0.000 0.000 [0.000]", "error": "WebRequestError"}}`
Klipper will always start processing requests in the order that they
are received. However, some request may not complete immediately,
which could cause the associated response to be sent out of order with
respect to responses from other requests. A JSON request will never
pause the processing of future JSON requests.
## Subscriptions
Some Klipper "endpoint" requests allow one to "subscribe" to future
asynchronous update messages.
For example:
`{"id": 123, "method": "gcode/subscribe_output", "params":
{"response_template":{"key": 345}}}`
may initially respond with:
`{"id": 123, "result": {}}`
and cause Klipper to send future messages similar to:
`{"params": {"response": "ok B:22.8 /0.0 T0:22.4 /0.0"}, "key": 345}`
A subscription request accepts a "response_template" dictionary in the
"params" field of the request. That "response_template" dictionary is
used as a template for future asynchronous messages - it may contain
arbitrary key/value pairs. When sending these future asynchronous
messages, Klipper will add a "params" field containing a dictionary
with "endpoint" specific contents to the response template and then
send that template. If a "response_template" field is not provided
then it defaults to an empty dictionary (`{}`).
## Available "endpoints"
By convention, Klipper "endpoints" are of the form
`<module_name>/<some_name>`. When making a request to an "endpoint",
the full name must be set in the "method" parameter of the request
dictionary (eg, `{"method"="gcode/restart"}`).
### info
The "info" endpoint is used to obtain system and version information
from Klipper. It is also used to provide the client's version
information to Klipper. For example:
`{"id": 123, "method": "info", "params": { "client_info": { "version":
"v1"}}}`
If present, the "client_info" parameter must be a dictionary, but that
dictionary may have arbitrary contents. Clients are encouraged to
provide the name of the client and its software version when first
connecting to the Klipper API server.
### emergency_stop
The "emergency_stop" endpoint is used to instruct Klipper to
transition to a "shutdown" state. It behaves similarly to the G-Code
`M112` command. For example:
`{"id": 123, "method": "emergency_stop"}`
### register_remote_method
This endpoint allows clients to register methods that can be called
from klipper. It will return an empty object upon success.
For example:
`{"id": 123, "method": "register_remote_method",
"params": {"response_template": {"action": "run_paneldue_beep"},
"remote_method": "paneldue_beep"}}`
will return:
`{"id": 123, "result": {}}`
The remote method `paneldue_beep` may now be called from Klipper. Note
that if the method takes parameters they should be provided as keyword
arguments. Below is an example of how it may called from a gcode_macro:
```
[gcode_macro PANELDUE_BEEP]
gcode:
{action_call_remote_method("paneldue_beep", frequency=300, duration=1.0)}
```
When the PANELDUE_BEEP gcode macro is executed, Klipper would send something
like the following over the socket:
`{"action": "run_paneldue_beep",
"params": {"frequency": 300, "duration": 1.0}}`
### objects/list
This endpoint queries the list of available printer "objects" that one
may query (via the "objects/query" endpoint). For example:
`{"id": 123, "method": "objects/list"}`
might return:
`{"id": 123, "result": {"objects":
["webhooks", "configfile", "heaters", "gcode_move", "query_endstops",
"idle_timeout", "toolhead", "extruder"]}}`
### objects/query
This endpoint allows one to query information from printer objects.
For example:
`{"id": 123, "method": "objects/query", "params": {"objects":
{"toolhead": ["position"], "webhooks": null}}}`
might return:
`{"id": 123, "result": {"status": {"webhooks": {"state": "ready",
"state_message": "Printer is ready"}, "toolhead": {"position":
[0.0, 0.0, 0.0, 0.0]}}, "eventtime": 3051555.377933684}}`
The "objects" parameter in the request must be a dictionary containing
the printer objects that are to be queried - the key contains the
printer object name and the value is either "null" (to query all
fields) or a list of field names.
The response message will contain a "status" field containing a
dictionary with the queried information - the key contains the printer
object name and the value is a dictionary containing its fields. The
response message will also contain an "eventtime" field containing the
timestamp from when the query was taken.
Available fields are documented in the
[Status Reference](Status_Reference.md) document.
### objects/subscribe
This endpoint allows one to query and then subscribe to information
from printer objects. The endpoint request and response is identical
to the "objects/query" endpoint. For example:
`{"id": 123, "method": "objects/subscribe", "params":
{"objects":{"toolhead": ["position"], "webhooks": ["state"]},
"response_template":{}}}`
might return:
`{"id": 123, "result": {"status": {"webhooks": {"state": "ready"},
"toolhead": {"position": [0.0, 0.0, 0.0, 0.0]}},
"eventtime": 3052153.382083195}}`
and result in subsequent asynchronous messages such as:
`{"params": {"status": {"webhooks": {"state": "shutdown"}},
"eventtime": 3052165.418815847}}`
### gcode/help
This endpoint allows one to query available G-Code commands that have
a help string defined. For example:
`{"id": 123, "method": "gcode/help"}`
might return:
`{"id": 123, "result": {"RESTORE_GCODE_STATE": "Restore a previously
saved G-Code state", "PID_CALIBRATE": "Run PID calibration test",
"QUERY_ADC": "Report the last value of an analog pin", ...}}`
### gcode/script
This endpoint allows one to run a series of G-Code commands. For example:
`{"id": 123, "method": "gcode/script", "params": {"script": "G90"}}`
If the provided G-Code script raises an error, then an error response
is generated. However, if the G-Code command produces terminal output,
that terminal output is not provided in the response. (Use the
"gcode/subscribe_output" endpoint to obtain G-Code terminal output.)
If there is a G-Code command being processed when this request is
received, then the provided script will be queued. This delay could be
significant (eg, if a G-Code wait for temperature command is running).
The JSON response message is sent when the processing of the script
fully completes.
### gcode/restart
This endpoint allows one to request a restart - it is similar to
running the G-Code "RESTART" command. For example:
`{"id": 123, "method": "gcode/restart"}`
As with the "gcode/script" endpoint, this endpoint only completes
after any pending G-Code commands complete.
### gcode/firmware_restart
This is similar to the "gcode/restart" endpoint - it implements the
G-Code "FIRMWARE_RESTART" command. For example:
`{"id": 123, "method": "gcode/firmware_restart"}`
As with the "gcode/script" endpoint, this endpoint only completes
after any pending G-Code commands complete.
### gcode/subscribe_output
This endpoint is used to subscribe to G-Code terminal messages that
are generated by Klipper. For example:
`{"id": 123, "method": "gcode/subscribe_output", "params":
{"response_template":{}}}`
might later produce asynchronous messages such as:
`{"params": {"response": "// Klipper state: Shutdown"}}`
This endpoint is intended to support human interaction via a "terminal
window" interface. Parsing content from the G-Code terminal output is
discouraged. Use the "objects/subscribe" endpoint to obtain updates on
Klipper's state.
### motion_report/dump_stepper
This endpoint is used to subscribe to Klipper's internal stepper
queue_step command stream for a stepper. Obtaining these low-level
motion updates may be useful for diagnostic and debugging
purposes. Using this endpoint may increase Klipper's system load.
A request may look like:
`{"id": 123, "method":"motion_report/dump_stepper",
"params": {"name": "stepper_x", "response_template": {}}}`
and might return:
`{"id": 123, "result": {"header": ["interval", "count", "add"]}}`
and might later produce asynchronous messages such as:
`{"params": {"first_clock": 179601081, "first_time": 8.98,
"first_position": 0, "last_clock": 219686097, "last_time": 10.984,
"data": [[179601081, 1, 0], [29573, 2, -8685], [16230, 4, -1525],
[10559, 6, -160], [10000, 976, 0], [10000, 1000, 0], [10000, 1000, 0],
[10000, 1000, 0], [9855, 5, 187], [11632, 4, 1534], [20756, 2, 9442]]}}`
The "header" field in the initial query response is used to describe
the fields found in later "data" responses.
### motion_report/dump_trapq
This endpoint is used to subscribe to Klipper's internal "trapezoid
motion queue". Obtaining these low-level motion updates may be useful
for diagnostic and debugging purposes. Using this endpoint may
increase Klipper's system load.
A request may look like:
`{"id": 123, "method": "motion_report/dump_trapq", "params":
{"name": "toolhead", "response_template":{}}}`
and might return:
`{"id": 1, "result": {"header": ["time", "duration",
"start_velocity", "acceleration", "start_position", "direction"]}}`
and might later produce asynchronous messages such as:
`{"params": {"data": [[4.05, 1.0, 0.0, 0.0, [300.0, 0.0, 0.0],
[0.0, 0.0, 0.0]], [5.054, 0.001, 0.0, 3000.0, [300.0, 0.0, 0.0],
[-1.0, 0.0, 0.0]]]}}`
The "header" field in the initial query response is used to describe
the fields found in later "data" responses.
### adxl345/dump_adxl345
This endpoint is used to subscribe to ADXL345 accelerometer data.
Obtaining these low-level motion updates may be useful for diagnostic
and debugging purposes. Using this endpoint may increase Klipper's
system load.
A request may look like:
`{"id": 123, "method":"adxl345/dump_adxl345",
"params": {"sensor": "adxl345", "response_template": {}}}`
and might return:
`{"id": 123,"result":{"header":["time","x_acceleration","y_acceleration",
"z_acceleration"]}}`
and might later produce asynchronous messages such as:
`{"params":{"overflows":0,"data":[[3292.432935,-535.44309,-1529.8374,9561.4],
[3292.433256,-382.45935,-1606.32927,9561.48375]]}}`
The "header" field in the initial query response is used to describe
the fields found in later "data" responses.
### angle/dump_angle
This endpoint is used to subscribe to
[angle sensor data](Config_Reference.md#angle). Obtaining these
low-level motion updates may be useful for diagnostic and debugging
purposes. Using this endpoint may increase Klipper's system load.
A request may look like:
`{"id": 123, "method":"angle/dump_angle",
"params": {"sensor": "my_angle_sensor", "response_template": {}}}`
and might return:
`{"id": 123,"result":{"header":["time","angle"]}}`
and might later produce asynchronous messages such as:
`{"params":{"position_offset":3.151562,"errors":0,
"data":[[1290.951905,-5063],[1290.952321,-5065]]}}`
The "header" field in the initial query response is used to describe
the fields found in later "data" responses.
### pause_resume/cancel
This endpoint is similar to running the "PRINT_CANCEL" G-Code command.
For example:
`{"id": 123, "method": "pause_resume/cancel"}`
As with the "gcode/script" endpoint, this endpoint only completes
after any pending G-Code commands complete.
### pause_resume/pause
This endpoint is similar to running the "PAUSE" G-Code command. For
example:
`{"id": 123, "method": "pause_resume/pause"}`
As with the "gcode/script" endpoint, this endpoint only completes
after any pending G-Code commands complete.
### pause_resume/resume
This endpoint is similar to running the "RESUME" G-Code command. For
example:
`{"id": 123, "method": "pause_resume/resume"}`
As with the "gcode/script" endpoint, this endpoint only completes
after any pending G-Code commands complete.
### query_endstops/status
This endpoint will query the active endpoints and return their status.
For example:
`{"id": 123, "method": "query_endstops/status"}`
might return:
`{"id": 123, "result": {"y": "open", "x": "open", "z": "TRIGGERED"}}`
As with the "gcode/script" endpoint, this endpoint only completes
after any pending G-Code commands complete.

262
docs/BLTouch.md Normal file
View File

@@ -0,0 +1,262 @@
# BL-Touch
## Connecting BL-Touch
A **warning** before you start: Avoid touching the BL-Touch pin with
your bare fingers, since it is quite sensitive to finger grease. And
if you do touch it, be very gentle, in order to not bend or push
anything.
Hook up the BL-Touch "servo" connector to a `control_pin` according to
the BL-Touch documentation or your MCU documentation. Using the
original wiring, the yellow wire from the triple is the `control_pin`
and the white wire from the pair is the `sensor_pin`. You need to
configure these pins according to your wiring. Most BL-Touch devices
require a pullup on the sensor pin (prefix the pin name with "^"). For
example:
```
[bltouch]
sensor_pin: ^P1.24
control_pin: P1.26
```
If the BL-Touch will be used to home the Z axis then set `endstop_pin:
probe:z_virtual_endstop` and remove `position_endstop` in the `[stepper_z]` config section,
then add a `[safe_z_home]` config section to raise the z axis, home the xy axes,
move to the center of the bed, and home the z axis. For example:
```
[safe_z_home]
home_xy_position: 100, 100 # Change coordinates to the center of your print bed
speed: 50
z_hop: 10 # Move up 10mm
z_hop_speed: 5
```
It's important that the z_hop movement in safe_z_home is high enough
that the probe doesn't hit anything even if the probe pin happens to
be in its lowest state.
## Initial tests
Before moving on, verify that the BL-Touch is mounted at the correct
height, the pin should be roughly 2 mm above the nozzle when retracted
When you turn on the printer, the BL-Touch probe should perform a
self-test and move the pin up and down a couple of times. Once the
self-test is completed, the pin should be retracted and the red LED on
the probe should be lit. If there are any errors, for example the
probe is flashing red or the pin is down instead of up, please turn
off the printer and check the wiring and configuration.
If the above is looking good, it's time to test that the control pin
is working correctly. First run `BLTOUCH_DEBUG COMMAND=pin_down` in
your printer terminal. Verify that the pin moves down and that the red
LED on the probe turns off. If not, check your wiring and
configuration again. Next issue a `BLTOUCH_DEBUG COMMAND=pin_up`,
verify that the pin moves up, and that the red light turns on
again. If it's flashing then there's some problem.
The next step is to confirm that the sensor pin is working correctly.
Run `BLTOUCH_DEBUG COMMAND=pin_down`, verify that the pin moves down,
run `BLTOUCH_DEBUG COMMAND=touch_mode`, run `QUERY_PROBE`, and verify
that command reports "probe: open". Then while gently pushing the pin
up slightly with the nail of your finger run `QUERY_PROBE` again.
Verify the command reports "probe: TRIGGERED". If either query does
not report the correct message then it usually indicates an incorrect
wiring or configuration (though some [clones](#bl-touch-clones) may
require special handling). At the completion of this test run
`BLTOUCH_DEBUG COMMAND=pin_up` and verify that the pin moves up.
After completing the BL-Touch control pin and sensor pin tests, it is
now time to test probing, but with a twist. Instead of letting the
probe pin touch the print bed, let it touch the nail on your finger.
Position the toolhead far from the bed, issue a `G28` (or `PROBE` if
not using probe:z_virtual_endstop), wait until the toolhead starts to
move down, and stop the movement by very gently touching the pin with
your nail. You may have to do it twice, since the default homing
configuration probes twice. Be prepared to turn off the printer if it
doesn't stop when you touch the pin.
If that was successful, do another `G28` (or `PROBE`) but this time
let it touch the bed as it should.
## BL-Touch gone bad
Once the BL-Touch is in inconsistent state, it starts blinking red.
You can force it to leave that state by issuing:
BLTOUCH_DEBUG COMMAND=reset
This may happen if its calibration is interrupted by the probe being
blocked from being extracted.
However, the BL-Touch may also not be able to calibrate itself
anymore. This happens if the screw on its top is in the wrong position
or the magnetic core inside the probe pin has moved. If it has moved
up so that it sticks to the screw, it may not be able to lower its pin
anymore. With this behavior you need to open the screw and use a
ball-point pen to push it gently back into place. Re-Insert the pin
into the BL-Touch so that it falls into the extracted position.
Carefully readjust the headless screw into place. You need to find the
right position so it is able to lower and raise the pin and the red
light turns on and of. Use the `reset`, `pin_up` and `pin_down`
commands to achieve this.
## BL-Touch "clones"
Many BL-Touch "clone" devices work correctly with Klipper using the
default configuration. However, some "clone" devices may not support
the `QUERY_PROBE` command and some "clone" devices may require
configuration of `pin_up_reports_not_triggered` or
`pin_up_touch_mode_reports_triggered`.
Important! Do not configure `pin_up_reports_not_triggered` or
`pin_up_touch_mode_reports_triggered` to False without first following
these directions. Do not configure either of these to False on a
genuine BL-Touch. Incorrectly setting these to False can increase
probing time and can increase the risk of damaging the printer.
Some "clone" devices do not support `touch_mode` and as a result the
`QUERY_PROBE` command does not work. Despite this, it may still be
possible to perform probing and homing with these devices. On these
devices the `QUERY_PROBE` command during the
[initial tests](#initial-tests) will not succeed, however the
subsequent `G28` (or `PROBE`) test does succeed. It may be possible to
use these "clone" devices with Klipper if one does not utilize the
`QUERY_PROBE` command and one does not enable the
`probe_with_touch_mode` feature.
Some "clone" devices are unable to perform Klipper's internal sensor
verification test. On these devices, attempts to home or probe can
result in Klipper reporting a "BLTouch failed to verify sensor state"
error. If this occurs, then manually run the steps to confirm the
sensor pin is working as described in the
[initial tests section](#initial-tests). If the `QUERY_PROBE` commands
in that test always produce the expected results and "BLTouch failed
to verify sensor state" errors still occur, then it may be necessary
to set `pin_up_touch_mode_reports_triggered` to False in the Klipper
config file.
A rare number of old "clone" devices are unable to report when they
have successfully raised their probe. On these devices Klipper will
report a "BLTouch failed to raise probe" error after every home or
probe attempt. One can test for these devices - move the head far from
the bed, run `BLTOUCH_DEBUG COMMAND=pin_down`, verify the pin has
moved down, run `QUERY_PROBE`, verify that command reports "probe:
open", run `BLTOUCH_DEBUG COMMAND=pin_up`, verify the pin has moved
up, and run `QUERY_PROBE`. If the pin remains up, the device does not
enter an error state, and the first query reports "probe: open" while
the second query reports "probe: TRIGGERED" then it indicates that
`pin_up_reports_not_triggered` should be set to False in the Klipper
config file.
## BL-Touch v3
Some BL-Touch v3.0 and BL-Touch 3.1 devices may require configuring
`probe_with_touch_mode` in the printer config file.
If the BL-Touch v3.0 has its signal wire connected to an endstop pin
(with a noise filtering capacitor), then the BL-Touch v3.0 may not be
able to consistently send a signal during homing and probing. If the
`QUERY_PROBE` commands in the [initial tests section](#initial-tests)
always produce the expected results, but the toolhead does not always
stop during G28/PROBE commands, then it is indicative of this issue. A
workaround is to set `probe_with_touch_mode: True` in the config file.
The BL-Touch v3.1 may incorrectly enter an error state after a
successful probe attempt. The symptoms are an occasional flashing
light on the BL-Touch v3.1 that lasts for a couple of seconds after it
successfully contacts the bed. Klipper should clear this error
automatically and it is generally harmless. However, one may set
`probe_with_touch_mode` in the config file to avoid this issue.
Important! Some "clone" devices and the BL-Touch v2.0 (and earlier)
may have reduced accuracy when `probe_with_touch_mode` is set to True.
Setting this to True also increases the time it takes to deploy the
probe. If configuring this value on a "clone" or older BL-Touch
device, be sure to test the probe accuracy before and after setting
this value (use the `PROBE_ACCURACY` command to test).
## Multi-probing without stowing
By default, Klipper will deploy the probe at the start of each probe
attempt and then stow the probe afterwards. This repetitive deploying
and stowing of the probe may increase the total time of calibration
sequences that involve many probe measurements. Klipper supports
leaving the probe deployed between consecutive probes, which can
reduce the total time of probing. This mode is enabled by configuring
`stow_on_each_sample` to False in the config file.
Important! Setting `stow_on_each_sample` to False can lead to Klipper
making horizontal toolhead movements while the probe is deployed. Be
sure to verify all probing operations have sufficient Z clearance
prior to setting this value to False. If there is insufficient
clearance then a horizontal move may cause the pin to catch on an
obstruction and result in damage to the printer.
Important! It is recommended to use `probe_with_touch_mode` configured
to True when using `stow_on_each_sample` configured to False. Some
"clone" devices may not detect a subsequent bed contact if
`probe_with_touch_mode` is not set. On all devices, using the
combination of these two settings simplifies the device signaling,
which can improve overall stability.
Note, however, that some "clone" devices and the BL-Touch v2.0 (and
earlier) may have reduced accuracy when `probe_with_touch_mode` is set
to True. On these devices it is a good idea to test the probe accuracy
before and after setting `probe_with_touch_mode` (use the
`PROBE_ACCURACY` command to test).
## Calibrating the BL-Touch offsets
Follow the directions in the [Probe Calibrate](Probe_Calibrate.md)
guide to set the x_offset, y_offset, and z_offset config parameters.
It's a good idea to verify that the Z offset is close to 1mm. If not,
then you probably want to move the probe up or down to fix this. You
want it to trigger well before the nozzle hits the bed, so that
possible stuck filament or a warped bed doesn't affect any probing
action. But at the same time, you want the retracted position to be as
far above the nozzle as possible to avoid it touching printed parts.
If an adjustment is made to the probe position, then rerun the probe
calibration steps.
## BL-Touch output mode
* A BL-Touch V3.0 supports setting a 5V or OPEN-DRAIN output mode,
a BL-Touch V3.1 supports this too, but can also store this in its
internal EEPROM. If your controller board needs the fixed 5V high
logic level of the 5V mode you may set the 'set_output_mode'
parameter in the [bltouch] section of the printer config file to
"5V".
*** Only use the 5V mode if your controller boards input line is
5V tolerant. This is why the default configuration of these BL-Touch
versions is OPEN-DRAIN mode. You could potentially damage your
controller boards CPU ***
So therefore:
If a controller board NEEDs 5V mode AND it is 5V tolerant on its
input signal line AND if
- you have a BL-Touch Smart V3.0, you need the use 'set_output_mode: 5V'
parameter to ensure this setting at each startup, since the probe
cannot remember the needed setting.
- you have a BL-Touch Smart V3.1, you have the choice of using
'set_output_mode: 5V' or storing the mode once by use of a
'BLTOUCH_STORE MODE=5V' command manually and NOT using the parameter
'set_output_mode:'.
- you have some other probe: Some probes have a trace on the circuit board
to cut or a jumper to set in order to (permanently) set the output mode.
In that case, omit the 'set_output_mode' parameter completely.
If you have a V3.1, do not automate or repeat storing the output mode to
avoid wearing out the EEPROM of the probe.The BLTouch EEPROM is good for
about 100.000 updates. 100 stores per day would add up to about 3 years
of operation prior to wearing it out. Thus, storing the output mode in a
V3.1 is designed by the vendor to be a complicated operation (the factory
default being a safe OPEN DRAIN mode) and is not suited to be repeatedly
issued by any slicer, macro or anything else, it is preferably only to be
used when first integrating the probe into a printers electronics.

100
docs/Beaglebone.md Normal file
View File

@@ -0,0 +1,100 @@
# Beaglebone
This document describes the process of running Klipper on a Beaglebone
PRU.
## Building an OS image
Start by installing the
[Debian 9.9 2019-08-03 4GB SD IoT](https://beagleboard.org/latest-images)
image. One may run the image from either a micro-SD card or from
builtin eMMC. If using the eMMC, install it to eMMC now by following
the instructions from the above link.
Then ssh into the Beaglebone machine (`ssh debian@beaglebone` --
password is `temppwd`) and install Klipper by running the following
commands:
```
git clone https://github.com/Klipper3d/klipper
./klipper/scripts/install-beaglebone.sh
```
## Install Octoprint
One may then install Octoprint:
```
git clone https://github.com/foosel/OctoPrint.git
cd OctoPrint/
virtualenv venv
./venv/bin/python setup.py install
```
And setup OctoPrint to start at bootup:
```
sudo cp ~/OctoPrint/scripts/octoprint.init /etc/init.d/octoprint
sudo chmod +x /etc/init.d/octoprint
sudo cp ~/OctoPrint/scripts/octoprint.default /etc/default/octoprint
sudo update-rc.d octoprint defaults
```
It is necessary to modify OctoPrint's **/etc/default/octoprint**
configuration file. One must change the `OCTOPRINT_USER` user to
`debian`, change `NICELEVEL` to `0`, uncomment the `BASEDIR`, `CONFIGFILE`,
and `DAEMON` settings and change the references from `/home/pi/` to
`/home/debian/`:
```
sudo nano /etc/default/octoprint
```
Then start the Octoprint service:
```
sudo systemctl start octoprint
```
Make sure the OctoPrint web server is accessible - it should be at:
[http://beaglebone:5000/](http://beaglebone:5000/)
## Building the micro-controller code
To compile the Klipper micro-controller code, start by configuring it
for the "Beaglebone PRU":
```
cd ~/klipper/
make menuconfig
```
To build and install the new micro-controller code, run:
```
sudo service klipper stop
make flash
sudo service klipper start
```
It is also necessary to compile and install the micro-controller code
for a Linux host process. Configure it a second time for a "Linux process":
```
make menuconfig
```
Then install this micro-controller code as well:
```
sudo service klipper stop
make flash
sudo service klipper start
```
## Remaining configuration
Complete the installation by configuring Klipper and Octoprint
following the instructions in
the main [Installation](Installation.md#configuring-klipper) document.
## Printing on the Beaglebone
Unfortunately, the Beaglebone processor can sometimes struggle to run
OctoPrint well. Print stalls have been known to occur on complex
prints (the printer may move faster than OctoPrint can send movement
commands). If this occurs, consider using the "virtual_sdcard" feature
(see [Config Reference](Config_Reference.md#virtual_sdcard) for
details) to print directly from Klipper.

217
docs/Bed_Level.md Normal file
View File

@@ -0,0 +1,217 @@
# Bed leveling
Bed leveling (sometimes also referred to as "bed tramming") is
critical to getting high quality prints. If a bed is not properly
"leveled" it can lead to poor bed adhesion, "warping", and subtle
problems throughout the print. This document serves as a guide to
performing bed leveling in Klipper.
It's important to understand the goal of bed leveling. If the printer
is commanded to a position `X0 Y0 Z10` during a print, then the goal
is for the printer's nozzle to be exactly 10mm from the printer's
bed. Further, should the printer then be commanded to a position of
`X50 Z10` the goal is for the nozzle to maintain an exact distance of
10mm from the bed during that entire horizontal move.
In order to get good quality prints the printer should be calibrated
so that Z distances are accurate to within about 25 microns (.025mm).
This is a small distance - significantly smaller than the width of a
typical human hair. This scale can not be measured "by eye". Subtle
effects (such as heat expansion) impact measurements at this scale.
The secret to getting high accuracy is to use a repeatable process and
to use a leveling method that leverages the high accuracy of the
printer's own motion system.
## Choose the appropriate calibration mechanism
Different types of printers use different methods for performing bed
leveling. All of them ultimately depend on the "paper test" (described
below). However, the actual process for a particular type of printer
is described in other documents.
Prior to running any of these calibration tools, be sure to run the
checks described in the [config check document](Config_checks.md). It
is necessary to verify basic printer motion before performing bed
leveling.
For printers with an "automatic Z probe" be sure to calibrate the
probe following the directions in the
[Probe Calibrate](Probe_Calibrate.md) document. For delta printers,
see the [Delta Calibrate](Delta_Calibrate.md) document. For printers
with bed screws and traditional Z endstops, see the
[Manual Level](Manual_Level.md) document.
During calibration it may be necessary to set the printer's Z
`position_min` to a negative number (eg, `position_min = -2`). The
printer enforces boundary checks even during calibration
routines. Setting a negative number allows the printer to move below
the nominal position of the bed, which may help when trying to
determine the actual bed position.
## The "paper test"
The primary bed calibration mechanism is the "paper test". It involves
placing a regular piece of "copy machine paper" between the printer's
bed and nozzle, and then commanding the nozzle to different Z heights
until one feels a small amount of friction when pushing the paper back
and forth.
It is important to understand the "paper test" even if one has an
"automatic Z probe". The probe itself often needs to be calibrated to
get good results. That probe calibration is done using this "paper
test".
In order to perform the paper test, cut a small rectangular piece of
paper using a pair of scissors (eg, 5x3 cm). The paper generally has a
thickness of around 100 microns (0.100mm). (The exact thickness of the paper
isn't crucial.)
The first step of the paper test is to inspect the printer's nozzle
and bed. Make sure there is no plastic (or other debris) on the nozzle
or bed.
**Inspect the nozzle and bed to ensure no plastic is present!**
If one always prints on a particular tape or printing surface then one
may perform the paper test with that tape/surface in place. However,
note that tape itself has a thickness and different tapes (or any other
printing surface) will impact Z measurements. Be sure to rerun the
paper test to measure each type of surface that is in use.
If there is plastic on the nozzle then heat up the extruder and use a
metal tweezers to remove that plastic. Wait for the extruder to fully
cool to room temperature before continuing with the paper test. While
the nozzle is cooling, use the metal tweezers to remove any plastic
that may ooze out.
**Always perform the paper test when both nozzle and bed are at room
temperature!**
When the nozzle is heated, its position (relative to the bed) changes
due to thermal expansion. This thermal expansion is typically around a
100 microns, which is about the same thickness as a typical piece of
printer paper. The exact amount of thermal expansion isn't crucial,
just as the exact thickness of the paper isn't crucial. Start with the
assumption that the two are equal (see below for a method of
determining the difference between the two distances).
It may seem odd to calibrate the distance at room temperature when the
goal is to have a consistent distance when heated. However, if one
calibrates when the nozzle is heated, it tends to impart small amounts
of molten plastic on to the paper, which changes the amount of
friction felt. That makes it harder to get a good calibration.
Calibrating while the bed/nozzle is hot also greatly increases the
risk of burning oneself. The amount of thermal expansion is stable, so
it is easily accounted for later in the calibration process.
**Use an automated tool to determine precise Z heights!**
Klipper has several helper scripts available (eg, MANUAL_PROBE,
Z_ENDSTOP_CALIBRATE, PROBE_CALIBRATE, DELTA_CALIBRATE). See the
documents
[described above](#choose-the-appropriate-calibration-mechanism) to
choose one of them.
Run the appropriate command in the OctoPrint terminal window. The
script will prompt for user interaction in the OctoPrint terminal
output. It will look something like:
```
Recv: // Starting manual Z probe. Use TESTZ to adjust position.
Recv: // Finish with ACCEPT or ABORT command.
Recv: // Z position: ?????? --> 5.000 <-- ??????
```
The current height of the nozzle (as the printer currently understands
it) is shown between the "--> <--". The number to the right is the
height of the last probe attempt just greater than the current height,
and to the left is the last probe attempt less than the current height
(or ?????? if no attempt has been made).
Place the paper between the nozzle and bed. It can be useful to fold a
corner of the paper so that it is easier to grab. (Try not to push
down on the bed when moving the paper back and forth.)
![paper-test](img/paper-test.jpg)
Use the TESTZ command to request the nozzle to move closer to the
paper. For example:
```
TESTZ Z=-.1
```
The TESTZ command will move the nozzle a relative distance from the
nozzle's current position. (So, `Z=-.1` requests the nozzle to move
closer to the bed by .1mm.) After the nozzle stops moving, push the
paper back and forth to check if the nozzle is in contact with the
paper and to feel the amount of friction. Continue issuing TESTZ
commands until one feels a small amount of friction when testing with
the paper.
If too much friction is found then one can use a positive Z value to
move the nozzle up. It is also possible to use `TESTZ Z=+` or `TESTZ
Z=-` to "bisect" the last position - that is to move to a position
half way between two positions. For example, if one received the
following prompt from a TESTZ command:
```
Recv: // Z position: 0.130 --> 0.230 <-- 0.280
```
Then a `TESTZ Z=-` would move the nozzle to a Z position of 0.180
(half way between 0.130 and 0.230). One can use this feature to help
rapidly narrow down to a consistent friction. It is also possible to
use `Z=++` and `Z=--` to return directly to a past measurement - for
example, after the above prompt a `TESTZ Z=--` command would move the
nozzle to a Z position of 0.130.
After finding a small amount of friction run the ACCEPT command:
```
ACCEPT
```
This will accept the given Z height and proceed with the given
calibration tool.
The exact amount of friction felt isn't crucial, just as the amount of
thermal expansion and exact width of the paper isn't crucial. Just try
to obtain the same amount of friction each time one runs the test.
If something goes wrong during the test, one can use the `ABORT`
command to exit the calibration tool.
## Determining Thermal Expansion
After successfully performing bed leveling, one may go on to calculate
a more precise value for the combined impact of "thermal expansion",
"thickness of the paper", and "amount of friction felt during the paper
test".
This type of calculation is generally not needed as most users find
the simple "paper test" provides good results.
The easiest way to make this calculation is to print a test object
that has straight walls on all sides. The large hollow square found in
[docs/prints/square.stl](prints/square.stl) can be used for this.
When slicing the object, make sure the slicer uses the same layer
height and extrusion widths for the first level that it does for all
subsequent layers. Use a coarse layer height (the layer height should
be around 75% of the nozzle diameter) and do not use a brim or raft.
Print the test object, wait for it to cool, and remove it from the
bed. Inspect the lowest layer of the object. (It may also be useful to
run a finger or nail along the bottom edge.) If one finds the bottom
layer bulges out slightly along all sides of the object then it
indicates the nozzle was slightly closer to the bed then it should
be. One can issue a `SET_GCODE_OFFSET Z=+.010` command to increase the
height. In subsequent prints one can inspect for this behavior and
make further adjustment as needed. Adjustments of this type are
typically in 10s of microns (.010mm).
If the bottom layer consistently appears narrower than subsequent
layers then one can use the SET_GCODE_OFFSET command to make a
negative Z adjustment. If one is unsure, then one can decrease the Z
adjustment until the bottom layer of prints exhibit a small bulge, and
then back-off until it disappears.
The easiest way to apply the desired Z adjustment is to create a
START_PRINT g-code macro, arrange for the slicer to call that macro
during the start of each print, and add a SET_GCODE_OFFSET command to
that macro. See the [slicers](Slicers.md) document for further
details.

451
docs/Bed_Mesh.md Normal file
View File

@@ -0,0 +1,451 @@
# Bed Mesh
The Bed Mesh module may be used to compensate for bed surface irregularties to
achieve a better first layer across the entire bed. It should be noted that
software based correction will not achieve perfect results, it can only
approximate the shape of the bed. Bed Mesh also cannot compensate for
mechanical and electrical issues. If an axis is skewed or a probe is not
accurate then the bed_mesh module will not receive accurate results from
the probing process.
Prior to Mesh Calibration you will need to be sure that your Probe's
Z-Offset is calibrated. If using an endstop for Z homing it will need
to be calibrated as well. See [Probe Calibrate](Probe_Calibrate.md)
and Z_ENDSTOP_CALIBRATE in [Manual Level](Manual_Level.md) for more
information.
## Basic Configuration
### Rectangular Beds
This example assumes a printer with a 250 mm x 220 mm rectangular
bed and a probe with an x-offset of 24 mm and y-offset of 5 mm.
```
[bed_mesh]
speed: 120
horizontal_move_z: 5
mesh_min: 35, 6
mesh_max: 240, 198
probe_count: 5, 3
```
- `speed: 120`\
_Default Value: 50_\
The speed in which the tool moves between points.
- `horizontal_move_z: 5`\
_Default Value: 5_\
The Z coordinate the probe rises to prior to traveling between points.
- `mesh_min: 35, 6`\
_Required_\
The first probed coordinate, nearest to the origin. This coordinate
is relative to the probe's location.
- `mesh_max: 240, 198`\
_Required_\
The probed coordinate farthest farthest from the origin. This is not
necessarily the last point probed, as the probing process occurs in a
zig-zag fashion. As with `mesh_min`, this coordiante is relative to
the probe's location.
- `probe_count: 5, 3`\
_Default Value: 3, 3_\
The number of points to probe on each axis, specified as X, Y integer
values. In this example 5 points will be probed along the X axis, with
3 points along the Y axis, for a total of 15 probed points. Note that
if you wanted a square grid, for example 3x3, this could be specified
as a single integer value that is used for both axes, ie `probe_count: 3`.
Note that a mesh requires a minimum probe_count of 3 along each axis.
The illustration below demonstrates how the `mesh_min`, `mesh_max`, and
`probe_count` options are used to generate probe points. The arrows indicate
the direction of the probing procedure, beginning at `mesh_min`. For reference,
when the probe is at `mesh_min` the nozzle will be at (11, 1), and when the probe
is at `mesh_max`, the nozzle will be at (206, 193).
![bedmesh_rect_basic](img/bedmesh_rect_basic.svg)
### Round beds
This example assumes a printer equipped with a round bed radius of 100mm.
We will use the same probe offsets as the rectangular example, 24 mm on X
and 5 mm on Y.
```
[bed_mesh]
speed: 120
horizontal_move_z: 5
mesh_radius: 75
mesh_origin: 0, 0
round_probe_count: 5
```
- `mesh_radius: 75`\
_Required_\
The radius of the probed mesh in mm, relative to the `mesh_origin`. Note
that the probe's offsets limit the size of the mesh radius. In this example,
a radius larger than 76 would move the tool beyond the range of the printer.
- `mesh_origin: 0, 0`\
_Default Value: 0, 0_\
The center point of the mesh. This coordinate is relative to the probe's
location. While the default is 0, 0, it may be useful to adjust the origin
in an effort to probe a larger portion of the bed. See the illustration
below.
- `round_probe_count: 5`\
_Default Value: 5_\
This is an integer value that defines the maximum number of probed points
along the X and Y axes. By "maximum", we mean the number of points probed
along the mesh origin. This value must be an odd number, as it is required
that the center of the mesh is probed.
The illustration below shows how the probed points are generated. As you can see,
setting the `mesh_origin` to (-10, 0) allows us to specifiy a larger mesh radius
of 85.
![bedmesh_round_basic](img/bedmesh_round_basic.svg)
## Advanced Configuration
Below the more advanced configuration options are explained in detail. Each
example will build upon the basic rectangular bed configuration shown above.
Each of the advanced options apply to round beds in the same manner.
### Mesh Interpolation
While its possible to sample the probed matrix directly using simple bilinear
interpolation to determine the Z-Values between probed points, it is often
useful to interpolate extra points using more advanced interpolation algorithms
to increase mesh density. These algorithms add curvature to the mesh,
attempting to simulate the material properties of the bed. Bed Mesh offers
lagrange and bicubic interpolation to accomplish this.
```
[bed_mesh]
speed: 120
horizontal_move_z: 5
mesh_min: 35, 6
mesh_max: 240, 198
probe_count: 5, 3
mesh_pps: 2, 3
algorithm: bicubic
bicubic_tension: 0.2
```
- `mesh_pps: 2, 3`\
_Default Value: 2, 2_\
The `mesh_pps` option is shorthand for Mesh Points Per Segment. This
option specifies how many points to interpolate for each segment along
the X and Y axes. Consider a 'segment' to be the space between each
probed point. Like `probe_count`, `mesh_pps` is specified as an X, Y
integer pair, and also may be specified a single integer that is applied
to both axes. In this example there are 4 segments along the X axis
and 2 segments along the Y axis. This evaluates to 8 interpolated
points along X, 6 interpolated points along Y, which results in a 13x8
mesh. Note that if mesh_pps is set to 0 then mesh interpolation is
disabled and the probed matrix will be sampled directly.
- `algorithm: lagrange`\
_Default Value: lagrange_\
The algorithm used to interpolate the mesh. May be `lagrange` or `bicubic`.
Lagrange interpolation is capped at 6 probed points as oscillation tends to
occur with a larger number of samples. Bicubic interpolation requires a
minimum of 4 probed points along each axis, if less than 4 points are
specified then lagrange sampling is forced. If `mesh_pps` is set to 0 then
this value is ignored as no mesh interpolation is done.
- `bicubic_tension: 0.2`\
_Default Value: 0.2_\
If the `algorithm` option is set to bicubic it is possible to specify the
tension value. The higher the tension the more slope is interpolated. Be
careful when adjusting this, as higher values also create more overshoot,
which will result in interpolated values higher or lower than your probed
points.
The illustration below shows how the options above are used to generate an
interpolated mesh.
![bedmesh_interpolated](img/bedmesh_interpolated.svg)
### Move Splitting
Bed Mesh works by intercepting gcode move commands and applying a
transform to their Z coordinate. Long moves must be split into smaller
moves to correctly follow the shape of the bed. The options below
control the splitting behavior.
```
[bed_mesh]
speed: 120
horizontal_move_z: 5
mesh_min: 35, 6
mesh_max: 240, 198
probe_count: 5, 3
move_check_distance: 5
split_delta_z: .025
```
- `move_check_distance: 5`\
_Default Value: 5_\
The minimum distance to check for the desired change in Z before performing
a split. In this example, a move longer than 5mm will be traversed by the
algorithm. Each 5mm a mesh Z lookup will occur, comparing it with the Z
value of the previous move. If the delta meets the threshold set by
`split_delta_z`, the move will be split and traversal will continue. This
process repeats until the end of the move is reached, where a final
adjustment will be applied. Moves shorter than the `move_check_distance`
have the correct Z adjustment applied directly to the move without
traversal or splitting.
- `split_delta_z: .025`\
_Default Value: .025_\
As mentioned above, this is the minimum deviation required to trigger a
move split. In this example, any Z value with a deviation +/- .025mm
will trigger a split.
Generally the default values for these options are sufficient, in fact the
default value of 5mm for the `move_check_distance` may be overkill. However an
advanced user may wish to experiment with these options in an effort to squeeze
out the optimial first layer.
### Mesh Fade
When "fade" is enabled Z adjustment is phased out over a distance defined
by the configuration. This is accomplished by applying small adjustments
to the layer height, either increasing or decreasing depending on the shape
of the bed. When fade has completed, Z adjustment is no longer applied,
allowing the top of the print to be flat rather than mirror the shape of the
bed. Fade also may have some undesirable traits, if you fade too quickly it
can result in visible artifacts on the print. Also, if your bed is
significantly warped, fade can shrink or stretch the Z height of the print.
As such, fade is disabled by default.
```
[bed_mesh]
speed: 120
horizontal_move_z: 5
mesh_min: 35, 6
mesh_max: 240, 198
probe_count: 5, 3
fade_start: 1
fade_end: 10
fade_target: 0
```
- `fade_start: 1`\
_Default Value: 1_\
The Z height in which to start phasing out adjustment. It is a good idea
to get a few layers down before starting the fade process.
- `fade_end: 10`\
_Default Value: 0_\
The Z height in which fade should complete. If this value is lower than
`fade_start` then fade is disabled. This value may be adjusted depending
on how warped the print surface is. A significantly warped surface should
fade out over a longer distance. A near flat surface may be able to reduce
this value to phase out more quickly. 10mm is a sane value to begin with if
using the default value of 1 for `fade_start`.
- `fade_target: 0`\
_Default Value: The average Z value of the mesh_\
The `fade_target` can be thought of as an additional Z offset applied to the
entire bed after fade completes. Generally speaking we would like this value
to be 0, however there are circumstances where it should not be. For
example, lets assume your homing position on the bed is an outlier, its
.2 mm lower than the average probed height of the bed. If the `fade_target`
is 0, fade will shrink the print by an average of .2 mm across the bed. By
setting the `fade_target` to .2, the homed area will expand by .2 mm, however
the rest of the bed will have an accurately sized. Generally its a good idea
to leave `fade_target` out of the configuration so the average height of the
mesh is used, however it may be desirable to manually adjust the fade target
if one wants to print on a specific portion of the bed.
### The Relative Reference Index
Most probes are suceptible to drift, ie: inaccuracies in probing introduced by
heat or interference. This can make calculating the probe's z-offset
challenging, particuarly at different bed temperatures. As such, some printers
use an endstop for homing the Z axis, and a probe for calibrating the mesh.
These printers can benefit from configuring the relative reference index.
```
[bed_mesh]
speed: 120
horizontal_move_z: 5
mesh_min: 35, 6
mesh_max: 240, 198
probe_count: 5, 3
relative_reference_index: 7
```
- `relative_reference_index: 7`\
_Default Value: None (disabled)_\
When the probed points are generated they are each assigned an index. You
can look up this index in klippy.log or by using BED_MESH_OUTPUT (see the
section on Bed Mesh GCodes below for more information). If you assign an
index to the `relative_reference_index` option, the value probed at this
coordinate will replace the probe's z_offset. This effectively makes
this coordinate the "zero" reference for the mesh.
When using the relative reference index, you should choose the index nearest
to the spot on the bed where Z endstop calibration was done. Note that
when looking up the index using the log or BED_MESH_OUTPUT, you should use
the coordinates listed under the "Probe" header to find the correct index.
### Faulty Regions
It is possible for some areas of a bed to report inaccurate results when
probing due to a "fault" at specific locations. The best example of this
are beds with series of integrated magnets used to retain removable steel
sheets. The magnetic field at and around these magnets may cause an inductive
probe to trigger at a distance higher or lower than it would otherwise,
resulting in a mesh that does not accurately represent the surface at these
locations. **Note: This should not be confused with probe location bias, which
produces inaccurate results across the entire bed.**
The `faulty_region` options may be configured to compensate for this affect.
If a generated point lies within a faulty region bed mesh will attempt to
probe up to 4 points at the boundaries of this region. These probed values
will be averaged and inserted in the mesh as the Z value at the generated
(X, Y) coordinate.
```
[bed_mesh]
speed: 120
horizontal_move_z: 5
mesh_min: 35, 6
mesh_max: 240, 198
probe_count: 5, 3
faulty_region_1_min: 130.0, 0.0
faulty_region_1_max: 145.0, 40.0
faulty_region_2_min: 225.0, 0.0
faulty_region_2_max: 250.0, 25.0
faulty_region_3_min: 165.0, 95.0
faulty_region_3_max: 205.0, 110.0
faulty_region_4_min: 30.0, 170.0
faulty_region_4_max: 45.0, 210.0
```
- `faulty_region_{1...99}_min`\
`faulty_region_{1..99}_max`\
_Default Value: None (disabled)_\
Faulty Regions are defined in a way similar to that of mesh itself, where
minimum and maximum (X, Y) coordinates must be specified for each region.
A faulty region may extend outside of a mesh, however the alternate points
generated will always be within the mesh boundary. No two regions may
overlap.
The image below illustrates how replacement points are generated when
a generated point lies within a faulty region. The regions shown match those
in the sample config above. The replacement points and their coordinates
are identified in green.
![bedmesh_interpolated](img/bedmesh_faulty_regions.svg)
## Bed Mesh Gcodes
### Calibration
`BED_MESH_CALIBRATE PROFILE=<name> METHOD=[manual | automatic] [<probe_parameter>=<value>]
[<mesh_parameter>=<value>]`\
_Default Profile: default_\
_Default Method: automatic if a probe is detected, otherwise manual_
Initiates the probing procedure for Bed Mesh Calibration.
The mesh will be saved into a profile specified by the `PROFILE` parameter,
or `default` if unspecified. If `METHOD=manual` is selected then manual probing
will occur. When switching between automatic and manual probing the generated
mesh points will automatically be adjusted.
It is possible to specify mesh parameters to modify the probed area. The
following parameters are available:
- Rectangular beds (cartesian):
- `MESH_MIN`
- `MESH_MAX`
- `PROBE_COUNT`
- Round beds (delta):
- `MESH_RADIUS`
- `MESH_ORIGIN`
- `ROUND_PROBE_COUNT`
- All beds:
- `RELATIVE_REFERNCE_INDEX`
- `ALGORITHM`
See the configuration documentation above for details on how each parameter
applies to the mesh.
### Profiles
`BED_MESH_PROFILE SAVE=<name> LOAD=<name> REMOVE=<name>`
After a BED_MESH_CALIBRATE has been performed, it is possible to save the
current mesh state into a named profile. This makes it possible to load
a mesh without re-probing the bed. After a profile has been saved using
`BED_MESH_PROFILE SAVE=<name>` the `SAVE_CONFIG` gcode may be executed
to write the profile to printer.cfg.
Profiles can be loaded by executing `BED_MESH_PROFILE LOAD=<name>`.
It should be noted that each time a BED_MESH_CALIBRATE occurs, the current
state is automatically saved to the _default_ profile. If this profile
exists it is automatically loaded when Klipper starts. If this behavior
is not desirable the _default_ profile can be removed as follows:
`BED_MESH_PROFILE REMOVE=default`
Any other saved profile can be removed in the same fashion, replacing
_default_ with the named profile you wish to remove.
### Output
`BED_MESH_OUTPUT PGP=[0 | 1]`
Outputs the current mesh state to the terminal. Note that the mesh itself
is output
The PGP parameter is shorthand for "Print Generated Points". If `PGP=1` is
set, the generated probed points will be output to the terminal:
```
// bed_mesh: generated points
// Index | Tool Adjusted | Probe
// 0 | (11.0, 1.0) | (35.0, 6.0)
// 1 | (62.2, 1.0) | (86.2, 6.0)
// 2 | (113.5, 1.0) | (137.5, 6.0)
// 3 | (164.8, 1.0) | (188.8, 6.0)
// 4 | (216.0, 1.0) | (240.0, 6.0)
// 5 | (216.0, 97.0) | (240.0, 102.0)
// 6 | (164.8, 97.0) | (188.8, 102.0)
// 7 | (113.5, 97.0) | (137.5, 102.0)
// 8 | (62.2, 97.0) | (86.2, 102.0)
// 9 | (11.0, 97.0) | (35.0, 102.0)
// 10 | (11.0, 193.0) | (35.0, 198.0)
// 11 | (62.2, 193.0) | (86.2, 198.0)
// 12 | (113.5, 193.0) | (137.5, 198.0)
// 13 | (164.8, 193.0) | (188.8, 198.0)
// 14 | (216.0, 193.0) | (240.0, 198.0)
```
The "Tool Adjusted" points refer to the nozzle location for each point, and
the "Probe" points refer to the probe location. Note that when manually
probing the "Probe" points will refer to both the tool and nozzle locations.
### Clear Mesh State
`BED_MESH_CLEAR`
This gcode may be used to clear the internal mesh state.
### Apply X/Y offsets
`BED_MESH_OFFSET [X=<value>] [Y=<value>]`
This is useful for printers with multiple independent extruders, as an offset
is necessary to produce correct Z adjustment after a tool change. Offsets
should be specified relative to the primary extruder. That is, a positive
X offset should be specified if the secondary extruder is mounted to the
right of the primary extruder, and a positive Y offset should be specified
if the secondary extruder is mounted "behind" the primary extruder.

428
docs/Benchmarks.md Normal file
View File

@@ -0,0 +1,428 @@
# Benchmarks
This document describes Klipper benchmarks.
## Micro-controller Benchmarks
This section describes the mechanism used to generate the Klipper
micro-controller step rate benchmarks.
The primary goal of the benchmarks is to provide a consistent
mechanism for measuring the impact of coding changes within the
software. A secondary goal is to provide high-level metrics for
comparing the performance between chips and between software
platforms.
The step rate benchmark is designed to find the maximum stepping rate
that the hardware and software can reach. This benchmark stepping rate
is not achievable in day-to-day use as Klipper needs to perform other
tasks (eg, mcu/host communication, temperature reading, endstop
checking) in any real-world usage.
In general, the pins for the benchmark tests are chosen to flash LEDs
or other innocuous pins. **Always verify that it is safe to drive the
configured pins prior to running a benchmark.** It is not recommended
to drive an actual stepper during a benchmark.
### Step rate benchmark test
The test is performed using the console.py tool (described in
[Debugging.md](Debugging.md)). The micro-controller is configured for
the particular hardware platform (see below) and then the following is
cut-and-paste into the console.py terminal window:
```
SET start_clock {clock+freq}
SET ticks 1000
reset_step_clock oid=0 clock={start_clock}
set_next_step_dir oid=0 dir=0
queue_step oid=0 interval={ticks} count=60000 add=0
set_next_step_dir oid=0 dir=1
queue_step oid=0 interval=3000 count=1 add=0
reset_step_clock oid=1 clock={start_clock}
set_next_step_dir oid=1 dir=0
queue_step oid=1 interval={ticks} count=60000 add=0
set_next_step_dir oid=1 dir=1
queue_step oid=1 interval=3000 count=1 add=0
reset_step_clock oid=2 clock={start_clock}
set_next_step_dir oid=2 dir=0
queue_step oid=2 interval={ticks} count=60000 add=0
set_next_step_dir oid=2 dir=1
queue_step oid=2 interval=3000 count=1 add=0
```
The above tests three steppers simultaneously stepping. If running the
above results in a "Rescheduled timer in the past" or "Stepper too far
in past" error then it indicates the `ticks` parameter is too low (it
results in a stepping rate that is too fast). The goal is to find the
lowest setting of the ticks parameter that reliably results in a
successful completion of the test. It should be possible to bisect the
ticks parameter until a stable value is found.
On a failure, one can copy-and-paste the following to clear the error
in preparation for the next test:
```
clear_shutdown
```
To obtain the single stepper benchmarks, the same configuration
sequence is used, but only the first block of the above test is
cut-and-paste into the console.py window.
To produce the benchmarks found in the [Features](Features.md) document, the total
number of steps per second is calculated by multiplying the number of
active steppers with the nominal mcu frequency and dividing by the
final ticks parameter. The results are rounded to the nearest K. For
example, with three active steppers:
```
ECHO Test result is: {"%.0fK" % (3. * freq / ticks / 1000.)}
```
The benchmarks are run with parameters suitable for TMC Drivers. For
micro-controllers that support `STEPPER_BOTH_EDGE=1` (as reported in
the `MCU config` line when console.py first starts) use
`step_pulse_duration=0` and `invert_step=-1` to enable optimized
stepping on both edges of the step pulse. For other micro-controllers
use a `step_pulse_duration` corresponding to 100ns.
### AVR step rate benchmark
The following configuration sequence is used on AVR chips:
```
allocate_oids count=3
config_stepper oid=0 step_pin=PA5 dir_pin=PA4 invert_step=0 step_pulse_ticks=32
config_stepper oid=1 step_pin=PA3 dir_pin=PA2 invert_step=0 step_pulse_ticks=32
config_stepper oid=2 step_pin=PC7 dir_pin=PC6 invert_step=0 step_pulse_ticks=32
finalize_config crc=0
```
The test was last run on commit `59314d99` with gcc version `avr-gcc
(GCC) 5.4.0`. Both the 16Mhz and 20Mhz tests were run using simulavr
configured for an atmega644p (previous tests have confirmed simulavr
results match tests on both a 16Mhz at90usb and a 16Mhz atmega2560).
| avr | ticks |
| ---------------- | ----- |
| 1 stepper | 102 |
| 3 stepper | 486 |
### Arduino Due step rate benchmark
The following configuration sequence is used on the Due:
```
allocate_oids count=3
config_stepper oid=0 step_pin=PB27 dir_pin=PA21 invert_step=-1 step_pulse_ticks=0
config_stepper oid=1 step_pin=PB26 dir_pin=PC30 invert_step=-1 step_pulse_ticks=0
config_stepper oid=2 step_pin=PA21 dir_pin=PC30 invert_step=-1 step_pulse_ticks=0
finalize_config crc=0
```
The test was last run on commit `59314d99` with gcc version
`arm-none-eabi-gcc (Fedora 10.2.0-4.fc34) 10.2.0`.
| sam3x8e | ticks |
| -------------------- | ----- |
| 1 stepper | 66 |
| 3 stepper | 257 |
### Duet Maestro step rate benchmark
The following configuration sequence is used on the Duet Maestro:
```
allocate_oids count=3
config_stepper oid=0 step_pin=PC26 dir_pin=PC18 invert_step=-1 step_pulse_ticks=0
config_stepper oid=1 step_pin=PC26 dir_pin=PA8 invert_step=-1 step_pulse_ticks=0
config_stepper oid=2 step_pin=PC26 dir_pin=PB4 invert_step=-1 step_pulse_ticks=0
finalize_config crc=0
```
The test was last run on commit `59314d99` with gcc version
`arm-none-eabi-gcc (Fedora 10.2.0-4.fc34) 10.2.0`.
| sam4s8c | ticks |
| -------------------- | ----- |
| 1 stepper | 71 |
| 3 stepper | 260 |
### Duet Wifi step rate benchmark
The following configuration sequence is used on the Duet Wifi:
```
allocate_oids count=3
config_stepper oid=0 step_pin=PD6 dir_pin=PD11 invert_step=-1 step_pulse_ticks=0
config_stepper oid=1 step_pin=PD7 dir_pin=PD12 invert_step=-1 step_pulse_ticks=0
config_stepper oid=2 step_pin=PD8 dir_pin=PD13 invert_step=-1 step_pulse_ticks=0
finalize_config crc=0
```
The test was last run on commit `59314d99` with gcc version
`gcc version 10.3.1 20210621 (release) (GNU Arm Embedded Toolchain 10.3-2021.07)`.
| sam4e8e | ticks |
| ---------------- | ----- |
| 1 stepper | 48 |
| 3 stepper | 215 |
### Beaglebone PRU step rate benchmark
The following configuration sequence is used on the PRU:
```
allocate_oids count=3
config_stepper oid=0 step_pin=gpio0_23 dir_pin=gpio1_12 invert_step=0 step_pulse_ticks=20
config_stepper oid=1 step_pin=gpio1_15 dir_pin=gpio0_26 invert_step=0 step_pulse_ticks=20
config_stepper oid=2 step_pin=gpio0_22 dir_pin=gpio2_1 invert_step=0 step_pulse_ticks=20
finalize_config crc=0
```
The test was last run on commit `59314d99` with gcc version `pru-gcc
(GCC) 8.0.0 20170530 (experimental)`.
| pru | ticks |
| ---------------- | ----- |
| 1 stepper | 231 |
| 3 stepper | 847 |
### STM32F042 step rate benchmark
The following configuration sequence is used on the STM32F042:
```
allocate_oids count=3
config_stepper oid=0 step_pin=PA1 dir_pin=PA2 invert_step=-1 step_pulse_ticks=0
config_stepper oid=1 step_pin=PA3 dir_pin=PA2 invert_step=-1 step_pulse_ticks=0
config_stepper oid=2 step_pin=PB8 dir_pin=PA2 invert_step=-1 step_pulse_ticks=0
finalize_config crc=0
```
The test was last run on commit `59314d99` with gcc version
`arm-none-eabi-gcc (Fedora 10.2.0-4.fc34) 10.2.0`.
| stm32f042 | ticks |
| ---------------- | ----- |
| 1 stepper | 59 |
| 3 stepper | 249 |
### STM32F103 step rate benchmark
The following configuration sequence is used on the STM32F103:
```
allocate_oids count=3
config_stepper oid=0 step_pin=PC13 dir_pin=PB5 invert_step=-1 step_pulse_ticks=0
config_stepper oid=1 step_pin=PB3 dir_pin=PB6 invert_step=-1 step_pulse_ticks=0
config_stepper oid=2 step_pin=PA4 dir_pin=PB7 invert_step=-1 step_pulse_ticks=0
finalize_config crc=0
```
The test was last run on commit `59314d99` with gcc version
`arm-none-eabi-gcc (Fedora 10.2.0-4.fc34) 10.2.0`.
| stm32f103 | ticks |
| -------------------- | ----- |
| 1 stepper | 61 |
| 3 stepper | 264 |
### STM32F4 step rate benchmark
The following configuration sequence is used on the STM32F4:
```
allocate_oids count=3
config_stepper oid=0 step_pin=PA5 dir_pin=PB5 invert_step=-1 step_pulse_ticks=0
config_stepper oid=1 step_pin=PB2 dir_pin=PB6 invert_step=-1 step_pulse_ticks=0
config_stepper oid=2 step_pin=PB3 dir_pin=PB7 invert_step=-1 step_pulse_ticks=0
finalize_config crc=0
```
The test was last run on commit `59314d99` with gcc version
`arm-none-eabi-gcc (Fedora 10.2.0-4.fc34) 10.2.0`. The STM32F407
results were obtained by running an STM32F407 binary on an STM32F446
(and thus using a 168Mhz clock).
| stm32f446 | ticks |
| -------------------- | ----- |
| 1 stepper | 46 |
| 3 stepper | 205 |
| stm32f407 | ticks |
| -------------------- | ----- |
| 1 stepper | 46 |
| 3 stepper | 205 |
### STM32G0B1 step rate benchmark
The following configuration sequence is used on the STM32G0B1:
```
allocate_oids count=3
config_stepper oid=0 step_pin=PB13 dir_pin=PB12 invert_step=-1 step_pulse_ticks=0
config_stepper oid=1 step_pin=PB10 dir_pin=PB2 invert_step=-1 step_pulse_ticks=0
config_stepper oid=2 step_pin=PB0 dir_pin=PC5 invert_step=-1 step_pulse_ticks=0
finalize_config crc=0
```
The test was last run on commit `247cd753` with gcc version
`arm-none-eabi-gcc (Fedora 10.2.0-4.fc34) 10.2.0`.
| stm32g0b1 | ticks |
| ---------------- | ----- |
| 1 stepper | 58 |
| 3 stepper | 243 |
### LPC176x step rate benchmark
The following configuration sequence is used on the LPC176x:
```
allocate_oids count=3
config_stepper oid=0 step_pin=P1.20 dir_pin=P1.18 invert_step=-1 step_pulse_ticks=0
config_stepper oid=1 step_pin=P1.21 dir_pin=P1.18 invert_step=-1 step_pulse_ticks=0
config_stepper oid=2 step_pin=P1.23 dir_pin=P1.18 invert_step=-1 step_pulse_ticks=0
finalize_config crc=0
```
The test was last run on commit `59314d99` with gcc version
`arm-none-eabi-gcc (Fedora 10.2.0-4.fc34) 10.2.0`. The 120Mhz LPC1769
results were obtained by overclocking an LPC1768 to 120Mhz.
| lpc1768 | ticks |
| -------------------- | ----- |
| 1 stepper | 52 |
| 3 stepper | 222 |
| lpc1769 | ticks |
| -------------------- | ----- |
| 1 stepper | 51 |
| 3 stepper | 222 |
### SAMD21 step rate benchmark
The following configuration sequence is used on the SAMD21:
```
allocate_oids count=3
config_stepper oid=0 step_pin=PA27 dir_pin=PA20 invert_step=-1 step_pulse_ticks=0
config_stepper oid=1 step_pin=PB3 dir_pin=PA21 invert_step=-1 step_pulse_ticks=0
config_stepper oid=2 step_pin=PA17 dir_pin=PA21 invert_step=-1 step_pulse_ticks=0
finalize_config crc=0
```
The test was last run on commit `59314d99` with gcc version
`arm-none-eabi-gcc (Fedora 10.2.0-4.fc34) 10.2.0` on a SAMD21G18
micro-controller.
| samd21 | ticks |
| -------------------- | ----- |
| 1 stepper | 70 |
| 3 stepper | 306 |
### SAMD51 step rate benchmark
The following configuration sequence is used on the SAMD51:
```
allocate_oids count=3
config_stepper oid=0 step_pin=PA22 dir_pin=PA20 invert_step=-1 step_pulse_ticks=0
config_stepper oid=1 step_pin=PA22 dir_pin=PA21 invert_step=-1 step_pulse_ticks=0
config_stepper oid=2 step_pin=PA22 dir_pin=PA19 invert_step=-1 step_pulse_ticks=0
finalize_config crc=0
```
The test was last run on commit `59314d99` with gcc version
`arm-none-eabi-gcc (Fedora 10.2.0-4.fc34) 10.2.0` on a SAMD51J19A
micro-controller.
| samd51 | ticks |
| -------------------- | ----- |
| 1 stepper | 39 |
| 3 stepper | 191 |
| 1 stepper (200Mhz) | 39 |
| 3 stepper (200Mhz) | 181 |
### RP2040 step rate benchmark
The following configuration sequence is used on the RP2040:
```
allocate_oids count=3
config_stepper oid=0 step_pin=gpio25 dir_pin=gpio3 invert_step=-1 step_pulse_ticks=0
config_stepper oid=1 step_pin=gpio26 dir_pin=gpio4 invert_step=-1 step_pulse_ticks=0
config_stepper oid=2 step_pin=gpio27 dir_pin=gpio5 invert_step=-1 step_pulse_ticks=0
finalize_config crc=0
```
The test was last run on commit `59314d99` with gcc version
`arm-none-eabi-gcc (Fedora 10.2.0-4.fc34) 10.2.0` on a Raspberry Pi
Pico board.
| rp2040 | ticks |
| -------------------- | ----- |
| 1 stepper | 5 |
| 3 stepper | 22 |
### Linux MCU step rate benchmark
The following configuration sequence is used on a Raspberry Pi:
```
allocate_oids count=3
config_stepper oid=0 step_pin=gpio2 dir_pin=gpio3 invert_step=0 step_pulse_ticks=5
config_stepper oid=1 step_pin=gpio4 dir_pin=gpio5 invert_step=0 step_pulse_ticks=5
config_stepper oid=2 step_pin=gpio6 dir_pin=gpio17 invert_step=0 step_pulse_ticks=5
finalize_config crc=0
```
The test was last run on commit `59314d99` with gcc version
`gcc (Raspbian 8.3.0-6+rpi1) 8.3.0` on a Raspberry Pi 3 (revision
a02082). It was difficult to get stable results in this benchmark.
| Linux (RPi3) | ticks |
| -------------------- | ----- |
| 1 stepper | 160 |
| 3 stepper | 380 |
## Command dispatch benchmark
The command dispatch benchmark tests how many "dummy" commands the
micro-controller can process. It is primarily a test of the hardware
communication mechanism. The test is run using the console.py tool
(described in [Debugging.md](Debugging.md)). The following is
cut-and-paste into the console.py terminal window:
```
DELAY {clock + 2*freq} get_uptime
FLOOD 100000 0.0 debug_nop
get_uptime
```
When the test completes, determine the difference between the clocks
reported in the two "uptime" response messages. The total number of
commands per second is then `100000 * mcu_frequency / clock_diff`.
Note that this test may saturate the USB/CPU capacity of a Raspberry
Pi. If running on a Raspberry Pi, Beaglebone, or similar host computer
then increase the delay (eg, `DELAY {clock + 20*freq} get_uptime`).
Where applicable, the benchmarks below are with console.py running on
a desktop class machine with the device connected via a high-speed
hub.
| MCU | Rate | Build | Build compiler |
| ------------------- | ---- | -------- | ------------------- |
| stm32f042 (CAN) | 18K | c105adc8 | arm-none-eabi-gcc (GNU Tools 7-2018-q3-update) 7.3.1 |
| atmega2560 (serial) | 23K | b161a69e | avr-gcc (GCC) 4.8.1 |
| sam3x8e (serial) | 23K | b161a69e | arm-none-eabi-gcc (Fedora 7.1.0-5.fc27) 7.1.0 |
| at90usb1286 (USB) | 75K | 01d2183f | avr-gcc (GCC) 5.4.0 |
| samd21 (USB) | 223K | 01d2183f | arm-none-eabi-gcc (Fedora 7.4.0-1.fc30) 7.4.0 |
| pru (shared memory) | 260K | c5968a08 | pru-gcc (GCC) 8.0.0 20170530 (experimental) |
| stm32f103 (USB) | 355K | 01d2183f | arm-none-eabi-gcc (Fedora 7.4.0-1.fc30) 7.4.0 |
| sam3x8e (USB) | 418K | 01d2183f | arm-none-eabi-gcc (Fedora 7.4.0-1.fc30) 7.4.0 |
| lpc1768 (USB) | 534K | 01d2183f | arm-none-eabi-gcc (Fedora 7.4.0-1.fc30) 7.4.0 |
| lpc1769 (USB) | 628K | 01d2183f | arm-none-eabi-gcc (Fedora 7.4.0-1.fc30) 7.4.0 |
| sam4s8c (USB) | 650K | 8d4a5c16 | arm-none-eabi-gcc (Fedora 7.4.0-1.fc30) 7.4.0 |
| samd51 (USB) | 864K | 01d2183f | arm-none-eabi-gcc (Fedora 7.4.0-1.fc30) 7.4.0 |
| stm32f446 (USB) | 870K | 01d2183f | arm-none-eabi-gcc (Fedora 7.4.0-1.fc30) 7.4.0 |
| rp2040 (USB) | 873K | c5667193 | arm-none-eabi-gcc (Fedora 10.2.0-4.fc34) 10.2.0 |
## Host Benchmarks
It is possible to run timing tests on the host software using the
"batch mode" processing mechanism (described in
[Debugging.md](Debugging.md)). This is typically done by choosing a
large and complex G-Code file and timing how long it takes for the
host software to process it. For example:
```
time ~/klippy-env/bin/python ./klippy/klippy.py config/example-cartesian.cfg -i something_complex.gcode -o /dev/null -d out/klipper.dict
```

620
docs/Bootloaders.md Normal file
View File

@@ -0,0 +1,620 @@
# Bootloaders
This document provides information on common bootloaders found on
micro-controllers that Klipper supports.
The bootloader is 3rd-party software that runs on the micro-controller
when it is first powered on. It is typically used to flash a new
application (eg, Klipper) to the micro-controller without requiring
specialized hardware. Unfortunately, there is no industry wide
standard for flashing a micro-controller, nor is there a standard
bootloader that works across all micro-controllers. Worse, it is
common for each bootloader to require a different set of steps to
flash an application.
If one can flash a bootloader to a micro-controller then one can
generally also use that mechanism to flash an application, but care
should be taken when doing this as one may inadvertently remove the
bootloader. In contrast, a bootloader will generally only permit a
user to flash an application. It is therefore recommended to use a
bootloader to flash an application where possible.
This document attempts to describe common bootloaders, the steps
needed to flash a bootloader, and the steps needed to flash an
application. This document is not an authoritative reference; it is
intended as a collection of useful information that the Klipper
developers have accumulated.
## AVR micro-controllers
In general, the Arduino project is a good reference for bootloaders
and flashing procedures on the 8-bit Atmel Atmega micro-controllers.
In particular, the "boards.txt" file:
[https://github.com/arduino/Arduino/blob/1.8.5/hardware/arduino/avr/boards.txt](https://github.com/arduino/Arduino/blob/1.8.5/hardware/arduino/avr/boards.txt)
is a useful reference.
To flash a bootloader itself, the AVR chips require an external
hardware flashing tool (which communicates with the chip using
SPI). This tool can be purchased (for example, do a web search for
"avr isp", "arduino isp", or "usb tiny isp"). It is also possible to
use another Arduino or Raspberry Pi to flash an AVR bootloader (for
example, do a web search for "program an avr using raspberry pi"). The
examples below are written assuming an "AVR ISP Mk2" type device is in
use.
The "avrdude" program is the most common tool used to flash atmega
chips (both bootloader flashing and application flashing).
### Atmega2560
This chip is typically found in the "Arduino Mega" and is very common
in 3d printer boards.
To flash the bootloader itself use something like:
```
wget 'https://github.com/arduino/Arduino/raw/1.8.5/hardware/arduino/avr/bootloaders/stk500v2/stk500boot_v2_mega2560.hex'
avrdude -cavrispv2 -patmega2560 -P/dev/ttyACM0 -b115200 -e -u -U lock:w:0x3F:m -U efuse:w:0xFD:m -U hfuse:w:0xD8:m -U lfuse:w:0xFF:m
avrdude -cavrispv2 -patmega2560 -P/dev/ttyACM0 -b115200 -U flash:w:stk500boot_v2_mega2560.hex
avrdude -cavrispv2 -patmega2560 -P/dev/ttyACM0 -b115200 -U lock:w:0x0F:m
```
To flash an application use something like:
```
avrdude -cwiring -patmega2560 -P/dev/ttyACM0 -b115200 -D -Uflash:w:out/klipper.elf.hex:i
```
### Atmega1280
This chip is typically found in earlier versions of the "Arduino
Mega".
To flash the bootloader itself use something like:
```
wget 'https://github.com/arduino/Arduino/raw/1.8.5/hardware/arduino/avr/bootloaders/atmega/ATmegaBOOT_168_atmega1280.hex'
avrdude -cavrispv2 -patmega1280 -P/dev/ttyACM0 -b115200 -e -u -U lock:w:0x3F:m -U efuse:w:0xF5:m -U hfuse:w:0xDA:m -U lfuse:w:0xFF:m
avrdude -cavrispv2 -patmega1280 -P/dev/ttyACM0 -b115200 -U flash:w:ATmegaBOOT_168_atmega1280.hex
avrdude -cavrispv2 -patmega1280 -P/dev/ttyACM0 -b115200 -U lock:w:0x0F:m
```
To flash an application use something like:
```
avrdude -carduino -patmega1280 -P/dev/ttyACM0 -b57600 -D -Uflash:w:out/klipper.elf.hex:i
```
### Atmega1284p
This chip is commonly found in "Melzi" style 3d printer boards.
To flash the bootloader itself use something like:
```
wget 'https://github.com/Lauszus/Sanguino/raw/1.0.2/bootloaders/optiboot/optiboot_atmega1284p.hex'
avrdude -cavrispv2 -patmega1284p -P/dev/ttyACM0 -b115200 -e -u -U lock:w:0x3F:m -U efuse:w:0xFD:m -U hfuse:w:0xDE:m -U lfuse:w:0xFF:m
avrdude -cavrispv2 -patmega1284p -P/dev/ttyACM0 -b115200 -U flash:w:optiboot_atmega1284p.hex
avrdude -cavrispv2 -patmega1284p -P/dev/ttyACM0 -b115200 -U lock:w:0x0F:m
```
To flash an application use something like:
```
avrdude -carduino -patmega1284p -P/dev/ttyACM0 -b115200 -D -Uflash:w:out/klipper.elf.hex:i
```
Note that a number of "Melzi" style boards come preloaded with a
bootloader that uses a baud rate of 57600. In this case, to flash an
application use something like this instead:
```
avrdude -carduino -patmega1284p -P/dev/ttyACM0 -b57600 -D -Uflash:w:out/klipper.elf.hex:i
```
### At90usb1286
This document does not cover the method to flash a bootloader to the
At90usb1286 nor does it cover general application flashing to this
device.
The Teensy++ device from pjrc.com comes with a proprietary bootloader.
It requires a custom flashing tool from
[https://github.com/PaulStoffregen/teensy_loader_cli](https://github.com/PaulStoffregen/teensy_loader_cli).
One can flash an application with it using something like:
```
teensy_loader_cli --mcu=at90usb1286 out/klipper.elf.hex -v
```
### Atmega168
The atmega168 has limited flash space. If using a bootloader, it is
recommended to use the Optiboot bootloader. To flash that bootloader
use something like:
```
wget 'https://github.com/arduino/Arduino/raw/1.8.5/hardware/arduino/avr/bootloaders/optiboot/optiboot_atmega168.hex'
avrdude -cavrispv2 -patmega168 -P/dev/ttyACM0 -b115200 -e -u -U lock:w:0x3F:m -U efuse:w:0x04:m -U hfuse:w:0xDD:m -U lfuse:w:0xFF:m
avrdude -cavrispv2 -patmega168 -P/dev/ttyACM0 -b115200 -U flash:w:optiboot_atmega168.hex
avrdude -cavrispv2 -patmega168 -P/dev/ttyACM0 -b115200 -U lock:w:0x0F:m
```
To flash an application via the Optiboot bootloader use something
like:
```
avrdude -carduino -patmega168 -P/dev/ttyACM0 -b115200 -D -Uflash:w:out/klipper.elf.hex:i
```
## SAM3 micro-controllers (Arduino Due)
It is not common to use a bootloader with the SAM3 mcu. The chip
itself has a ROM that allows the flash to be programmed from 3.3V
serial port or from USB.
To enable the ROM, the "erase" pin is held high during a reset, which
erases the flash contents, and causes the ROM to run. On an Arduino
Due, this sequence can be accomplished by setting a baud rate of 1200
on the "programming usb port" (the USB port closest to the power
supply).
The code at
[https://github.com/shumatech/BOSSA](https://github.com/shumatech/BOSSA)
can be used to program the SAM3. It is recommended to use version 1.9
or later.
To flash an application use something like:
```
bossac -U -p /dev/ttyACM0 -a -e -w out/klipper.bin -v -b
bossac -U -p /dev/ttyACM0 -R
```
## SAM4 micro-controllers (Duet Wifi)
It is not common to use a bootloader with the SAM4 mcu. The chip
itself has a ROM that allows the flash to be programmed from 3.3V
serial port or from USB.
To enable the ROM, the "erase" pin is held high during a reset, which
erases the flash contents, and causes the ROM to run.
The code at
[https://github.com/shumatech/BOSSA](https://github.com/shumatech/BOSSA)
can be used to program the SAM4. It is necessary to use version
`1.8.0` or higher.
To flash an application use something like:
```
bossac --port=/dev/ttyACM0 -b -U -e -w -v -R out/klipper.bin
```
## SAMD21 micro-controllers (Arduino Zero)
The SAMD21 bootloader is flashed via the ARM Serial Wire Debug (SWD)
interface. This is commonly done with a dedicated SWD hardware dongle.
Alternatively, one can use a
[Raspberry Pi with OpenOCD](#running-openocd-on-the-raspberry-pi).
To flash a bootloader with OpenOCD use the following chip config:
```
source [find target/at91samdXX.cfg]
```
Obtain a bootloader - for example:
```
wget 'https://github.com/arduino/ArduinoCore-samd/raw/1.8.3/bootloaders/zero/samd21_sam_ba.bin'
```
Flash with OpenOCD commands similar to:
```
at91samd bootloader 0
program samd21_sam_ba.bin verify
```
The most common bootloader on the SAMD21 is the one found on the
"Arduino Zero". It uses an 8KiB bootloader (the application must be
compiled with a start address of 8KiB). One can enter this bootloader
by double clicking the reset button. To flash an application use
something like:
```
bossac -U -p /dev/ttyACM0 --offset=0x2000 -w out/klipper.bin -v -b -R
```
In contrast, the "Arduino M0" uses a 16KiB bootloader (the application
must be compiled with a start address of 16KiB). To flash an
application on this bootloader, reset the micro-controller and run the
flash command within the first few seconds of boot - something like:
```
avrdude -c stk500v2 -p atmega2560 -P /dev/ttyACM0 -u -Uflash:w:out/klipper.elf.hex:i
```
## SAMD51 micro-controllers (Adafruit Metro-M4 and similar)
Like the SAMD21, the SAMD51 bootloader is flashed via the ARM Serial
Wire Debug (SWD) interface. To flash a bootloader with
[OpenOCD on a Raspberry Pi](#running-openocd-on-the-raspberry-pi) use
the following chip config:
```
source [find target/atsame5x.cfg]
```
Obtain a bootloader - several bootloaders are available from
[https://github.com/adafruit/uf2-samdx1/releases/latest](https://github.com/adafruit/uf2-samdx1/releases/latest). For example:
```
wget 'https://github.com/adafruit/uf2-samdx1/releases/download/v3.7.0/bootloader-itsybitsy_m4-v3.7.0.bin'
```
Flash with OpenOCD commands similar to:
```
at91samd bootloader 0
program bootloader-itsybitsy_m4-v3.7.0.bin verify
at91samd bootloader 16384
```
The SAMD51 uses a 16KiB bootloader (the application must be compiled
with a start address of 16KiB). To flash an application use something
like:
```
bossac -U -p /dev/ttyACM0 --offset=0x4000 -w out/klipper.bin -v -b -R
```
## STM32F103 micro-controllers (Blue Pill devices)
The STM32F103 devices have a ROM that can flash a bootloader or
application via 3.3V serial. Typically one would wire the PA10 (MCU
Rx) and PA9 (MCU Tx) pins to a 3.3V UART adapter. To access the ROM,
one should connect the "boot 0" pin to high and "boot 1" pin to low,
and then reset the device. The "stm32flash" package can then be used
to flash the device using something like:
```
stm32flash -w out/klipper.bin -v -g 0 /dev/ttyAMA0
```
Note that if one is using a Raspberry Pi for the 3.3V serial, the
stm32flash protocol uses a serial parity mode which the Raspberry Pi's
"mini UART" does not support. See
[https://www.raspberrypi.com/documentation/computers/configuration.html#configuring-uarts](https://www.raspberrypi.com/documentation/computers/configuration.html#configuring-uarts)
for details on enabling the full uart on the Raspberry Pi GPIO pins.
After flashing, set both "boot 0" and "boot 1" back to low so that
future resets boot from flash.
### STM32F103 with stm32duino bootloader
The "stm32duino" project has a USB capable bootloader - see:
[https://github.com/rogerclarkmelbourne/STM32duino-bootloader](https://github.com/rogerclarkmelbourne/STM32duino-bootloader)
This bootloader can be flashed via 3.3V serial with something like:
```
wget 'https://github.com/rogerclarkmelbourne/STM32duino-bootloader/raw/master/binaries/generic_boot20_pc13.bin'
stm32flash -w generic_boot20_pc13.bin -v -g 0 /dev/ttyAMA0
```
This bootloader uses 8KiB of flash space (the application must be
compiled with a start address of 8KiB). Flash an application with
something like:
```
dfu-util -d 1eaf:0003 -a 2 -R -D out/klipper.bin
```
The bootloader typically runs for only a short period after boot. It
may be necessary to time the above command so that it runs while the
bootloader is still active (the bootloader will flash a board led
while it is running). Alternatively, set the "boot 0" pin to low and
"boot 1" pin to high to stay in the bootloader after a reset.
### STM32F103 with HID bootloader
The [HID bootloader](https://github.com/Serasidis/STM32_HID_Bootloader) is a
compact, driverless bootloader capable of flashing over USB. Also available
is a [fork with builds specific to the SKR Mini E3 1.2](
https://github.com/Arksine/STM32_HID_Bootloader/releases/latest).
For generic STM32F103 boards such as the blue pill it is possible to flash
the bootloader via 3.3v serial using stm32flash as noted in the stm32duino
section above, substituting the file name for the desired hid bootloader binary
(ie: hid_generic_pc13.bin for the blue pill).
It is not possible to use stm32flash for the SKR Mini E3 as the boot0 pin is
tied directly to ground and not broken out via header pins. It is recommended
to use a STLink V2 with STM32Cubeprogrammer to flash the bootloader. If you
don't have access to a STLink it is also possible to use a
[Raspberry Pi and OpenOCD](#running-openocd-on-the-raspberry-pi) with
the following chip config:
```
source [find target/stm32f1x.cfg]
```
If you wish you can make a backup of the current flash with the following
command. Note that it may take some time to complete:
```
flash read_bank 0 btt_skr_mini_e3_backup.bin
```
finally, you can flash with commands similar to:
```
stm32f1x mass_erase 0
program hid_btt_skr_mini_e3.bin verify 0x08000000
```
NOTES:
- The example above erases the chip then programs the bootloader. Regardless
of the method chosen to flash it is recommended to erase the chip prior to
flashing.
- Prior flashing the SKR Mini E3 with this bootloader you should be aware
that you will no longer be able to update firmware via the sdcard.
- You may need to hold down the reset button on the board while launching
OpenOCD. It should display something like:
```
Open On-Chip Debugger 0.10.0+dev-01204-gc60252ac-dirty (2020-04-27-16:00)
Licensed under GNU GPL v2
For bug reports, read
http://openocd.org/doc/doxygen/bugs.html
DEPRECATED! use 'adapter speed' not 'adapter_khz'
Info : BCM2835 GPIO JTAG/SWD bitbang driver
Info : JTAG and SWD modes enabled
Info : clock speed 40 kHz
Info : SWD DPIDR 0x1ba01477
Info : stm32f1x.cpu: hardware has 6 breakpoints, 4 watchpoints
Info : stm32f1x.cpu: external reset detected
Info : starting gdb server for stm32f1x.cpu on 3333
Info : Listening on port 3333 for gdb connections
```
After which you can release the reset button.
This bootloader requires 2KiB of flash space (the application
must be compiled with a start address of 2KiB).
The hid-flash program is used to upload a binary to the bootloader. You
can install this software with the following commands:
```
sudo apt install libusb-1.0
cd ~/klipper/lib/hidflash
make
```
If the bootloader is running you can flash with something like:
```
~/klipper/lib/hidflash/hid-flash ~/klipper/out/klipper.bin
```
alternatively, you can use `make flash` to flash klipper directly:
```
make flash FLASH_DEVICE=1209:BEBA
```
OR if klipper has been previously flashed:
```
make flash FLASH_DEVICE=/dev/ttyACM0
```
It may be necessary to manually enter the bootloader, this can be done by
setting "boot 0" low and "boot 1" high. On the SKR Mini E3 "Boot 1" is
not available, so it may be done by setting pin PA2 low if you flashed
"hid_btt_skr_mini_e3.bin". This pin is labeld "TX0" on the TFT header in
the SKR Mini E3's "PIN" document. There is a ground pin next to PA2
which you can use to pull PA2 low.
### STM32F103/STM32F072 with MSC bootloader
The [MSC bootloader](https://github.com/Telekatz/MSC-stm32f103-bootloader) is a driverless bootloader capable of flashing over USB.
It is possible to flash the bootloader via 3.3v serial using stm32flash as noted
in the stm32duino section above, substituting the file name for the desired
MSC bootloader binary (ie: MSCboot-Bluepill.bin for the blue pill).
For STM32F072 boards it is also possible to flash the bootloader over USB (via DFU)
with something like:
```
dfu-util -d 0483:df11 -a 0 -R -D MSCboot-STM32F072.bin -s0x08000000:leave
```
This bootloader uses 8KiB or 16KiB of flash space, see description of the bootloader
(the application must be compiled with with the corresponding starting address).
The bootloader can be activated by pressing the reset button of the board twice.
As soon as the bootloader is activated, the board appears as a USB flash drive
onto which the klipper.bin file can be copied.
### STM32F103/STM32F0x2 with CanBoot bootloader
The [CanBoot](https://github.com/Arksine/CanBoot) bootloader provides an option
for uploading Klipper firmware over the CANBUS. The bootloader itself is
derived from Klipper's source code. Currently CanBoot supports the STM32F103,
STM32F042, and STM32F072 models.
It is recommended to use a ST-Link Programmer to flash CanBoot, however it
should be possible to flash using `stm32flash` on STM32F103 devices, and
`dfu-util` on STM32F042/STM32F072 devices. See the previous sections in this
document for instructions on these flashing methods, substituting `canboot.bin`
for the file name where appropriate. The CanBoot repo linked above provides
instructions for building the bootloader.
The first time CanBoot has been flashed it should detect that no application
is present and enter the bootloader. If this doesn't occur it is possible to
enter the bootloader by pressing the reset button twice in succession.
The `flash_can.py` utility supplied in the `lib/canboot` folder may be used to
upload Klipper firmware. The device UUID is necessary to flash. If you do not
have a UUID it is possible to query nodes currently running the bootloader:
```
python3 flash_can.py -q
```
This will return UUIDs for all connected nodes not currently assigned a UUID.
This should include all nodes currently in the bootloader.
Once you have a UUID, you may upload firmware with following command:
```
python3 flash_can.py -i can0 -f ~/klipper/out/klipper.bin -u aabbccddeeff
```
Where `aabbccddeeff` is replaced by your UUID. Note that the `-i` and `-f`
options may be omitted, they default to `can0` and `~/klipper/out/klipper.bin`
respectively.
When building Klipper for use with CanBoot, select the 8 KiB Bootloader option.
## STM32F4 micro-controllers (SKR Pro 1.1)
STM32F4 microcontrollers come equipped with a built-in system bootloader
capable of flashing over USB (via DFU), 3.3v Serial, and various other
methods (see STM Document AN2606 for more information). Some
STM32F4 boards, such as the SKR Pro 1.1, are not able to enter the DFU
bootloader. The HID bootloader is available for STM32F405/407
based boards should the user prefer flashing over USB over using the sdcard.
Note that you may need to configure and build a version specific to your
board, a [build for the SKR Pro 1.1 is available here](
https://github.com/Arksine/STM32_HID_Bootloader/releases/latest).
Unless your board is DFU capable the most accessable flashing method
is likely via 3.3v serial, which follows the same procedure as
[flashing the STM32F103 using stm32flash](#stm32f103-micro-controllers-blue-pill-devices).
For example:
```
wget https://github.com/Arksine/STM32_HID_Bootloader/releases/download/v0.5-beta/hid_bootloader_SKR_PRO.bin
stm32flash -w hid_bootloader_SKR_PRO.bin -v -g 0 /dev/ttyAMA0
```
This bootloader requires 16Kib of flash space on the STM32F4 (the application
must be compiled with a start address of 16KiB).
As with the STM32F1, the STM32F4 uses the hid-flash tool to upload binaries to
the MCU. See the instructions above for details on how to build and use
hid-flash.
It may be necessary to manually enter the bootloader, this can be done by
setting "boot 0" low, "boot 1" high and plugging in the device. After
programming is complete unplug the device and set "boot 1" back to low
so the application will be loaded.
## LPC176x micro-controllers (Smoothieboards)
This document does not describe the method to flash a bootloader
itself - see:
[http://smoothieware.org/flashing-the-bootloader](http://smoothieware.org/flashing-the-bootloader)
for further information on that topic.
It is common for Smoothieboards to come with a bootloader from:
[https://github.com/triffid/LPC17xx-DFU-Bootloader](https://github.com/triffid/LPC17xx-DFU-Bootloader).
When using this bootloader the application must be compiled with a
start address of 16KiB. The easiest way to flash an application with
this bootloader is to copy the application file (eg,
`out/klipper.bin`) to a file named `firmware.bin` on an SD card, and
then to reboot the micro-controller with that SD card.
## Running OpenOCD on the Raspberry PI
OpenOCD is a software package that can perform low-level chip flashing
and debugging. It can use the GPIO pins on a Raspberry Pi to
communicate with a variety of ARM chips.
This section describes how one can install and launch OpenOCD. It is
derived from the instructions at:
[https://learn.adafruit.com/programming-microcontrollers-using-openocd-on-raspberry-pi](https://learn.adafruit.com/programming-microcontrollers-using-openocd-on-raspberry-pi)
Begin by downloading and compiling the software (each step may take
several minutes and the "make" step may take 30+ minutes):
```
sudo apt-get update
sudo apt-get install autoconf libtool telnet
mkdir ~/openocd
cd ~/openocd/
git clone http://openocd.zylin.com/openocd
cd openocd
./bootstrap
./configure --enable-sysfsgpio --enable-bcm2835gpio --prefix=/home/pi/openocd/install
make
make install
```
### Configure OpenOCD
Create an OpenOCD config file:
```
nano ~/openocd/openocd.cfg
```
Use a config similar to the following:
```
# Uses RPi pins: GPIO25 for SWDCLK, GPIO24 for SWDIO, GPIO18 for nRST
source [find interface/raspberrypi2-native.cfg]
bcm2835gpio_swd_nums 25 24
bcm2835gpio_srst_num 18
transport select swd
# Use hardware reset wire for chip resets
reset_config srst_only
adapter_nsrst_delay 100
adapter_nsrst_assert_width 100
# Specify the chip type
source [find target/atsame5x.cfg]
# Set the adapter speed
adapter_khz 40
# Connect to chip
init
targets
reset halt
```
### Wire the Raspberry Pi to the target chip
Poweroff both the the Raspberry Pi and the target chip before wiring!
Verify the target chip uses 3.3V prior to connecting to a Raspberry
Pi!
Connect GND, SWDCLK, SWDIO, and RST on the target chip to GND, GPIO25,
GPIO24, and GPIO18 respectively on the Raspberry Pi.
Then power up the Raspberry Pi and provide power to the target chip.
### Run OpenOCD
Run OpenOCD:
```
cd ~/openocd/
sudo ~/openocd/install/bin/openocd -f ~/openocd/openocd.cfg
```
The above should cause OpenOCD to emit some text messages and then
wait (it should not immediately return to the Unix shell prompt). If
OpenOCD exits on its own or if it continues to emit text messages then
double check the wiring.
Once OpenOCD is running and is stable, one can send it commands via
telnet. Open another ssh session and run the following:
```
telnet 127.0.0.1 4444
```
(One can exit telnet by pressing ctrl+] and then running the "quit"
command.)
### OpenOCD and gdb
It is possible to use OpenOCD with gdb to debug Klipper. The following
commands assume one is running gdb on a desktop class machine.
Add the following to the OpenOCD config file:
```
bindto 0.0.0.0
gdb_port 44444
```
Restart OpenOCD on the Raspberry Pi and then run the following Unix
command on the desktop machine:
```
cd /path/to/klipper/
gdb out/klipper.elf
```
Within gdb run:
```
target remote octopi:44444
```
(Replace "octopi" with the host name of the Raspberry Pi.) Once gdb is
running it is possible to set breakpoints and to inspect registers.

124
docs/CANBUS.md Normal file
View File

@@ -0,0 +1,124 @@
# CANBUS
This document describes Klipper's CAN bus support.
## Device Hardware
Klipper currently only supports CAN on stm32 chips. In addition, the
micro-controller chip must support CAN and it must be on a board that
has a CAN transceiver.
To compile for CAN, run `make menuconfig` and select "CAN bus" as the
communication interface. Finally, compile the micro-controller code
and flash it to the target board.
## Host Hardware
In order to use a CAN bus, it is necessary to have a host adapter.
There are currently two common options:
1. Use a
[Waveshare Raspberry Pi CAN hat](https://www.waveshare.com/rs485-can-hat.htm)
or one of its many clones.
2. Use a USB CAN adapter (for example
[https://hacker-gadgets.com/product/cantact-usb-can-adapter/](https://hacker-gadgets.com/product/cantact-usb-can-adapter/)). There
are many different USB to CAN adapters available - when choosing
one, we recommend verifying it can run the
[candlelight firmware](https://github.com/candle-usb/candleLight_fw).
(Unfortunately, we've found some USB adapters run defective
firmware and are locked down, so verify before purchasing.)
It is also necessary to configure the host operating system to use the
adapter. This is typically done by creating a new file named
`/etc/network/interfaces.d/can0` with the following contents:
```
auto can0
iface can0 can static
bitrate 500000
up ifconfig $IFACE txqueuelen 128
```
Note that the "Raspberry Pi CAN hat" also requires
[changes to config.txt](https://www.waveshare.com/wiki/RS485_CAN_HAT).
## Terminating Resistors
A CAN bus should have two 120 ohm resistors between the CANH and CANL
wires. Ideally, one resistor located at each the end of the bus.
Note that some devices have a builtin 120 ohm resistor (for example,
the "Waveshare Raspberry Pi CAN hat" has a soldered on resistor that
can not be easily removed). Some devices do not include a resistor at
all. Other devices have a mechanism to select the resistor (typically
by connecting a "pin jumper"). Be sure to check the schematics of all
devices on the CAN bus to verify that there are two and only two 120
Ohm resistors on the bus.
To test that the resistors are correct, one can remove power to the
printer and use a multi-meter to check the resistance between the CANH
and CANL wires - it should report ~60 ohms on a correctly wired CAN
bus.
## Finding the canbus_uuid for new micro-controllers
Each micro-controller on the CAN bus is assigned a unique id based on
the factory chip identifier encoded into each micro-controller. To
find each micro-controller device id, make sure the hardware is
powered and wired correctly, and then run:
```
~/klippy-env/bin/python ~/klipper/scripts/canbus_query.py can0
```
If uninitialized CAN devices are detected the above command will
report lines like the following:
```
Found canbus_uuid=11aa22bb33cc
```
Each device will have a unique identifier. In the above example,
`11aa22bb33cc` is the micro-controller's "canbus_uuid".
Note that the `canbus_query.py` tool will only report uninitialized
devices - if Klipper (or a similar tool) configures the device then it
will no longer appear in the list.
## Configuring Klipper
Update the Klipper [mcu configuration](Config_Reference.md#mcu) to use
the CAN bus to communicate with the device - for example:
```
[mcu my_can_mcu]
canbus_uuid: 11aa22bb33cc
```
## USB to CAN bus bridge mode
Some micro-controllers support selecting "USB to CAN bus bridge" mode
during "make menuconfig". This mode may allow one to use a
micro-controller as both a "USB to CAN bus adapter" and as a Klipper
node.
When Klipper uses this mode the micro-controller appears as a "USB CAN
bus adapter" under Linux. The "Klipper bridge mcu" itself will appear
as if was on this CAN bus - it can be identified via `canbus_query.py`
and configured like other CAN bus Klipper nodes. It will appear
alongside other devices that are actually on the CAN bus.
Some important notes when using this mode:
* The "bridge mcu" is not actually on the CAN bus. Messages to and
from it do not consume bandwidth on the CAN bus. The mcu can not be
seen by other adapters that may be on the CAN bus.
* It is necessary to configure the `can0` (or similar) interface in
Linux in order to communicate with the bus. However, Linux CAN bus
speed and CAN bus bit-timing options are ignored by Klipper.
Currently, the CAN bus frequency is specified during "make
menuconfig" and the bus speed specified in Linux is ignored.
* Whenever the "bridge mcu" is reset, Linux will disable the
corresponding `can0` interface. Generally, this may require running
commands such as "ip up" to restart the interface. Thus, Klipper
FIRMWARE_RESTART commands (or regular RESTART after a config change)
may require restarting the `can0` interface.

69
docs/CANBUS_protocol.md Normal file
View File

@@ -0,0 +1,69 @@
# CANBUS protocol
This document describes the protocol Klipper uses to communicate over
[CAN bus](https://en.wikipedia.org/wiki/CAN_bus). See
[CANBUS.md](CANBUS.md) for information on configuring Klipper with CAN
bus.
## Micro-controller id assignment
Klipper uses only CAN 2.0A standard size CAN bus packets, which are
limited to 8 data bytes and an 11-bit CAN bus identifier. In order to
support efficient communication, each micro-controller is assigned at
run-time a unique 1-byte CAN bus nodeid (`canbus_nodeid`) for general
Klipper command and response traffic. Klipper command messages going
from host to micro-controller use the CAN bus id of `canbus_nodeid *
2 + 256`, while Klipper response messages from micro-controller to
host use `canbus_nodeid * 2 + 256 + 1`.
Each micro-controller has a factory assigned unique chip identifier
that is used during id assignment. This identifier can exceed the
length of one CAN packet, so a hash function is used to generate a
unique 6-byte id (`canbus_uuid`) from the factory id.
## Admin messages
Admin messages are used for id assignment. Admin messages sent from
host to micro-controller use the CAN bus id `0x3f0` and messages sent
from micro-controller to host use the CAN bus id `0x3f1`. All
micro-controllers listen to messages on id `0x3f0`; that id can be
thought of as a "broadcast address".
### CMD_QUERY_UNASSIGNED message
This command queries all micro-controllers that have not yet been
assigned a `canbus_nodeid`. Unassigned micro-controllers will respond
with a RESP_NEED_NODEID response message.
The CMD_QUERY_UNASSIGNED message format is:
`<1-byte message_id = 0x00>`
### CMD_SET_NODEID message
This command assigns a `canbus_nodeid` to the micro-controller with a
given `canbus_uuid`.
The CMD_SET_NODEID message format is:
`<1-byte message_id = 0x01><6-byte canbus_uuid><1-byte canbus_nodeid>`
### RESP_NEED_NODEID message
The RESP_NEED_NODEID message format is:
`<1-byte message_id = 0x20><6-byte canbus_uuid>`
## Data Packets
A micro-controller that has been assigned a nodeid via the
CMD_SET_NODEID command can send and receive data packets.
The packet data in messages using the node's receive CAN bus id
(`canbus_nodeid * 2 + 256`) are simply appended to a buffer, and when
a complete [mcu protocol message](Protocol.md) is found its contents
are parsed and processed. The data is treated as a byte stream - there
is no requirement for the start of a Klipper message block to align
with the start of a CAN bus packet.
Similarly, mcu protocol message responses are sent from
micro-controller to host by copying the message data into one or more
packets with the node's transmit CAN bus id (`canbus_nodeid * 2 +
256 + 1`).

1
docs/CNAME Normal file
View File

@@ -0,0 +1 @@
www.klipper3d.org

331
docs/CONTRIBUTING.md Normal file
View File

@@ -0,0 +1,331 @@
# Contributing to Klipper
Thank you for contributing to Klipper! This document describes the
process for contributing changes to Klipper.
Please see the [contact page](Contact.md) for information on reporting
an issue or for details on contacting the developers.
## Overview of Contribution Process
Contributions to Klipper generally follow a high-level process:
1. A submitter starts by creating a
[GitHub Pull Request](https://github.com/Klipper3d/klipper/pulls)
when a submission is ready for widespread deployment.
2. When a [reviewer](#reviewers) is available to
[review](#what-to-expect-in-a-review) the submission, they will
assign themselves to the Pull Request on GitHub. The goal of the
review is to look for defects and to check that the submission
follows documented guidelines.
3. After a successful review, the reviewer will "approve the review"
on GitHub and a [maintainer](#reviewers) will commit the change to
the Klipper master branch.
When working on enhancements, consider starting (or contributing to) a
topic on [Klipper Discourse](Contact.md). An ongoing discussion on the
forum can improve visibility of development work and may attract
others interested in testing new work.
## What to expect in a review
Contributions to Klipper are reviewed before merging. The primary goal
of the review process is to check for defects and to check that the
submission follows guidelines specified in the Klipper documentation.
It is understood that there are many ways to accomplish a task; it is
not the intent of the review to discuss the "best" implementation.
Where possible, review discussions focused on facts and measurements
are preferable.
The majority of submissions will result in feedback from a review. Be
prepared to obtain feedback, provide further details, and to update
the submission if needed.
Common things a reviewer will look for:
1. Is the submission free of defects and is it ready to be widely
deployed?
Submitters are expected to test their changes prior to submission.
The reviewers look for errors, but they don't, in general, test
submissions. An accepted submission is often deployed to thousands
of printers within a few weeks of acceptance. Quality of
submissions is therefore considered a priority.
The main [Klipper3d/klipper](https://github.com/Klipper3d/klipper)
GitHub repository does not accept experimental work. Submitters
should perform experimentation, debugging, and testing in their own
repositories. The [Klipper Discourse](Contact.md) server is a good
place to raise awareness of new work and to find users interested
in providing real-world feedback.
Submissions must pass all [regression test cases](Debugging.md).
Code submissions should not contain excessive debugging code,
debugging options, nor run-time debug logging.
Comments in code submissions should focus on enhancing code
maintenance. Submissions should not contain "commented out code"
nor excessive comments describing past implementations. There
should not be excessive "todo" comments.
Updates to documentation should not declare that they are a "work
in progress".
2. Does the submission provide a "high impact" benefit to real-world
users performing real-world tasks?
Reviewers need to identify, at least in their own minds, roughly
"who the target audience is", a rough scale of "the size of that
audience", the "benefit" they will obtain, how the "benefit is
measured", and the "results of those measurement tests". In most
cases this will be obvious to both the submitter and the reviewer,
and it is not explicitly stated during a review.
Submissions to the master Klipper branch are expected to have a
noteworthy target audience. As a general "rule of thumb",
submissions should target a user base of at least a 100 real-world
users.
If a reviewer asks for details on the "benefit" of a submission,
please don't consider it criticism. Being able to understand the
real-world benefits of a change is a natural part of a review.
When discussing benefits it is preferable to discuss "facts and
measurements". In general, reviewers are not looking for responses
of the form "someone may find option X useful", nor are they
looking for responses of the form "this submission adds a feature
that firmware X implements". Instead, it is generally preferable to
discuss details on how the quality improvement was measured and
what were the results of those measurements - for example, "tests
on Acme X1000 printers show improved corners as seen in picture
...", or for example "print time of real-world object X on a
Foomatic X900 printer went from 4 hours to 3.5 hours". It is
understood that testing of this type can take significant time and
effort. Some of Klipper's most notable features took months of
discussion, rework, testing, and documentation prior to being
merged into the master branch.
All new modules, config options, commands, command parameters, and
documents should have "high impact". We do not want to burden users
with options that they can not reasonably configure nor do we want
to burden them with options that don't provide a notable benefit.
A reviewer may ask for clarification on how a user is to configure
an option - an ideal response will contain details on the process -
for example, "users of the MegaX500 are expected to set option X to
99.3 while users of the Elite100Y are expected to calibrate option
X using procedure ...".
If the goal of an option is to make the code more modular then
prefer using code constants instead of user facing config options.
New modules, new options, and new parameters should not provide
similar functionality to existing modules - if the differences are
arbitrary than it's preferable to utilize the existing system or
refactor the existing code.
3. Is the copyright of the submission clear, non-gratuitous, and
compatible?
New C files and Python files should have an unambiguous copyright
statement. See the existing files for the preferred format.
Declaring a copyright on an existing file when making minor changes
to that file is discouraged.
Code taken from 3rd party sources must be compatible with the
Klipper license (GNU GPLv3). Large 3rd party code additions should
be added to the `lib/` directory (and follow the format described
in [lib/README](../lib/README)).
Submitters must provide a
[Signed-off-by line](#format-of-commit-messages) using their full
real name. It indicates the submitter agrees with the
[developer certificate of origin](developer-certificate-of-origin).
4. Does the submission follow guidelines specified in the Klipper
documentation?
In particular, code should follow the guidelines in
[Code_Overview.md](Code_Overview.md) and config files should follow
the guidelines in [Example_Configs.md](Example_Configs.md).
5. Is the Klipper documentation updated to reflect new changes?
At a minimum, the reference documentation must be updated with
corresponding changes to the code:
* All commands and command parameters must be documented in
[G-Codes.md](G-Codes.md).
* All user facing modules and their config parameters must be
documented in [Config_Reference.md](Config_Reference.md).
* All exported "status variables" must be documented in
[Status_Reference.md](Status_Reference.md).
* All new "webhooks" and their parameters must be documented in
[API_Server.md](API_Server.md).
* Any change that makes a non-backwards compatible change to a
command or config file setting must be documented in
[Config_Changes.md](Config_Changes.md).
New documents should be added to [Overview.md](Overview.md) and be
added to the website index
[docs/_klipper3d/mkdocs.yml](../docs/_klipper3d/mkdocs.yml).
6. Are commits well formed, address a single topic per commit, and
independent?
Commit messages should follow the
[preferred format](#format-of-commit-messages).
Commits must not have a merge conflict. New additions to the
Klipper master branch are always done via a "rebase" or "squash and
rebase". It is generally not necessary for submitters to re-merge
their submission on every update to the Klipper master repository.
However, if there is a merge conflict, then submitters are
recommended to use `git rebase` to address the conflict.
Each commit should address a single high-level change. Large
changes should be broken up into multiple independent commits. Each
commit should "stand on its own" so that tools like `git bisect`
and `git revert` work reliably.
Whitespace changes should not be mixed with functional changes. In
general, gratuitous whitespace changes are not accepted unless they
are from the established "owner" of the code being modified.
Klipper does not implement a strict "coding style guide", but
modifications to existing code should follow the high-level code flow,
code indentation style, and format of that existing code. Submissions
of new modules and systems have more flexibility in coding style, but
it is preferable for that new code to follow an internally consistent
style and to generally follow industry wide coding norms.
It is not a goal of a review to discuss "better implementations".
However, if a reviewer struggles to understand the implementation of a
submission, then they may ask for changes to make the implementation
more transparent. In particular, if reviewers can not convince
themselves that a submission is free of defects then changes may be
necessary.
As part of a review, a reviewer may create an alternate Pull Request
for a topic. This may be done to avoid excessive "back and forth" on
minor procedural items and thus streamline the submission process. It
may also be done because the discussion inspires a reviewer to build
an alternative implementation. Both situations are a normal result of
a review and should not be considered criticism of the original
submission.
### Helping with reviews
We appreciate help with reviews! It is not necessary to be a
[listed reviewer](#reviewers) to perform a review. Submitters of
GitHub Pull Requests are also encouraged to review their own
submissions.
To help with a review, follow the steps outlined in
[what to expect in a review](#what-to-expect-in-a-review) to verify
the submission. After completing the review, add a comment to the
GitHub Pull Request with your findings. If the submission passes the
review then please state that explicitly in the comment - for example
something like "I reviewed this change according to the steps in the
CONTRIBUTING document and everything looks good to me". If unable to
complete some steps in the review then please explicitly state which
steps were reviewed and which steps were not reviewed - for example
something like "I didn't check the code for defects, but I reviewed
everything else in the CONTRIBUTING document and it looks good".
We also appreciate testing of submissions. If the code was tested then
please add a comment to the GitHub Pull Request with the results of
your test - success or failure. Please explicitly state that the code
was tested and the results - for example something like "I tested this
code on my Acme900Z printer with a vase print and the results were
good".
### Reviewers
The Klipper "reviewers" are:
| Name | GitHub Id | Areas of interest |
| ---------------------- | ----------------- | ----------------- |
| Dmitry Butyugin | @dmbutyugin | Input shaping, resonance testing, kinematics |
| Eric Callahan | @Arksine | Bed leveling, MCU flashing |
| Kevin O'Connor | @KevinOConnor | Core motion system, Micro-controller code |
| Paul McGowan | @mental405 | Configuration files, documentation |
Please do not "ping" any of the reviewers and please do not direct
submissions at them. All of the reviewers monitor the forums and PRs,
and will take on reviews when they have time to.
The Klipper "maintainers" are:
| Name | GitHub name |
| ---------------------- | ----------------- |
| Kevin O'Connor | @KevinOConnor |
## Format of commit messages
Each commit should have a commit message formatted similar to the
following:
```
module: Capitalized, short (50 chars or less) summary
More detailed explanatory text, if necessary. Wrap it to about 75
characters or so. In some contexts, the first line is treated as the
subject of an email and the rest of the text as the body. The blank
line separating the summary from the body is critical (unless you omit
the body entirely); tools like rebase can get confused if you run the
two together.
Further paragraphs come after blank lines..
Signed-off-by: My Name <myemail@example.org>
```
In the above example, `module` should be the name of a file or
directory in the repository (without a file extension). For example,
`clocksync: Fix typo in pause() call at connect time`. The purpose of
specifying a module name in the commit message is to help provide
context for the commit comments.
It is important to have a "Signed-off-by" line on each commit - it
certifies that you agree to the
[developer certificate of origin](developer-certificate-of-origin). It
must contain your real name (sorry, no pseudonyms or anonymous
contributions) and contain a current email address.
## Contributing to Klipper Translations
[Klipper-translations Project](https://github.com/Klipper3d/klipper-translations)
is a project dedicated to translating Klipper to different languages.
[Weblate](https://hosted.weblate.org/projects/klipper/) hosts all the
Gettext strings for translating and reviewing. Locales can be displayed on
[klipper3d.org](https://www.klipper3d.org) once they satisfy the following requirements:
- [ ] 75% Total coverage
- [ ] All titles (H1) are translated
- [ ] An updated navigation hierarchy PR in klipper-translations.
To reduce the frustration of translating domain-specific terms and
gain awareness of the ongoing translations, you can submit a PR
modifying the
[Klipper-translations Project](https://github.com/Klipper3d/klipper-translations)
`readme.md`. Once a translation is ready, the corresponding
modification to the Klipper project can be made.
If a translation already exists in the Klipper repository and no
longer meets the checklist above, it will be marked out-of-date after
a month without updates.
Once the requirements are met, you need to:
1. update klipper-tranlations repository
[active_translations](https://github.com/Klipper3d/klipper-translations/blob/translations/active_translations)
2. Optional: add a manual-index.md file in klipper-translations repository's
`docs\locals\<lang>` folder to replace the language specific index.md (generated
index.md does not render correctly).
Known Issues:
1. Currently, there isn't a method for correctly translating pictures in
the documentation
2. It is impossible to translate titles in mkdocs.yml.

581
docs/Code_Overview.md Normal file
View File

@@ -0,0 +1,581 @@
# Code overview
This document describes the overall code layout and major code flow of
Klipper.
## Directory Layout
The **src/** directory contains the C source for the micro-controller
code. The **src/atsam/**, **src/atsamd/**, **src/avr/**,
**src/linux/**, **src/lpc176x/**, **src/pru/**, and **src/stm32/**
directories contain architecture specific micro-controller code. The
**src/simulator/** contains code stubs that allow the micro-controller
to be test compiled on other architectures. The **src/generic/**
directory contains helper code that may be useful across different
architectures. The build arranges for includes of "board/somefile.h"
to first look in the current architecture directory (eg,
src/avr/somefile.h) and then in the generic directory (eg,
src/generic/somefile.h).
The **klippy/** directory contains the host software. Most of the host
software is written in Python, however the **klippy/chelper/**
directory contains some C code helpers. The **klippy/kinematics/**
directory contains the robot kinematics code. The **klippy/extras/**
directory contains the host code extensible "modules".
The **lib/** directory contains external 3rd-party library code that
is necessary to build some targets.
The **config/** directory contains example printer configuration
files.
The **scripts/** directory contains build-time scripts useful for
compiling the micro-controller code.
The **test/** directory contains automated test cases.
During compilation, the build may create an **out/** directory. This
contains temporary build time objects. The final micro-controller
object that is built is **out/klipper.elf.hex** on AVR and
**out/klipper.bin** on ARM.
## Micro-controller code flow
Execution of the micro-controller code starts in architecture specific
code (eg, **src/avr/main.c**) which ultimately calls sched_main()
located in **src/sched.c**. The sched_main() code starts by running
all functions that have been tagged with the DECL_INIT() macro. It
then goes on to repeatedly run all functions tagged with the
DECL_TASK() macro.
One of the main task functions is command_dispatch() located in
**src/command.c**. This function is called from the board specific
input/output code (eg, **src/avr/serial.c**,
**src/generic/serial_irq.c**) and it runs the command functions
associated with the commands found in the input stream. Command
functions are declared using the DECL_COMMAND() macro (see the
[protocol](Protocol.md) document for more information).
Task, init, and command functions always run with interrupts enabled
(however, they can temporarily disable interrupts if needed). These
functions should avoid long pauses, delays, or do work that lasts a
significant time. (Long delays in these "task" functions result in
scheduling jitter for other "tasks" - delays over 100us may become
noticeable, delays over 500us may result in command retransmissions,
delays over 100ms may result in watchdog reboots.) These functions
schedule work at specific times by scheduling timers.
Timer functions are scheduled by calling sched_add_timer() (located in
**src/sched.c**). The scheduler code will arrange for the given
function to be called at the requested clock time. Timer interrupts
are initially handled in an architecture specific interrupt handler
(eg, **src/avr/timer.c**) which calls sched_timer_dispatch() located
in **src/sched.c**. The timer interrupt leads to execution of schedule
timer functions. Timer functions always run with interrupts disabled.
The timer functions should always complete within a few micro-seconds.
At completion of the timer event, the function may choose to
reschedule itself.
In the event an error is detected the code can invoke shutdown() (a
macro which calls sched_shutdown() located in **src/sched.c**).
Invoking shutdown() causes all functions tagged with the
DECL_SHUTDOWN() macro to be run. Shutdown functions always run with
interrupts disabled.
Much of the functionality of the micro-controller involves working
with General-Purpose Input/Output pins (GPIO). In order to abstract
the low-level architecture specific code from the high-level task
code, all GPIO events are implemented in architecture specific
wrappers (eg, **src/avr/gpio.c**). The code is compiled with gcc's
"-flto -fwhole-program" optimization which does an excellent job of
inlining functions across compilation units, so most of these tiny
gpio functions are inlined into their callers, and there is no
run-time cost to using them.
## Klippy code overview
The host code (Klippy) is intended to run on a low-cost computer (such
as a Raspberry Pi) paired with the micro-controller. The code is
primarily written in Python, however it does use CFFI to implement
some functionality in C code.
Initial execution starts in **klippy/klippy.py**. This reads the
command-line arguments, opens the printer config file, instantiates
the main printer objects, and starts the serial connection. The main
execution of G-code commands is in the process_commands() method in
**klippy/gcode.py**. This code translates the G-code commands into
printer object calls, which frequently translate the actions to
commands to be executed on the micro-controller (as declared via the
DECL_COMMAND macro in the micro-controller code).
There are four threads in the Klippy host code. The main thread
handles incoming gcode commands. A second thread (which resides
entirely in the **klippy/chelper/serialqueue.c** C code) handles
low-level IO with the serial port. The third thread is used to process
response messages from the micro-controller in the Python code (see
**klippy/serialhdl.py**). The fourth thread writes debug messages to
the log (see **klippy/queuelogger.py**) so that the other threads
never block on log writes.
## Code flow of a move command
A typical printer movement starts when a "G1" command is sent to the
Klippy host and it completes when the corresponding step pulses are
produced on the micro-controller. This section outlines the code flow
of a typical move command. The [kinematics](Kinematics.md) document
provides further information on the mechanics of moves.
* Processing for a move command starts in gcode.py. The goal of
gcode.py is to translate G-code into internal calls. A G1 command
will invoke cmd_G1() in klippy/extras/gcode_move.py. The
gcode_move.py code handles changes in origin (eg, G92), changes in
relative vs absolute positions (eg, G90), and unit changes (eg,
F6000=100mm/s). The code path for a move is: `_process_data() ->
_process_commands() -> cmd_G1()`. Ultimately the ToolHead class is
invoked to execute the actual request: `cmd_G1() -> ToolHead.move()`
* The ToolHead class (in toolhead.py) handles "look-ahead" and tracks
the timing of printing actions. The main codepath for a move is:
`ToolHead.move() -> MoveQueue.add_move() -> MoveQueue.flush() ->
Move.set_junction() -> ToolHead._process_moves()`.
* ToolHead.move() creates a Move() object with the parameters of the
move (in cartesian space and in units of seconds and millimeters).
* The kinematics class is given the opportunity to audit each move
(`ToolHead.move() -> kin.check_move()`). The kinematics classes are
located in the klippy/kinematics/ directory. The check_move() code
may raise an error if the move is not valid. If check_move()
completes successfully then the underlying kinematics must be able
to handle the move.
* MoveQueue.add_move() places the move object on the "look-ahead"
queue.
* MoveQueue.flush() determines the start and end velocities of each
move.
* Move.set_junction() implements the "trapezoid generator" on a
move. The "trapezoid generator" breaks every move into three parts:
a constant acceleration phase, followed by a constant velocity
phase, followed by a constant deceleration phase. Every move
contains these three phases in this order, but some phases may be of
zero duration.
* When ToolHead._process_moves() is called, everything about the
move is known - its start location, its end location, its
acceleration, its start/cruising/end velocity, and distance traveled
during acceleration/cruising/deceleration. All the information is
stored in the Move() class and is in cartesian space in units of
millimeters and seconds.
* Klipper uses an
[iterative solver](https://en.wikipedia.org/wiki/Root-finding_algorithm)
to generate the step times for each stepper. For efficiency reasons,
the stepper pulse times are generated in C code. The moves are first
placed on a "trapezoid motion queue": `ToolHead._process_moves() ->
trapq_append()` (in klippy/chelper/trapq.c). The step times are then
generated: `ToolHead._process_moves() ->
ToolHead._update_move_time() -> MCU_Stepper.generate_steps() ->
itersolve_generate_steps() -> itersolve_gen_steps_range()` (in
klippy/chelper/itersolve.c). The goal of the iterative solver is to
find step times given a function that calculates a stepper position
from a time. This is done by repeatedly "guessing" various times
until the stepper position formula returns the desired position of
the next step on the stepper. The feedback produced from each guess
is used to improve future guesses so that the process rapidly
converges to the desired time. The kinematic stepper position
formulas are located in the klippy/chelper/ directory (eg,
kin_cart.c, kin_corexy.c, kin_delta.c, kin_extruder.c).
* Note that the extruder is handled in its own kinematic class:
`ToolHead._process_moves() -> PrinterExtruder.move()`. Since
the Move() class specifies the exact movement time and since step
pulses are sent to the micro-controller with specific timing,
stepper movements produced by the extruder class will be in sync
with head movement even though the code is kept separate.
* After the iterative solver calculates the step times they are added
to an array: `itersolve_gen_steps_range() -> stepcompress_append()`
(in klippy/chelper/stepcompress.c). The array (struct
stepcompress.queue) stores the corresponding micro-controller clock
counter times for every step. Here the "micro-controller clock
counter" value directly corresponds to the micro-controller's
hardware counter - it is relative to when the micro-controller was
last powered up.
* The next major step is to compress the steps: `stepcompress_flush()
-> compress_bisect_add()` (in klippy/chelper/stepcompress.c). This
code generates and encodes a series of micro-controller "queue_step"
commands that correspond to the list of stepper step times built in
the previous stage. These "queue_step" commands are then queued,
prioritized, and sent to the micro-controller (via
stepcompress.c:steppersync and serialqueue.c:serialqueue).
* Processing of the queue_step commands on the micro-controller starts
in src/command.c which parses the command and calls
`command_queue_step()`. The command_queue_step() code (in
src/stepper.c) just appends the parameters of each queue_step
command to a per stepper queue. Under normal operation the
queue_step command is parsed and queued at least 100ms before the
time of its first step. Finally, the generation of stepper events is
done in `stepper_event()`. It's called from the hardware timer
interrupt at the scheduled time of the first step. The
stepper_event() code generates a step pulse and then reschedules
itself to run at the time of the next step pulse for the given
queue_step parameters. The parameters for each queue_step command
are "interval", "count", and "add". At a high-level, stepper_event()
runs the following, 'count' times: `do_step(); next_wake_time =
last_wake_time + interval; interval += add;`
The above may seem like a lot of complexity to execute a movement.
However, the only really interesting parts are in the ToolHead and
kinematic classes. It's this part of the code which specifies the
movements and their timings. The remaining parts of the processing is
mostly just communication and plumbing.
## Adding a host module
The Klippy host code has a dynamic module loading capability. If a
config section named "[my_module]" is found in the printer config file
then the software will automatically attempt to load the python module
klippy/extras/my_module.py . This module system is the preferred
method for adding new functionality to Klipper.
The easiest way to add a new module is to use an existing module as a
reference - see **klippy/extras/servo.py** as an example.
The following may also be useful:
* Execution of the module starts in the module level `load_config()`
function (for config sections of the form [my_module]) or in
`load_config_prefix()` (for config sections of the form
[my_module my_name]). This function is passed a "config" object and
it must return a new "printer object" associated with the given
config section.
* During the process of instantiating a new printer object, the config
object can be used to read parameters from the given config
section. This is done using `config.get()`, `config.getfloat()`,
`config.getint()`, etc. methods. Be sure to read all values from the
config during the construction of the printer object - if the user
specifies a config parameter that is not read during this phase then
it will be assumed it is a typo in the config and an error will be
raised.
* Use the `config.get_printer()` method to obtain a reference to the
main "printer" class. This "printer" class stores references to all
the "printer objects" that have been instantiated. Use the
`printer.lookup_object()` method to find references to other printer
objects. Almost all functionality (even core kinematic modules) are
encapsulated in one of these printer objects. Note, though, that
when a new module is instantiated, not all other printer objects
will have been instantiated. The "gcode" and "pins" modules will
always be available, but for other modules it is a good idea to
defer the lookup.
* Register event handlers using the `printer.register_event_handler()`
method if the code needs to be called during "events" raised by
other printer objects. Each event name is a string, and by
convention it is the name of the main source module that raises the
event along with a short name for the action that is occurring (eg,
"klippy:connect"). The parameters passed to each event handler are
specific to the given event (as are exception handling and execution
context). Two common startup events are:
* klippy:connect - This event is generated after all printer objects
are instantiated. It is commonly used to lookup other printer
objects, to verify config settings, and to perform an initial
"handshake" with printer hardware.
* klippy:ready - This event is generated after all connect handlers
have completed successfully. It indicates the printer is
transitioning to a state ready to handle normal operations. Do not
raise an error in this callback.
* If there is an error in the user's config, be sure to raise it
during the `load_config()` or "connect event" phases. Use either
`raise config.error("my error")` or `raise printer.config_error("my
error")` to report the error.
* Use the "pins" module to configure a pin on a micro-controller. This
is typically done with something similar to
`printer.lookup_object("pins").setup_pin("pwm",
config.get("my_pin"))`. The returned object can then be commanded at
run-time.
* If the printer object defines a `get_status()` method then the
module can export [status information](Status_Reference.md) via
[macros](Command_Templates.md) and via the
[API Server](API_Server.md). The `get_status()` method must return a
Python dictionary with keys that are strings and values that are
integers, floats, strings, lists, dictionaries, True, False, or
None. Tuples (and named tuples) may also be used (these appear as
lists when accessed via the API Server). Lists and dictionaries that
are exported must be treated as "immutable" - if their contents
change then a new object must be returned from `get_status()`,
otherwise the API Server will not detect those changes.
* If the module needs access to system timing or external file
descriptors then use `printer.get_reactor()` to obtain access to the
global "event reactor" class. This reactor class allows one to
schedule timers, wait for input on file descriptors, and to "sleep"
the host code.
* Do not use global variables. All state should be stored in the
printer object returned from the `load_config()` function. This is
important as otherwise the RESTART command may not perform as
expected. Also, for similar reasons, if any external files (or
sockets) are opened then be sure to register a "klippy:disconnect"
event handler and close them from that callback.
* Avoid accessing the internal member variables (or calling methods
that start with an underscore) of other printer objects. Observing
this convention makes it easier to manage future changes.
* It is recommended to assign a value to all member variables in the
Python constructor of Python classes. (And therefore avoid utilizing
Python's ability to dynamically create new member variables.)
* If a Python variable is to store a floating point value then it is
recommended to always assign and manipulate that variable with
floating point constants (and never use integer constants). For
example, prefer `self.speed = 1.` over `self.speed = 1`, and prefer
`self.speed = 2. * x` over `self.speed = 2 * x`. Consistent use of
floating point values can avoid hard to debug quirks in Python type
conversions.
* If submitting the module for inclusion in the main Klipper code, be
sure to place a copyright notice at the top of the module. See the
existing modules for the preferred format.
## Adding new kinematics
This section provides some tips on adding support to Klipper for
additional types of printer kinematics. This type of activity requires
excellent understanding of the math formulas for the target
kinematics. It also requires software development skills - though one
should only need to update the host software.
Useful steps:
1. Start by studying the
"[code flow of a move](#code-flow-of-a-move-command)" section and
the [Kinematics document](Kinematics.md).
2. Review the existing kinematic classes in the klippy/kinematics/
directory. The kinematic classes are tasked with converting a move
in cartesian coordinates to the movement on each stepper. One
should be able to copy one of these files as a starting point.
3. Implement the C stepper kinematic position functions for each
stepper if they are not already available (see kin_cart.c,
kin_corexy.c, and kin_delta.c in klippy/chelper/). The function
should call `move_get_coord()` to convert a given move time (in
seconds) to a cartesian coordinate (in millimeters), and then
calculate the desired stepper position (in millimeters) from that
cartesian coordinate.
4. Implement the `calc_position()` method in the new kinematics class.
This method calculates the position of the toolhead in cartesian
coordinates from the position of each stepper. It does not need to
be efficient as it is typically only called during homing and
probing operations.
5. Other methods. Implement the `check_move()`, `get_status()`,
`get_steppers()`, `home()`, and `set_position()` methods. These
functions are typically used to provide kinematic specific checks.
However, at the start of development one can use boiler-plate code
here.
6. Implement test cases. Create a g-code file with a series of moves
that can test important cases for the given kinematics. Follow the
[debugging documentation](Debugging.md) to convert this g-code file
to micro-controller commands. This is useful to exercise corner
cases and to check for regressions.
## Porting to a new micro-controller
This section provides some tips on porting Klipper's micro-controller
code to a new architecture. This type of activity requires good
knowledge of embedded development and hands-on access to the target
micro-controller.
Useful steps:
1. Start by identifying any 3rd party libraries that will be used
during the port. Common examples include "CMSIS" wrappers and
manufacturer "HAL" libraries. All 3rd party code needs to be GNU
GPLv3 compatible. The 3rd party code should be committed to the
Klipper lib/ directory. Update the lib/README file with information
on where and when the library was obtained. It is preferable to
copy the code into the Klipper repository unchanged, but if any
changes are required then those changes should be listed explicitly
in the lib/README file.
2. Create a new architecture sub-directory in the src/ directory and
add initial Kconfig and Makefile support. Use the existing
architectures as a guide. The src/simulator provides a basic
example of a minimum starting point.
3. The first main coding task is to bring up communication support to
the target board. This is the most difficult step in a new port.
Once basic communication is working, the remaining steps tend to be
much easier. It is typical to use a UART type serial device during
initial development as these types of hardware devices are
generally easier to enable and control. During this phase, make
liberal use of helper code from the src/generic/ directory (check
how src/simulator/Makefile includes the generic C code into the
build). It is also necessary to define timer_read_time() (which
returns the current system clock) in this phase, but it is not
necessary to fully support timer irq handling.
4. Get familiar with the the console.py tool (as described in the
[debugging document](Debugging.md)) and verify connectivity to the
micro-controller with it. This tool translates the low-level
micro-controller communication protocol to a human readable form.
5. Add support for timer dispatch from hardware interrupts. See
Klipper
[commit 970831ee](https://github.com/Klipper3d/klipper/commit/970831ee0d3b91897196e92270d98b2a3067427f)
as an example of steps 1-5 done for the LPC176x architecture.
6. Bring up basic GPIO input and output support. See Klipper
[commit c78b9076](https://github.com/Klipper3d/klipper/commit/c78b90767f19c9e8510c3155b89fb7ad64ca3c54)
as an example of this.
7. Bring up additional peripherals - for example see Klipper commit
[65613aed](https://github.com/Klipper3d/klipper/commit/65613aeddfb9ef86905cb1dade9e773a02ef3c27),
[c812a40a](https://github.com/Klipper3d/klipper/commit/c812a40a3782415e454b04bf7bd2158a6f0ec8b5),
and
[c381d03a](https://github.com/Klipper3d/klipper/commit/c381d03aad5c3ee761169b7c7bced519cc14da29).
8. Create a sample Klipper config file in the config/ directory. Test
the micro-controller with the main klippy.py program.
9. Consider adding build test cases in the test/ directory.
Additional coding tips:
1. Avoid using "C bitfields" to access IO registers; prefer direct
read and write operations of 32bit, 16bit, or 8bit integers. The C
language specifications don't clearly specify how the compiler must
implement C bitfields (eg, endianness, and bit layout), and it's
difficult to determine what IO operations will occur on a C
bitfield read or write.
2. Prefer writing explicit values to IO registers instead of using
read-modify-write operations. That is, if updating a field in an IO
register where the other fields have known values, then it is
preferable to explicitly write the full contents of the register.
Explicit writes produce code that is smaller, faster, and easier to
debug.
## Coordinate Systems
Internally, Klipper primarily tracks the position of the toolhead in
cartesian coordinates that are relative to the coordinate system
specified in the config file. That is, most of the Klipper code will
never experience a change in coordinate systems. If the user makes a
request to change the origin (eg, a `G92` command) then that effect is
obtained by translating future commands to the primary coordinate
system.
However, in some cases it is useful to obtain the toolhead position in
some other coordinate system and Klipper has several tools to
facilitate that. This can be seen by running the GET_POSITION
command. For example:
```
Send: GET_POSITION
Recv: // mcu: stepper_a:-2060 stepper_b:-1169 stepper_c:-1613
Recv: // stepper: stepper_a:457.254159 stepper_b:466.085669 stepper_c:465.382132
Recv: // kinematic: X:8.339144 Y:-3.131558 Z:233.347121
Recv: // toolhead: X:8.338078 Y:-3.123175 Z:233.347878 E:0.000000
Recv: // gcode: X:8.338078 Y:-3.123175 Z:233.347878 E:0.000000
Recv: // gcode base: X:0.000000 Y:0.000000 Z:0.000000 E:0.000000
Recv: // gcode homing: X:0.000000 Y:0.000000 Z:0.000000
```
The "mcu" position (`stepper.get_mcu_position()` in the code) is the
total number of steps the micro-controller has issued in a positive
direction minus the number of steps issued in a negative direction
since the micro-controller was last reset. If the robot is in motion
when the query is issued then the reported value includes moves
buffered on the micro-controller, but does not include moves on the
look-ahead queue.
The "stepper" position (`stepper.get_commanded_position()`) is the
position of the given stepper as tracked by the kinematics code. This
generally corresponds to the position (in mm) of the carriage along
its rail, relative to the position_endstop specified in the config
file. (Some kinematics track stepper positions in radians instead of
millimeters.) If the robot is in motion when the query is issued then
the reported value includes moves buffered on the micro-controller,
but does not include moves on the look-ahead queue. One may use the
`toolhead.flush_step_generation()` or `toolhead.wait_moves()` calls to
fully flush the look-ahead and step generation code.
The "kinematic" position (`kin.calc_position()`) is the cartesian
position of the toolhead as derived from "stepper" positions and is
relative to the coordinate system specified in the config file. This
may differ from the requested cartesian position due to the
granularity of the stepper motors. If the robot is in motion when the
"stepper" positions are taken then the reported value includes moves
buffered on the micro-controller, but does not include moves on the
look-ahead queue. One may use the `toolhead.flush_step_generation()`
or `toolhead.wait_moves()` calls to fully flush the look-ahead and
step generation code.
The "toolhead" position (`toolhead.get_position()`) is the last
requested position of the toolhead in cartesian coordinates relative
to the coordinate system specified in the config file. If the robot is
in motion when the query is issued then the reported value includes
all requested moves (even those in buffers waiting to be issued to the
stepper motor drivers).
The "gcode" position is the last requested position from a `G1` (or
`G0`) command in cartesian coordinates relative to the coordinate
system specified in the config file. This may differ from the
"toolhead" position if a g-code transformation (eg, bed_mesh,
bed_tilt, skew_correction) is in effect. This may differ from the
actual coordinates specified in the last `G1` command if the g-code
origin has been changed (eg, `G92`, `SET_GCODE_OFFSET`, `M221`). The
`M114` command (`gcode_move.get_status()['gcode_position']`) will
report the last g-code position relative to the current g-code
coordinate system.
The "gcode base" is the location of the g-code origin in cartesian
coordinates relative to the coordinate system specified in the config
file. Commands such as `G92`, `SET_GCODE_OFFSET`, and `M221` alter
this value.
The "gcode homing" is the location to use for the g-code origin (in
cartesian coordinates relative to the coordinate system specified in
the config file) after a `G28` home command. The `SET_GCODE_OFFSET`
command can alter this value.
## Time
Fundamental to the operation of Klipper is the handling of clocks,
times, and timestamps. Klipper executes actions on the printer by
scheduling events to occur in the near future. For example, to turn on
a fan, the code might schedule a change to a GPIO pin in a 100ms. It
is rare for the code to attempt to take an instantaneous action. Thus,
the handling of time within Klipper is critical to correct operation.
There are three types of times tracked internally in the Klipper host
software:
* System time. The system time uses the system's monotonic clock - it
is a floating point number stored as seconds and it is (generally)
relative to when the host computer was last started. System times
have limited use in the software - they are primarily used when
interacting with the operating system. Within the host code, system
times are frequently stored in variables named *eventtime* or
*curtime*.
* Print time. The print time is synchronized to the main
micro-controller clock (the micro-controller defined in the "[mcu]"
config section). It is a floating point number stored as seconds and
is relative to when the main mcu was last restarted. It is possible
to convert from a "print time" to the main micro-controller's
hardware clock by multiplying the print time by the mcu's statically
configured frequency rate. The high-level host code uses print times
to calculate almost all physical actions (eg, head movement, heater
changes, etc.). Within the host code, print times are generally
stored in variables named *print_time* or *move_time*.
* MCU clock. This is the hardware clock counter on each
micro-controller. It is stored as an integer and its update rate is
relative to the frequency of the given micro-controller. The host
software translates its internal times to clocks before transmission
to the mcu. The mcu code only ever tracks time in clock
ticks. Within the host code, clock values are tracked as 64bit
integers, while the mcu code uses 32bit integers. Within the host
code, clocks are generally stored in variables with names containing
*clock* or *ticks*.
Conversion between the different time formats is primarily implemented
in the **klippy/clocksync.py** code.
Some things to be aware of when reviewing the code:
* 32bit and 64bit clocks: To reduce bandwidth and to improve
micro-controller efficiency, clocks on the micro-controller are
tracked as 32bit integers. When comparing two clocks in the mcu
code, the `timer_is_before()` function must always be used to ensure
integer rollovers are handled properly. The host software converts
32bit clocks to 64bit clocks by appending the high-order bits from
the last mcu timestamp it has received - no message from the mcu is
ever more than 2^31 clock ticks in the future or past so this
conversion is never ambiguous. The host converts from 64bit clocks
to 32bit clocks by simply truncating the high-order bits. To ensure
there is no ambiguity in this conversion, the
**klippy/chelper/serialqueue.c** code will buffer messages until
they are within 2^31 clock ticks of their target time.
* Multiple micro-controllers: The host software supports using
multiple micro-controllers on a single printer. In this case, the
"MCU clock" of each micro-controller is tracked separately. The
clocksync.py code handles clock drift between micro-controllers by
modifying the way it converts from "print time" to "MCU clock". On
secondary mcus, the mcu frequency that is used in this conversion is
regularly updated to account for measured drift.

348
docs/Command_Templates.md Normal file
View File

@@ -0,0 +1,348 @@
# Commands templates
This document provides information on implementing G-Code command
sequences in gcode_macro (and similar) config sections.
## G-Code Macro Naming
Case is not important for the G-Code macro name - MY_MACRO and
my_macro will evaluate the same and may be called in either upper or
lower case. If any numbers are used in the macro name then they must
all be at the end of the name (eg, TEST_MACRO25 is valid, but
MACRO25_TEST3 is not).
## Formatting of G-Code in the config
Indentation is important when defining a macro in the config file. To
specify a multi-line G-Code sequence it is important for each line to
have proper indentation. For example:
```
[gcode_macro blink_led]
gcode:
SET_PIN PIN=my_led VALUE=1
G4 P2000
SET_PIN PIN=my_led VALUE=0
```
Note how the `gcode:` config option always starts at the beginning of
the line and subsequent lines in the G-Code macro never start at the
beginning.
## Add a description to your macro
To help identify the functionality a short description can be added.
Add `description:` with a short text to describe the functionality.
Default is "G-Code macro" if not specified.
For example:
```
[gcode_macro blink_led]
description: Blink my_led one time
gcode:
SET_PIN PIN=my_led VALUE=1
G4 P2000
SET_PIN PIN=my_led VALUE=0
```
The terminal will display the description when you use the `HELP` command or the autocomplete function.
## Save/Restore state for G-Code moves
Unfortunately, the G-Code command language can be challenging to use.
The standard mechanism to move the toolhead is via the `G1` command
(the `G0` command is an alias for `G1` and it can be used
interchangeably with it). However, this command relies on the "G-Code
parsing state" setup by `M82`, `M83`, `G90`, `G91`, `G92`, and
previous `G1` commands. When creating a G-Code macro it is a good
idea to always explicitly set the G-Code parsing state prior to
issuing a `G1` command. (Otherwise, there is a risk the `G1` command
will make an undesirable request.)
A common way to accomplish that is to wrap the `G1` moves in
`SAVE_GCODE_STATE`, `G91`, and `RESTORE_GCODE_STATE`. For example:
```
[gcode_macro MOVE_UP]
gcode:
SAVE_GCODE_STATE NAME=my_move_up_state
G91
G1 Z10 F300
RESTORE_GCODE_STATE NAME=my_move_up_state
```
The `G91` command places the G-Code parsing state into "relative move
mode" and the `RESTORE_GCODE_STATE` command restores the state to what
it was prior to entering the macro. Be sure to specify an explicit
speed (via the `F` parameter) on the first `G1` command.
## Template expansion
The gcode_macro `gcode:` config section is evaluated using the Jinja2
template language. One can evaluate expressions at run-time by
wrapping them in `{ }` characters or use conditional statements
wrapped in `{% %}`. See the
[Jinja2 documentation](http://jinja.pocoo.org/docs/2.10/templates/)
for further information on the syntax.
An example of a complex macro:
```
[gcode_macro clean_nozzle]
gcode:
{% set wipe_count = 8 %}
SAVE_GCODE_STATE NAME=clean_nozzle_state
G90
G0 Z15 F300
{% for wipe in range(wipe_count) %}
{% for coordinate in [(275, 4),(235, 4)] %}
G0 X{coordinate[0]} Y{coordinate[1] + 0.25 * wipe} Z9.7 F12000
{% endfor %}
{% endfor %}
RESTORE_GCODE_STATE NAME=clean_nozzle_state
```
### Macro parameters
It is often useful to inspect parameters passed to the macro when
it is called. These parameters are available via the `params`
pseudo-variable. For example, if the macro:
```
[gcode_macro SET_PERCENT]
gcode:
M117 Now at { params.VALUE|float * 100 }%
```
were invoked as `SET_PERCENT VALUE=.2` it would evaluate to `M117 Now
at 20%`. Note that parameter names are always in upper-case when
evaluated in the macro and are always passed as strings. If performing
math then they must be explicitly converted to integers or floats.
It's common to use the Jinja2 `set` directive to use a default
parameter and assign the result to a local name. For example:
```
[gcode_macro SET_BED_TEMPERATURE]
gcode:
{% set bed_temp = params.TEMPERATURE|default(40)|float %}
M140 S{bed_temp}
```
### The "rawparams" variable
The full unparsed parameters for the running macro can be access via the
`rawparams` pseudo-variable.
Note that this will include any comments that were part of the original command.
See the [sample-macros.cfg](../config/sample-macros.cfg) file for an example
showing how to override the `M117` command using `rawparams`.
### The "printer" Variable
It is possible to inspect (and alter) the current state of the printer
via the `printer` pseudo-variable. For example:
```
[gcode_macro slow_fan]
gcode:
M106 S{ printer.fan.speed * 0.9 * 255}
```
Available fields are defined in the
[Status Reference](Status_Reference.md) document.
Important! Macros are first evaluated in entirety and only then are
the resulting commands executed. If a macro issues a command that
alters the state of the printer, the results of that state change will
not be visible during the evaluation of the macro. This can also
result in subtle behavior when a macro generates commands that call
other macros, as the called macro is evaluated when it is invoked
(which is after the entire evaluation of the calling macro).
By convention, the name immediately following `printer` is the name of
a config section. So, for example, `printer.fan` refers to the fan
object created by the `[fan]` config section. There are some
exceptions to this rule - notably the `gcode_move` and `toolhead`
objects. If the config section contains spaces in it, then one can
access it via the `[ ]` accessor - for example:
`printer["generic_heater my_chamber_heater"].temperature`.
Note that the Jinja2 `set` directive can assign a local name to an
object in the `printer` hierarchy. This can make macros more readable
and reduce typing. For example:
```
[gcode_macro QUERY_HTU21D]
gcode:
{% set sensor = printer["htu21d my_sensor"] %}
M117 Temp:{sensor.temperature} Humidity:{sensor.humidity}
```
## Actions
There are some commands available that can alter the state of the
printer. For example, `{ action_emergency_stop() }` would cause the
printer to go into a shutdown state. Note that these actions are taken
at the time that the macro is evaluated, which may be a significant
amount of time before the generated g-code commands are executed.
Available "action" commands:
- `action_respond_info(msg)`: Write the given `msg` to the
/tmp/printer pseudo-terminal. Each line of `msg` will be sent with a
"// " prefix.
- `action_raise_error(msg)`: Abort the current macro (and any calling
macros) and write the given `msg` to the /tmp/printer
pseudo-terminal. The first line of `msg` will be sent with a "!! "
prefix and subsequent lines will have a "// " prefix.
- `action_emergency_stop(msg)`: Transition the printer to a shutdown
state. The `msg` parameter is optional, it may be useful to describe
the reason for the shutdown.
- `action_call_remote_method(method_name)`: Calls a method registered
by a remote client. If the method takes parameters they should
be provided via keyword arguments, ie:
`action_call_remote_method("print_stuff", my_arg="hello_world")`
## Variables
The SET_GCODE_VARIABLE command may be useful for saving state between
macro calls. Variable names may not contain any upper case characters.
For example:
```
[gcode_macro start_probe]
variable_bed_temp: 0
gcode:
# Save target temperature to bed_temp variable
SET_GCODE_VARIABLE MACRO=start_probe VARIABLE=bed_temp VALUE={printer.heater_bed.target}
# Disable bed heater
M140
# Perform probe
PROBE
# Call finish_probe macro at completion of probe
finish_probe
[gcode_macro finish_probe]
gcode:
# Restore temperature
M140 S{printer["gcode_macro start_probe"].bed_temp}
```
Be sure to take the timing of macro evaluation and command execution
into account when using SET_GCODE_VARIABLE.
## Delayed Gcodes
The [delayed_gcode] configuration option can be used to execute a delayed
gcode sequence:
```
[delayed_gcode clear_display]
gcode:
M117
[gcode_macro load_filament]
gcode:
G91
G1 E50
G90
M400
M117 Load Complete!
UPDATE_DELAYED_GCODE ID=clear_display DURATION=10
```
When the `load_filament` macro above executes, it will display a
"Load Complete!" message after the extrusion is finished. The
last line of gcode enables the "clear_display" delayed_gcode, set
to execute in 10 seconds.
The `initial_duration` config option can be set to execute the
delayed_gcode on printer startup. The countdown begins when the
printer enters the "ready" state. For example, the below delayed_gcode
will execute 5 seconds after the printer is ready, initializing
the display with a "Welcome!" message:
```
[delayed_gcode welcome]
initial_duration: 5.
gcode:
M117 Welcome!
```
Its possible for a delayed gcode to repeat by updating itself in
the gcode option:
```
[delayed_gcode report_temp]
initial_duration: 2.
gcode:
{action_respond_info("Extruder Temp: %.1f" % (printer.extruder0.temperature))}
UPDATE_DELAYED_GCODE ID=report_temp DURATION=2
```
The above delayed_gcode will send "// Extruder Temp: [ex0_temp]" to
Octoprint every 2 seconds. This can be canceled with the following
gcode:
```
UPDATE_DELAYED_GCODE ID=report_temp DURATION=0
```
## Menu templates
If a [display config section](Config_Reference.md#display) is enabled,
then it is possible to customize the menu with
[menu](Config_Reference.md#menu) config sections.
The following read-only attributes are available in menu templates:
* `menu.width` - element width (number of display columns)
* `menu.ns` - element namespace
* `menu.event` - name of the event that triggered the script
* `menu.input` - input value, only available in input script context
The following actions are available in menu templates:
* `menu.back(force, update)`: will execute menu back command, optional
boolean parameters `<force>` and `<update>`.
* When `<force>` is set True then it will also stop editing. Default
value is False.
* When `<update>` is set False then parent container items are not
updated. Default value is True.
* `menu.exit(force)` - will execute menu exit command, optional
boolean parameter `<force>` default value False.
* When `<force>` is set True then it will also stop editing. Default
value is False.
## Save Variables to disk
If a
[save_variables config section](Config_Reference.md#save_variables)
has been enabled, `SAVE_VARIABLE VARIABLE=<name> VALUE=<value>` can be
used to save the variable to disk so that it can be used across
restarts. All stored variables are loaded into the
`printer.save_variables.variables` dict at startup and can be used in
gcode macros. to avoid overly long lines you can add the following at
the top of the macro:
```
{% set svv = printer.save_variables.variables %}
```
As an example, it could be used to save the state of 2-in-1-out hotend
and when starting a print ensure that the active extruder is used,
instead of T0:
```
[gcode_macro T1]
gcode:
ACTIVATE_EXTRUDER extruder=extruder1
SAVE_VARIABLE VARIABLE=currentextruder VALUE='"extruder1"'
[gcode_macro T0]
gcode:
ACTIVATE_EXTRUDER extruder=extruder
SAVE_VARIABLE VARIABLE=currentextruder VALUE='"extruder"'
[gcode_macro START_GCODE]
gcode:
{% set svv = printer.save_variables.variables %}
ACTIVATE_EXTRUDER extruder={svv.currentextruder}
```

435
docs/Config_Changes.md Normal file
View File

@@ -0,0 +1,435 @@
# Configuration Changes
This document covers recent software changes to the config file that
are not backwards compatible. It is a good idea to review this
document when upgrading the Klipper software.
All dates in this document are approximate.
## Changes
20220616: It was previously possible to flash an rp2040 in bootloader
mode by running `make flash FLASH_DEVICE=first`. The equivalent
command is now `make flash FLASH_DEVICE=2e8a:0003`.
20220612: The rp2040 micro-controller now has a workaround for the
"rp2040-e5" USB errata. This should make initial USB connections more
reliable. However, it may result in a change in behavior for the
gpio15 pin. It is unlikely the gpio15 behavior change will be
noticeable.
20220407: The temperature_fan `pid_integral_max` config option has
been removed (it was deprecated on 20210612).
20220407: The default color order for pca9632 LEDs is now "RGBW". Add
an explicit `color_order: RBGW` setting to the pca9632 config section
to obtain the previous behavior.
20220330: The format of the `printer.neopixel.color_data` status
information for neopixel and dotstar modules has changed. The
information is now stored as a list of color lists (instead of a list
of dictionaries). See the [status reference](Status_Reference.md#led)
for details.
20220307: `M73` will no longer set print progress to 0 if `P` is missing.
20220304: There is no longer a default for the `extruder` parameter of
[extruder_stepper](Config_Reference.md#extruder_stepper) config
sections. If desired, specify `extruder: extruder` explicitly to
associate the stepper motor with the "extruder" motion queue at
startup.
20220210: The `SYNC_STEPPER_TO_EXTRUDER` command is deprecated; the
`SET_EXTRUDER_STEP_DISTANCE` command is deprecated; the
[extruder](Config_Reference.md#extruder) `shared_heater` config option
is deprecated. These features will be removed in the near future.
Replace `SET_EXTRUDER_STEP_DISTANCE` with
`SET_EXTRUDER_ROTATION_DISTANCE`. Replace `SYNC_STEPPER_TO_EXTRUDER`
with `SYNC_EXTRUDER_MOTION`. Replace extruder config sections using
`shared_heater` with
[extruder_stepper](Config_Reference.md#extruder_stepper) config
sections and update any activation macros to use
[SYNC_EXTRUDER_MOTION](G-Codes.md#sync_extruder_motion).
20220116: The tmc2130, tmc2208, tmc2209, and tmc2660 `run_current`
calculation code has changed. For some `run_current` settings the
drivers may now be configured differently. This new configuration
should be more accurate, but it may invalidate previous tmc driver
tuning.
20211230: Scripts to tune input shaper (`scripts/calibrate_shaper.py`
and `scripts/graph_accelerometer.py`) were migrated to use Python3
by default. As a result, users must install Python3 versions of certain
packages (e.g. `sudo apt install python3-numpy python3-matplotlib`) to
continue using these scripts. For more details, refer to
[Software installation](Measuring_Resonances.md#software-installation).
Alternatively, users can temporarily force the execution of these scripts
under Python 2 by explicitly calling Python2 interpretor in the console:
`python2 ~/klipper/scripts/calibrate_shaper.py ...`
20211110: The "NTC 100K beta 3950" temperature sensor is deprecated.
This sensor will be removed in the near future. Most users will find
the "Generic 3950" temperature sensor more accurate. To continue to
use the older (typically less accurate) definition, define a custom
[thermistor](Config_Reference.md#thermistor) with `temperature1: 25`,
`resistance1: 100000`, and `beta: 3950`.
20211104: The "step pulse duration" option in "make menuconfig" has
been removed. The default step duration for TMC drivers configured in
UART or SPI mode is now 100ns. A new `step_pulse_duration` setting in
the [stepper config section](Config_Reference.md#stepper) should be
set for all steppers that need a custom pulse duration.
20211102: Several deprecated features have been removed. The stepper
`step_distance` option has been removed (deprecated on 20201222). The
`rpi_temperature` sensor alias has been removed (deprecated on
20210219). The mcu `pin_map` option has been removed (deprecated on
20210325). The gcode_macro `default_parameter_<name>` and macro
access to command parameters other than via the `params`
pseudo-variable has been removed (deprecated on 20210503). The heater
`pid_integral_max` option has been removed (deprecated on 20210612).
20210929: Klipper v0.10.0 released.
20210903: The default [`smooth_time`](Config_Reference.md#extruder)
for heaters has changed to 1 second (from 2 seconds). For most
printers this will result in more stable temperature control.
20210830: The default adxl345 name is now "adxl345". The default CHIP
parameter for the `ACCELEROMETER_MEASURE` and `ACCELEROMETER_QUERY` is
now also "adxl345".
20210830: The adxl345 ACCELEROMETER_MEASURE command no longer supports
a RATE parameter. To alter the query rate, update the printer.cfg
file and issue a RESTART command.
20210821: Several config settings in `printer.configfile.settings`
will now be reported as lists instead of raw strings. If the actual
raw string is desired, use `printer.configfile.config` instead.
20210819: In some cases, a `G28` homing move may end in a position
that is nominally outside the valid movement range. In rare
situations this may result in confusing "Move out of range" errors
after homing. If this occurs, change your start scripts to move the
toolhead to a valid position immediately after homing.
20210814: The analog only pseudo-pins on the atmega168 and atmega328
have been renamed from PE0/PE1 to PE2/PE3.
20210720: A controller_fan section now monitors all stepper motors by
default (not just the kinematic stepper motors). If the previous
behavior is desired, see the `stepper` config option in the
[config reference](Config_Reference.md#controller_fan).
20210703: A `samd_sercom` config section must now specify the sercom
bus it is configuring via the `sercom` option.
20210612: The `pid_integral_max` config option in heater and
temperature_fan sections is deprecated. The option will be removed in
the near future.
20210503: The gcode_macro `default_parameter_<name>` config option is
deprecated. Use the `params` pseudo-variable to access macro
parameters. Other methods for accessing macro parameters will be
removed in the near future. Most users can replace a
`default_parameter_NAME: VALUE` config option with a line like the
following in the start of the macro: ` {% set NAME =
params.NAME|default(VALUE)|float %}`. See the [Command Templates
document](Command_Templates.md#macro-parameters) for examples.
20210430: The SET_VELOCITY_LIMIT (and M204) command may now set a
velocity, acceleration, and square_corner_velocity larger than the
specified values in the config file.
20210325: Support for the `pin_map` config option is deprecated. Use
the [sample-aliases.cfg](../config/sample-aliases.cfg) file to
translate to the actual micro-controller pin names. The `pin_map`
config option will be removed in the near future.
20210313: Klipper's support for micro-controllers that communicate
with CAN bus has changed. If using CAN bus then all micro-controllers
must be reflashed and the
[Klipper configuration must be updated](CANBUS.md).
20210310: The TMC2660 default for driver_SFILT has been changed from 1
to 0.
20210227: TMC stepper motor drivers in UART or SPI mode are now
queried once per second whenever they are enabled - if the driver can
not be contacted or if the driver reports an error, then Klipper will
transition to a shutdown state.
20210219: The `rpi_temperature` module has been renamed to
`temperature_host`. Replace any occurrences of `sensor_type:
rpi_temperature` with `sensor_type: temperature_host`. The path to
the temperature file may be specified in the `sensor_path` config
variable. The `rpi_temperature` name is deprecated and will be
removed in the near future.
20210201: The `TEST_RESONANCES` command will now disable input shaping
if it was previously enabled (and re-enable it after the test). In order
to override this behavior and keep the input shaping enabled, one can
pass an additional parameter `INPUT_SHAPING=1` to the command.
20210201: The `ACCELEROMETER_MEASURE` command will now append the name
of the accelerometer chip to the output file name if the chip was given
a name in the corresponding adxl345 section of the printer.cfg.
20201222: The `step_distance` setting in the stepper config sections
is deprecated. It is advised to update the config to use the
[`rotation_distance`](Rotation_Distance.md) setting. Support for
`step_distance` will be removed in the near future.
20201218: The `endstop_phase` setting in the endstop_phase module has
been replaced with `trigger_phase`. If using the endstop phases module
then it will be necessary to convert to
[`rotation_distance`](Rotation_Distance.md) and recalibrate any
endstop phases by running the ENDSTOP_PHASE_CALIBRATE command.
20201218: Rotary delta and polar printers must now specify a
`gear_ratio` for their rotary steppers, and they may no longer specify
a `step_distance` parameter. See the
[config reference](Config_Reference.md#stepper) for the format of the
new gear_ratio paramter.
20201213: It is not valid to specify a Z "position_endstop" when using
"probe:z_virtual_endstop". An error will now be raised if a Z
"position_endstop" is specified with "probe:z_virtual_endstop".
Remove the Z "position_endstop" definition to fix the error.
20201120: The `[board_pins]` config section now specifies the mcu name
in an explicit `mcu:` parameter. If using board_pins for a secondary
mcu, then the config must be updated to specify that name. See the
[config reference](Config_Reference.md#board_pins) for further
details.
20201112: The time reported by `print_stats.print_duration` has
changed. The duration prior to the first detected extrusion is
now excluded.
20201029: The neopixel `color_order_GRB` config option has been
removed. If necessary, update the config to set the new `color_order`
option to RGB, GRB, RGBW, or GRBW.
20201029: The serial option in the mcu config section no longer
defaults to /dev/ttyS0. In the rare situation where /dev/ttyS0 is the
desired serial port, it must be specified explicitly.
20201020: Klipper v0.9.0 released.
20200902: The RTD resistance-to-temperature calculation for MAX31865
converters has been corrected to not read low. If you are using such a
device, you should recalibrate your print temperature and PID settings.
20200816: The gcode macro `printer.gcode` object has been renamed to
`printer.gcode_move`. Several undocumented variables in
`printer.toolhead` and `printer.gcode` have been removed. See
docs/Command_Templates.md for a list of available template variables.
20200816: The gcode macro "action_" system has changed. Replace any
calls to `printer.gcode.action_emergency_stop()` with
`action_emergency_stop()`, `printer.gcode.action_respond_info()` with
`action_respond_info()`, and `printer.gcode.action_respond_error()`
with `action_raise_error()`.
20200809: The menu system has been rewritten. If the menu has been
customized then it will be necessary to update to the new
configuration. See config/example-menu.cfg for configuration details
and see klippy/extras/display/menu.cfg for examples.
20200731: The behavior of the `progress` attribute reported by
the `virtual_sdcard` printer object has changed. Progress is no
longer reset to 0 when a print is paused. It will now always report
progress based on the internal file position, or 0 if no file is
currently loaded.
20200725: The servo `enable` config parameter and the SET_SERVO
`ENABLE` parameter have been removed. Update any macros to use
`SET_SERVO SERVO=my_servo WIDTH=0` to disable a servo.
20200608: The LCD display support has changed the name of some
internal "glyphs". If a custom display layout was implemented it may
be necessary to update to the latest glyph names (see
klippy/extras/display/display.cfg for a list of available glyphs).
20200606: The pin names on linux mcu have changed. Pins now have names
of the form `gpiochip<chipid>/gpio<gpio>`. For gpiochip0 you can also
use a short `gpio<gpio>`. For example, what was previously referred
to as `P20` now becomes `gpio20` or `gpiochip0/gpio20`.
20200603: The default 16x4 LCD layout will no longer show the
estimated time remaining in a print. (Only the elapsed time will be
shown.) If the old behavior is desired one can customize the menu
display with that information (see the description of display_data in
config/example-extras.cfg for details).
20200531: The default USB vendor/product id is now 0x1d50/0x614e.
These new ids are reserved for Klipper (thanks to the openmoko
project). This change should not require any config changes, but the
new ids may appear in system logs.
20200524: The default value for the tmc5160 pwm_freq field is now zero
(instead of one).
20200425: The gcode_macro command template variable `printer.heater`
was renamed to `printer.heaters`.
20200313: The default lcd layout for multi-extruder printers with a
16x4 screen has changed. The single extruder screen layout is now the
default and it will show the currently active extruder. To use the
previous display layout set "display_group: _multiextruder_16x4" in
the [display] section of the printer.cfg file.
20200308: The default `__test` menu item was removed. If the config
file has a custom menu then be sure to remove all references to this
`__test` menu item.
20200308: The menu "deck" and "card" options were removed. To
customize the layout of an lcd screen use the new display_data config
sections (see config/example-extras.cfg for the details).
20200109: The bed_mesh module now references the probe's location
in for the mesh configuration. As such, some configuration options
have been renamed to more accurately reflect their intended
functionality. For rectangular beds, `min_point` and `max_point`
have been renamed to `mesh_min` and `mesh_max` respectively. For
round beds, `bed_radius` has been renamed to `mesh_radius`. A new
`mesh_origin` option has also been added for round beds. Note that
these changes are also incompatible with previously saved mesh profiles.
If an incompatible profile is detected it will be ignored and scheduled
for removal. The removal process can be completed by issuing the
SAVE_CONFIG command. The user will need to re-calibrate each profile.
20191218: The display config section no longer supports "lcd_type:
st7567". Use the "uc1701" display type instead - set "lcd_type:
uc1701" and change the "rs_pin: some_pin" to "rst_pin: some_pin". It
may also be necessary to add a "contrast: 60" config setting.
20191210: The builtin T0, T1, T2, ... commands have been removed. The
extruder activate_gcode and deactivate_gcode config options have been
removed. If these commands (and scripts) are needed then define
individual [gcode_macro T0] style macros that call the
ACTIVATE_EXTRUDER command. See the config/sample-idex.cfg and
sample-multi-extruder.cfg files for examples.
20191210: Support for the M206 command has been removed. Replace with
calls to SET_GCODE_OFFSET. If support for M206 is needed, add a
[gcode_macro M206] config section that calls SET_GCODE_OFFSET. (For
example "SET_GCODE_OFFSET Z=-{params.Z}".)
20191202: Support for the undocumented "S" parameter of the "G4"
command has been removed. Replace any occurrences of S with the
standard "P" parameter (the delay specified in milliseconds).
20191126: The USB names have changed on micro-controllers with native
USB support. They now use a unique chip id by default (where
available). If an "mcu" config section uses a "serial" setting that
starts with "/dev/serial/by-id/" then it may be necessary to update
the config. Run "ls /dev/serial/by-id/*" in an ssh terminal to
determine the new id.
20191121: The pressure_advance_lookahead_time parameter has been
removed. See example.cfg for alternate configuration settings.
20191112: The tmc stepper driver virtual enable capability is now
automatically enabled if the stepper does not have a dedicated stepper
enable pin. Remove references to tmcXXXX:virtual_enable from the
config. The ability to control multiple pins in the stepper
enable_pin config has been removed. If multiple pins are needed then
use a multi_pin config section.
20191107: The primary extruder config section must be specified as
"extruder" and may no longer be specified as "extruder0". Gcode
command templates that query the extruder status are now accessed via
"{printer.extruder}".
20191021: Klipper v0.8.0 released
20191003: The move_to_previous option in [safe_z_homing] now defaults
to False. (It was effectively False prior to 20190918.)
20190918: The zhop option in [safe_z_homing] is always re-applied
after Z axis homing completed. This might need users to update custom
scripts based on this module.
20190806: The SET_NEOPIXEL command has been renamed to SET_LED.
20190726: The mcp4728 digital-to-analog code has changed. The default
i2c_address is now 0x60 and the voltage reference is now relative to
the mcp4728's internal 2.048 volt reference.
20190710: The z_hop option was removed from the [firmware_retract]
config section. The z_hop support was incomplete and could cause
incorrect behavior with several common slicers.
20190710: The optional parameters of the PROBE_ACCURACY command have
changed. It may be necessary to update any macros or scripts that use
that command.
20190628: All configuration options have been removed from the
[skew_correction] section. Configuration for skew_correction
is now done via the SET_SKEW gcode. See [Skew Correction](Skew_Correction.md)
for recommended usage.
20190607: The "variable_X" parameters of gcode_macro (along with the
VALUE parameter of SET_GCODE_VARIABLE) are now parsed as Python
literals. If a value needs to be assigned a string then wrap the value
in quotes so that it is evaluated as a string.
20190606: The "samples", "samples_result", and "sample_retract_dist"
config options have been moved to the "probe" config section. These
options are no longer supported in the "delta_calibrate", "bed_tilt",
"bed_mesh", "screws_tilt_adjust", "z_tilt", or "quad_gantry_level"
config sections.
20190528: The magic "status" variable in gcode_macro template
evaluation has been renamed to "printer".
20190520: The SET_GCODE_OFFSET command has changed; update any g-code
macros accordingly. The command will no longer apply the requested
offset to the next G1 command. The old behavior may be approximated by
using the new "MOVE=1" parameter.
20190404: The Python host software packages were updated. Users will
need to rerun the ~/klipper/scripts/install-octopi.sh script (or
otherwise upgrade the python dependencies if not using a standard
OctoPi installation).
20190404: The i2c_bus and spi_bus parameters (in various config
sections) now take a bus name instead of a number.
20190404: The sx1509 config parameters have changed. The 'address'
parameter is now 'i2c_address' and it must be specified as a decimal
number. Where 0x3E was previously used, specify 62.
20190328: The min_speed value in [temperature_fan] config
will now be respected and the fan will always run at this
speed or higher in PID mode.
20190322: The default value for "driver_HEND" in [tmc2660] config
sections was changed from 6 to 3. The "driver_VSENSE" field was
removed (it is now automatically calculated from run_current).
20190310: The [controller_fan] config section now always takes a name
(such as [controller_fan my_controller_fan]).
20190308: The "driver_BLANK_TIME_SELECT" field in [tmc2130] and
[tmc2208] config sections has been renamed to "driver_TBL".
20190308: The [tmc2660] config section has changed. A new
sense_resistor config parameter must now be provided. The meaning of
several of the driver_XXX parameters has changed.
20190228: Users of SPI or I2C on SAMD21 boards must now specify the
bus pins via a [samd_sercom] config section.
20190224: The bed_shape option has been removed from bed_mesh. The
radius option has been renamed to bed_radius. Users with round beds
should supply the bed_radius and round_probe_count options.
20190107: The i2c_address parameter in the mcp4451 config section
changed. This is a common setting on Smoothieboards. The new value is
half the old value (88 should be changed to 44, and 90 should be
changed to 45).
20181220: Klipper v0.7.0 released

4252
docs/Config_Reference.md Normal file

File diff suppressed because it is too large Load Diff

169
docs/Config_checks.md Normal file
View File

@@ -0,0 +1,169 @@
# Configuration checks
This document provides a list of steps to help confirm the pin
settings in the Klipper printer.cfg file. It is a good idea to run
through these steps after following the steps in the
[installation document](Installation.md).
During this guide, it may be necessary to make changes to the Klipper
config file. Be sure to issue a RESTART command after every change to
the config file to ensure that the change takes effect (type "restart"
in the Octoprint terminal tab and then click "Send"). It's also a good
idea to issue a STATUS command after every RESTART to verify that the
config file is successfully loaded.
## Verify temperature
Start by verifying that temperatures are being properly reported.
Navigate to the Octoprint temperature tab.
![octoprint-temperature](img/octoprint-temperature.png)
Verify that the temperature of the nozzle and bed (if applicable) are
present and not increasing. If it is increasing, remove power from the
printer. If the temperatures are not accurate, review the
"sensor_type" and "sensor_pin" settings for the nozzle and/or bed.
## Verify M112
Navigate to the Octoprint terminal tab and issue an M112 command in
the terminal box. This command requests Klipper to go into a
"shutdown" state. It will cause Octoprint to disconnect from Klipper -
navigate to the Connection area and click on "Connect" to cause
Octoprint to reconnect. Then navigate to the Octoprint temperature tab
and verify that temperatures continue to update and the temperatures
are not increasing. If temperatures are increasing, remove power from
the printer.
The M112 command causes Klipper to go into a "shutdown" state. To
clear this state, issue a FIRMWARE_RESTART command in the Octoprint
terminal tab.
## Verify heaters
Navigate to the Octoprint temperature tab and type in 50 followed by
enter in the "Tool" temperature box. The extruder temperature in the
graph should start to increase (within about 30 seconds or so). Then
go to the "Tool" temperature drop-down box and select "Off". After
several minutes the temperature should start to return to its initial
room temperature value. If the temperature does not increase then
verify the "heater_pin" setting in the config.
If the printer has a heated bed then perform the above test again with
the bed.
## Verify stepper motor enable pin
Verify that all of the printer axes can manually move freely (the
stepper motors are disabled). If not, issue an M84 command to disable
the motors. If any of the axes still can not move freely, then verify
the stepper "enable_pin" configuration for the given axis. On most
commodity stepper motor drivers, the motor enable pin is "active low"
and therefore the enable pin should have a "!" before the pin (for
example, "enable_pin: !ar38").
## Verify endstops
Manually move all the printer axes so that none of them are in contact
with an endstop. Send a QUERY_ENDSTOPS command via the Octoprint
terminal tab. It should respond with the current state of all of the
configured endstops and they should all report a state of "open". For
each of the endstops, rerun the QUERY_ENDSTOPS command while manually
triggering the endstop. The QUERY_ENDSTOPS command should report the
endstop as "TRIGGERED".
If the endstop appears inverted (it reports "open" when triggered and
vice-versa) then add a "!" to the pin definition (for example,
"endstop_pin: ^!ar3"), or remove the "!" if there is already one
present.
If the endstop does not change at all then it generally indicates that
the endstop is connected to a different pin. However, it may also
require a change to the pullup setting of the pin (the '^' at the
start of the endstop_pin name - most printers will use a pullup
resistor and the '^' should be present).
## Verify stepper motors
Use the STEPPER_BUZZ command to verify the connectivity of each
stepper motor. Start by manually positioning the given axis to a
midway point and then run `STEPPER_BUZZ STEPPER=stepper_x`. The
STEPPER_BUZZ command will cause the given stepper to move one
millimeter in a positive direction and then it will return to its
starting position. (If the endstop is defined at position_endstop=0
then at the start of each movement the stepper will move away from the
endstop.) It will perform this oscillation ten times.
If the stepper does not move at all, then verify the "enable_pin" and
"step_pin" settings for the stepper. If the stepper motor moves but
does not return to its original position then verify the "dir_pin"
setting. If the stepper motor oscillates in an incorrect direction,
then it generally indicates that the "dir_pin" for the axis needs to
be inverted. This is done by adding a '!' to the "dir_pin" in the
printer config file (or removing it if one is already there). If the
motor moves significantly more or significantly less than one
millimeter then verify the "rotation_distance" setting.
Run the above test for each stepper motor defined in the config
file. (Set the STEPPER parameter of the STEPPER_BUZZ command to the
name of the config section that is to be tested.) If there is no
filament in the extruder then one can use STEPPER_BUZZ to verify the
extruder motor connectivity (use STEPPER=extruder). Otherwise, it's
best to test the extruder motor separately (see the next section).
After verifying all endstops and verifying all stepper motors the
homing mechanism should be tested. Issue a G28 command to home all
axes. Remove power from the printer if it does not home properly.
Rerun the endstop and stepper motor verification steps if necessary.
## Verify extruder motor
To test the extruder motor it will be necessary to heat the extruder
to a printing temperature. Navigate to the Octoprint temperature tab
and select a target temperature from the temperature drop-down box (or
manually enter an appropriate temperature). Wait for the printer to
reach the desired temperature. Then navigate to the Octoprint control
tab and click the "Extrude" button. Verify that the extruder motor
turns in the correct direction. If it does not, see the
troubleshooting tips in the previous section to confirm the
"enable_pin", "step_pin", and "dir_pin" settings for the extruder.
## Calibrate PID settings
Klipper supports
[PID control](https://en.wikipedia.org/wiki/PID_controller) for the
extruder and bed heaters. In order to use this control mechanism, it is
necessary to calibrate the PID settings on each printer (PID settings
found in other firmwares or in the example configuration files often
work poorly).
To calibrate the extruder, navigate to the OctoPrint terminal tab and
run the PID_CALIBRATE command. For example: `PID_CALIBRATE
HEATER=extruder TARGET=170`
At the completion of the tuning test run `SAVE_CONFIG` to update the
printer.cfg file the new PID settings.
If the printer has a heated bed and it supports being driven by PWM
(Pulse Width Modulation) then it is recommended to use PID control for
the bed. (When the bed heater is controlled using the PID algorithm it
may turn on and off ten times a second, which may not be suitable for
heaters using a mechanical switch.) A typical bed PID calibration
command is: `PID_CALIBRATE HEATER=heater_bed TARGET=60`
## Next steps
This guide is intended to help with basic verification of pin settings
in the Klipper configuration file. Be sure to read the
[bed leveling](Bed_Level.md) guide. Also see the [Slicers](Slicers.md)
document for information on configuring a slicer with Klipper.
After one has verified that basic printing works, it is a good idea to
consider calibrating [pressure advance](Pressure_Advance.md).
It may be necessary to perform other types of detailed printer
calibration - a number of guides are available online to help with
this (for example, do a web search for "3d printer calibration").
As an example, if you experience the effect called ringing,
you may try following [resonance compensation](Resonance_Compensation.md)
tuning guide.

165
docs/Contact.md Normal file
View File

@@ -0,0 +1,165 @@
# Contact
This document provides contact information for Klipper.
1. [Community Forum](#community-forum)
2. [Discord Chat](#discord-chat)
3. [I have a question about Klipper](#i-have-a-question-about-klipper)
4. [I have a feature request](#i-have-a-feature-request)
5. [Help! It doesn't work!](#help-it-doesnt-work)
6. [I have diagnosed a defect in the Klipper software](#i-have-diagnosed-a-defect-in-the-klipper-software)
7. [I am making changes that I'd like to include in Klipper](#i-am-making-changes-that-id-like-to-include-in-klipper)
## Community Forum
There is a
[Klipper Community Discourse server](https://community.klipper3d.org)
for discussions on Klipper.
## Discord Chat
There is a Discord server dedicated to Klipper at:
[https://discord.klipper3d.org](https://discord.klipper3d.org).
This server is run by a community of Klipper enthusiasts dedicated to
discussions on Klipper. It allows users to chat with other users in
real-time.
## I have a question about Klipper
Many questions we receive are already answered in the
[Klipper documentation](Overview.md). Please be sure to to read the
documentation and follow the directions provided there.
It is also possible to search for similar questions in the
[Klipper Community Forum](#community-forum).
If you are interested in sharing your knowledge and experience with
other Klipper users then you can join the
[Klipper Community Forum](#community-forum) or
[Klipper Discord Chat](#discord-chat). Both are communities where
Klipper users can discuss Klipper with other users.
Many questions we receive are general 3d-printing questions that are
not specific to Klipper. If you have a general question or are
experiencing general printing problems, then you will likely get a
better response by asking in a general 3d-printing forum or a forum
dedicated to your printer hardware.
Do not open a Klipper github issue to ask a question.
## I have a feature request
All new features require someone interested and able to implement that
feature. If you are interested in helping to implement or test a new
feature, you can search for ongoing developments in the
[Klipper Community Forum](#community-forum). There is also
[Klipper Discord Chat](#discord-chat) for discussions between
collaborators.
Do not open a Klipper github issue to request a feature.
## Help! It doesn't work!
Unfortunately, we receive many more requests for help than we could
possibly answer. Most problem reports we see are eventually tracked
down to:
1. Subtle errors in the hardware, or
2. Not following all the steps described in the Klipper documentation.
If you are experiencing problems we recommend you carefully read the
[Klipper documentation](Overview.md) and double check that all steps
were followed.
If you are experiencing a printing problem, then we recommend
carefully inspecting the printer hardware (all joints, wires, screws,
etc.) and verify nothing is abnormal. We find most printing problems
are not related to the Klipper software. If you do find a problem with
the printer hardware then you will likely get a better response by
searching in a general 3d-printing forum or in a forum dedicated to
your printer hardware.
It is also possible to search for similar issues in the
[Klipper Community Forum](#community-forum).
If you are interested in sharing your knowledge and experience with
other Klipper users then you can join the
[Klipper Community Forum](#community-forum) or
[Klipper Discord Chat](#discord-chat). Both are communities where
Klipper users can discuss Klipper with other users.
Do not open a Klipper github issue to request help.
## I have diagnosed a defect in the Klipper software
Klipper is an open-source project and we appreciate when collaborators
diagnose errors in the software.
There is important information that will be needed in order to fix a
bug. Please follow these steps:
1. Be sure the bug is in the Klipper software. If you are thinking
"there is a problem, I can't figure out why, and therefore it is a
Klipper bug", then **do not** open a github issue. In that case,
someone interested and able will need to first research and
diagnose the root cause of the problem. If you would like to share
the results of your research or check if other users are
experiencing similar issues then you can search the
[Klipper Community Forum](#community-forum).
2. Make sure you are running unmodified code from
[https://github.com/Klipper3d/klipper](https://github.com/Klipper3d/klipper).
If the code has been modified or is obtained from another source,
then you will need to reproduce the problem on the unmodified code
from
[https://github.com/Klipper3d/klipper](https://github.com/Klipper3d/klipper)
prior to reporting an issue.
3. If possible, run an `M112` command in the OctoPrint terminal window
immediately after the undesirable event occurs. This causes Klipper
to go into a "shutdown state" and it will cause additional
debugging information to be written to the log file.
4. Obtain the Klipper log file from the event. The log file has been
engineered to answer common questions the Klipper developers have
about the software and its environment (software version, hardware
type, configuration, event timing, and hundreds of other
questions).
1. The Klipper log file is located in `/tmp/klippy.log` on the
Klipper "host" computer (the Raspberry Pi).
2. An "scp" or "sftp" utility is needed to copy this log file to
your desktop computer. The "scp" utility comes standard with
Linux and MacOS desktops. There are freely available scp
utilities for other desktops (eg, WinSCP). If using a graphical
scp utility that can not directly copy `/tmp/klippy.log` then
repeatedly click on `..` or `parent folder` until you get to the
root directory, click on the `tmp` folder, and then select the
`klippy.log` file.
3. Copy the log file to your desktop so that it can be attached to
an issue report.
4. Do not modify the log file in any way; do not provide a snippet
of the log. Only the full unmodified log file provides the
necessary information.
5. If the log file is very large (eg, greater than 2MB) then one
may need to compress the log with zip or gzip.
5. Open a new github issue at
[https://github.com/Klipper3d/klipper/issues](https://github.com/Klipper3d/klipper/issues)
and provide a clear description of the problem. The Klipper
developers need to understand what steps were taken, what the
desired outcome was, and what outcome actually occurred. The
Klipper log file **must be attached** to that ticket:
![attach-issue](img/attach-issue.png)
## I am making changes that I'd like to include in Klipper
Klipper is open-source software and we appreciate new contributions.
New contributions (for both code and documentation) are submitted via
Github Pull Requests. See the [CONTRIBUTING document](CONTRIBUTING.md)
for important information.
There are several
[documents for developers](Overview.md#developer-documentation). If
you have questions on the code then you can also ask in the
[Klipper Community Forum](#community-forum) or on the
[Klipper Community Discord](#discord-chat). If you would like to
provide an update on your current progress then you can open a Github
issue with the location of your code, an overview of the changes, and
a description of its current status.

280
docs/Debugging.md Normal file
View File

@@ -0,0 +1,280 @@
# Debugging
This document describes some of the Klipper debugging tools.
## Running the regression tests
The main Klipper GitHub repository uses "github actions" to run a
series of regression tests. It can be useful to run some of these
tests locally.
The source code "whitespace check" can be run with:
```
./scripts/check_whitespace.sh
```
The Klippy regression test suite requires "data dictionaries" from
many platforms. The easiest way to obtain them is to
[download them from github](https://github.com/Klipper3d/klipper/issues/1438).
Once the data dictionaries are downloaded, use the following to run
the regression suite:
```
tar xfz klipper-dict-20??????.tar.gz
~/klippy-env/bin/python ~/klipper/scripts/test_klippy.py -d dict/ ~/klipper/test/klippy/*.test
```
## Manually sending commands to the micro-controller
Normally, the host klippy.py process would be used to translate gcode
commands to Klipper micro-controller commands. However, it's also
possible to manually send these MCU commands (functions marked with
the DECL_COMMAND() macro in the Klipper source code). To do so, run:
```
~/klippy-env/bin/python ./klippy/console.py /tmp/pseudoserial
```
See the "HELP" command within the tool for more information on its
functionality.
Some command-line options are available. For more information run:
`~/klippy-env/bin/python ./klippy/console.py --help`
## Translating gcode files to micro-controller commands
The Klippy host code can run in a batch mode to produce the low-level
micro-controller commands associated with a gcode file. Inspecting
these low-level commands is useful when trying to understand the
actions of the low-level hardware. It can also be useful to compare
the difference in micro-controller commands after a code change.
To run Klippy in this batch mode, there is a one time step necessary
to generate the micro-controller "data dictionary". This is done by
compiling the micro-controller code to obtain the **out/klipper.dict**
file:
```
make menuconfig
make
```
Once the above is done it is possible to run Klipper in batch mode
(see [installation](Installation.md) for the steps necessary to build
the python virtual environment and a printer.cfg file):
```
~/klippy-env/bin/python ./klippy/klippy.py ~/printer.cfg -i test.gcode -o test.serial -v -d out/klipper.dict
```
The above will produce a file **test.serial** with the binary serial
output. This output can be translated to readable text with:
```
~/klippy-env/bin/python ./klippy/parsedump.py out/klipper.dict test.serial > test.txt
```
The resulting file **test.txt** contains a human readable list of
micro-controller commands.
The batch mode disables certain response / request commands in order
to function. As a result, there will be some differences between
actual commands and the above output. The generated data is useful for
testing and inspection; it is not useful for sending to a real
micro-controller.
## Motion analysis and data logging
Klipper supports logging its internal motion history, which can be
later analyzed. To use this feature, Klipper must be started with the
[API Server](API_Server.md) enabled.
Data logging is enabled with the `data_logger.py` tool. For example:
```
~/klipper/scripts/motan/data_logger.py /tmp/klippy_uds mylog
```
This command will connect to the Klipper API Server, subscribe to
status and motion information, and log the results. Two files are
generated - a compressed data file and an index file (eg,
`mylog.json.gz` and `mylog.index.gz`). After starting the logging, it
is possible to complete prints and other actions - the logging will
continue in the background. When done logging, hit `ctrl-c` to exit
from the `data_logger.py` tool.
The resulting files can be read and graphed using the `motan_graph.py`
tool. To generate graphs on a Raspberry Pi, a one time step is
necessary to install the "matplotlib" package:
```
sudo apt-get update
sudo apt-get install python-matplotlib
```
However, it may be more convenient to copy the data files to a desktop
class machine along with the Python code in the `scripts/motan/`
directory. The motion analysis scripts should run on any machine with
a recent version of [Python](https://python.org) and
[Matplotlib](https://matplotlib.org/) installed.
Graphs can be generated with a command like the following:
```
~/klipper/scripts/motan/motan_graph.py mylog -o mygraph.png
```
One can use the `-g` option to specify the datasets to graph (it takes
a Python literal containing a list of lists). For example:
```
~/klipper/scripts/motan/motan_graph.py mylog -g '[["trapq(toolhead,velocity)"], ["trapq(toolhead,accel)"]]'
```
The list of available datasets can be found using the `-l` option -
for example:
```
~/klipper/scripts/motan/motan_graph.py -l
```
It is also possible to specify matplotlib plot options for each
dataset:
```
~/klipper/scripts/motan/motan_graph.py mylog -g '[["trapq(toolhead,velocity)?color=red&alpha=0.4"]]'
```
Many matplotlib options are available; some examples are "color",
"label", "alpha", and "linestyle".
The `motan_graph.py` tool supports several other command-line
options - use the `--help` option to see a list. It may also be
convenient to view/modify the
[motan_graph.py](../scripts/motan/motan_graph.py) script itself.
The raw data logs produced by the `data_logger.py` tool follow the
format described in the [API Server](API_Server.md). It may be useful
to inspect the data with a Unix command like the following:
`gunzip < mylog.json.gz | tr '\03' '\n' | less`
## Generating load graphs
The Klippy log file (/tmp/klippy.log) stores statistics on bandwidth,
micro-controller load, and host buffer load. It can be useful to graph
these statistics after a print.
To generate a graph, a one time step is necessary to install the
"matplotlib" package:
```
sudo apt-get update
sudo apt-get install python-matplotlib
```
Then graphs can be produced with:
```
~/klipper/scripts/graphstats.py /tmp/klippy.log -o loadgraph.png
```
One can then view the resulting **loadgraph.png** file.
Different graphs can be produced. For more information run:
`~/klipper/scripts/graphstats.py --help`
## Extracting information from the klippy.log file
The Klippy log file (/tmp/klippy.log) also contains debugging
information. There is a logextract.py script that may be useful when
analyzing a micro-controller shutdown or similar problem. It is
typically run with something like:
```
mkdir work_directory
cd work_directory
cp /tmp/klippy.log .
~/klipper/scripts/logextract.py ./klippy.log
```
The script will extract the printer config file and will extract MCU
shutdown information. The information dumps from an MCU shutdown (if
present) will be reordered by timestamp to assist in diagnosing cause
and effect scenarios.
## Testing with simulavr
The [simulavr](http://www.nongnu.org/simulavr/) tool enables one to
simulate an Atmel ATmega micro-controller. This section describes how
one can run test gcode files through simulavr. It is recommended to
run this on a desktop class machine (not a Raspberry Pi) as it does
require significant cpu to run efficiently.
To use simulavr, download the simulavr package and compile with python
support. Note that the build system may need to have some packages (such as
swig) installed in order to build the python module.
```
git clone git://git.savannah.nongnu.org/simulavr.git
cd simulavr
make python
make build
```
Make sure a file like **./build/pysimulavr/_pysimulavr.*.so** is present
after the above compilation:
```
ls ./build/pysimulavr/_pysimulavr.*.so
```
This commmand should report a specific file (e.g.
**./build/pysimulavr/_pysimulavr.cpython-39-x86_64-linux-gnu.so**) and
not an error.
If you are on a Debian-based system (Debian, Ubuntu, etc.) you can
install the following packages and generate *.deb files for system-wide
installation of simulavr:
```
sudo apt update
sudo apt install g++ make cmake swig rst2pdf help2man texinfo
make cfgclean python debian
sudo dpkg -i build/debian/python3-simulavr*.deb
```
To compile Klipper for use in simulavr, run:
```
cd /path/to/klipper
make menuconfig
```
and compile the micro-controller software for an AVR atmega644p and
select SIMULAVR software emulation support. Then one can compile
Klipper (run `make`) and then start the simulation with:
```
PYTHONPATH=/path/to/simulavr/build/pysimulavr/ ./scripts/avrsim.py out/klipper.elf
```
Note that if you have installed python3-simulavr system-wide, you do
not need to set `PYTHONPATH`, and can simply run the simulator as
```
./scripts/avrsim.py out/klipper.elf
```
Then, with simulavr running in another window, one can run the
following to read gcode from a file (eg, "test.gcode"), process it
with Klippy, and send it to Klipper running in simulavr (see
[installation](Installation.md) for the steps necessary to build the
python virtual environment):
```
~/klippy-env/bin/python ./klippy/klippy.py config/generic-simulavr.cfg -i test.gcode -v
```
### Using simulavr with gtkwave
One useful feature of simulavr is its ability to create signal wave
generation files with the exact timing of events. To do this, follow
the directions above, but run avrsim.py with a command-line like the
following:
```
PYTHONPATH=/path/to/simulavr/src/python/ ./scripts/avrsim.py out/klipper.elf -t PORTA.PORT,PORTC.PORT
```
The above would create a file **avrsim.vcd** with information on each
change to the GPIOs on PORTA and PORTB. This could then be viewed
using gtkwave with:
```
gtkwave avrsim.vcd
```

250
docs/Delta_Calibrate.md Normal file
View File

@@ -0,0 +1,250 @@
# Delta calibration
This document describes Klipper's automatic calibration system for
"delta" style printers.
Delta calibration involves finding the tower endstop positions, tower
angles, delta radius, and delta arm lengths. These settings control
printer motion on a delta printer. Each one of these parameters has a
non-obvious and non-linear impact and it is difficult to calibrate
them manually. In contrast, the software calibration code can provide
excellent results with just a few minutes of time. No special probing
hardware is necessary.
Ultimately, the delta calibration is dependent on the precision of the
tower endstop switches. If one is using Trinamic stepper motor drivers
then consider enabling [endstop phase](Endstop_Phase.md) detection to
improve the accuracy of those switches.
## Automatic vs manual probing
Klipper supports calibrating the delta parameters via a manual probing
method or via an automatic Z probe.
A number of delta printer kits come with automatic Z probes that are
not sufficiently accurate (specifically, small differences in arm
length can cause effector tilt which can skew an automatic probe). If
using an automatic probe then first
[calibrate the probe](Probe_Calibrate.md) and then check for a
[probe location bias](Probe_Calibrate.md#location-bias-check). If the
automatic probe has a bias of more than 25 microns (.025mm) then use
manual probing instead. Manual probing only takes a few minutes and it
eliminates error introduced by the probe.
If using a probe that is mounted on the side of the hotend (that is,
it has an X or Y offset) then note that performing delta calibration
will invalidate the results of probe calibration. These types of
probes are rarely suitable for use on a delta (because minor effector
tilt will result in a probe location bias). If using the probe anyway,
then be sure to rerun probe calibration after any delta calibration.
## Basic delta calibration
Klipper has a DELTA_CALIBRATE command that can perform basic delta
calibration. This command probes seven different points on the bed and
calculates new values for the tower angles, tower endstops, and delta
radius.
In order to perform this calibration the initial delta parameters (arm
lengths, radius, and endstop positions) must be provided and they
should have an accuracy to within a few millimeters. Most delta
printer kits will provide these parameters - configure the printer
with these initial defaults and then go on to run the DELTA_CALIBRATE
command as described below. If no defaults are available then search
online for a delta calibration guide that can provide a basic starting
point.
During the delta calibration process it may be necessary for the
printer to probe below what would otherwise be considered the plane of
the bed. It is typical to permit this during calibration by updating
the config so that the printer's `minimum_z_position=-5`. (Once
calibration completes, one can remove this setting from the config.)
There are two ways to perform the probing - manual probing
(`DELTA_CALIBRATE METHOD=manual`) and automatic probing
(`DELTA_CALIBRATE`). The manual probing method will move the head near
the bed and then wait for the user to follow the steps described at
["the paper test"](Bed_Level.md#the-paper-test) to determine the
actual distance between the nozzle and bed at the given location.
To perform the basic probe, make sure the config has a
[delta_calibrate] section defined and then run the tool:
```
G28
DELTA_CALIBRATE METHOD=manual
```
After probing the seven points new delta parameters will be
calculated. Save and apply these parameters by running:
```
SAVE_CONFIG
```
The basic calibration should provide delta parameters that are
accurate enough for basic printing. If this is a new printer, this is
a good time to print some basic objects and verify general
functionality.
## Enhanced delta calibration
The basic delta calibration generally does a good job of calculating
delta parameters such that the nozzle is the correct distance from the
bed. However, it does not attempt to calibrate X and Y dimensional
accuracy. It's a good idea to perform an enhanced delta calibration to
verify dimensional accuracy.
This calibration procedure requires printing a test object and
measuring parts of that test object with digital calipers.
Prior to running an enhanced delta calibration one must run the basic
delta calibration (via the DELTA_CALIBRATE command) and save the
results (via the SAVE_CONFIG command). Make sure there hasn't been any
notable change to the printer configuration nor hardware since last
performing a basic delta calibration (if unsure, rerun the
[basic delta calibration](#basic-delta-calibration), including
SAVE_CONFIG, just prior to printing the test object described below.)
Use a slicer to generate G-Code from the
[docs/prints/calibrate_size.stl](prints/calibrate_size.stl) file.
Slice the object using a slow speed (eg, 40mm/s). If possible, use a
stiff plastic (such as PLA) for the object. The object has a diameter
of 140mm. If this is too large for the printer then one can scale it
down (but be sure to uniformly scale both the X and Y axes). If the
printer supports significantly larger prints then this object can also
be increased in size. A larger size can improve the measurement
accuracy, but good print adhesion is more important than a larger
print size.
Print the test object and wait for it to fully cool. The commands
described below must be run with the same printer settings used to
print the calibration object (don't run DELTA_CALIBRATE between
printing and measuring, or do something that would otherwise change
the printer configuration).
If possible, perform the measurements described below while the object
is still attached to the print bed, but don't worry if the part
detaches from the bed - just try to avoid bending the object when
performing the measurements.
Start by measuring the distance between the center pillar and the
pillar next to the "A" label (which should also be pointing towards
the "A" tower).
![delta-a-distance](img/delta-a-distance.jpg)
Then go counterclockwise and measure the distances between the center
pillar and the other pillars (distance from center to pillar across
from C label, distance from center to pillar with B label, etc.).
![delta_cal_e_step1](img/delta_cal_e_step1.png)
Enter these parameters into Klipper with a comma separated list of
floating point numbers:
```
DELTA_ANALYZE CENTER_DISTS=<a_dist>,<far_c_dist>,<b_dist>,<far_a_dist>,<c_dist>,<far_b_dist>
```
Provide the values without spaces between them.
Then measure the distance between the A pillar and the pillar across
from the C label.
![delta-ab-distance](img/delta-outer-distance.jpg)
Then go counterclockwise and measure the distance between the pillar
across from C to the B pillar, the distance between the B pillar and
the pillar across from A, and so on.
![delta_cal_e_step2](img/delta_cal_e_step2.png)
Enter these parameters into Klipper:
```
DELTA_ANALYZE OUTER_DISTS=<a_to_far_c>,<far_c_to_b>,<b_to_far_a>,<far_a_to_c>,<c_to_far_b>,<far_b_to_a>
```
At this point it is okay to remove the object from the bed. The final
measurements are of the pillars themselves. Measure the size of the
center pillar along the A spoke, then the B spoke, and then the C
spoke.
![delta-a-pillar](img/delta-a-pillar.jpg)
![delta_cal_e_step3](img/delta_cal_e_step3.png)
Enter them into Klipper:
```
DELTA_ANALYZE CENTER_PILLAR_WIDTHS=<a>,<b>,<c>
```
The final measurements are of the outer pillars. Start by measuring
the distance of the A pillar along the line from A to the pillar
across from C.
![delta-ab-pillar](img/delta-outer-pillar.jpg)
Then go counterclockwise and measure the remaining outer pillars
(pillar across from C along the line to B, B pillar along the line to
pillar across from A, etc.).
![delta_cal_e_step4](img/delta_cal_e_step4.png)
And enter them into Klipper:
```
DELTA_ANALYZE OUTER_PILLAR_WIDTHS=<a>,<far_c>,<b>,<far_a>,<c>,<far_b>
```
If the object was scaled to a smaller or larger size then provide the
scale factor that was used when slicing the object:
```
DELTA_ANALYZE SCALE=1.0
```
(A scale value of 2.0 would mean the object is twice its original
size, 0.5 would be half its original size.)
Finally, perform the enhanced delta calibration by running:
```
DELTA_ANALYZE CALIBRATE=extended
```
This command can take several minutes to complete. After completion it
will calculate updated delta parameters (delta radius, tower angles,
endstop positions, and arm lengths). Use the SAVE_CONFIG command to
save and apply the settings:
```
SAVE_CONFIG
```
The SAVE_CONFIG command will save both the updated delta parameters
and information from the distance measurements. Future DELTA_CALIBRATE
commands will also utilize this distance information. Do not attempt
to reenter the raw distance measurements after running SAVE_CONFIG, as
this command changes the printer configuration and the raw
measurements no longer apply.
### Additional notes
* If the delta printer has good dimensional accuracy then the distance
between any two pillars should be around 74mm and the width of every
pillar should be around 9mm. (Specifically, the goal is for the
distance between any two pillars minus the width of one of the
pillars to be exactly 65mm.) Should there be a dimensional
inaccuracy in the part then the DELTA_ANALYZE routine will calculate
new delta parameters using both the distance measurements and the
previous height measurements from the last DELTA_CALIBRATE command.
* DELTA_ANALYZE may produce delta parameters that are surprising. For
example, it may suggest arm lengths that do not match the printer's
actual arm lengths. Despite this, testing has shown that
DELTA_ANALYZE often produces superior results. It is believed that
the calculated delta parameters are able to account for slight
errors elsewhere in the hardware. For example, small differences in
arm length may result in a tilt to the effector and some of that
tilt may be accounted for by adjusting the arm length parameters.
## Using Bed Mesh on a Delta
It is possible to use [bed mesh](Bed_Mesh.md) on a delta. However, it
is important to obtain good delta calibration prior to enabling a bed
mesh. Running bed mesh with poor delta calibration will result in
confusing and poor results.
Note that performing delta calibration will invalidate any previously
obtained bed mesh. After performing a new delta calibration be sure to
rerun BED_MESH_CALIBRATE.

126
docs/Endstop_Phase.md Normal file
View File

@@ -0,0 +1,126 @@
# Endstop phase
This document describes Klipper's stepper phase adjusted endstop
system. This functionality can improve the accuracy of traditional
endstop switches. It is most useful when using a Trinamic stepper
motor driver that has run-time configuration.
A typical endstop switch has an accuracy of around 100 microns. (Each
time an axis is homed the switch may trigger slightly earlier or
slightly later.) Although this is a relatively small error, it can
result in unwanted artifacts. In particular, this positional deviation
may be noticeable when printing the first layer of an object. In
contrast, typical stepper motors can obtain significantly higher
precision.
The stepper phase adjusted endstop mechanism can use the precision of
the stepper motors to improve the precision of the endstop switches.
A stepper motor moves by cycling through a series of phases until in
completes four "full steps". So, a stepper motor using 16 micro-steps
would have 64 phases and when moving in a positive direction it would
cycle through phases: 0, 1, 2, ... 61, 62, 63, 0, 1, 2, etc.
Crucially, when the stepper motor is at a particular position on a
linear rail it should always be at the same stepper phase. Thus, when
a carriage triggers the endstop switch the stepper controlling that
carriage should always be at the same stepper motor phase. Klipper's
endstop phase system combines the stepper phase with the endstop
trigger to improve the accuracy of the endstop.
In order to use this functionality it is necessary to be able to
identify the phase of the stepper motor. If one is using Trinamic
TMC2130, TMC2208, TMC2224 or TMC2660 drivers in run-time configuration
mode (ie, not stand-alone mode) then Klipper can query the stepper
phase from the driver. (It is also possible to use this system on
traditional stepper drivers if one can reliably reset the stepper
drivers - see below for details.)
## Calibrating endstop phases
If using Trinamic stepper motor drivers with run-time configuration
then one can calibrate the endstop phases using the
ENDSTOP_PHASE_CALIBRATE command. Start by adding the following to the
config file:
```
[endstop_phase]
```
Then RESTART the printer and run a `G28` command followed by an
`ENDSTOP_PHASE_CALIBRATE` command. Then move the toolhead to a new
location and run `G28` again. Try moving the toolhead to several
different locations and rerun `G28` from each position. Run at least
five `G28` commands.
After performing the above, the `ENDSTOP_PHASE_CALIBRATE` command will
often report the same (or nearly the same) phase for the stepper. This
phase can be saved in the config file so that all future G28 commands
use that phase. (So, in future homing operations, Klipper will obtain
the same position even if the endstop triggers a little earlier or a
little later.)
To save the endstop phase for a particular stepper motor, run
something like the following:
```
ENDSTOP_PHASE_CALIBRATE STEPPER=stepper_z
```
Run the above for all the steppers one wishes to save. Typically, one
would use this on stepper_z for cartesian and corexy printers, and for
stepper_a, stepper_b, and stepper_c on delta printers. Finally, run
the following to update the configuration file with the data:
```
SAVE_CONFIG
```
### Additional notes
* This feature is most useful on delta printers and on the Z endstop
of cartesian/corexy printers. It is possible to use this feature on
the XY endstops of cartesian printers, but that isn't particularly
useful as a minor error in X/Y endstop position is unlikely to
impact print quality. It is not valid to use this feature on the XY
endstops of corexy printers (as the XY position is not determined by
a single stepper on corexy kinematics). It is not valid to use this
feature on a printer using a "probe:z_virtual_endstop" Z endstop (as
the stepper phase is only stable if the endstop is at a static
location on a rail).
* After calibrating the endstop phase, if the endstop is later moved
or adjusted then it will be necessary to recalibrate the endstop.
Remove the calibration data from the config file and rerun the steps
above.
* In order to use this system the endstop must be accurate enough to
identify the stepper position within two "full steps". So, for
example, if a stepper is using 16 micro-steps with a step distance
of 0.005mm then the endstop must have an accuracy of at least
0.160mm. If one gets "Endstop stepper_z incorrect phase" type error
messages than in may be due to an endstop that is not sufficiently
accurate. If recalibration does not help then disable endstop phase
adjustments by removing them from the config file.
* If one is using a traditional stepper controlled Z axis (as on a
cartesian or corexy printer) along with traditional bed leveling
screws then it is also possible to use this system to arrange for
each print layer to be performed on a "full step" boundary. To
enable this feature be sure the G-Code slicer is configured with a
layer height that is a multiple of a "full step", manually enable
the endstop_align_zero option in the endstop_phase config section
(see [config reference](Config_Reference.md#endstop_phase) for
further details), and then re-level the bed screws.
* It is possible to use this system with traditional (non-Trinamic)
stepper motor drivers. However, doing this requires making sure that
the stepper motor drivers are reset every time the micro-controller
is reset. (If the two are always reset together then Klipper can
determine the stepper phase by tracking the total number of steps it
has commanded the stepper to move.) Currently, the only way to do
this reliably is if both the micro-controller and stepper motor
drivers are powered solely from USB and that USB power is provided
from a host running on a Raspberry Pi. In this situation one can
specify an mcu config with "restart_method: rpi_usb" - that option
will arrange for the micro-controller to always be reset via a USB
power reset, which would arrange for both the micro-controller and
stepper motor drivers to be reset together. If using this mechanism,
one would then need to manually configure the "trigger_phase" config
sections (see [config reference](Config_Reference.md#endstop_phase)
for the details).

110
docs/Example_Configs.md Normal file
View File

@@ -0,0 +1,110 @@
# Example configurations
This document contains guidelines for contributing an example Klipper
configuration to the Klipper github repository (located in the
[config directory](../config/)).
Note that the
[Klipper Community Discourse server](https://community.klipper3d.org)
is also a useful resource for finding and sharing config files.
## Guidelines
1. Select the appropriate config filename prefix:
1. The `printer` prefix is used for stock printers sold by a
mainstream manufacturer.
2. The `generic` prefix is used for a 3d printer board that may be
used in many different types of printers.
3. The `kit` prefix is for 3d printers that are assembled according
to a widely used specification. These "kit" printers are
generally distinct from normal "printers" in that they are not
sold by a manufacturer.
4. The `sample` prefix is used for config "snippets" that one may
copy-and-paste into the main config file.
5. The `example` prefix is used to describe printer kinematics.
This type of config is typically only added along with code for
a new type of printer kinematics.
2. All configuration files must end in a `.cfg` suffix. The `printer`
config files must end in a year followed by `.cfg` (eg,
`-2019.cfg`). In this case, the year is an approximate year the
given printer was sold.
3. Do not use spaces or special characters in the config filename. The
filename should contain only characters `A-Z`, `a-z`, `0-9`, `-`,
and `.`.
4. Klipper must be able to start `printer`, `generic`, and `kit`
example config file without error. These config files should be
added to the
[test/klippy/printers.test](../test/klippy/printers.test)
regression test case. Add new config files to that test case in the
appropriate section and in alphabetical order within that section.
5. The example configuration should be for the "stock" configuration
of the printer. (There are too many "customized" configurations to
track in the main Klipper repository.) Similarly, we only add
example config files for printers, kits, and boards that have
mainstream popularity (eg, there should be at least a 100 of them
in active use). Consider using the
[Klipper Community Discourse server](https://community.klipper3d.org)
for other configs.
6. Only specify those devices present on the given printer or board.
Do not specify settings specific to your particular setup.
1. For `generic` config files, only those devices on the mainboard
should be described. For example, it would not make sense to add
a display config section to a "generic" config as there is no
way to know if the board will be attached to that type of
display. If the board has a specific hardware port to facilitate
an optional peripheral (eg, a bltouch port) then one can add a
"commented out" config section for the given device.
2. Do not specify `pressure_advance` in an example config, as that
value is specific to the filament, not the printer hardware.
Similarly, do not specify `max_extrude_only_velocity` nor
`max_extrude_only_accel` settings.
3. Do not specify a config section containing a host path or host
hardware. For example, do not specify `[virtual_sdcard]` nor
`[temperature_host]` config sections.
4. Only define macros that utilize functionality specific to the
given printer or to define g-codes that are commonly emitted by
slicers configured for the given printer.
7. Where possible, it is best to use the same wording, phrasing,
indentation, and section ordering as the existing config files.
1. The top of each config file should list the type of
micro-controller the user should select during "make
menuconfig". It should also have a reference to
"docs/Config_Reference.md".
2. Do not copy the field documentation into the example config
files. (Doing so creates a maintenance burden as an update to
the documentation would then require changing it in many
places.)
3. Example config files should not contain a "SAVE_CONFIG" section.
If necessary, copy the relevant fields from the SAVE_CONFIG
section to the appropriate section in the main config area.
4. Use `field: value` syntax instead of `field=value`.
5. When adding an extruder `rotation_distance` it is preferable to
specify a `gear_ratio` if the extruder has a gearing mechanism.
We expect the rotation_distance in the example configs to
correlate with the circumference of the hobbed gear in the
extruder - it is normally in the range of 20 to 35mm. When
specifying a `gear_ratio` it is preferable to specify the actual
gears on the mechanism (eg, prefer `gear_ratio: 80:20` over
`gear_ratio: 4:1`). See the
[rotation distance document](Rotation_Distance.md#using-a-gear_ratio)
for more information.
6. Avoid defining field values that are set to their default
value. For example, one should not specify `min_extrude_temp:
170` as that is already the default value.
7. Where possible, lines should not exceed 80 columns.
8. Avoid adding attribution or revision messages to the config
files. (For example, avoid adding lines like "this file was
created by ...".) Place attribution and change history in the
git commit message.
8. Do not use any deprecated features in the example config file.
9. Do not disable a default safety system in an example config file.
For example, a config should not specify a custom
`max_extrude_cross_section`. Do not enable debugging features. For
example there should not be a `force_move` config section.
10. All known boards that Klipper supports can use the default serial
baud rate of 250000. Do not recommend a different baud rate in an
example config file.
Example config files are submitted by creating a github "pull
request". Please also follow the directions in the
[contributing document](CONTRIBUTING.md).

99
docs/Exclude_Object.md Normal file
View File

@@ -0,0 +1,99 @@
# Exclude Objects
The `[exclude_object]` module allows Klipper to exclude objects while a print is
in progress. To enable this feature include an [exclude_object config
section](Config_Reference.md#exclude_object) (also see the [command
reference](G-Codes.md#exclude-object) and
[sample-macros.cfg](../config/sample-macros.cfg) file for a
Marlin/RepRapFirmware compatible M486 G-Code macro.)
Unlike other 3D printer firmware options, a printer running Klipper utilizes a
suite of components and users have many options to choose from. Therefore, in
order to provide a a consistent user experience, the `[exclude_object]` module
will establish a contract or API of sorts. The contract covers the contents of
the gcode file, how the internal state of the module is controlled, and how that
state is provided to clients.
## Workflow Overview
A typical workflow for printing a file might look like this:
1. Slicing is completed and the file is uploaded for printing. During the
upload, the file is processed and `[exclude_object]` markers are added to
the file. Alternately, slicers may be configured to prepare object exclusion
markers natively, or in it's own pre-processing step.
2. When printing starts, Klipper will reset the `[exclude_object]`
[status](Status_Reference.md#exclude_object).
3. When Klipper processes the `EXCLUDE_OBJECT_DEFINE` block, it will update the
status with the known objects and pass it on to clients.
4. The client may use that information to present a UI to the user so that
progress can be tracked. Klipper will update the status to include the
currently printing object which the client can use for display purposes.
5. If the user requests that an object be cancelled, the client will issue an
`EXCLUDE_OBJECT NAME=<name>` command to Klipper.
6. When Klipper process the command, it will add the object to the list of
excluded objects and update the status for the client.
7. The client will receive the updated status from Klipper and can use that
information to reflect the object's status in the UI.
8. When printing finishes, the `[exclude_object]` status will continue to be
available until another action resets it.
## The GCode File
The specialized gcode processing needed to support excluding objects does not
fit into Klipper's core design goals. Therefore, this module requires that the
file is processed before being sent to Klipper for printing. Using a
post-process script in the slicer or having middleware process the file on
upload are two possibilities for preparing the file for Klipper. A reference
post-processing script is available both as an executable and a python library,
see
[cancelobject-preprocessor](https://github.com/kageurufu/cancelobject-preprocessor).
### Object Definitions
The `EXCLUDE_OBJECT_DEFINE` command is used to provide a summary of each object
in the gcode file to be printed. Provides a summary of an object in the file.
Objects don't need to be defined in order to be referenced by other commands.
The primary purpose of this command is to provide information to the UI without
needing to parse the entire gcode file.
Object definitions are named, to allow users to easily select an object to be
excluded, and additional metadata may be provided to allow for graphical
cancellation displays. Currently defined metadata includes a `CENTER` X,Y
coordinate, and a `POLYGON` list of X,Y points representing a minimal outline of
the object. This could be a simple bounding box, or a complicated hull for
showing more detailed visualizations of the printed objects. Especially when
gcode files include multiple parts with overlapping bounding regions, center
points become hard to visually distinguish. `POLYGONS` must be a json-compatible
array of point `[X,Y]` tuples without whitespace. Additional parameters will be
saved as strings in the object definition and provided in status updates.
`EXCLUDE_OBJECT_DEFINE NAME=calibration_pyramid CENTER=50,50
POLYGON=[[40,40],[50,60],[60,40]]`
All available G-Code commands are documented in the [G-Code
Reference](./G-Codes.md#excludeobject)
## Status Information
The state of this module is provided to clients by the [exclude_object
status](Status_Reference.md#exclude_object).
The status is reset when:
- The Klipper firmware is restarted.
- There is a reset of the `[virtual_sdcard]`. Notably, this is reset by Klipper
at the start of a print.
- When an `EXCLUDE_OBJECT_DEFINE RESET=1` command is issued.
The list of defined objects is represented in the `exclude_object.objects`
status field. In a well defined gcode file, this will be done with
`EXCLUDE_OBJECT_DEFINE` commands at the beginning of the file. This will
provide clients with object names and coordinates so the UI can provide a
graphical representation of the objects if desired.
As the print progresses, the `exclude_object.current_object` status field will
be updated as Klipper processes `EXCLUDE_OBJECT_START` and `EXCLUDE_OBJECT_END`
commands. The `current_object` field will be set even if the object has been
excluded. Undefined objects marked with a `EXCLUDE_OBJECT_START` will be added
to the known objects to assist in UI hinting, without any additional metadata.
As `EXCLUDE_OBJECT` commands are issued, the list of excluded objects is
provided in the `exclude_object.excluded_objects` array. Since Klipper looks
ahead to process upcoming gcode, there may be a delay between when the command
is issued and when the status is updated.

492
docs/FAQ.md Normal file
View File

@@ -0,0 +1,492 @@
# Frequently Asked Questions
## How can I donate to the project?
Thank you for your support. See the [Sponsors page](Sponsors.md) for
information.
## How do I calculate the rotation_distance config parameter?
See the [rotation distance document](Rotation_Distance.md).
## Where's my serial port?
The general way to find a USB serial port is to run `ls
/dev/serial/by-id/*` from an ssh terminal on the host machine. It will
likely produce output similar to the following:
```
/dev/serial/by-id/usb-1a86_USB2.0-Serial-if00-port0
```
The name found in the above command is stable and it is possible to
use it in the config file and while flashing the micro-controller
code. For example, a flash command might look similar to:
```
sudo service klipper stop
make flash FLASH_DEVICE=/dev/serial/by-id/usb-1a86_USB2.0-Serial-if00-port0
sudo service klipper start
```
and the updated config might look like:
```
[mcu]
serial: /dev/serial/by-id/usb-1a86_USB2.0-Serial-if00-port0
```
Be sure to copy-and-paste the name from the "ls" command that you ran
above as the name will be different for each printer.
If you are using multiple micro-controllers and they do not have
unique ids (common on boards with a CH340 USB chip) then follow the
directions above using the command `ls /dev/serial/by-path/*` instead.
## When the micro-controller restarts the device changes to /dev/ttyUSB1
Follow the directions in the
"[Where's my serial port?](#wheres-my-serial-port)" section to prevent
this from occurring.
## The "make flash" command doesn't work
The code attempts to flash the device using the most common method for
each platform. Unfortunately, there is a lot of variance in flashing
methods, so the "make flash" command may not work on all boards.
If you're having an intermittent failure or you do have a standard
setup, then double check that Klipper isn't running when flashing
(sudo service klipper stop), make sure OctoPrint isn't trying to
connect directly to the device (open the Connection tab in the web
page and click Disconnect if the Serial Port is set to the device),
and make sure FLASH_DEVICE is set correctly for your board (see the
[question above](#wheres-my-serial-port)).
However, if "make flash" just doesn't work for your board, then you
will need to manually flash. See if there is a config file in the
[config directory](../config) with specific instructions for flashing
the device. Also, check the board manufacturer's documentation to see
if it describes how to flash the device. Finally, it may be possible
to manually flash the device using tools such as "avrdude" or
"bossac" - see the [bootloader document](Bootloaders.md) for
additional information.
## How do I change the serial baud rate?
The recommended baud rate for Klipper is 250000. This baud rate works
well on all micro-controller boards that Klipper supports. If you've
found an online guide recommending a different baud rate, then ignore
that part of the guide and continue with the default value of 250000.
If you want to change the baud rate anyway, then the new rate will
need to be configured in the micro-controller (during **make
menuconfig**) and that updated code will need to be compiled and
flashed to the micro-controller. The Klipper printer.cfg file will
also need to be updated to match that baud rate (see the
[config reference](Config_Reference.md#mcu) for details). For
example:
```
[mcu]
baud: 250000
```
The baud rate shown on the OctoPrint web page has no impact on the
internal Klipper micro-controller baud rate. Always set the OctoPrint
baud rate to 250000 when using Klipper.
The Klipper micro-controller baud rate is not related to the baud rate
of the micro-controller's bootloader. See the
[bootloader document](Bootloaders.md) for additional information on
bootloaders.
## Can I run Klipper on something other than a Raspberry Pi 3?
The recommended hardware is a Raspberry Pi 2, Raspberry Pi 3, or
Raspberry Pi 4.
Klipper will run on a Raspberry Pi 1 and on the Raspberry Pi Zero, but
these boards don't have enough processing power to run OctoPrint
well. It is common for print stalls to occur on these slower machines
when printing directly from OctoPrint. (The printer may move faster
than OctoPrint can send movement commands.) If you wish to run on one
one of these slower boards anyway, consider using the "virtual_sdcard"
feature when printing (see
[config reference](Config_Reference.md#virtual_sdcard) for details).
For running on the Beaglebone, see the
[Beaglebone specific installation instructions](Beaglebone.md).
Klipper has been run on other machines. The Klipper host software only
requires Python running on a Linux (or similar) computer. However, if
you wish to run it on a different machine you will need Linux admin
knowledge to install the system prerequisites for that particular
machine. See the [install-octopi.sh](../scripts/install-octopi.sh)
script for further information on the necessary Linux admin steps.
If you are looking to run the Klipper host software on a low-end chip,
then be aware that, at a minimum, a machine with "double precision
floating point" hardware is required.
If you are looking to run the Klipper host software on a shared
general-purpose desktop or server class machine, then note that
Klipper has some real-time scheduling requirements. If, during a
print, the host computer also performs an intensive general-purpose
computing task (such as defragmenting a hard drive, 3d rendering,
heavy swapping, etc.), then it may cause Klipper to report print
errors.
Note: If you are not using an OctoPi image, be aware that several
Linux distributions enable a "ModemManager" (or similar) package that
can disrupt serial communication. (Which can cause Klipper to report
seemingly random "Lost communication with MCU" errors.) If you install
Klipper on one of these distributions you may need to disable that
package.
## Can I run multiple instances of Klipper on the same host machine?
It is possible to run multiple instances of the Klipper host software,
but doing so requires Linux admin knowledge. The Klipper installation
scripts ultimately cause the following Unix command to be run:
```
~/klippy-env/bin/python ~/klipper/klippy/klippy.py ~/printer.cfg -l /tmp/klippy.log
```
One can run multiple instances of the above command as long as each
instance has its own printer config file, its own log file, and its
own pseudo-tty. For example:
```
~/klippy-env/bin/python ~/klipper/klippy/klippy.py ~/printer2.cfg -l /tmp/klippy2.log -I /tmp/printer2
```
If you choose to do this, you will need to implement the necessary
start, stop, and installation scripts (if any). The
[install-octopi.sh](../scripts/install-octopi.sh) script and the
[klipper-start.sh](../scripts/klipper-start.sh) script may be useful
as examples.
## Do I have to use OctoPrint?
The Klipper software is not dependent on OctoPrint. It is possible to
use alternative software to send commands to Klipper, but doing so
requires Linux admin knowledge.
Klipper creates a "virtual serial port" via the "/tmp/printer" file,
and it emulates a classic 3d-printer serial interface via that file.
In general, alternative software may work with Klipper as long as it
can be configured to use "/tmp/printer" for the printer serial port.
## Why can't I move the stepper before homing the printer?
The code does this to reduce the chance of accidentally commanding the
head into the bed or a wall. Once the printer is homed the software
attempts to verify each move is within the position_min/max defined in
the config file. If the motors are disabled (via an M84 or M18
command) then the motors will need to be homed again prior to
movement.
If you want to move the head after canceling a print via OctoPrint,
consider changing the OctoPrint cancel sequence to do that for
you. It's configured in OctoPrint via a web browser under:
Settings->GCODE Scripts
If you want to move the head after a print finishes, consider adding
the desired movement to the "custom g-code" section of your slicer.
If the printer requires some additional movement as part of the homing
process itself (or fundamentally does not have a homing process) then
consider using a safe_z_home or homing_override section in the config
file. If you need to move a stepper for diagnostic or debugging
purposes then consider adding a force_move section to the config
file. See [config reference](Config_Reference.md#customized_homing)
for further details on these options.
## Why is the Z position_endstop set to 0.5 in the default configs?
For cartesian style printers the Z position_endstop specifies how far
the nozzle is from the bed when the endstop triggers. If possible, it
is recommended to use a Z-max endstop and home away from the bed (as
this reduces the potential for bed collisions). However, if one must
home towards the bed then it is recommended to position the endstop so
it triggers when the nozzle is still a small distance away from the
bed. This way, when homing the axis, it will stop before the nozzle
touches the bed. See the [bed level document](Bed_Level.md) for more
information.
## I converted my config from Marlin and the X/Y axes work fine, but I just get a screeching noise when homing the Z axis
Short answer: First, make sure you have verified the stepper
configuration as described in the
[config check document](Config_checks.md). If the problem persists,
try reducing the max_z_velocity setting in the printer config.
Long answer: In practice Marlin can typically only step at a rate of
around 10000 steps per second. If it is requested to move at a speed
that would require a higher step rate then Marlin will generally just
step as fast as it can. Klipper is able to achieve much higher step
rates, but the stepper motor may not have sufficient torque to move at
a higher speed. So, for a Z axis with a high gearing ratio or high
microsteps setting the actual obtainable max_z_velocity may be smaller
than what is configured in Marlin.
## My TMC motor driver turns off in the middle of a print
If using the TMC2208 (or TMC2224) driver in "standalone mode" then
make sure to use the
[latest version of Klipper](#how-do-i-upgrade-to-the-latest-software). A
workaround for a TMC2208 "stealthchop" driver problem was added to
Klipper in mid-March of 2020.
## I keep getting random "Lost communication with MCU" errors
This is commonly caused by hardware errors on the USB connection
between the host machine and the micro-controller. Things to look for:
- Use a good quality USB cable between the host machine and
micro-controller. Make sure the plugs are secure.
- If using a Raspberry Pi, use a
[good quality power supply](https://www.raspberrypi.com/documentation/computers/raspberry-pi.html#power-supply)
for the Raspberry Pi and use a
[good quality USB cable](https://forums.raspberrypi.com/viewtopic.php?p=589877#p589877)
to connect that power supply to the Pi. If you get "under voltage"
warnings from OctoPrint, this is related to the power supply and it
must be fixed.
- Make sure the printer's power supply is not being overloaded. (Power
fluctuations to the micro-controller's USB chip may result in resets
of that chip.)
- Verify stepper, heater, and other printer wires are not crimped or
frayed. (Printer movement may place stress on a faulty wire causing
it to lose contact, briefly short, or generate excessive noise.)
- There have been reports of high USB noise when both the printer's
power supply and the host's 5V power supply are mixed. (If you find
that the micro-controller powers on when either the printer's power
supply is on or the USB cable is plugged in, then it indicates the
5V power supplies are being mixed.) It may help to configure the
micro-controller to use power from only one source. (Alternatively,
if the micro-controller board can not configure its power source,
one may modify a USB cable so that it does not carry 5V power
between the host and micro-controller.)
## My Raspberry Pi keeps rebooting during prints
This is most likely do to voltage fluctuations. Follow the same
troubleshooting steps for a
["Lost communication with MCU"](#i-keep-getting-random-lost-communication-with-mcu-errors)
error.
## When I set `restart_method=command` my AVR device just hangs on a restart
Some old versions of the AVR bootloader have a known bug in watchdog
event handling. This typically manifests when the printer.cfg file has
restart_method set to "command". When the bug occurs, the AVR device
will be unresponsive until power is removed and reapplied to the
device (the power or status LEDs may also blink repeatedly until the
power is removed).
The workaround is to use a restart_method other than "command" or to
flash an updated bootloader to the AVR device. Flashing a new
bootloader is a one time step that typically requires an external
programmer - see [Bootloaders](Bootloaders.md) for further details.
## Will the heaters be left on if the Raspberry Pi crashes?
The software has been designed to prevent that. Once the host enables
a heater, the host software needs to confirm that enablement every 5
seconds. If the micro-controller does not receive a confirmation every
5 seconds it goes into a "shutdown" state which is designed to turn
off all heaters and stepper motors.
See the "config_digital_out" command in the
[MCU commands](MCU_Commands.md) document for further details.
In addition, the micro-controller software is configured with a
minimum and maximum temperature range for each heater at startup (see
the min_temp and max_temp parameters in the
[config reference](Config_Reference.md#extruder) for details). If the
micro-controller detects that the temperature is outside of that range
then it will also enter a "shutdown" state.
Separately, the host software also implements code to check that
heaters and temperature sensors are functioning correctly. See the
[config reference](Config_Reference.md#verify_heater) for further
details.
## How do I convert a Marlin pin number to a Klipper pin name?
Short answer: A mapping is available in the
[sample-aliases.cfg](../config/sample-aliases.cfg) file. Use that file
as a guide to finding the actual micro-controller pin names. (It is
also possible to copy the relevant
[board_pins](Config_Reference.md#board_pins) config section into your
config file and use the aliases in your config, but it is preferable
to translate and use the actual micro-controller pin names.) Note that
the sample-aliases.cfg file uses pin names that start with the prefix
"ar" instead of "D" (eg, Arduino pin `D23` is Klipper alias `ar23`)
and the prefix "analog" instead of "A" (eg, Arduino pin `A14` is
Klipper alias `analog14`).
Long answer: Klipper uses the standard pin names defined by the
micro-controller. On the Atmega chips these hardware pins have names
like `PA4`, `PC7`, or `PD2`.
Long ago, the Arduino project decided to avoid using the standard
hardware names in favor of their own pin names based on incrementing
numbers - these Arduino names generally look like `D23` or `A14`. This
was an unfortunate choice that has lead to a great deal of confusion.
In particular the Arduino pin numbers frequently don't translate to
the same hardware names. For example, `D21` is `PD0` on one common
Arduino board, but is `PC7` on another common Arduino board.
To avoid this confusion, the core Klipper code uses the standard pin
names defined by the micro-controller.
## Do I have to wire my device to a specific type of micro-controller pin?
It depends on the type of device and type of pin:
ADC pins (or Analog pins): For thermistors and similar "analog"
sensors, the device must be wired to an "analog" or "ADC" capable pin
on the micro-controller. If you configure Klipper to use a pin that is
not analog capable, Klipper will report a "Not a valid ADC pin" error.
PWM pins (or Timer pins): Klipper does not use hardware PWM by default
for any device. So, in general, one may wire heaters, fans, and
similar devices to any general purpose IO pin. However, fans and
output_pin devices may be optionally configured to use `hardware_pwm:
True`, in which case the micro-controller must support hardware PWM on
the pin (otherwise, Klipper will report a "Not a valid PWM pin"
error).
IRQ pins (or Interrupt pins): Klipper does not use hardware interrupts
on IO pins, so it is never necessary to wire a device to one of these
micro-controller pins.
SPI pins: When using hardware SPI it is necessary to wire the pins to
the micro-controller's SPI capable pins. However, most devices can be
configured to use "software SPI", in which case any general purpose IO
pins may be used.
I2C pins: When using I2C it is necessary to wire the pins to the
micro-controller's I2C capable pins.
Other devices may be wired to any general purpose IO pin. For example,
steppers, heaters, fans, Z probes, servos, LEDs, common hd44780/st7920
LCD displays, the Trinamic UART control line may be wired to any
general purpose IO pin.
## How do I cancel an M109/M190 "wait for temperature" request?
Navigate to the OctoPrint terminal tab and issue an M112 command in
the terminal box. The M112 command will cause Klipper to enter into a
"shutdown" state, and it will cause OctoPrint to disconnect from
Klipper. Navigate to the OctoPrint connection area and click on
"Connect" to cause OctoPrint to reconnect. Navigate back to the
terminal tab and issue a FIRMWARE_RESTART command to clear the Klipper
error state. After completing this sequence, the previous heating
request will be canceled and a new print may be started.
## Can I find out whether the printer has lost steps?
In a way, yes. Home the printer, issue a `GET_POSITION` command, run
your print, home again and issue another `GET_POSITION`. Then compare
the values in the `mcu:` line.
This might be helpful to tune settings like stepper motor currents,
accelerations and speeds without needing to actually print something
and waste filament: just run some high-speed moves in between the
`GET_POSITION` commands.
Note that endstop switches themselves tend to trigger at slightly
different positions, so a difference of a couple of microsteps is
likely the result of endstop inaccuracies. A stepper motor itself can
only lose steps in increments of 4 full steps. (So, if one is using 16
microsteps, then a lost step on the stepper would result in the "mcu:"
step counter being off by a multiple of 64 microsteps.)
## Why does Klipper report errors? I lost my print!
Short answer: We want to know if our printers detect a problem so that
the underlying issue can be fixed and we can obtain great quality
prints. We definitely do not want our printers to silently produce low
quality prints.
Long answer: Klipper has been engineered to automatically workaround
many transient problems. For example, it automatically detects
communication errors and will retransmit; it schedules actions in
advance and buffers commands at multiple layers to enable precise
timing even with intermittent interference. However, should the
software detect an error that it can not recover from, if it is
commanded to take an invalid action, or if it detects it is hopelessly
unable to perform its commanded task, then Klipper will report an
error. In these situations there is a high risk of producing a
low-quality print (or worse). It is hoped that alerting the user will
empower them to fix the underlying issue and improve the overall
quality of their prints.
There are some related questions: Why doesn't Klipper pause the print
instead? Report a warning instead? Check for errors before the print?
Ignore errors in user typed commands? etc? Currently Klipper reads
commands using the G-Code protocol, and unfortunately the G-Code
command protocol is not flexible enough to make these alternatives
practical today. There is developer interest in improving the user
experience during abnormal events, but it is expected that will
require notable infrastructure work (including a shift away from
G-Code).
## How do I upgrade to the latest software?
The first step to upgrading the software is to review the latest
[config changes](Config_Changes.md) document. On occasion, changes are
made to the software that require users to update their settings as
part of a software upgrade. It is a good idea to review this document
prior to upgrading.
When ready to upgrade, the general method is to ssh into the Raspberry
Pi and run:
```
cd ~/klipper
git pull
~/klipper/scripts/install-octopi.sh
```
Then one can recompile and flash the micro-controller code. For
example:
```
make menuconfig
make clean
make
sudo service klipper stop
make flash FLASH_DEVICE=/dev/ttyACM0
sudo service klipper start
```
However, it's often the case that only the host software changes. In
this case, one can update and restart just the host software with:
```
cd ~/klipper
git pull
sudo service klipper restart
```
If after using this shortcut the software warns about needing to
reflash the micro-controller or some other unusual error occurs, then
follow the full upgrade steps outlined above.
If any errors persist then double check the
[config changes](Config_Changes.md) document, as you may need to
modify the printer configuration.
Note that the RESTART and FIRMWARE_RESTART g-code commands do not load
new software - the above "sudo service klipper restart" and "make
flash" commands are needed for a software change to take effect.
## How do I uninstall Klipper?
On the firmware end, nothing special needs to happen. Just follow the
flashing directions for the new firmware.
On the raspberry pi end, an uninstall script is available in
[scripts/klipper-uninstall.sh](../scripts/klipper-uninstall.sh). For
example:
```
sudo ~/klipper/scripts/klipper-uninstall.sh
rm -rf ~/klippy-env ~/klipper
```

184
docs/Features.md Normal file
View File

@@ -0,0 +1,184 @@
# Features
Klipper has several compelling features:
* High precision stepper movement. Klipper utilizes an application
processor (such as a low-cost Raspberry Pi) when calculating printer
movements. The application processor determines when to step each
stepper motor, it compresses those events, transmits them to the
micro-controller, and then the micro-controller executes each event
at the requested time. Each stepper event is scheduled with a
precision of 25 micro-seconds or better. The software does not use
kinematic estimations (such as the Bresenham algorithm) - instead it
calculates precise step times based on the physics of acceleration
and the physics of the machine kinematics. More precise stepper
movement translates to quieter and more stable printer operation.
* Best in class performance. Klipper is able to achieve high stepping
rates on both new and old micro-controllers. Even old 8bit
micro-controllers can obtain rates over 175K steps per second. On
more recent micro-controllers, several million steps per second are
possible. Higher stepper rates enable higher print velocities. The
stepper event timing remains precise even at high speeds which
improves overall stability.
* Klipper supports printers with multiple micro-controllers. For
example, one micro-controller could be used to control an extruder,
while another controls the printer's heaters, while a third controls
the rest of the printer. The Klipper host software implements clock
synchronization to account for clock drift between
micro-controllers. No special code is needed to enable multiple
micro-controllers - it just requires a few extra lines in the config
file.
* Configuration via simple config file. There's no need to reflash the
micro-controller to change a setting. All of Klipper's configuration
is stored in a standard config file which can be easily edited. This
makes it easier to setup and maintain the hardware.
* Klipper supports "Smooth Pressure Advance" - a mechanism to account
for the effects of pressure within an extruder. This reduces
extruder "ooze" and improves the quality of print corners. Klipper's
implementation does not introduce instantaneous extruder speed
changes, which improves overall stability and robustness.
* Klipper supports "Input Shaping" to reduce the impact of vibrations
on print quality. This can reduce or eliminate "ringing" (also known
as "ghosting", "echoing", or "rippling") in prints. It may also
allow one to obtain faster printing speeds while still maintaining
high print quality.
* Klipper uses an "iterative solver" to calculate precise step times
from simple kinematic equations. This makes porting Klipper to new
types of robots easier and it keeps timing precise even with complex
kinematics (no "line segmentation" is needed).
* Portable code. Klipper works on ARM, AVR, and PRU based
micro-controllers. Existing "reprap" style printers can run Klipper
without hardware modification - just add a Raspberry Pi. Klipper's
internal code layout makes it easier to support other
micro-controller architectures as well.
* Simpler code. Klipper uses a very high level language (Python) for
most code. The kinematics algorithms, the G-code parsing, the
heating and thermistor algorithms, etc. are all written in Python.
This makes it easier to develop new functionality.
* Custom programmable macros. New G-Code commands can be defined in
the printer config file (no code changes are necessary). Those
commands are programmable - allowing them to produce different
actions depending on the state of the printer.
* Builtin API server. In addition to the standard G-Code interface,
Klipper supports a rich JSON based application interface. This
enables programmers to build external applications with detailed
control of the printer.
## Additional features
Klipper supports many standard 3d printer features:
* Works with Octoprint. This allows the printer to be controlled using
a regular web-browser. The same Raspberry Pi that runs Klipper can
also run Octoprint.
* Standard G-Code support. Common g-code commands that are produced by
typical "slicers" (SuperSlicer, Cura, PrusaSlicer, etc.) are
supported.
* Support for multiple extruders. Extruders with shared heaters and
extruders on independent carriages (IDEX) are also supported.
* Support for cartesian, delta, corexy, corexz, hybrid-corexy,
hybrid-corexz, rotary delta, polar, and cable winch style printers.
* Automatic bed leveling support. Klipper can be configured for basic
bed tilt detection or full mesh bed leveling. If the bed uses
multiple Z steppers then Klipper can also level by independently
manipulating the Z steppers. Most Z height probes are supported,
including BL-Touch probes and servo activated probes.
* Automatic delta calibration support. The calibration tool can
perform basic height calibration as well as an enhanced X and Y
dimension calibration. The calibration can be done with a Z height
probe or via manual probing.
* Support for common temperature sensors (eg, common thermistors,
AD595, AD597, AD849x, PT100, PT1000, MAX6675, MAX31855, MAX31856,
MAX31865, BME280, HTU21D, DS18B20, and LM75). Custom thermistors and
custom analog temperature sensors can also be configured. One can
monitor the internal micro-controller temperature sensor and the
internal temperature sensor of a Raspberry Pi.
* Basic thermal heater protection enabled by default.
* Support for standard fans, nozzle fans, and temperature controlled
fans. No need to keep fans running when the printer is idle. Fan
speed can be monitored on fans that have a tachometer.
* Support for run-time configuration of TMC2130, TMC2208/TMC2224,
TMC2209, TMC2660, and TMC5160 stepper motor drivers. There is also
support for current control of traditional stepper drivers via
AD5206, MCP4451, MCP4728, MCP4018, and PWM pins.
* Support for common LCD displays attached directly to the printer. A
default menu is also available. The contents of the display and menu
can be fully customized via the config file.
* Constant acceleration and "look-ahead" support. All printer moves
will gradually accelerate from standstill to cruising speed and then
decelerate back to a standstill. The incoming stream of G-Code
movement commands are queued and analyzed - the acceleration between
movements in a similar direction will be optimized to reduce print
stalls and improve overall print time.
* Klipper implements a "stepper phase endstop" algorithm that can
improve the accuracy of typical endstop switches. When properly
tuned it can improve a print's first layer bed adhesion.
* Support for filament presence sensors, filament motion sensors, and
filament width sensors.
* Support for measuring and recording acceleration using an adxl345
accelerometer.
* Support for limiting the top speed of short "zigzag" moves to reduce
printer vibration and noise. See the [kinematics](Kinematics.md)
document for more information.
* Sample configuration files are available for many common printers.
Check the [config directory](../config/) for a list.
To get started with Klipper, read the [installation](Installation.md)
guide.
## Step Benchmarks
Below are the results of stepper performance tests. The numbers shown
represent total number of steps per second on the micro-controller.
| Micro-controller | 1 stepper active | 3 steppers active |
| ------------------------------- | ----------------- | ----------------- |
| 16Mhz AVR | 157K | 99K |
| 20Mhz AVR | 196K | 123K |
| SAMD21 | 686K | 471K |
| STM32F042 | 814K | 578K |
| Beaglebone PRU | 866K | 708K |
| STM32G0B1 | 1103K | 790K |
| STM32F103 | 1180K | 818K |
| SAM3X8E | 1273K | 981K |
| SAM4S8C | 1690K | 1385K |
| LPC1768 | 1923K | 1351K |
| LPC1769 | 2353K | 1622K |
| RP2040 | 2400K | 1636K |
| SAM4E8E | 2500K | 1674K |
| SAMD51 | 3077K | 1885K |
| STM32F407 | 3652K | 2459K |
| STM32F446 | 3913K | 2634K |
If unsure of the micro-controller on a particular board, find the
appropriate [config file](../config/), and look for the
micro-controller name in the comments at the top of that file.
Further details on the benchmarks are available in the
[Benchmarks document](Benchmarks.md).

1279
docs/G-Codes.md Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,67 @@
# Hall filament width sensor
This document describes Filament Width Sensor host module. Hardware used for
developing this host module is based on two Hall linear sensors (ss49e for
example). Sensors in the body are located opposite sides. Principle of operation:
two hall sensors work in differential mode, temperature drift same for sensor.
Special temperature compensation not needed.
You can find designs at [Thingiverse](https://www.thingiverse.com/thing:4138933),
an assembly video is also available on [Youtube](https://www.youtube.com/watch?v=TDO9tME8vp4)
To use Hall filament width sensor, read
[Config Reference](Config_Reference.md#hall_filament_width_sensor) and
[G-Code documentation](G-Codes.md#hall_filament_width_sensor).
## How does it work?
Sensor generates two analog output based on calculated filament width. Sum of
output voltage always equals to detected filament width. Host module monitors
voltage changes and adjusts extrusion multiplier. I use aux2 connector on
ramps-like board analog11 and analog12 pins. You can use different pins and
differenr boards.
## Template for menu variables
```
[menu __main __filament __width_current]
type: command
enable: {'hall_filament_width_sensor' in printer}
name: Dia: {'%.2F' % printer.hall_filament_width_sensor.Diameter}
index: 0
[menu __main __filament __raw_width_current]
type: command
enable: {'hall_filament_width_sensor' in printer}
name: Raw: {'%4.0F' % printer.hall_filament_width_sensor.Raw}
index: 1
```
## Calibration procedure
To get raw sensor value you can use menu item or **QUERY_RAW_FILAMENT_WIDTH**
command in terminal.
1. Insert first calibration rod (1.5 mm size) get first raw sensor value
2. Insert second calibration rod (2.0 mm size) get second raw sensor value
3. Save raw sensor values in config parameter `Raw_dia1` and `Raw_dia2`
## How to enable sensor
By default, the sensor is disabled at power-on.
To enable the sensor, issue **ENABLE_FILAMENT_WIDTH_SENSOR** command or
set the `enable` parameter to `true`.
## Logging
By default, diameter logging is disabled at power-on.
Issue **ENABLE_FILAMENT_WIDTH_LOG** command to start logging and issue
**DISABLE_FILAMENT_WIDTH_LOG** command to stop logging. To enable logging
at power-on, set the `logging` parameter to `true`.
Filament diameter is logged on every measurement interval (10 mm by default).

222
docs/Installation.md Normal file
View File

@@ -0,0 +1,222 @@
# Installation
These instructions assume the software will run on a Raspberry Pi
computer in conjunction with OctoPrint. It is recommended that a
Raspberry Pi 2, 3, or 4 computer be used as the host machine (see the
[FAQ](FAQ.md#can-i-run-klipper-on-something-other-than-a-raspberry-pi-3)
for other machines).
## Obtain a Klipper Configuration File
Most Klipper settings are determined by a "printer configuration file"
that will be stored on the Raspberry Pi. An appropriate configuration
file can often be found by looking in the Klipper
[config directory](../config/) for a file starting with a "printer-"
prefix that corresponds to the target printer. The Klipper
configuration file contains technical information about the printer
that will be needed during the installation.
If there isn't an appropriate printer configuration file in the
Klipper config directory then try searching the printer manufacturer's
website to see if they have an appropriate Klipper configuration file.
If no configuration file for the printer can be found, but the type of
printer control board is known, then look for an appropriate
[config file](../config/) starting with a "generic-" prefix. These
example printer board files should allow one to successfully complete
the initial installation, but will require some customization to
obtain full printer functionality.
It is also possible to define a new printer configuration from
scratch. However, this requires significant technical knowledge about
the printer and its electronics. It is recommended that most users
start with an appropriate configuration file. If creating a new custom
printer configuration file, then start with the closest example
[config file](../config/) and use the Klipper
[config reference](Config_Reference.md) for further information.
## Prepping an OS image
Start by installing [OctoPi](https://github.com/guysoft/OctoPi) on the
Raspberry Pi computer. Use OctoPi v0.17.0 or later - see the
[OctoPi releases](https://github.com/guysoft/OctoPi/releases) for
release information. One should verify that OctoPi boots and that the
OctoPrint web server works. After connecting to the OctoPrint web
page, follow the prompt to upgrade OctoPrint to v1.4.2 or later.
After installing OctoPi and upgrading OctoPrint, it will be necessary
to ssh into the target machine to run a handful of system commands. If
using a Linux or MacOS desktop, then the "ssh" software should already
be installed on the desktop. There are free ssh clients available for
other desktops (eg,
[PuTTY](https://www.chiark.greenend.org.uk/~sgtatham/putty/)). Use the
ssh utility to connect to the Raspberry Pi (ssh pi@octopi -- password
is "raspberry") and run the following commands:
```
git clone https://github.com/Klipper3d/klipper
./klipper/scripts/install-octopi.sh
```
The above will download Klipper, install some system dependencies,
setup Klipper to run at system startup, and start the Klipper host
software. It will require an internet connection and it may take a few
minutes to complete.
## Building and flashing the micro-controller
To compile the micro-controller code, start by running these commands
on the Raspberry Pi:
```
cd ~/klipper/
make menuconfig
```
The comments at the top of the
[printer configuration file](#obtain-a-klipper-configuration-file)
should describe the settings that need to be set during "make
menuconfig". Open the file in a web browser or text editor and look
for these instructions near the top of the file. Once the appropriate
"menuconfig" settings have been configured, press "Q" to exit, and
then "Y" to save. Then run:
```
make
```
If the comments at the top of the
[printer configuration file](#obtain-a-klipper-configuration-file)
describe custom steps for "flashing" the final image to the printer
control board then follow those steps and then proceed to
[configuring OctoPrint](#configuring-octoprint-to-use-klipper).
Otherwise, the following steps are often used to "flash" the printer
control board. First, it is necessary to determine the serial port
connected to the micro-controller. Run the following:
```
ls /dev/serial/by-id/*
```
It should report something similar to the following:
```
/dev/serial/by-id/usb-1a86_USB2.0-Serial-if00-port0
```
It's common for each printer to have its own unique serial port name.
This unique name will be used when flashing the micro-controller. It's
possible there may be multiple lines in the above output - if so,
choose the line corresponding to the micro-controller (see the
[FAQ](FAQ.md#wheres-my-serial-port) for more information).
For common micro-controllers, the code can be flashed with something
similar to:
```
sudo service klipper stop
make flash FLASH_DEVICE=/dev/serial/by-id/usb-1a86_USB2.0-Serial-if00-port0
sudo service klipper start
```
Be sure to update the FLASH_DEVICE with the printer's unique serial
port name.
When flashing for the first time, make sure that OctoPrint is not
connected directly to the printer (from the OctoPrint web page, under
the "Connection" section, click "Disconnect").
## Configuring OctoPrint to use Klipper
The OctoPrint web server needs to be configured to communicate with
the Klipper host software. Using a web browser, login to the OctoPrint
web page and then configure the following items:
Navigate to the Settings tab (the wrench icon at the top of the
page). Under "Serial Connection" in "Additional serial ports" add
"/tmp/printer". Then click "Save".
Enter the Settings tab again and under "Serial Connection" change the
"Serial Port" setting to "/tmp/printer".
In the Settings tab, navigate to the "Behavior" sub-tab and select the
"Cancel any ongoing prints but stay connected to the printer"
option. Click "Save".
From the main page, under the "Connection" section (at the top left of
the page) make sure the "Serial Port" is set to "/tmp/printer" and
click "Connect". (If "/tmp/printer" is not an available selection then
try reloading the page.)
Once connected, navigate to the "Terminal" tab and type "status"
(without the quotes) into the command entry box and click "Send". The
terminal window will likely report there is an error opening the
config file - that means OctoPrint is successfully communicating with
Klipper. Proceed to the next section.
## Configuring Klipper
The next step is to copy the
[printer configuration file](#obtain-a-klipper-configuration-file) to
the Raspberry Pi.
Arguably the easiest way to set the Klipper configuration file is to
use a desktop editor that supports editing files over the "scp" and/or
"sftp" protocols. There are freely available tools that support this
(eg, Notepad++, WinSCP, and Cyberduck). Load the printer config file
in the editor and then save it as a file named "printer.cfg" in the
home directory of the pi user (ie, /home/pi/printer.cfg).
Alternatively, one can also copy and edit the file directly on the
Raspberry Pi via ssh. That may look something like the following (be
sure to update the command to use the appropriate printer config
filename):
```
cp ~/klipper/config/example-cartesian.cfg ~/printer.cfg
nano ~/printer.cfg
```
It's common for each printer to have its own unique name for the
micro-controller. The name may change after flashing Klipper, so rerun
these steps again even if they were already done when flashing. Run:
```
ls /dev/serial/by-id/*
```
It should report something similar to the following:
```
/dev/serial/by-id/usb-1a86_USB2.0-Serial-if00-port0
```
Then update the config file with the unique name. For example, update
the `[mcu]` section to look something similar to:
```
[mcu]
serial: /dev/serial/by-id/usb-1a86_USB2.0-Serial-if00-port0
```
After creating and editing the file it will be necessary to issue a
"restart" command in the OctoPrint web terminal to load the config. A
"status" command will report the printer is ready if the Klipper
config file is successfully read and the micro-controller is
successfully found and configured.
When customizing the printer config file, it is not uncommon for
Klipper to report a configuration error. If an error occurs, make any
necessary corrections to the printer config file and issue "restart"
until "status" reports the printer is ready.
Klipper reports error messages via the OctoPrint terminal tab. The
"status" command can be used to re-report error messages. The default
Klipper startup script also places a log in **/tmp/klippy.log** which
provides more detailed information.
After Klipper reports that the printer is ready, proceed to the
[config check document](Config_checks.md) to perform some basic checks
on the definitions in the config file. See the main
[documentation reference](Overview.md) for other information.

293
docs/Kinematics.md Normal file
View File

@@ -0,0 +1,293 @@
# Kinematics
This document provides an overview of how Klipper implements robot
motion (its [kinematics](https://en.wikipedia.org/wiki/Kinematics)).
The contents may be of interest to both developers interested in
working on the Klipper software as well as users interested in better
understanding the mechanics of their machines.
## Acceleration
Klipper implements a constant acceleration scheme whenever the print
head changes velocity - the velocity is gradually changed to the new
speed instead of suddenly jerking to it. Klipper always enforces
acceleration between the tool head and the print. The filament leaving
the extruder can be quite fragile - rapid jerks and/or extruder flow
changes lead to poor quality and poor bed adhesion. Even when not
extruding, if the print head is at the same level as the print then
rapid jerking of the head can cause disruption of recently deposited
filament. Limiting speed changes of the print head (relative to the
print) reduces risks of disrupting the print.
It is also important to limit acceleration so that the stepper motors
do not skip or put excessive stress on the machine. Klipper limits the
torque on each stepper by virtue of limiting the acceleration of the
print head. Enforcing acceleration at the print head naturally also
limits the torque of the steppers that move the print head (the
inverse is not always true).
Klipper implements constant acceleration. The key formula for constant
acceleration is:
```
velocity(time) = start_velocity + accel*time
```
## Trapezoid generator
Klipper uses a traditional "trapezoid generator" to model the motion
of each move - each move has a start speed, it accelerates to a
cruising speed at constant acceleration, it cruises at a constant
speed, and then decelerates to the end speed using constant
acceleration.
![trapezoid](img/trapezoid.svg.png)
It's called a "trapezoid generator" because a velocity diagram of the
move looks like a trapezoid.
The cruising speed is always greater than or equal to both the start
speed and the end speed. The acceleration phase may be of zero
duration (if the start speed is equal to the cruising speed), the
cruising phase may be of zero duration (if the move immediately starts
decelerating after acceleration), and/or the deceleration phase may be
of zero duration (if the end speed is equal to the cruising speed).
![trapezoids](img/trapezoids.svg.png)
## Look-ahead
The "look-ahead" system is used to determine cornering speeds between
moves.
Consider the following two moves contained on an XY plane:
![corner](img/corner.svg.png)
In the above situation it is possible to fully decelerate after the
first move and then fully accelerate at the start of the next move,
but that is not ideal as all that acceleration and deceleration would
greatly increase the print time and the frequent changes in extruder
flow would result in poor print quality.
To solve this, the "look-ahead" mechanism queues multiple incoming
moves and analyzes the angles between moves to determine a reasonable
speed that can be obtained during the "junction" between two moves. If
the next move is nearly in the same direction then the head need only
slow down a little (if at all).
![lookahead](img/lookahead.svg.png)
However, if the next move forms an acute angle (the head is going to
travel in nearly a reverse direction on the next move) then only a
small junction speed is permitted.
![lookahead](img/lookahead-slow.svg.png)
The junction speeds are determined using "approximated centripetal
acceleration". Best
[described by the author](https://onehossshay.wordpress.com/2011/09/24/improving_grbl_cornering_algorithm/).
However, in Klipper, junction speeds are configured by specifying the
desired speed that a 90° corner should have (the "square corner
velocity"), and the junction speeds for other angles are derived from
that.
Key formula for look-ahead:
```
end_velocity^2 = start_velocity^2 + 2*accel*move_distance
```
### Smoothed look-ahead
Klipper also implements a mechanism for smoothing out the motions of
short "zigzag" moves. Consider the following moves:
![zigzag](img/zigzag.svg.png)
In the above, the frequent changes from acceleration to deceleration
can cause the machine to vibrate which causes stress on the machine
and increases the noise. To reduce this, Klipper tracks both regular
move acceleration as well as a virtual "acceleration to deceleration"
rate. Using this system, the top speed of these short "zigzag" moves
are limited to smooth out the printer motion:
![smoothed](img/smoothed.svg.png)
Specifically, the code calculates what the velocity of each move would
be if it were limited to this virtual "acceleration to deceleration"
rate (half the normal acceleration rate by default). In the above
picture the dashed gray lines represent this virtual acceleration rate
for the first move. If a move can not reach its full cruising speed
using this virtual acceleration rate then its top speed is reduced to
the maximum speed it could obtain at this virtual acceleration
rate. For most moves the limit will be at or above the move's existing
limits and no change in behavior is induced. For short zigzag moves,
however, this limit reduces the top speed. Note that it does not
change the actual acceleration within the move - the move continues to
use the normal acceleration scheme up to its adjusted top-speed.
## Generating steps
Once the look-ahead process completes, the print head movement for the
given move is fully known (time, start position, end position,
velocity at each point) and it is possible to generate the step times
for the move. This process is done within "kinematic classes" in the
Klipper code. Outside of these kinematic classes, everything is
tracked in millimeters, seconds, and in cartesian coordinate space.
It's the task of the kinematic classes to convert from this generic
coordinate system to the hardware specifics of the particular printer.
Klipper uses an
[iterative solver](https://en.wikipedia.org/wiki/Root-finding_algorithm)
to generate the step times for each stepper. The code contains the
formulas to calculate the ideal cartesian coordinates of the head at
each moment in time, and it has the kinematic formulas to calculate
the ideal stepper positions based on those cartesian coordinates. With
these formulas, Klipper can determine the ideal time that the stepper
should be at each step position. The given steps are then scheduled at
these calculated times.
The key formula to determine how far a move should travel under
constant acceleration is:
```
move_distance = (start_velocity + .5 * accel * move_time) * move_time
```
and the key formula for movement with constant velocity is:
```
move_distance = cruise_velocity * move_time
```
The key formulas for determining the cartesian coordinate of a move
given a move distance is:
```
cartesian_x_position = start_x + move_distance * total_x_movement / total_movement
cartesian_y_position = start_y + move_distance * total_y_movement / total_movement
cartesian_z_position = start_z + move_distance * total_z_movement / total_movement
```
### Cartesian Robots
Generating steps for cartesian printers is the simplest case. The
movement on each axis is directly related to the movement in cartesian
space.
Key formulas:
```
stepper_x_position = cartesian_x_position
stepper_y_position = cartesian_y_position
stepper_z_position = cartesian_z_position
```
### CoreXY Robots
Generating steps on a CoreXY machine is only a little more complex
than basic cartesian robots. The key formulas are:
```
stepper_a_position = cartesian_x_position + cartesian_y_position
stepper_b_position = cartesian_x_position - cartesian_y_position
stepper_z_position = cartesian_z_position
```
### Delta Robots
Step generation on a delta robot is based on Pythagoras's theorem:
```
stepper_position = (sqrt(arm_length^2
- (cartesian_x_position - tower_x_position)^2
- (cartesian_y_position - tower_y_position)^2)
+ cartesian_z_position)
```
### Stepper motor acceleration limits
With delta kinematics it is possible for a move that is accelerating
in cartesian space to require an acceleration on a particular stepper
motor greater than the move's acceleration. This can occur when a
stepper arm is more horizontal than vertical and the line of movement
passes near that stepper's tower. Although these moves could require a
stepper motor acceleration greater than the printer's maximum
configured move acceleration, the effective mass moved by that stepper
would be smaller. Thus the higher stepper acceleration does not result
in significantly higher stepper torque and it is therefore considered
harmless.
However, to avoid extreme cases, Klipper enforces a maximum ceiling on
stepper acceleration of three times the printer's configured maximum
move acceleration. (Similarly, the maximum velocity of the stepper is
limited to three times the maximum move velocity.) In order to enforce
this limit, moves at the extreme edge of the build envelope (where a
stepper arm may be nearly horizontal) will have a lower maximum
acceleration and velocity.
### Extruder kinematics
Klipper implements extruder motion in its own kinematic class. Since
the timing and speed of each print head movement is fully known for
each move, it's possible to calculate the step times for the extruder
independently from the step time calculations of the print head
movement.
Basic extruder movement is simple to calculate. The step time
generation uses the same formulas that cartesian robots use:
```
stepper_position = requested_e_position
```
### Pressure advance
Experimentation has shown that it's possible to improve the modeling
of the extruder beyond the basic extruder formula. In the ideal case,
as an extrusion move progresses, the same volume of filament should be
deposited at each point along the move and there should be no volume
extruded after the move. Unfortunately, it's common to find that the
basic extrusion formulas cause too little filament to exit the
extruder at the start of extrusion moves and for excess filament to
extrude after extrusion ends. This is often referred to as "ooze".
![ooze](img/ooze.svg.png)
The "pressure advance" system attempts to account for this by using a
different model for the extruder. Instead of naively believing that
each mm^3 of filament fed into the extruder will result in that amount
of mm^3 immediately exiting the extruder, it uses a model based on
pressure. Pressure increases when filament is pushed into the extruder
(as in [Hooke's law](https://en.wikipedia.org/wiki/Hooke%27s_law)) and
the pressure necessary to extrude is dominated by the flow rate
through the nozzle orifice (as in
[Poiseuille's law](https://en.wikipedia.org/wiki/Poiseuille_law)). The
key idea is that the relationship between filament, pressure, and flow
rate can be modeled using a linear coefficient:
```
pa_position = nominal_position + pressure_advance_coefficient * nominal_velocity
```
See the [pressure advance](Pressure_Advance.md) document for
information on how to find this pressure advance coefficient.
The basic pressure advance formula can cause the extruder motor to
make sudden velocity changes. Klipper implements "smoothing" of the
extruder movement to avoid this.
![pressure-advance](img/pressure-velocity.png)
The above graph shows an example of two extrusion moves with a
non-zero cornering velocity between them. Note that the pressure
advance system causes additional filament to be pushed into the
extruder during acceleration. The higher the desired filament flow
rate, the more filament must be pushed in during acceleration to
account for pressure. During head deceleration the extra filament is
retracted (the extruder will have a negative velocity).
The "smoothing" is implemented using a weighted average of the
extruder position over a small time period (as specified by the
`pressure_advance_smooth_time` config parameter). This averaging can
span multiple g-code moves. Note how the extruder motor will start
moving prior to the nominal start of the first extrusion move and will
continue to move after the nominal end of the last extrusion move.
Key formula for "smoothed pressure advance":
```
smooth_pa_position(t) =
( definitive_integral(pa_position(x) * (smooth_time/2 - abs(t - x)) * dx,
from=t-smooth_time/2, to=t+smooth_time/2)
/ (smooth_time/2)^2 )
```

293
docs/MCU_Commands.md Normal file
View File

@@ -0,0 +1,293 @@
# MCU commands
This document provides information on the low-level micro-controller
commands that are sent from the Klipper "host" software and processed
by the Klipper micro-controller software. This document is not an
authoritative reference for these commands, nor is it an exclusive
list of all available commands.
This document may be useful for developers interested in understanding
the low-level micro-controller commands.
See the [protocol](Protocol.md) document for more information on the
format of commands and their transmission. The commands here are
described using their "printf" style syntax - for those unfamiliar
with that format, just note that where a '%...' sequence is seen it
should be replaced with an actual integer. For example, a description
with "count=%c" could be replaced with the text "count=10". Note that
parameters that are considered "enumerations" (see the above protocol
document) take a string value which is automatically converted to an
integer value for the micro-controller. This is common with parameters
named "pin" (or that have a suffix of "_pin").
## Startup Commands
It may be necessary to take certain one-time actions to configure the
micro-controller and its peripherals. This section lists common
commands available for that purpose. Unlike most micro-controller
commands, these commands run as soon as they are received and they do
not require any particular setup.
Common startup commands:
* `set_digital_out pin=%u value=%c` : This command immediately
configures the given pin as a digital out GPIO and it sets it to
either a low level (value=0) or a high level (value=1). This command
may be useful for configuring the initial value of LEDs and for
configuring the initial value of stepper driver micro-stepping pins.
* `set_pwm_out pin=%u cycle_ticks=%u value=%hu` : This command will
immediately configure the given pin to use hardware based
pulse-width-modulation (PWM) with the given number of
cycle_ticks. The "cycle_ticks" is the number of MCU clock ticks each
power on and power off cycle should last. A cycle_ticks value of 1
can be used to request the fastest possible cycle time. The "value"
parameter is between 0 and 255 with 0 indicating a full off state
and 255 indicating a full on state. This command may be useful for
enabling CPU and nozzle cooling fans.
## Low-level micro-controller configuration
Most commands in the micro-controller require an initial setup before
they can be successfully invoked. This section provides an overview of
the configuration process. This section and the following sections are
likely only of interest to developers interested in the internal
details of Klipper.
When the host first connects to the micro-controller it always starts
by obtaining a data dictionary (see [protocol](Protocol.md) for more
information). After the data dictionary is obtained the host will
check if the micro-controller is in a "configured" state and configure
it if not. Configuration involves the following phases:
* `get_config` : The host starts by checking if the micro-controller
is already configured. The micro-controller responds to this command
with a "config" response message. The micro-controller software
always starts in an unconfigured state at power-on. It remains in
this state until the host completes the configuration processes (by
issuing a finalize_config command). If the micro-controller is
already configured from a previous session (and is configured with
the desired settings) then no further action is needed by the host
and the configuration process ends successfully.
* `allocate_oids count=%c` : This command is issued to inform the
micro-controller of the maximum number of object-ids (oid) that the
host requires. It is only valid to issue this command once. An oid
is an integer identifier allocated to each stepper, each endstop,
and each schedulable gpio pin. The host determines in advance the
number of oids it will require to operate the hardware and passes
this to the micro-controller so that it may allocate sufficient
memory to store a mapping from oid to internal object.
* `config_XXX oid=%c ...` : By convention any command starting with
the "config_" prefix creates a new micro-controller object and
assigns the given oid to it. For example, the config_digital_out
command will configure the specified pin as a digital output GPIO
and create an internal object that the host can use to schedule
changes to the given GPIO. The oid parameter passed into the config
command is selected by the host and must be between zero and the
maximum count supplied in the allocate_oids command. The config
commands may only be run when the micro-controller is not in a
configured state (ie, prior to the host sending finalize_config) and
after the allocate_oids command has been sent.
* `finalize_config crc=%u` : The finalize_config command transitions
the micro-controller from an unconfigured state to a configured
state. The crc parameter passed to the micro-controller is stored
and provided back to the host in "config" response messages. By
convention, the host takes a 32bit CRC of the configuration it will
request and at the start of subsequent communication sessions it
checks that the CRC stored in the micro-controller exactly matches
its desired CRC. If the CRC does not match then the host knows the
micro-controller has not been configured in the state desired by the
host.
### Common micro-controller objects
This section lists some commonly used config commands.
* `config_digital_out oid=%c pin=%u value=%c default_value=%c
max_duration=%u` : This command creates an internal micro-controller
object for the given GPIO 'pin'. The pin will be configured in
digital output mode and set to an initial value as specified by
'value' (0 for low, 1 for high). Creating a digital_out object
allows the host to schedule GPIO updates for the given pin at
specified times (see the queue_digital_out command described below).
Should the micro-controller software go into shutdown mode then all
configured digital_out objects will be set to 'default_value'. The
'max_duration' parameter is used to implement a safety check - if it
is non-zero then it is the maximum number of clock ticks that the
host may set the given GPIO to a non-default value without further
updates. For example, if the default_value is zero and the
max_duration is 16000 then if the host sets the gpio to a value of
one then it must schedule another update to the gpio pin (to either
zero or one) within 16000 clock ticks. This safety feature can be
used with heater pins to ensure the host does not enable the heater
and then go off-line.
* `config_pwm_out oid=%c pin=%u cycle_ticks=%u value=%hu
default_value=%hu max_duration=%u` : This command creates an
internal object for hardware based PWM pins that the host may
schedule updates for. Its usage is analogous to config_digital_out -
see the description of the 'set_pwm_out' and 'config_digital_out'
commands for parameter description.
* `config_analog_in oid=%c pin=%u` : This command is used to configure
a pin in analog input sampling mode. Once configured, the pin can be
sampled at regular interval using the query_analog_in command (see
below).
* `config_stepper oid=%c step_pin=%c dir_pin=%c invert_step=%c
step_pulse_ticks=%u` : This command creates an internal stepper
object. The 'step_pin' and 'dir_pin' parameters specify the step and
direction pins respectively; this command will configure them in
digital output mode. The 'invert_step' parameter specifies whether a
step occurs on a rising edge (invert_step=0) or falling edge
(invert_step=1). The 'step_pulse_ticks' parameter specifies the
minimum duration of the step pulse. If the mcu exports the constant
'STEPPER_BOTH_EDGE=1' then setting step_pulse_ticks=0 and
invert_step=-1 will setup for stepping on both the rising and
falling edges of the step pin.
* `config_endstop oid=%c pin=%c pull_up=%c stepper_count=%c` : This
command creates an internal "endstop" object. It is used to specify
the endstop pins and to enable "homing" operations (see the
endstop_home command below). The command will configure the
specified pin in digital input mode. The 'pull_up' parameter
determines whether hardware provided pullup resistors for the pin
(if available) will be enabled. The 'stepper_count' parameter
specifies the maximum number of steppers that this endstop may need
to halt during a homing operation (see endstop_home below).
* `config_spi oid=%c bus=%u pin=%u mode=%u rate=%u shutdown_msg=%*s` :
This command creates an internal SPI object. It is used with
spi_transfer and spi_send commands (see below). The "bus"
identifies the SPI bus to use (if the micro-controller has more than
one SPI bus available). The "pin" specifies the chip select (CS) pin
for the device. The "mode" is the SPI mode (should be between 0 and
3). The "rate" parameter specifies the SPI bus rate (in cycles per
second). Finally, the "shutdown_msg" is an SPI command to send to
the given device should the micro-controller go into a shutdown
state.
* `config_spi_without_cs oid=%c bus=%u mode=%u rate=%u
shutdown_msg=%*s` : This command is similar to config_spi, but
without a CS pin definition. It is useful for SPI devices that do
not have a chip select line.
## Common commands
This section lists some commonly used run-time commands. It is likely
only of interest to developers looking to gain insight into Klipper.
* `set_digital_out_pwm_cycle oid=%c cycle_ticks=%u` : This command
configures a digital output pin (as created by config_digital_out)
to use "software PWM". The 'cycle_ticks' is the number of clock
ticks for the PWM cycle. Because the output switching is implemented
in the micro-controller software, it is recommended that
'cycle_ticks' correspond to a time of 10ms or greater.
* `queue_digital_out oid=%c clock=%u on_ticks=%u` : This command will
schedule a change to a digital output GPIO pin at the given clock
time. To use this command a 'config_digital_out' command with the
same 'oid' parameter must have been issued during micro-controller
configuration. If 'set_digital_out_pwm_cycle' has been called then
'on_ticks' is the on duration (in clock ticks) for the pwm cycle.
Otherwise, 'on_ticks' should be either 0 (for low voltage) or 1 (for
high voltage).
* `queue_pwm_out oid=%c clock=%u value=%hu` : Schedules a change to a
hardware PWM output pin. See the 'queue_digital_out' and
'config_pwm_out' commands for more info.
* `query_analog_in oid=%c clock=%u sample_ticks=%u sample_count=%c
rest_ticks=%u min_value=%hu max_value=%hu` : This command sets up a
recurring schedule of analog input samples. To use this command a
'config_analog_in' command with the same 'oid' parameter must have
been issued during micro-controller configuration. The samples will
start as of 'clock' time, it will report on the obtained value every
'rest_ticks' clock ticks, it will over-sample 'sample_count' number
of times, and it will pause 'sample_ticks' number of clock ticks
between over-sample samples. The 'min_value' and 'max_value'
parameters implement a safety feature - the micro-controller
software will verify the sampled value (after any oversampling) is
always between the supplied range. This is intended for use with
pins attached to thermistors controlling heaters - it can be used to
check that a heater is within a temperature range.
* `get_clock` : This command causes the micro-controller to generate a
"clock" response message. The host sends this command once a second
to obtain the value of the micro-controller clock and to estimate
the drift between host and micro-controller clocks. It enables the
host to accurately estimate the micro-controller clock.
### Stepper commands
* `queue_step oid=%c interval=%u count=%hu add=%hi` : This command
schedules 'count' number of steps for the given stepper, with
'interval' number of clock ticks between each step. The first step
will be 'interval' number of clock ticks since the last scheduled
step for the given stepper. If 'add' is non-zero then the interval
will be adjusted by 'add' amount after each step. This command
appends the given interval/count/add sequence to a per-stepper
queue. There may be hundreds of these sequences queued during normal
operation. New sequence are appended to the end of the queue and as
each sequence completes its 'count' number of steps it is popped
from the front of the queue. This system allows the micro-controller
to queue potentially hundreds of thousands of steps - all with
reliable and predictable schedule times.
* `set_next_step_dir oid=%c dir=%c` : This command specifies the value
of the dir_pin that the next queue_step command will use.
* `reset_step_clock oid=%c clock=%u` : Normally, step timing is
relative to the last step for a given stepper. This command resets
the clock so that the next step is relative to the supplied 'clock'
time. The host usually only sends this command at the start of a
print.
* `stepper_get_position oid=%c` : This command causes the
micro-controller to generate a "stepper_position" response message
with the stepper's current position. The position is the total
number of steps generated with dir=1 minus the total number of steps
generated with dir=0.
* `endstop_home oid=%c clock=%u sample_ticks=%u sample_count=%c
rest_ticks=%u pin_value=%c` : This command is used during stepper
"homing" operations. To use this command a 'config_endstop' command
with the same 'oid' parameter must have been issued during
micro-controller configuration. When this command is invoked, the
micro-controller will sample the endstop pin every 'rest_ticks'
clock ticks and check if it has a value equal to 'pin_value'. If the
value matches (and it continues to match for 'sample_count'
additional samples spread 'sample_ticks' apart) then the movement
queue for the associated stepper will be cleared and the stepper
will come to an immediate halt. The host uses this command to
implement homing - the host instructs the endstop to sample for the
endstop trigger and then it issues a series of queue_step commands
to move a stepper towards the endstop. Once the stepper hits the
endstop, the trigger will be detected, the movement halted, and the
host notified.
### Move queue
Each queue_step command utilizes an entry in the micro-controller
"move queue". This queue is allocated when it receives the
"finalize_config" command, and it reports the number of available
queue entries in "config" response messages.
It is the responsibility of the host to ensure that there is available
space in the queue before sending a queue_step command. The host does
this by calculating when each queue_step command completes and
scheduling new queue_step commands accordingly.
### SPI Commands
* `spi_transfer oid=%c data=%*s` : This command causes the
micro-controller to send 'data' to the spi device specified by 'oid'
and it generates a "spi_transfer_response" response message with the
data returned during the transmission.
* `spi_send oid=%c data=%*s` : This command is similar to
"spi_transfer", but it does not generate a "spi_transfer_response"
message.

215
docs/Manual_Level.md Normal file
View File

@@ -0,0 +1,215 @@
# Manual leveling
This document describes tools for calibrating a Z endstop and for
performing adjustments to bed leveling screws.
## Calibrating a Z endstop
An accurate Z endstop position is critical to obtaining high quality
prints.
Note, though, the accuracy of the Z endstop switch itself can be a
limiting factor. If one is using Trinamic stepper motor drivers then
consider enabling [endstop phase](Endstop_Phase.md) detection to
improve the accuracy of the switch.
To perform a Z endstop calibration, home the printer, command the head
to move to a Z position that is at least five millimeters above the
bed (if it is not already), command the head to move to an XY position
near the center of the bed, then navigate to the OctoPrint terminal
tab and run:
```
Z_ENDSTOP_CALIBRATE
```
Then follow the steps described at
["the paper test"](Bed_Level.md#the-paper-test) to determine the
actual distance between the nozzle and bed at the given location. Once
those steps are complete one can `ACCEPT` the position and save the
results to the config file with:
```
SAVE_CONFIG
```
It's preferable to use a Z endstop switch on the opposite end of the Z
axis from the bed. (Homing away from the bed is more robust as then it
is generally always safe to home the Z.) However, if one must home
towards the bed it is recommended to adjust the endstop so that it
triggers a small distance (eg, .5mm) above the bed. Almost all endstop
switches can safely be depressed a small distance beyond their trigger
point. When this is done, one should find that the
`Z_ENDSTOP_CALIBRATE` command reports a small positive value (eg,
.5mm) for the Z position_endstop. Triggering the endstop while it is
still some distance from the bed reduces the risk of inadvertent bed
crashes.
Some printers have the ability to manually adjust the location of the
physical endstop switch. However, it's recommended to perform Z
endstop positioning in software with Klipper - once the physical
location of the endstop is in a convenient location, one can make any
further adjustments by running Z_ENDSTOP_CALIBRATE or by manually
updating the Z position_endstop in the configuration file.
## Adjusting bed leveling screws
The secret to getting good bed leveling with bed leveling screws is to
utilize the printer's high precision motion system during the bed
leveling process itself. This is done by commanding the nozzle to a
position near each bed screw and then adjusting that screw until the
bed is a set distance from the nozzle. Klipper has a tool to assist
with this. In order to use the tool it is necessary to specify each
screw XY location.
This is done by creating a `[bed_screws]` config section. For example,
it might look something similar to:
```
[bed_screws]
screw1: 100, 50
screw2: 100, 150
screw3: 150, 100
```
If a bed screw is under the bed, then specify the XY position directly
above the screw. If the screw is outside the bed then specify an XY
position closest to the screw that is still within the range of the
bed.
Once the config file is ready, run `RESTART` to load that config, and
then one can start the tool by running:
```
BED_SCREWS_ADJUST
```
This tool will move the printer's nozzle to each screw XY location
and then move the nozzle to a Z=0 height. At this point one can use the
"paper test" to adjust the bed screw directly under the nozzle. See
the information described in
["the paper test"](Bed_Level.md#the-paper-test), but adjust the bed
screw instead of commanding the nozzle to different heights. Adjust
the bed screw until there is a small amount of friction when pushing
the paper back and forth.
Once the screw is adjusted so that a small amount of friction is felt,
run either the `ACCEPT` or `ADJUSTED` command. Use the `ADJUSTED`
command if the bed screw needed an adjustment (typically anything more
than about 1/8th of a turn of the screw). Use the `ACCEPT` command if
no significant adjustment is necessary. Both commands will cause the
tool to proceed to the next screw. (When an `ADJUSTED` command is
used, the tool will schedule an additional cycle of bed screw
adjustments; the tool completes successfully when all bed screws are
verified to not require any significant adjustments.) One can use the
`ABORT` command to exit the tool early.
This system works best when the printer has a flat printing surface
(such as glass) and has straight rails. Upon successful completion of
the bed leveling tool the bed should be ready for printing.
### Fine grained bed screw adjustments
If the printer uses three bed screws and all three screws are under
the bed, then it may be possible to perform a second "high precision"
bed leveling step. This is done by commanding the nozzle to locations
where the bed moves a larger distance with each bed screw adjustment.
For example, consider a bed with screws at locations A, B, and C:
![bed_screws](img/bed_screws.svg.png)
For each adjustment made to the bed screw at location C, the bed will
swing along a pendulum defined by the remaining two bed screws (shown
here as a green line). In this situation, each adjustment to the bed
screw at C will move the bed at position D a further amount than
directly at C. It is thus possible to make an improved C screw
adjustment when the nozzle is at position D.
To enable this feature, one would determine the additional nozzle
coordinates and add them to the config file. For example, it might
look like:
```
[bed_screws]
screw1: 100, 50
screw1_fine_adjust: 0, 0
screw2: 100, 150
screw2_fine_adjust: 300, 300
screw3: 150, 100
screw3_fine_adjust: 0, 100
```
When this feature is enabled, the `BED_SCREWS_ADJUST` tool will first
prompt for coarse adjustments directly above each screw position, and
once those are accepted, it will prompt for fine adjustments at the
additional locations. Continue to use `ACCEPT` and `ADJUSTED` at each
position.
## Adjusting bed leveling screws using the bed probe
This is another way to calibrate the bed level using the bed probe. To
use it you must have a Z probe (BL Touch, Inductive sensor, etc).
To enable this feature, one would determine the nozzle coordinates
such that the Z probe is above the screws, and then add them to the
config file. For example, it might look like:
```
[screws_tilt_adjust]
screw1: -5, 30
screw1_name: front left screw
screw2: 155, 30
screw2_name: front right screw
screw3: 155, 190
screw3_name: rear right screw
screw4: -5, 190
screw4_name: rear left screw
horizontal_move_z: 10.
speed: 50.
screw_thread: CW-M3
```
The screw1 is always the reference point for the others, so the system
assumes that screw1 is at the correct height. Always run `G28` first
and then run `SCREWS_TILT_CALCULATE` - it should produce output
similar to:
```
Send: G28
Recv: ok
Send: SCREWS_TILT_CALCULATE
Recv: // 01:20 means 1 full turn and 20 minutes, CW=clockwise, CCW=counter-clockwise
Recv: // front left screw (base) : x=-5.0, y=30.0, z=2.48750
Recv: // front right screw : x=155.0, y=30.0, z=2.36000 : adjust CW 01:15
Recv: // rear right screw : y=155.0, y=190.0, z=2.71500 : adjust CCW 00:50
Recv: // read left screw : x=-5.0, y=190.0, z=2.47250 : adjust CW 00:02
Recv: ok
```
This means that:
- front left screw is the reference point you must not change it.
- front right screw must be turned clockwise 1 full turn and a quarter turn
- rear right screw must be turned counter-clockwise 50 minutes
- rear left screw must be turned clockwise 2 minutes (not need it's ok)
Note that "minutes" refers to "minutes of a clock face". So, for
example, 15 minutes is a quarter of a full turn.
Repeat the process several times until you get a good level bed -
normally when all adjustments are below 6 minutes.
If using a probe that is mounted on the side of the hotend (that is,
it has an X or Y offset) then note that adjusting the bed tilt will
invalidate any previous probe calibration that was performed with a
tilted bed. Be sure to run [probe calibration](Probe_Calibrate.md)
after the bed screws have been adjusted.
The `MAX_DEVIATION` parameter is useful when a saved bed mesh is used,
to ensure that the bed level has not drifted too far from where it was when
the mesh was created. For example, `SCREWS_TILT_CALCULATE MAX_DEVIATION=0.01`
can be added to the custom start gcode of the slicer before the mesh is loaded.
It will abort the print if the configured limit is exceeded (0.01mm in this
example), giving the user a chance to adjust the screws and restart the print.
The `DIRECTION` parameter is useful if you can turn your bed adjustment
screws in one direction only. For example, you might have screws that start
tightened in their lowest (or highest) possible position, which can only be
turned in a single direction, to raise (or lower) the bed. If you can only
turn the screws clockwise, run `SCREWS_TILT_CALCULATE DIRECTION=CW`. If you can
only turn them counter-clockwise, run `SCREWS_TILT_CALCULATE DIRECTION=CCW`.
A suitable reference point will be chosen such that the bed can be leveled
by turning all the screws in the given direction.

View File

@@ -0,0 +1,560 @@
# Measuring Resonances
Klipper has built-in support for ADXL345 accelerometer, which can be used to
measure resonance frequencies of the printer for different axes, and auto-tune
[input shapers](Resonance_Compensation.md) to compensate for resonances.
Note that using ADXL345 requires some soldering and crimping. ADXL345 can be
connected to a Raspberry Pi directly, or to an SPI interface of an MCU
board (it needs to be reasonably fast).
When sourcing ADXL345, be aware that there is a variety of different PCB
board designs and different clones of them. Make sure that the board supports
SPI mode (small number of boards appear to be hard-configured for I2C by
pulling SDO to GND), and, if it is going to be connected to a 5V printer MCU,
that it has a voltage regulator and a level shifter.
## Installation instructions
### Wiring
You need to connect ADXL345 to your Raspberry Pi via SPI. Note that the I2C
connection, which is suggested by ADXL345 documentation, has too low throughput
and **will not work**. The recommended connection scheme:
| ADXL345 pin | RPi pin | RPi pin name |
|:--:|:--:|:--:|
| 3V3 (or VCC) | 01 | 3.3v DC power |
| GND | 06 | Ground |
| CS | 24 | GPIO08 (SPI0_CE0_N) |
| SDO | 21 | GPIO09 (SPI0_MISO) |
| SDA | 19 | GPIO10 (SPI0_MOSI) |
| SCL | 23 | GPIO11 (SPI0_SCLK) |
An alternative to the ADXL345 is the MPU-9250 (or MPU-6050). This
accelerometer has been tested to work over I2C on the RPi at 400kbaud.
Recommended connection scheme for I2C:
| MPU-9250 pin | RPi pin | RPi pin name |
|:--:|:--:|:--:|
| 3V3 (or VCC) | 01 | 3.3v DC power |
| GND | 09 | Ground |
| SDA | 03 | GPIO02 (SDA1) |
| SCL | 05 | GPIO03 (SCL1) |
Fritzing wiring diagrams for some of the ADXL345 boards:
![ADXL345-Rpi](img/adxl345-fritzing.png)
Double-check your wiring before powering up the Raspberry Pi to prevent
damaging it or the accelerometer.
### Mounting the accelerometer
The accelerometer must be attached to the toolhead. One needs to design a proper
mount that fits their own 3D printer. It is better to align the axes of the
accelerometer with the printer's axes (but if it makes it more convenient,
axes can be swapped - i.e. no need to align X axis with X and so forth - it
should be fine even if Z axis of accelerometer is X axis of the printer, etc.).
An example of mounting ADXL345 on the SmartEffector:
![ADXL345 on SmartEffector](img/adxl345-mount.jpg)
Note that on a bed slinger printer one must design 2 mounts: one for the
toolhead and one for the bed, and run the measurements twice. See the
corresponding [section](#bed-slinger-printers) for more details.
**Attention:** make sure the accelerometer and any screws that hold it in
place do not touch any metal parts of the printer. Basically, the mount must
be designed such as to ensure the electrical isolation of the accelerometer
from the printer frame. Failing to ensure that can create a ground loop in
the system that may damage the electronics.
### Software installation
Note that resonance measurements and shaper auto-calibration require additional
software dependencies not installed by default. First, run on your Raspberry Pi
the following commands:
```
sudo apt update
sudo apt install python3-numpy python3-matplotlib libatlas-base-dev
```
Next, in order to install NumPy in the Klipper environment, run the command:
```
~/klippy-env/bin/pip install -v numpy
```
Note that, depending on the performance of the CPU, it may take *a lot*
of time, up to 10-20 minutes. Be patient and wait for the completion of
the installation. On some occasions, if the board has too little RAM
the installation may fail and you will need to enable swap.
Afterwards, check and follow the instructions in the
[RPi Microcontroller document](RPi_microcontroller.md) to setup the
"linux mcu" on the Raspberry Pi.
Make sure the Linux SPI driver is enabled by running `sudo
raspi-config` and enabling SPI under the "Interfacing options" menu.
For the ADXL345, add the following to the printer.cfg file:
```
[mcu rpi]
serial: /tmp/klipper_host_mcu
[adxl345]
cs_pin: rpi:None
[resonance_tester]
accel_chip: adxl345
probe_points:
100, 100, 20 # an example
```
It is advised to start with 1 probe point, in the middle of the print bed,
slightly above it.
For the MPU-9250, make sure the Linux I2C driver is enabled and the baud rate is
set to 400000 (see [Enabling I2C](RPi_microcontroller.md#optional-enabling-i2c)
section for more details). Then, add the following to the printer.cfg:
```
[mcu rpi]
serial: /tmp/klipper_host_mcu
[mpu9250]
i2c_mcu: rpi
i2c_bus: i2c.1
[resonance_tester]
accel_chip: mpu9250
probe_points:
100, 100, 20 # an example
```
Restart Klipper via the `RESTART` command.
## Measuring the resonances
### Checking the setup
Now you can test a connection.
- For "non bed-slingers" (e.g. one accelerometer), in Octoprint,
enter `ACCELEROMETER_QUERY`
- For "bed-slingers" (e.g. more than one accelerometer), enter
`ACCELEROMETER_QUERY CHIP=<chip>` where `<chip>` is the name of the chip
as-entered, e.g. `CHIP=bed` (see: [bed-slinger](#bed-slinger-printers))
for all installed accelerometer chips.
You should see the current measurements from the accelerometer, including the
free-fall acceleration, e.g.
```
Recv: // adxl345 values (x, y, z): 470.719200, 941.438400, 9728.196800
```
If you get an error like `Invalid adxl345 id (got xx vs e5)`, where `xx`
is some other ID, it is indicative of the connection problem with ADXL345,
or the faulty sensor. Double-check the power, the wiring (that it matches
the schematics, no wire is broken or loose, etc.), and soldering quality.
Next, try running `MEASURE_AXES_NOISE` in Octoprint, you should get some
baseline numbers for the noise of accelerometer on the axes (should be
somewhere in the range of ~1-100). Too high axes noise (e.g. 1000 and more)
can be indicative of the sensor issues, problems with its power, or too
noisy imbalanced fans on a 3D printer.
### Measuring the resonances
Now you can run some real-life tests. Run the following command:
```
TEST_RESONANCES AXIS=X
```
Note that it will create vibrations on X axis. It will also disable input
shaping if it was enabled previously, as it is not valid to run the resonance
testing with the input shaper enabled.
**Attention!** Be sure to observe the printer for the first time, to make sure
the vibrations do not become too violent (`M112` command can be used to abort
the test in case of emergency; hopefully it will not come to this though).
If the vibrations do get too strong, you can attempt to specify a lower than the
default value for `accel_per_hz` parameter in `[resonance_tester]` section, e.g.
```
[resonance_tester]
accel_chip: adxl345
accel_per_hz: 50 # default is 75
probe_points: ...
```
If it works for X axis, run for Y axis as well:
```
TEST_RESONANCES AXIS=Y
```
This will generate 2 CSV files (`/tmp/resonances_x_*.csv` and
`/tmp/resonances_y_*.csv`). These files can be processed with the stand-alone
script on a Raspberry Pi. To do that, run the following commands:
```
~/klipper/scripts/calibrate_shaper.py /tmp/resonances_x_*.csv -o /tmp/shaper_calibrate_x.png
~/klipper/scripts/calibrate_shaper.py /tmp/resonances_y_*.csv -o /tmp/shaper_calibrate_y.png
```
This script will generate the charts `/tmp/shaper_calibrate_x.png` and
`/tmp/shaper_calibrate_y.png` with frequency responses. You will also get the
suggested frequencies for each input shaper, as well as which input shaper is
recommended for your setup. For example:
![Resonances](img/calibrate-y.png)
```
Fitted shaper 'zv' frequency = 34.4 Hz (vibrations = 4.0%, smoothing ~= 0.132)
To avoid too much smoothing with 'zv', suggested max_accel <= 4500 mm/sec^2
Fitted shaper 'mzv' frequency = 34.6 Hz (vibrations = 0.0%, smoothing ~= 0.170)
To avoid too much smoothing with 'mzv', suggested max_accel <= 3500 mm/sec^2
Fitted shaper 'ei' frequency = 41.4 Hz (vibrations = 0.0%, smoothing ~= 0.188)
To avoid too much smoothing with 'ei', suggested max_accel <= 3200 mm/sec^2
Fitted shaper '2hump_ei' frequency = 51.8 Hz (vibrations = 0.0%, smoothing ~= 0.201)
To avoid too much smoothing with '2hump_ei', suggested max_accel <= 3000 mm/sec^2
Fitted shaper '3hump_ei' frequency = 61.8 Hz (vibrations = 0.0%, smoothing ~= 0.215)
To avoid too much smoothing with '3hump_ei', suggested max_accel <= 2800 mm/sec^2
Recommended shaper is mzv @ 34.6 Hz
```
The suggested configuration can be added to `[input_shaper]` section of
`printer.cfg`, e.g.:
```
[input_shaper]
shaper_freq_x: ...
shaper_type_x: ...
shaper_freq_y: 34.6
shaper_type_y: mzv
[printer]
max_accel: 3000 # should not exceed the estimated max_accel for X and Y axes
```
or you can choose some other configuration yourself based on the generated
charts: peaks in the power spectral density on the charts correspond to
the resonance frequencies of the printer.
Note that alternatively you can run the input shaper autocalibration
from Klipper [directly](#input-shaper-auto-calibration), which can be
convenient, for example, for the input shaper
[re-calibration](#input-shaper-re-calibration).
### Bed-slinger printers
If your printer is a bed slinger printer, you will need to change the location
of the accelerometer between the measurements for X and Y axes: measure the
resonances of X axis with the accelerometer attached to the toolhead and the
resonances of Y axis - to the bed (the usual bed slinger setup).
However, you can also connect two accelerometers simultaneously, though they
must be connected to different boards (say, to an RPi and printer MCU board), or
to two different physical SPI interfaces on the same board (rarely available).
Then they can be configured in the following manner:
```
[adxl345 hotend]
# Assuming `hotend` chip is connected to an RPi
cs_pin: rpi:None
[adxl345 bed]
# Assuming `bed` chip is connected to a printer MCU board
cs_pin: ... # Printer board SPI chip select (CS) pin
[resonance_tester]
# Assuming the typical setup of the bed slinger printer
accel_chip_x: adxl345 hotend
accel_chip_y: adxl345 bed
probe_points: ...
```
Then the commands `TEST_RESONANCES AXIS=X` and `TEST_RESONANCES AXIS=Y`
will use the correct accelerometer for each axis.
### Max smoothing
Keep in mind that the input shaper can create some smoothing in parts.
Automatic tuning of the input shaper performed by `calibrate_shaper.py`
script or `SHAPER_CALIBRATE` command tries not to exacerbate the smoothing,
but at the same time they try to minimize the resulting vibrations.
Sometimes they can make a sub-optimal choice of the shaper frequency, or
maybe you simply prefer to have less smoothing in parts at the expense of
a larger remaining vibrations. In these cases, you can request to limit
the maximum smoothing from the input shaper.
Let's consider the following results from the automatic tuning:
![Resonances](img/calibrate-x.png)
```
Fitted shaper 'zv' frequency = 57.8 Hz (vibrations = 20.3%, smoothing ~= 0.053)
To avoid too much smoothing with 'zv', suggested max_accel <= 13000 mm/sec^2
Fitted shaper 'mzv' frequency = 34.8 Hz (vibrations = 3.6%, smoothing ~= 0.168)
To avoid too much smoothing with 'mzv', suggested max_accel <= 3600 mm/sec^2
Fitted shaper 'ei' frequency = 48.8 Hz (vibrations = 4.9%, smoothing ~= 0.135)
To avoid too much smoothing with 'ei', suggested max_accel <= 4400 mm/sec^2
Fitted shaper '2hump_ei' frequency = 45.2 Hz (vibrations = 0.1%, smoothing ~= 0.264)
To avoid too much smoothing with '2hump_ei', suggested max_accel <= 2200 mm/sec^2
Fitted shaper '3hump_ei' frequency = 48.0 Hz (vibrations = 0.0%, smoothing ~= 0.356)
To avoid too much smoothing with '3hump_ei', suggested max_accel <= 1500 mm/sec^2
Recommended shaper is 2hump_ei @ 45.2 Hz
```
Note that the reported `smoothing` values are some abstract projected values.
These values can be used to compare different configurations: the higher the
value, the more smoothing a shaper will create. However, these smoothing scores
do not represent any real measure of smoothing, because the actual smoothing
depends on [`max_accel`](#selecting-max-accel) and `square_corner_velocity`
parameters. Therefore, you should print some test prints to see how much
smoothing exactly a chosen configuration creates.
In the example above the suggested shaper parameters are not bad, but what if
you want to get less smoothing on the X axis? You can try to limit the maximum
shaper smoothing using the following command:
```
~/klipper/scripts/calibrate_shaper.py /tmp/resonances_x_*.csv -o /tmp/shaper_calibrate_x.png --max_smoothing=0.2
```
which limits the smoothing to 0.2 score. Now you can get the following result:
![Resonances](img/calibrate-x-max-smoothing.png)
```
Fitted shaper 'zv' frequency = 55.4 Hz (vibrations = 19.7%, smoothing ~= 0.057)
To avoid too much smoothing with 'zv', suggested max_accel <= 12000 mm/sec^2
Fitted shaper 'mzv' frequency = 34.6 Hz (vibrations = 3.6%, smoothing ~= 0.170)
To avoid too much smoothing with 'mzv', suggested max_accel <= 3500 mm/sec^2
Fitted shaper 'ei' frequency = 48.2 Hz (vibrations = 4.8%, smoothing ~= 0.139)
To avoid too much smoothing with 'ei', suggested max_accel <= 4300 mm/sec^2
Fitted shaper '2hump_ei' frequency = 52.0 Hz (vibrations = 2.7%, smoothing ~= 0.200)
To avoid too much smoothing with '2hump_ei', suggested max_accel <= 3000 mm/sec^2
Fitted shaper '3hump_ei' frequency = 72.6 Hz (vibrations = 1.4%, smoothing ~= 0.155)
To avoid too much smoothing with '3hump_ei', suggested max_accel <= 3900 mm/sec^2
Recommended shaper is 3hump_ei @ 72.6 Hz
```
If you compare to the previously suggested parameters, the vibrations are a bit
larger, but the smoothing is significantly smaller than previously, allowing
larger maximum acceleration.
When deciding which `max_smoothing` parameter to choose, you can use a
trial-and-error approach. Try a few different values and see which results
you get. Note that the actual smoothing produced by the input shaper depends,
primarily, on the lowest resonance frequency of the printer: the higher
the frequency of the lowest resonance - the smaller the smoothing. Therefore,
if you request the script to find a configuration of the input shaper with the
unrealistically small smoothing, it will be at the expense of increased ringing
at the lowest resonance frequencies (which are, typically, also more prominently
visible in prints). So, always double-check the projected remaining vibrations
reported by the script and make sure they are not too high.
Note that if you chose a good `max_smoothing` value for both of your axes, you
can store it in the `printer.cfg` as
```
[resonance_tester]
accel_chip: ...
probe_points: ...
max_smoothing: 0.25 # an example
```
Then, if you [rerun](#input-shaper-re-calibration) the input shaper auto-tuning
using `SHAPER_CALIBRATE` Klipper command in the future, it will use the stored
`max_smoothing` value as a reference.
### Selecting max_accel
Since the input shaper can create some smoothing in parts, especially at high
accelerations, you will still need to choose the `max_accel` value that
does not create too much smoothing in the printed parts. A calibration script
provides an estimate for `max_accel` parameter that should not create too much
smoothing. Note that the `max_accel` as displayed by the calibration script is
only a theoretical maximum at which the respective shaper is still able to work
without producing too much smoothing. It is by no means a recommendation to set
this acceleration for printing. The maximum acceleration your printer is able to
sustain depends on its mechanical properties and the maximum torque of the used
stepper motors. Therefore, it is suggested to set `max_accel` in `[printer]`
section that does not exceed the estimated values for X and Y axes, likely with
some conservative safety margin.
Alternatively, follow
[this](Resonance_Compensation.md#selecting-max_accel) part of
the input shaper tuning guide and print the test model to choose `max_accel`
parameter experimentally.
The same notice applies to the input shaper
[auto-calibration](#input-shaper-auto-calibration) with
`SHAPER_CALIBRATE` command: it is still necessary to choose the right
`max_accel` value after the auto-calibration, and the suggested acceleration
limits will not be applied automatically.
If you are doing a shaper re-calibration and the reported smoothing for the
suggested shaper configuration is almost the same as what you got during the
previous calibration, this step can be skipped.
### Testing custom axes
`TEST_RESONANCES` command supports custom axes. While this is not really
useful for input shaper calibration, it can be used to study printer
resonances in-depth and to check, for example, belt tension.
To check the belt tension on CoreXY printers, execute
```
TEST_RESONANCES AXIS=1,1 OUTPUT=raw_data
TEST_RESONANCES AXIS=1,-1 OUTPUT=raw_data
```
and use `graph_accelerometer.py` to process the generated files, e.g.
```
~/klipper/scripts/graph_accelerometer.py -c /tmp/raw_data_axis*.csv -o /tmp/resonances.png
```
which will generate `/tmp/resonances.png` comparing the resonances.
For Delta printers with the default tower placement
(tower A ~= 210 degrees, B ~= 330 degrees, and C ~= 90 degrees), execute
```
TEST_RESONANCES AXIS=0,1 OUTPUT=raw_data
TEST_RESONANCES AXIS=-0.866025404,-0.5 OUTPUT=raw_data
TEST_RESONANCES AXIS=0.866025404,-0.5 OUTPUT=raw_data
```
and then use the same command
```
~/klipper/scripts/graph_accelerometer.py -c /tmp/raw_data_axis*.csv -o /tmp/resonances.png
```
to generate `/tmp/resonances.png` comparing the resonances.
## Input Shaper auto-calibration
Besides manually choosing the appropriate parameters for the input shaper
feature, it is also possible to run the auto-tuning for the input shaper
directly from Klipper. Run the following command via Octoprint terminal:
```
SHAPER_CALIBRATE
```
This will run the full test for both axes and generate the csv output
(`/tmp/calibration_data_*.csv` by default) for the frequency response
and the suggested input shapers. You will also get the suggested
frequencies for each input shaper, as well as which input shaper is
recommended for your setup, on Octoprint console. For example:
```
Calculating the best input shaper parameters for y axis
Fitted shaper 'zv' frequency = 39.0 Hz (vibrations = 13.2%, smoothing ~= 0.105)
To avoid too much smoothing with 'zv', suggested max_accel <= 5900 mm/sec^2
Fitted shaper 'mzv' frequency = 36.8 Hz (vibrations = 1.7%, smoothing ~= 0.150)
To avoid too much smoothing with 'mzv', suggested max_accel <= 4000 mm/sec^2
Fitted shaper 'ei' frequency = 36.6 Hz (vibrations = 2.2%, smoothing ~= 0.240)
To avoid too much smoothing with 'ei', suggested max_accel <= 2500 mm/sec^2
Fitted shaper '2hump_ei' frequency = 48.0 Hz (vibrations = 0.0%, smoothing ~= 0.234)
To avoid too much smoothing with '2hump_ei', suggested max_accel <= 2500 mm/sec^2
Fitted shaper '3hump_ei' frequency = 59.0 Hz (vibrations = 0.0%, smoothing ~= 0.235)
To avoid too much smoothing with '3hump_ei', suggested max_accel <= 2500 mm/sec^2
Recommended shaper_type_y = mzv, shaper_freq_y = 36.8 Hz
```
If you agree with the suggested parameters, you can execute `SAVE_CONFIG`
now to save them and restart the Klipper. Note that this will not update
`max_accel` value in `[printer]` section. You should update it manually
following the considerations in [Selecting max_accel](#selecting-max_accel)
section.
If your printer is a bed slinger printer, you can specify which axis
to test, so that you can change the accelerometer mounting point between
the tests (by default the test is performed for both axes):
```
SHAPER_CALIBRATE AXIS=Y
```
You can execute `SAVE_CONFIG` twice - after calibrating each axis.
However, if you connected two accelerometers simultaneously, you simply run
`SHAPER_CALIBRATE` without specifying an axis to calibrate the input shaper
for both axes in one go.
### Input Shaper re-calibration
`SHAPER_CALIBRATE` command can be also used to re-calibrate the input shaper in
the future, especially if some changes to the printer that can affect its
kinematics are made. One can either re-run the full calibration using
`SHAPER_CALIBRATE` command, or restrict the auto-calibration to a single axis by
supplying `AXIS=` parameter, like
```
SHAPER_CALIBRATE AXIS=X
```
**Warning!** It is not advisable to run the shaper autocalibration very
frequently (e.g. before every print, or every day). In order to determine
resonance frequencies, autocalibration creates intensive vibrations on each of
the axes. Generally, 3D printers are not designed to withstand a prolonged
exposure to vibrations near the resonance frequencies. Doing so may increase
wear of the printer components and reduce their lifespan. There is also an
increased risk of some parts unscrewing or becoming loose. Always check that
all parts of the printer (including the ones that may normally not move) are
securely fixed in place after each auto-tuning.
Also, due to some noise in measurements, it is possible that the tuning results
will be slightly different from one calibration run to another one. Still, it
is not expected that the noise will affect the print quality too much.
However, it is still advised to double-check the suggested parameters, and
print some test prints before using them to confirm they are good.
## Offline processing of the accelerometer data
It is possible to generate the raw accelerometer data and process it offline
(e.g. on a host machine), for example to find resonances. In order to do so,
run the following commands via Octoprint terminal:
```
SET_INPUT_SHAPER SHAPER_FREQ_X=0 SHAPER_FREQ_Y=0
TEST_RESONANCES AXIS=X OUTPUT=raw_data
```
ignoring any errors for `SET_INPUT_SHAPER` command. For `TEST_RESONANCES`
command, specify the desired test axis. The raw data will be written into
`/tmp` directory on the RPi.
The raw data can also be obtained by running the command
`ACCELEROMETER_MEASURE` command twice during some normal printer
activity - first to start the measurements, and then to stop them and
write the output file. Refer to [G-Codes](G-Codes.md#adxl345) for more
details.
The data can be processed later by the following scripts:
`scripts/graph_accelerometer.py` and `scripts/calibrate_shaper.py`. Both
of them accept one or several raw csv files as the input depending on the
mode. The graph_accelerometer.py script supports several modes of operation:
* plotting raw accelerometer data (use `-r` parameter), only 1 input is
supported;
* plotting a frequency response (no extra parameters required), if multiple
inputs are specified, the average frequency response is computed;
* comparison of the frequency response between several inputs (use `-c`
parameter); you can additionally specify which accelerometer axis to
consider via `-a x`, `-a y` or `-a z` parameter (if none specified,
the sum of vibrations for all axes is used);
* plotting the spectrogram (use `-s` parameter), only 1 input is supported;
you can additionally specify which accelerometer axis to consider via
`-a x`, `-a y` or `-a z` parameter (if none specified, the sum of vibrations
for all axes is used).
Note that graph_accelerometer.py script supports only the raw_data\*.csv files
and not resonances\*.csv or calibration_data\*.csv files.
For example,
```
~/klipper/scripts/graph_accelerometer.py /tmp/raw_data_x_*.csv -o /tmp/resonances_x.png -c -a z
```
will plot the comparison of several `/tmp/raw_data_x_*.csv` files for Z axis to
`/tmp/resonances_x.png` file.
The shaper_calibrate.py script accepts 1 or several inputs and can run automatic
tuning of the input shaper and suggest the best parameters that work well for
all provided inputs. It prints the suggested parameters to the console, and can
additionally generate the chart if `-o output.png` parameter is provided, or
the CSV file if `-c output.csv` parameter is specified.
Providing several inputs to shaper_calibrate.py script can be useful if running
some advanced tuning of the input shapers, for example:
* Running `TEST_RESONANCES AXIS=X OUTPUT=raw_data` (and `Y` axis) for a single
axis twice on a bed slinger printer with the accelerometer attached to the
toolhead the first time, and the accelerometer attached to the bed the
second time in order to detect axes cross-resonances and attempt to cancel
them with input shapers.
* Running `TEST_RESONANCES AXIS=Y OUTPUT=raw_data` twice on a bed slinger with
a glass bed and a magnetic surfaces (which is lighter) to find the input
shaper parameters that work well for any print surface configuration.
* Combining the resonance data from multiple test points.
* Combining the resonance data from 2 axis (e.g. on a bed slinger printer
to configure X-axis input_shaper from both X and Y axes resonances to
cancel vibrations of the *bed* in case the nozzle 'catches' a print when
moving in X axis direction).

42
docs/Multi_MCU_Homing.md Normal file
View File

@@ -0,0 +1,42 @@
# Multiple Micro-controller Homing and Probing
Klipper supports a mechanism for homing with an endstop attached to
one micro-controller while its stepper motors are on a different
micro-controller. This support is referred to as "multi-mcu
homing". This feature is also used when a Z probe is on a different
micro-controller than the Z stepper motors.
This feature can be useful to simplify wiring, as it may be more
convenient to attach an endstop or probe to a closer micro-controller.
However, using this feature may result in "overshoot" of the stepper
motors during homing and probing operations.
The overshoot occurs due to possible message transmission delays
between the micro-controller monitoring the endstop and the
micro-controllers moving the stepper motors. The Klipper code is
designed to limit this delay to no more than 25ms. (When multi-mcu
homing is activated, the micro-controllers send periodic status
messages and check that corresponding status messages are received
within 25ms.)
So, for example, if homing at 10mm/s then it is possible for an
overshoot of up to 0.250mm (10mm/s * .025s == 0.250mm). Care should be
taken when configuring multi-mcu homing to account for this type of
overshoot. Using slower homing or probing speeds can reduce the
overshoot.
Stepper motor overshoot should not adversely impact the precision of
the homing and probing procedure. The Klipper code will detect the
overshoot and account for it in its calculations. However, it is
important that the hardware design is capable of handling overshoot
without causing damage to the machine.
Should Klipper detect a communication issue between micro-controllers
during multi-mcu homing then it will raise a "Communication timeout
during homing" error.
Note that an axis with multiple steppers (eg, `stepper_z` and
`stepper_z1`) need to be on the same micro-controller in order to use
multi-mcu homing. For example, if an endstop is on a separate
micro-controller from `stepper_z` then `stepper_z1` must be on the
same micro-controller as `stepper_z`.

96
docs/Overview.md Normal file
View File

@@ -0,0 +1,96 @@
# Overview
Welcome to the Klipper documentation. If new to Klipper, start with
the [features](Features.md) and [installation](Installation.md)
documents.
## Overview information
- [Features](Features.md): A high-level list of features in Klipper.
- [FAQ](FAQ.md): Frequently asked questions.
- [Releases](Releases.md): The history of Klipper releases.
- [Config changes](Config_Changes.md): Recent software changes that
may require users to update their printer config file.
- [Contact](Contact.md): Information on bug reporting and general
communication with the Klipper developers.
## Installation and Configuration
- [Installation](Installation.md): Guide to installing Klipper.
- [Config Reference](Config_Reference.md): Description of config
parameters.
- [Rotation Distance](Rotation_Distance.md): Calculating the
rotation_distance stepper parameter.
- [Config checks](Config_checks.md): Verify basic pin settings in the
config file.
- [Bed level](Bed_Level.md): Information on "bed leveling" in Klipper.
- [Delta calibrate](Delta_Calibrate.md): Calibration of delta
kinematics.
- [Probe calibrate](Probe_Calibrate.md): Calibration of automatic Z
probes.
- [BL-Touch](BLTouch.md): Configure a "BL-Touch" Z probe.
- [Manual level](Manual_Level.md): Calibration of Z endstops (and
similar).
- [Bed Mesh](Bed_Mesh.md): Bed height correction based on XY
locations.
- [Endstop phase](Endstop_Phase.md): Stepper assisted Z endstop
positioning.
- [Resonance compensation](Resonance_Compensation.md): A tool to
reduce ringing in prints.
- [Measuring resonances](Measuring_Resonances.md): Information on
using adxl345 accelerometer hardware to measure resonance.
- [Pressure advance](Pressure_Advance.md): Calibrate extruder
pressure.
- [G-Codes](G-Codes.md): Information on commands supported by Klipper.
- [Command Templates](Command_Templates.md): G-Code macros and
conditional evaluation.
- [Status Reference](Status_Reference.md): Information available to
macros (and similar).
- [TMC Drivers](TMC_Drivers.md): Using Trinamic stepper motor drivers
with Klipper.
- [Multi-MCU Homing](Multi_MCU_Homing.md): Homing and probing using multiple micro-controllers.
- [Slicers](Slicers.md): Configure "slicer" software for Klipper.
- [Skew correction](Skew_Correction.md): Adjustments for axes not
perfectly square.
- [PWM tools](Using_PWM_Tools.md): Guide on how to use PWM controlled
tools such as lasers or spindles.
- [Exclude Object](Exclude_Object.md): The guide to the Exclude Objecs
implementation.
## Developer Documentation
- [Code overview](Code_Overview.md): Developers should read this
first.
- [Kinematics](Kinematics.md): Technical details on how Klipper
implements motion.
- [Protocol](Protocol.md): Information on the low-level messaging
protocol between host and micro-controller.
- [API Server](API_Server.md): Information on Klipper's command and
control API.
- [MCU commands](MCU_Commands.md): A description of low-level commands
implemented in the micro-controller software.
- [CAN bus protocol](CANBUS_protocol.md): Klipper CAN bus message
format.
- [Debugging](Debugging.md): Information on how to test and debug
Klipper.
- [Benchmarks](Benchmarks.md): Information on the Klipper benchmark
method.
- [Contributing](CONTRIBUTING.md): Information on how to submit
improvements to Klipper.
- [Packaging](Packaging.md): Information on building OS packages.
## Device Specific Documents
- [Example configs](Example_Configs.md): Information on adding an
example config file to Klipper.
- [SDCard Updates](SDCard_Updates.md): Flash a micro-controller by
copying a binary to an sdcard in the micro-controller.
- [Raspberry Pi as Micro-controller](RPi_microcontroller.md): Details
for controlling devices wired to the GPIO pins of a Raspberry Pi.
- [Beaglebone](Beaglebone.md): Details for running Klipper on the
Beaglebone PRU.
- [Bootloaders](Bootloaders.md): Developer information on
micro-controller flashing.
- [CAN bus](CANBUS.md): Information on using CAN bus with Klipper.
- [TSL1401CL filament width sensor](TSL1401CL_Filament_Width_Sensor.md)
- [Hall filament width sensor](Hall_Filament_Width_Sensor.md)

30
docs/Packaging.md Normal file
View File

@@ -0,0 +1,30 @@
# Packaging Klipper
Klipper is somewhat of a packaging anomaly among python programs, as it doesn't
use setuptools to build and install. Some notes regarding how best to package it
are as follows:
## C modules
Klipper uses a C module to handle some kinematics calculations more quickly.
This module needs to be compiled at packaging time to avoid introducing a
runtime dependency on a compiler. To compile the C module, run `python2
klippy/chelper/__init__.py`.
## Compiling python code
Many distributions have a policy of compiling all python code before packaging
to improve startup time. You can do this by running `python2 -m compileall
klippy`.
## Versioning
If you are building a package of Klipper from git, it is usual practice not to
ship a .git directory, so the versioning must be handled without git. To do
this, use the script shipped in `scripts/make_version.py` which should be run as
follows: `python2 scripts/make_version.py YOURDISTRONAME > klippy/.version`.
## Sample packaging script
klipper-git is packaged for Arch Linux, and has a PKGBUILD (package build
script) available at [Arch User Repositiory](https://aur.archlinux.org/cgit/aur.git/tree/PKGBUILD?h=klipper-git).

147
docs/Pressure_Advance.md Normal file
View File

@@ -0,0 +1,147 @@
# Pressure advance
This document provides information on tuning the "pressure advance"
configuration variable for a particular nozzle and filament. The
pressure advance feature can be helpful in reducing ooze. For more
information on how pressure advance is implemented see the
[kinematics](Kinematics.md) document.
## Tuning pressure advance
Pressure advance does two useful things - it reduces ooze during
non-extrude moves and it reduces blobbing during cornering. This guide
uses the second feature (reducing blobbing during cornering) as a
mechanism for tuning.
In order to calibrate pressure advance the printer must be configured
and operational as the tuning test involves printing and inspecting a
test object. It is a good idea to read this document in full prior to
running the test.
Use a slicer to generate g-code for the large hollow square found in
[docs/prints/square_tower.stl](prints/square_tower.stl). Use a high
speed (eg, 100mm/s), zero infill, and a coarse layer height (the layer
height should be around 75% of the nozzle diameter). Make sure any
"dynamic acceleration control" is disabled in the slicer.
Prepare for the test by issuing the following G-Code command:
```
SET_VELOCITY_LIMIT SQUARE_CORNER_VELOCITY=1 ACCEL=500
```
This command makes the nozzle travel slower through corners to
emphasize the effects of extruder pressure. Then for printers with a
direct drive extruder run the command:
```
TUNING_TOWER COMMAND=SET_PRESSURE_ADVANCE PARAMETER=ADVANCE START=0 FACTOR=.005
```
For long bowden extruders use:
```
TUNING_TOWER COMMAND=SET_PRESSURE_ADVANCE PARAMETER=ADVANCE START=0 FACTOR=.020
```
Then print the object. When fully printed the test print looks like:
![tuning_tower](img/tuning_tower.jpg)
The above TUNING_TOWER command instructs Klipper to alter the
pressure_advance setting on each layer of the print. Higher layers in
the print will have a larger pressure advance value set. Layers below
the ideal pressure_advance setting will have blobbing at the corners,
and layers above the ideal setting can lead to rounded corners and
poor extrusion leading up to the corner.
One can cancel the print early if one observes that the corners are no
longer printing well (and thus one can avoid printing layers that are
known to be above the ideal pressure_advance value).
Inspect the print and then use a digital calipers to find the height
that has the best quality corners. When in doubt, prefer a lower
height.
![tune_pa](img/tune_pa.jpg)
The pressure_advance value can then be calculated as `pressure_advance
= <start> + <measured_height> * <factor>`. (For example, `0 + 12.90 *
.020` would be `.258`.)
It is possible to choose custom settings for START and FACTOR if that
helps identify the best pressure advance setting. When doing this, be
sure to issue the TUNING_TOWER command at the start of each test
print.
Typical pressure advance values are between 0.050 and 1.000 (the high
end usually only with bowden extruders). If there is no significant
improvement with a pressure advance up to 1.000, then pressure advance
is unlikely to improve the quality of prints. Return to a default
configuration with pressure advance disabled.
Although this tuning exercise directly improves the quality of
corners, it's worth remembering that a good pressure advance
configuration also reduces ooze throughout the print.
At the completion of this test, set
`pressure_advance = <calculated_value>` in the `[extruder]` section of
the configuration file and issue a RESTART command. The RESTART
command will clear the test state and return the acceleration and
cornering speeds to their normal values.
## Important Notes
* The pressure advance value is dependent on the extruder, the nozzle,
and the filament. It is common for filament from different
manufactures or with different pigments to require significantly
different pressure advance values. Therefore, one should calibrate
pressure advance on each printer and with each spool of filament.
* Printing temperature and extrusion rates can impact pressure
advance. Be sure to tune the
[extruder rotation_distance](Rotation_Distance.md#calibrating-rotation_distance-on-extruders)
and
[nozzle temperature](http://reprap.org/wiki/Triffid_Hunter%27s_Calibration_Guide#Nozzle_Temperature)
prior to tuning pressure advance.
* The test print is designed to run with a high extruder flow rate,
but otherwise "normal" slicer settings. A high flow rate is obtained
by using a high printing speed (eg, 100mm/s) and a coarse layer
height (typically around 75% of the nozzle diameter). Other slicer
settings should be similar to their defaults (eg, perimeters of 2 or
3 lines, normal retraction amount). It can be useful to set the
external perimeter speed to be the same speed as the rest of the
print, but it is not a requirement.
* It is common for the test print to show different behavior on each
corner. Often the slicer will arrange to change layers at one corner
which can result in that corner being significantly different from
the remaining three corners. If this occurs, then ignore that corner
and tune pressure advance using the other three corners. It is also
common for the remaining corners to vary slightly. (This can occur
due to small differences in how the printer's frame reacts to
cornering in certain directions.) Try to choose a value that works
well for all the remaining corners. If in doubt, prefer a lower
pressure advance value.
* If a high pressure advance value (eg, over 0.200) is used then one
may find that the extruder skips when returning to the printer's
normal acceleration. The pressure advance system accounts for
pressure by pushing in extra filament during acceleration and
retracting that filament during deceleration. With a high
acceleration and high pressure advance the extruder may not have
enough torque to push the required filament. If this occurs, either
use a lower acceleration value or disable pressure advance.
* Once pressure advance is tuned in Klipper, it may still be useful to
configure a small retract value in the slicer (eg, 0.75mm) and to
utilize the slicer's "wipe on retract option" if available. These
slicer settings may help counteract ooze caused by filament cohesion
(filament pulled out of the nozzle due to the stickiness of the
plastic). It is recommended to disable the slicer's "z-lift on
retract" option.
* The pressure advance system does not change the timing or path of
the toolhead. A print with pressure advance enabled will take the
same amount of time as a print without pressure advance. Pressure
advance also does not change the total amount of filament extruded
during a print. Pressure advance results in extra extruder movement
during move acceleration and deceleration. A very high pressure
advance setting will result in a very large amount of extruder
movement during acceleration and deceleration, and no configuration
setting places a limit on the amount of that movement.

203
docs/Probe_Calibrate.md Normal file
View File

@@ -0,0 +1,203 @@
# Probe calibration
This document describes the method for calibrating the X, Y, and Z
offsets of an "automatic z probe" in Klipper. This is useful for users
that have a `[probe]` or `[bltouch]` section in their config file.
## Calibrating probe X and Y offsets
To calibrate the X and Y offset, navigate to the OctoPrint "Control"
tab, home the printer, and then use the OctoPrint jogging buttons to
move the head to a position near the center of the bed.
Place a piece of blue painters tape (or similar) on the bed underneath
the probe. Navigate to the OctoPrint "Terminal" tab and issue a PROBE
command:
```
PROBE
```
Place a mark on the tape directly under where the probe is (or use a
similar method to note the location on the bed).
Issue a `GET_POSITION` command and record the toolhead XY location
reported by that command. For example if one sees:
```
Recv: // toolhead: X:46.500000 Y:27.000000 Z:15.000000 E:0.000000
```
then one would record a probe X position of 46.5 and probe Y position
of 27.
After recording the probe position, issue a series of G1 commands
until the nozzle is directly above the mark on the bed. For example,
one might issue:
```
G1 F300 X57 Y30 Z15
```
to move the nozzle to an X position of 57 and Y of 30. Once one finds
the position directly above the mark, use the `GET_POSITION` command
to report that position. This is the nozzle position.
The x_offset is then the `nozzle_x_position - probe_x_position` and
y_offset is similarly the `nozzle_y_position - probe_y_position`.
Update the printer.cfg file with the given values, remove the
tape/marks from the bed, and then issue a `RESTART` command so that
the new values take effect.
## Calibrating probe Z offset
Providing an accurate probe z_offset is critical to obtaining high
quality prints. The z_offset is the distance between the nozzle and
bed when the probe triggers. The Klipper `PROBE_CALIBRATE` tool can be
used to obtain this value - it will run an automatic probe to measure
the probe's Z trigger position and then start a manual probe to obtain
the nozzle Z height. The probe z_offset will then be calculated from
these measurements.
Start by homing the printer and then move the head to a position near
the center of the bed. Navigate to the OctoPrint terminal tab and run
the `PROBE_CALIBRATE` command to start the tool.
This tool will perform an automatic probe, then lift the head, move
the nozzle over the location of the probe point, and start the manual
probe tool. If the nozzle does not move to a position above the
automatic probe point, then `ABORT` the manual probe tool and perform
the XY probe offset calibration described above.
Once the manual probe tool starts, follow the steps described at
["the paper test"](Bed_Level.md#the-paper-test)) to determine the
actual distance between the nozzle and bed at the given location. Once
those steps are complete one can `ACCEPT` the position and save the
results to the config file with:
```
SAVE_CONFIG
```
Note that if a change is made to the printer's motion system, hotend
position, or probe location then it will invalidate the results of
PROBE_CALIBRATE.
If the probe has an X or Y offset and the bed tilt is changed (eg, by
adjusting bed screws, running DELTA_CALIBRATE, running Z_TILT_ADJUST,
running QUAD_GANTRY_LEVEL, or similar) then it will invalidate the
results of PROBE_CALIBRATE. After making any of the above adjustments
it will be necessary to run PROBE_CALIBRATE again.
If the results of PROBE_CALIBRATE are invalidated, then any previous
[bed mesh](Bed_Mesh.md) results that were obtained using the probe are
also invalidated - it will be necessary to rerun BED_MESH_CALIBRATE
after recalibrating the probe.
## Repeatability check
After calibrating the probe X, Y, and Z offsets it is a good idea to
verify that the probe provides repeatable results. Start by homing the
printer and then move the head to a position near the center of the
bed. Navigate to the OctoPrint terminal tab and run the
`PROBE_ACCURACY` command.
This command will run the probe ten times and produce output similar
to the following:
```
Recv: // probe accuracy: at X:0.000 Y:0.000 Z:10.000
Recv: // and read 10 times with speed of 5 mm/s
Recv: // probe at -0.003,0.005 is z=2.506948
Recv: // probe at -0.003,0.005 is z=2.519448
Recv: // probe at -0.003,0.005 is z=2.519448
Recv: // probe at -0.003,0.005 is z=2.506948
Recv: // probe at -0.003,0.005 is z=2.519448
Recv: // probe at -0.003,0.005 is z=2.519448
Recv: // probe at -0.003,0.005 is z=2.506948
Recv: // probe at -0.003,0.005 is z=2.506948
Recv: // probe at -0.003,0.005 is z=2.519448
Recv: // probe at -0.003,0.005 is z=2.506948
Recv: // probe accuracy results: maximum 2.519448, minimum 2.506948, range 0.012500, average 2.513198, median 2.513198, standard deviation 0.006250
```
Ideally the tool will report an identical maximum and minimum value.
(That is, ideally the probe obtains an identical result on all ten
probes.) However, it's normal for the minimum and maximum values to
differ by one Z "step distance" or up to 5 microns (.005mm). A "step
distance" is
`rotation_distance/(full_steps_per_rotation*microsteps)`. The distance
between the minimum and the maximum value is called the range. So, in
the above example, since the printer uses a Z step distance of .0125,
a range of 0.012500 would be considered normal.
If the results of the test show a range value that is greater than 25
microns (.025mm) then the probe does not have sufficient accuracy for
typical bed leveling procedures. It may be possible to tune the probe
speed and/or probe start height to improve the repeatability of the
probe. The `PROBE_ACCURACY` command allows one to run tests with
different parameters to see their impact - see the
[G-Codes document](G-Codes.md#probe_accuracy) for further details. If
the probe generally obtains repeatable results but has an occasional
outlier, then it may be possible to account for that by using multiple
samples on each probe - read the description of the probe `samples`
config parameters in the [config reference](Config_Reference.md#probe)
for more details.
If new probe speed, samples count, or other settings are needed, then
update the printer.cfg file and issue a `RESTART` command. If so, it
is a good idea to
[calibrate the z_offset](#calibrating-probe-z-offset) again. If
repeatable results can not be obtained then don't use the probe for
bed leveling. Klipper has several manual probing tools that can be
used instead - see the [Bed Level document](Bed_Level.md) for further
details.
## Location Bias Check
Some probes can have a systemic bias that corrupts the results of the
probe at certain toolhead locations. For example, if the probe mount
tilts slightly when moving along the Y axis then it could result in
the probe reporting biased results at different Y positions.
This is a common issue with probes on delta printers, however it can
occur on all printers.
One can check for a location bias by using the `PROBE_CALIBRATE`
command to measuring the probe z_offset at various X and Y locations.
Ideally, the probe z_offset would be a constant value at every printer
location.
For delta printers, try measuring the z_offset at a position near the
A tower, at a position near the B tower, and at a position near the C
tower. For cartesian, corexy, and similar printers, try measuring the
z_offset at positions near the four corners of the bed.
Before starting this test, first calibrate the probe X, Y, and Z
offsets as described at the beginning of this document. Then home the
printer and navigate to the first XY position. Follow the steps at
[calibrating probe Z offset](#calibrating-probe-z-offset) to run the
`PROBE_CALIBRATE` command, `TESTZ` commands, and `ACCEPT` command, but
do not run `SAVE_CONFIG`. Note the reported z_offset found. Then
navigate to the other XY positions, repeat these `PROBE_CALIBRATE`
steps, and note the reported z_offset.
If the difference between the minimum reported z_offset and the
maximum reported z_offset is greater than 25 microns (.025mm) then the
probe is not suitable for typical bed leveling procedures. See the
[Bed Level document](Bed_Level.md) for manual probe alternatives.
## Temperature Bias
Many probes have a systemic bias when probing at different
temperatures. For example, the probe may consistently trigger at a
lower height when the probe is at a higher temperature.
It is recommended to run the bed leveling tools at a consistent
temperature to account for this bias. For example, either always run
the tools when the printer is at room temperature, or always run the
tools after the printer has obtained a consistent print temperature.
In either case, it is a good idea to wait several minutes after the
desired temperature is reached, so that the printer apparatus is
consistently at the desired temperature.
To check for a temperature bias, start with the printer at room
temperature and then home the printer, move the head to a position
near the center of the bed, and run the `PROBE_ACCURACY` command. Note
the results. Then, without homing or disabling the stepper motors,
heat the printer nozzle and bed to printing temperature, and run the
`PROBE_ACCURACY` command again. Ideally, the command will report
identical results. As above, if the probe does have a temperature bias
then be careful to always use the probe at a consistent temperature.

350
docs/Protocol.md Normal file
View File

@@ -0,0 +1,350 @@
# Protocol
The Klipper messaging protocol is used for low-level communication
between the Klipper host software and the Klipper micro-controller
software. At a high level the protocol can be thought of as a series
of command and response strings that are compressed, transmitted, and
then processed at the receiving side. An example series of commands in
uncompressed human-readable format might look like:
```
set_digital_out pin=PA3 value=1
set_digital_out pin=PA7 value=1
schedule_digital_out oid=8 clock=4000000 value=0
queue_step oid=7 interval=7458 count=10 add=331
queue_step oid=7 interval=11717 count=4 add=1281
```
See the [mcu commands](MCU_Commands.md) document for information on
available commands. See the [debugging](Debugging.md) document for
information on how to translate a G-Code file into its corresponding
human-readable micro-controller commands.
This page provides a high-level description of the Klipper messaging
protocol itself. It describes how messages are declared, encoded in
binary format (the "compression" scheme), and transmitted.
The goal of the protocol is to enable an error-free communication
channel between the host and micro-controller that is low-latency,
low-bandwidth, and low-complexity for the micro-controller.
## Micro-controller Interface
The Klipper transmission protocol can be thought of as a
[RPC](https://en.wikipedia.org/wiki/Remote_procedure_call) mechanism
between micro-controller and host. The micro-controller software
declares the commands that the host may invoke along with the response
messages that it can generate. The host uses that information to
command the micro-controller to perform actions and to interpret the
results.
### Declaring commands
The micro-controller software declares a "command" by using the
DECL_COMMAND() macro in the C code. For example:
```
DECL_COMMAND(command_update_digital_out, "update_digital_out oid=%c value=%c");
```
The above declares a command named "update_digital_out". This allows
the host to "invoke" this command which would cause the
command_update_digital_out() C function to be executed in the
micro-controller. The above also indicates that the command takes two
integer parameters. When the command_update_digital_out() C code is
executed, it will be passed an array containing these two integers -
the first corresponding to the 'oid' and the second corresponding to
the 'value'.
In general, the parameters are described with printf() style syntax
(eg, "%u"). The formatting directly corresponds to the human-readable
view of commands (eg, "update_digital_out oid=7 value=1"). In the
above example, "value=" is a parameter name and "%c" indicates the
parameter is an integer. Internally, the parameter name is only used
as documentation. In this example, the "%c" is also used as
documentation to indicate the expected integer is 1 byte in size (the
declared integer size does not impact the parsing or encoding).
The micro-controller build will collect all commands declared with
DECL_COMMAND(), determine their parameters, and arrange for them to be
callable.
### Declaring responses
To send information from the micro-controller to the host a "response"
is generated. These are both declared and transmitted using the
sendf() C macro. For example:
```
sendf("status clock=%u status=%c", sched_read_time(), sched_is_shutdown());
```
The above transmits a "status" response message that contains two
integer parameters ("clock" and "status"). The micro-controller build
automatically finds all sendf() calls and generates encoders for
them. The first parameter of the sendf() function describes the
response and it is in the same format as command declarations.
The host can arrange to register a callback function for each
response. So, in effect, commands allow the host to invoke C functions
in the micro-controller and responses allow the micro-controller
software to invoke code in the host.
The sendf() macro should only be invoked from command or task
handlers, and it should not be invoked from interrupts or timers. The
code does not need to issue a sendf() in response to a received
command, it is not limited in the number of times sendf() may be
invoked, and it may invoke sendf() at any time from a task handler.
#### Output responses
To simplify debugging, there is also an output() C function. For
example:
```
output("The value of %u is %s with size %u.", x, buf, buf_len);
```
The output() function is similar in usage to printf() - it is intended
to generate and format arbitrary messages for human consumption.
### Declaring enumerations
Enumerations allow the host code to use string identifiers for
parameters that the micro-controller handles as integers. They are
declared in the micro-controller code - for example:
```
DECL_ENUMERATION("spi_bus", "spi", 0);
DECL_ENUMERATION_RANGE("pin", "PC0", 16, 8);
```
If the first example, the DECL_ENUMERATION() macro defines an
enumeration for any command/response message with a parameter name of
"spi_bus" or parameter name with a suffix of "_spi_bus". For those
parameters the string "spi" is a valid value and it will be
transmitted with an integer value of zero.
It's also possible to declare an enumeration range. In the second
example, a "pin" parameter (or any parameter with a suffix of "_pin")
would accept PC0, PC1, PC2, ..., PC7 as valid values. The strings will
be transmitted with integers 16, 17, 18, ..., 23.
### Declaring constants
Constants can also be exported. For example, the following:
```
DECL_CONSTANT("SERIAL_BAUD", 250000);
```
would export a constant named "SERIAL_BAUD" with a value of 250000
from the micro-controller to the host. It is also possible to declare
a constant that is a string - for example:
```
DECL_CONSTANT_STR("MCU", "pru");
```
## Low-level message encoding
To accomplish the above RPC mechanism, each command and response is
encoded into a binary format for transmission. This section describes
the transmission system.
### Message Blocks
All data sent from host to micro-controller and vice-versa are
contained in "message blocks". A message block has a two byte header
and a three byte trailer. The format of a message block is:
```
<1 byte length><1 byte sequence><n-byte content><2 byte crc><1 byte sync>
```
The length byte contains the number of bytes in the message block
including the header and trailer bytes (thus the minimum message
length is 5 bytes). The maximum message block length is currently 64
bytes. The sequence byte contains a 4 bit sequence number in the
low-order bits and the high-order bits always contain 0x10 (the
high-order bits are reserved for future use). The content bytes
contain arbitrary data and its format is described in the following
section. The crc bytes contain a 16bit CCITT
[CRC](https://en.wikipedia.org/wiki/Cyclic_redundancy_check) of the
message block including the header bytes but excluding the trailer
bytes. The sync byte is 0x7e.
The format of the message block is inspired by
[HDLC](https://en.wikipedia.org/wiki/High-Level_Data_Link_Control)
message frames. Like in HDLC, the message block may optionally contain
an additional sync character at the start of the block. Unlike in
HDLC, a sync character is not exclusive to the framing and may be
present in the message block content.
### Message Block Contents
Each message block sent from host to micro-controller contains a
series of zero or more message commands in its contents. Each command
starts with a [Variable Length Quantity](#variable-length-quantities)
(VLQ) encoded integer command-id followed by zero or more VLQ
parameters for the given command.
As an example, the following four commands might be placed in a single
message block:
```
update_digital_out oid=6 value=1
update_digital_out oid=5 value=0
get_config
get_clock
```
and encoded into the following eight VLQ integers:
```
<id_update_digital_out><6><1><id_update_digital_out><5><0><id_get_config><id_get_clock>
```
In order to encode and parse the message contents, both the host and
micro-controller must agree on the command ids and the number of
parameters each command has. So, in the above example, both the host
and micro-controller would know that "id_update_digital_out" is always
followed by two parameters, and "id_get_config" and "id_get_clock"
have zero parameters. The host and micro-controller share a "data
dictionary" that maps the command descriptions (eg,
"update_digital_out oid=%c value=%c") to their integer
command-ids. When processing the data, the parser will know to expect
a specific number of VLQ encoded parameters following a given command
id.
The message contents for blocks sent from micro-controller to host
follow the same format. The identifiers in these messages are
"response ids", but they serve the same purpose and follow the same
encoding rules. In practice, message blocks sent from the
micro-controller to the host never contain more than one response in
the message block contents.
#### Variable Length Quantities
See the [wikipedia article](https://en.wikipedia.org/wiki/Variable-length_quantity)
for more information on the general format of VLQ encoded
integers. Klipper uses an encoding scheme that supports both positive
and negative integers. Integers close to zero use less bytes to encode
and positive integers typically encode using less bytes than negative
integers. The following table shows the number of bytes each integer
takes to encode:
| Integer | Encoded size |
|---------------------------|--------------|
| -32 .. 95 | 1 |
| -4096 .. 12287 | 2 |
| -524288 .. 1572863 | 3 |
| -67108864 .. 201326591 | 4 |
| -2147483648 .. 4294967295 | 5 |
#### Variable length strings
As an exception to the above encoding rules, if a parameter to a
command or response is a dynamic string then the parameter is not
encoded as a simple VLQ integer. Instead it is encoded by transmitting
the length as a VLQ encoded integer followed by the contents itself:
```
<VLQ encoded length><n-byte contents>
```
The command descriptions found in the data dictionary allow both the
host and micro-controller to know which command parameters use simple
VLQ encoding and which parameters use string encoding.
## Data Dictionary
In order for meaningful communications to be established between
micro-controller and host, both sides must agree on a "data
dictionary". This data dictionary contains the integer identifiers for
commands and responses along with their descriptions.
The micro-controller build uses the contents of DECL_COMMAND() and
sendf() macros to generate the data dictionary. The build
automatically assigns unique identifiers to each command and
response. This system allows both the host and micro-controller code
to seamlessly use descriptive human-readable names while still using
minimal bandwidth.
The host queries the data dictionary when it first connects to the
micro-controller. Once the host downloads the data dictionary from the
micro-controller, it uses that data dictionary to encode all commands
and to parse all responses from the micro-controller. The host must
therefore handle a dynamic data dictionary. However, to keep the
micro-controller software simple, the micro-controller always uses its
static (compiled in) data dictionary.
The data dictionary is queried by sending "identify" commands to the
micro-controller. The micro-controller will respond to each identify
command with an "identify_response" message. Since these two commands
are needed prior to obtaining the data dictionary, their integer ids
and parameter types are hard-coded in both the micro-controller and
the host. The "identify_response" response id is 0, the "identify"
command id is 1. Other than having hard-coded ids the identify command
and its response are declared and transmitted the same way as other
commands and responses. No other command or response is hard-coded.
The format of the transmitted data dictionary itself is a zlib
compressed JSON string. The micro-controller build process generates
the string, compresses it, and stores it in the text section of the
micro-controller flash. The data dictionary can be much larger than
the maximum message block size - the host downloads it by sending
multiple identify commands requesting progressive chunks of the data
dictionary. Once all chunks are obtained the host will assemble the
chunks, uncompress the data, and parse the contents.
In addition to information on the communication protocol, the data
dictionary also contains the software version, enumerations (as
defined by DECL_ENUMERATION), and constants (as defined by
DECL_CONSTANT).
## Message flow
Message commands sent from host to micro-controller are intended to be
error-free. The micro-controller will check the CRC and sequence
numbers in each message block to ensure the commands are accurate and
in-order. The micro-controller always processes message blocks
in-order - should it receive a block out-of-order it will discard it
and any other out-of-order blocks until it receives blocks with the
correct sequencing.
The low-level host code implements an automatic retransmission system
for lost and corrupt message blocks sent to the micro-controller. To
facilitate this, the micro-controller transmits an "ack message block"
after each successfully received message block. The host schedules a
timeout after sending each block and it will retransmit should the
timeout expire without receiving a corresponding "ack". In addition,
if the micro-controller detects a corrupt or out-of-order block it may
transmit a "nak message block" to facilitate fast retransmission.
An "ack" is a message block with empty content (ie, a 5 byte message
block) and a sequence number greater than the last received host
sequence number. A "nak" is a message block with empty content and a
sequence number less than the last received host sequence number.
The protocol facilitates a "window" transmission system so that the
host can have many outstanding message blocks in-flight at a
time. (This is in addition to the many commands that may be present in
a given message block.) This allows maximum bandwidth utilization even
in the event of transmission latency. The timeout, retransmit,
windowing, and ack mechanism are inspired by similar mechanisms in
[TCP](https://en.wikipedia.org/wiki/Transmission_Control_Protocol).
In the other direction, message blocks sent from micro-controller to
host are designed to be error-free, but they do not have assured
transmission. (Responses should not be corrupt, but they may go
missing.) This is done to keep the implementation in the
micro-controller simple. There is no automatic retransmission system
for responses - the high-level code is expected to be capable of
handling an occasional missing response (usually by re-requesting the
content or setting up a recurring schedule of response
transmission). The sequence number field in message blocks sent to the
host is always one greater than the last received sequence number of
message blocks received from the host. It is not used to track
sequences of response message blocks.

2
docs/README.md Normal file
View File

@@ -0,0 +1,2 @@
Welcome to the Klipper documentation. The
[overview document](Overview.md) is a good starting point.

234
docs/RPi_microcontroller.md Normal file
View File

@@ -0,0 +1,234 @@
# RPi microcontroller
This document describes the process of running Klipper on a RPi and
use the same RPi as secondary mcu.
## Why use RPi as a secondary MCU?
Often the MCUs dedicated to controlling 3D printers have a limited and
pre-configured number of exposed pins to manage the main printing
functions (thermal resistors, extruders, steppers ...). Using the RPi
where Klipper is installed as a secondary MCU gives the possibility to
directly use the GPIOs and the buses (i2c, spi) of the RPi inside
klipper without using Octoprint plugins (if used) or external programs
giving the ability to control everything within the print GCODE.
**Warning**: If your platform is a _Beaglebone_ and you have correctly
followed the installation steps, the linux mcu is already installed
and configured for your system.
## Install the rc script
If you want to use the host as a secondary MCU the klipper_mcu process
must run before the klippy process.
After installing Klipper, install the script. run:
```
cd ~/klipper/
sudo cp "./scripts/klipper-mcu-start.sh" /etc/init.d/klipper_mcu
sudo update-rc.d klipper_mcu defaults
```
## Building the micro-controller code
To compile the Klipper micro-controller code, start by configuring it
for the "Linux process":
```
cd ~/klipper/
make menuconfig
```
In the menu, set "Microcontroller Architecture" to "Linux process,"
then save and exit.
To build and install the new micro-controller code, run:
```
sudo service klipper stop
make flash
sudo service klipper start
```
If klippy.log reports a "Permission denied" error when attempting to
connect to `/tmp/klipper_host_mcu` then you need to add your user to
the tty group. The following command will add the "pi" user to the
tty group:
```
sudo usermod -a -G tty pi
```
## Remaining configuration
Complete the installation by configuring Klipper secondary MCU
following the instructions in
[RaspberryPi sample config](../config/sample-raspberry-pi.cfg) and
[Multi MCU sample config](../config/sample-multi-mcu.cfg).
## Optional: Enabling SPI
Make sure the Linux SPI driver is enabled by running
`sudo raspi-config` and enabling SPI under the "Interfacing options"
menu.
## Optional: Enabling I2C
Make sure the Linux I2C driver is enabled by running `sudo raspi-config`
and enabling I2C under the "Interfacing options" menu.
If planning to use I2C for the MPU accelerometer, it is also required
to set the baud rate to 400000 by: adding/uncommenting
`dtparam=i2c_arm=on,i2c_arm_baudrate=400000` in `/boot/config.txt`
(or `/boot/firmware/config.txt` in some distros).
## Optional: Identify the correct gpiochip
On Raspberry Pi and on many clones the pins exposed on the GPIO belong
to the first gpiochip. They can therefore be used on klipper simply by
referring them with the name `gpio0..n`. However, there are cases in
which the exposed pins belong to gpiochips other than the first. For
example in the case of some OrangePi models or if a Port Expander is
used. In these cases it is useful to use the commands to access the
_Linux GPIO character device_ to verify the configuration.
To install the _Linux GPIO character device - binary_ on a debian
based distro like octopi run:
```
sudo apt-get install gpiod
```
To check available gpiochip run:
```
gpiodetect
```
To check the pin number and the pin availability tun:
```
gpioinfo
```
The chosen pin can thus be used within the configuration as
`gpiochip<n>/gpio<o>` where **n** is the chip number as seen by the
`gpiodetect` command and **o** is the line number seen by the`
gpioinfo` command.
***Warning:*** only gpio marked as `unused` can be used. It is not
possible for a _line_ to be used by multiple processes simultaneously.
For example on a RPi 3B+ where klipper use the GPIO20 for a switch:
```
$ gpiodetect
gpiochip0 [pinctrl-bcm2835] (54 lines)
gpiochip1 [raspberrypi-exp-gpio] (8 lines)
$ gpioinfo
gpiochip0 - 54 lines:
line 0: unnamed unused input active-high
line 1: unnamed unused input active-high
line 2: unnamed unused input active-high
line 3: unnamed unused input active-high
line 4: unnamed unused input active-high
line 5: unnamed unused input active-high
line 6: unnamed unused input active-high
line 7: unnamed unused input active-high
line 8: unnamed unused input active-high
line 9: unnamed unused input active-high
line 10: unnamed unused input active-high
line 11: unnamed unused input active-high
line 12: unnamed unused input active-high
line 13: unnamed unused input active-high
line 14: unnamed unused input active-high
line 15: unnamed unused input active-high
line 16: unnamed unused input active-high
line 17: unnamed unused input active-high
line 18: unnamed unused input active-high
line 19: unnamed unused input active-high
line 20: unnamed "klipper" output active-high [used]
line 21: unnamed unused input active-high
line 22: unnamed unused input active-high
line 23: unnamed unused input active-high
line 24: unnamed unused input active-high
line 25: unnamed unused input active-high
line 26: unnamed unused input active-high
line 27: unnamed unused input active-high
line 28: unnamed unused input active-high
line 29: unnamed "led0" output active-high [used]
line 30: unnamed unused input active-high
line 31: unnamed unused input active-high
line 32: unnamed unused input active-high
line 33: unnamed unused input active-high
line 34: unnamed unused input active-high
line 35: unnamed unused input active-high
line 36: unnamed unused input active-high
line 37: unnamed unused input active-high
line 38: unnamed unused input active-high
line 39: unnamed unused input active-high
line 40: unnamed unused input active-high
line 41: unnamed unused input active-high
line 42: unnamed unused input active-high
line 43: unnamed unused input active-high
line 44: unnamed unused input active-high
line 45: unnamed unused input active-high
line 46: unnamed unused input active-high
line 47: unnamed unused input active-high
line 48: unnamed unused input active-high
line 49: unnamed unused input active-high
line 50: unnamed unused input active-high
line 51: unnamed unused input active-high
line 52: unnamed unused input active-high
line 53: unnamed unused input active-high
gpiochip1 - 8 lines:
line 0: unnamed unused input active-high
line 1: unnamed unused input active-high
line 2: unnamed "led1" output active-low [used]
line 3: unnamed unused input active-high
line 4: unnamed unused input active-high
line 5: unnamed unused input active-high
line 6: unnamed unused input active-high
line 7: unnamed unused input active-high
```
## Optional: Hardware PWM
Raspberry Pi's have two PWM channels (PWM0 and PWM1) which are exposed
on the header or if not, can be routed to existing gpio pins. The
Linux mcu daemon uses the pwmchip sysfs interface to control hardware
pwm devices on Linux hosts. The pwm sysfs interface is not exposed by
default on a Raspberry and can be activated by adding a line to
`/boot/config.txt`:
```
# Enable pwmchip sysfs interface
dtoverlay=pwm,pin=12,func=4
```
This example enables only PWM0 and routes it to gpio12. If both PWM
channels need to be enabled you can use `pwm-2chan`.
The overlay does not expose the pwm line on sysfs on boot and needs to
be exported by echo'ing the number of the pwm channel to
`/sys/class/pwm/pwmchip0/export`:
```
echo 0 > /sys/class/pwm/pwmchip0/export
```
This will create device `/sys/class/pwm/pwmchip0/pwm0` in the
filesystem. The easiest way to do this is by adding this to
`/etc/rc.local` before the `exit 0` line.
With the sysfs in place, you can now use either the pwm channel(s) by
adding the following piece of configuration to your `printer.cfg`:
```
[output_pin caselight]
pin: host:pwmchip0/pwm0
pwm: True
hardware_pwm: True
cycle_time: 0.000001
```
This will add hardware pwm control to gpio12 on the Pi (because the
overlay was configured to route pwm0 to pin=12).
PWM0 can be routed to gpio12 and gpio18, PWM1 can be routed to gpio13
and gpio19:
| PWM | gpio PIN | Func |
| --- | -------- | ---- |
| 0 | 12 | 4 |
| 0 | 18 | 2 |
| 1 | 13 | 4 |
| 1 | 19 | 2 |

248
docs/Releases.md Normal file
View File

@@ -0,0 +1,248 @@
# Releases
History of Klipper releases. Please see
[installation](Installation.md) for information on installing Klipper.
## Klipper 0.10.0
Available on 20210929. Major changes in this release:
* Support for "Multi-MCU Homing". It is now possible for a stepper
motor and its endstop to be wired to separate micro-controllers.
This simplifies wiring of Z probes on "toolhead boards".
* Klipper now has a
[Community Discord Server](https://discord.klipper3d.org)
and a [Community Discourse Server](https://community.klipper3d.org).
* The [Klipper website](https://www.klipper3d.org) now uses the
"mkdocs" infrastructure. There is also a
[Klipper Translations](https://github.com/Klipper3d/klipper-translations)
project.
* Automated support for flashing firmware via sdcard on many boards.
* New kinematic support for "Hybrid CoreXY" and "Hybrid CoreXZ"
printers.
* Klipper now uses `rotation_distance` to configure stepper motor
travel distances.
* The main Klipper host code can now directly communicate with
micro-controllers using CAN bus.
* New "motion analysis" system. Klipper's internal motion updates and
sensor results can be tracked and logged for analysis.
* Trinamic stepper motor drivers are now continuously monitored for
error conditions.
* Support for the rp2040 micro-controller (Raspberry Pi Pico boards).
* The "make menuconfig" system now utilizes kconfiglib.
* Many additional modules added: ds18b20, duplicate_pin_override,
filament_motion_sensor, palette2, motion_report, pca9533,
pulse_counter, save_variables, sdcard_loop, temperature_host,
temperature_mcu
* Several bug fixes and code cleanups.
## Klipper 0.9.0
Available on 20201020. Major changes in this release:
* Support for "Input Shaping" - a mechanism to counteract printer
resonance. It can reduce or eliminate "ringing" in prints.
* New "Smooth Pressure Advance" system. This implements "Pressure
Advance" without introducing instantaneous velocity changes. It is
also now possible to tune pressure advance using a "Tuning Tower"
method.
* New "webhooks" API server. This provides a programmable JSON
interface to Klipper.
* The LCD display and menu are now configurable using the Jinja2
template language.
* The TMC2208 stepper motor drivers can now be used in "standalone"
mode with Klipper.
* Improved BL-Touch v3 support.
* Improved USB identification. Klipper now has its own USB
identification code and micro-controllers can now report their
unique serial numbers during USB identification.
* New kinematic support for "Rotary Delta" and "CoreXZ" printers.
* Micro-controller improvements: support for stm32f070, support for
stm32f207, support for GPIO pins on "Linux MCU", stm32 "HID
bootloader" support, Chitu bootloader support, MKS Robin bootloader
support.
* Improved handling of Python "garbage collection" events.
* Many additional modules added: adc_scaled, adxl345, bme280,
display_status, extruder_stepper, fan_generic,
hall_filament_width_sensor, htu21d, homing_heaters, input_shaper,
lm75, print_stats, resonance_tester, shaper_calibrate, query_adc,
graph_accelerometer, graph_extruder, graph_motion, graph_shaper,
graph_temp_sensor, whconsole
* Several bug fixes and code cleanups.
### Klipper 0.9.1
Available on 20201028. Release containing only bug fixes.
## Klipper 0.8.0
Available on 20191021. Major changes in this release:
* New G-Code command template support. G-Code in the config file is
now evaluated with the Jinja2 template language.
* Improvements to Trinamic stepper drivers:
* New support for TMC2209 and TMC5160 drivers.
* Improved DUMP_TMC, SET_TMC_CURRENT, and INIT_TMC G-Code commands.
* Improved support for TMC UART handling with an analog mux.
* Improved homing, probing, and bed leveling support:
* New manual_probe, bed_screws, screws_tilt_adjust, skew_correction,
safe_z_home modules added.
* Enhanced multi-sample probing with median, average, and retry
logic.
* Improved documentation for BL-Touch, probe calibration, endstop
calibration, delta calibration, sensorless homing, and endstop
phase calibration.
* Improved homing support on a large Z axis.
* Many Klipper micro-controller improvements:
* Klipper ported to: SAM3X8C, SAM4S8C, SAMD51, STM32F042, STM32F4
* New USB CDC driver implementations on SAM3X, SAM4, STM32F4.
* Enhanced support for flashing Klipper over USB.
* Software SPI support.
* Greatly improved temperature filtering on the LPC176x.
* Early output pin settings can be configured in the
micro-controller.
* New website with the Klipper documentation: http://klipper3d.org/
* Klipper now has a logo.
* Experimental support for polar and "cable winch" kinematics.
* The config file can now include other config files.
* Many additional modules added: board_pins, controller_fan,
delayed_gcode, dotstar, filament_switch_sensor, firmware_retraction,
gcode_arcs, gcode_button, heater_generic, manual_stepper, mcp4018,
mcp4728, neopixel, pause_resume, respond, temperature_sensor
tsl1401cl_filament_width_sensor, tuning_tower
* Many additional commands added: RESTORE_GCODE_STATE,
SAVE_GCODE_STATE, SET_GCODE_VARIABLE, SET_HEATER_TEMPERATURE,
SET_IDLE_TIMEOUT, SET_TEMPERATURE_FAN_TARGET
* Several bug fixes and code cleanups.
## Klipper 0.7.0
Available on 20181220. Major changes in this release:
* Klipper now supports "mesh" bed leveling
* New support for "enhanced" delta calibration (calibrates print x/y
dimensions on delta printers)
* Support for run-time configuration of Trinamic stepper motor drivers
(tmc2130, tmc2208, tmc2660)
* Improved temperature sensor support: MAX6675, MAX31855, MAX31856,
MAX31865, custom thermistors, common pt100 style sensors
* Several new modules: temperature_fan, sx1509, force_move, mcp4451,
z_tilt, quad_gantry_level, endstop_phase, bltouch
* Several new commands added: SAVE_CONFIG, SET_PRESSURE_ADVANCE,
SET_GCODE_OFFSET, SET_VELOCITY_LIMIT, STEPPER_BUZZ, TURN_OFF_HEATERS,
M204, custom g-code macros
* Expanded LCD display support:
* Support for run-time menus
* New display icons
* Support for "uc1701" and "ssd1306" displays
* Additional micro-controller support:
* Klipper ported to: LPC176x (Smoothieboards), SAM4E8E (Duet2),
SAMD21 (Arduino Zero), STM32F103 ("Blue pill" devices), atmega32u4
* New Generic USB CDC driver implemented on AVR, LPC176x, SAMD21, and
STM32F103
* Performance improvements on ARM processors
* The kinematics code was rewritten to use an "iterative solver"
* New automatic test cases for the Klipper host software
* Many new example config files for common off-the-shelf printers
* Documentation updates for bootloaders, benchmarking,
micro-controller porting, config checks, pin mapping, slicer
settings, packaging, and more
* Several bug fixes and code cleanups
## Klipper 0.6.0
Available on 20180331. Major changes in this release:
* Enhanced heater and thermistor hardware failure checks
* Support for Z probes
* Initial support for automatic parameter calibration on deltas (via a
new delta_calibrate command)
* Initial support for bed tilt compensation (via bed_tilt_calibrate
command)
* Initial support for "safe homing" and homing overrides
* Initial support for displaying status on RepRapDiscount style 2004
and 12864 displays
* New multi-extruder improvements:
* Support for shared heaters
* Initial support for dual carriages
* Support for configuring multiple steppers per axis (eg, dual Z)
* Support for custom digital and pwm output pins (with a new SET_PIN command)
* Initial support for a "virtual sdcard" that allows printing directly
from Klipper (helps on machines too slow to run OctoPrint well)
* Support for setting different arm lengths on each tower of a delta
* Support for G-Code M220/M221 commands (speed factor override /
extrude factor override)
* Several documentation updates:
* Many new example config files for common off-the-shelf printers
* New multiple MCU config example
* New bltouch sensor config example
* New FAQ, config check, and G-Code documents
* Initial support for continuous integration testing on all github commits
* Several bug fixes and code cleanups
## Klipper 0.5.0
Available on 20171025. Major changes in this release:
* Support for printers with multiple extruders.
* Initial support for running on the Beaglebone PRU. Initial support
for the Replicape board.
* Initial support for running the micro-controller code in a real-time
Linux process.
* Support for multiple micro-controllers. (For example, one could
control an extruder with one micro-controller and the rest of the
printer with another.) Software clock synchronization is implemented
to coordinate actions between micro-controllers.
* Stepper performance improvements (20Mhz AVRs up to 189K steps per
second).
* Support for controlling servos and support for defining nozzle
cooling fans.
* Several bug fixes and code cleanups
## Klipper 0.4.0
Available on 20170503. Major changes in this release:
* Improved installation on Raspberry Pi machines. Most of the install
is now scripted.
* Support for corexy kinematics
* Documentation updates: New Kinematics document, new Pressure Advance
tuning guide, new example config files, and more
* Stepper performance improvements (20Mhz AVRs over 175K steps per
second, Arduino Due over 460K)
* Support for automatic micro-controller resets. Support for resets
via toggling USB power on Raspberry Pi.
* The pressure advance algorithm now works with look-ahead to reduce
pressure changes during cornering.
* Support for limiting the top speed of short zigzag moves
* Support for AD595 sensors
* Several bug fixes and code cleanups
## Klipper 0.3.0
Available on 20161223. Major changes in this release:
* Improved documentation
* Support for robots with delta kinematics
* Support for Arduino Due micro-controller (ARM cortex-M3)
* Support for USB based AVR micro-controllers
* Support for "pressure advance" algorithm - it reduces ooze during
prints.
* New "stepper phased based endstop" feature - enables higher
precision on endstop homing.
* Support for "extended g-code" commands such as "help", "restart",
and "status".
* Support for reloading the Klipper config and restarting the host
software by issuing a "restart" command from the terminal.
* Stepper performance improvements (20Mhz AVRs up to 158K steps per
second).
* Improved error reporting. Most errors now shown via the terminal
along with help on how to resolve.
* Several bug fixes and code cleanups
## Klipper 0.2.0
Initial release of Klipper. Available on 20160525. Major features
available in the initial release include:
* Basic support for cartesian printers (steppers, extruder, heated
bed, cooling fan).
* Support for common g-code commands. Support for interfacing with
OctoPrint.
* Acceleration and lookahead handling
* Support for AVR micro-controllers via standard serial ports

View File

@@ -0,0 +1,499 @@
# Resonance Compensation
Klipper supports Input Shaping - a technique that can be used to reduce ringing
(also known as echoing, ghosting or rippling) in prints. Ringing is a surface
printing defect when, typically, elements like edges repeat themselves on a
printed surface as a subtle 'echo':
|![Ringing test](img/ringing-test.jpg)|![3D Benchy](img/ringing-3dbenchy.jpg)|
Ringing is caused by mechanical vibrations in the printer due to quick changes
of the printing direction. Note that ringing usually has mechanical origins:
insufficiently rigid printer frame, non-tight or too springy belts, alignment
issues of mechanical parts, heavy moving mass, etc. Those should be checked
and fixed first, if possible.
[Input shaping](https://en.wikipedia.org/wiki/Input_shaping) is an open-loop
control technique which creates a commanding signal that cancels its
own vibrations. Input shaping requires some tuning and measurements before it
can be enabled. Besides ringing, Input Shaping typically reduces the vibrations
and shaking of the printer in general, and may also improve the reliability
of the stealthChop mode of Trinamic stepper drivers.
## Tuning
Basic tuning requires measuring the ringing frequencies of the printer
by printing a test model.
Slice the ringing test model, which can be found in
[docs/prints/ringing_tower.stl](prints/ringing_tower.stl), in the slicer:
* Suggested layer height is 0.2 or 0.25 mm.
* Infill and top layers can be set to 0.
* Use 1-2 perimeters, or even better the smooth vase mode with 1-2 mm base.
* Use sufficiently high speed, around 80-100 mm/sec, for **external** perimeters.
* Make sure that the minimum layer time is **at most** 3 seconds.
* Make sure any "dynamic acceleration control" is disabled in the slicer.
* Do not turn the model. The model has X and Y marks at the back of the model.
Note the unusual location of the marks vs. the axes of the printer - it is
not a mistake. The marks can be used later in the tuning process as a
reference, because they show which axis the measurements correspond to.
### Ringing frequency
First, measure the **ringing frequency**.
1. If `square_corner_velocity` parameter was changed, revert it back
to 5.0. It is not advised to increase it when using input shaper
because it can cause more smoothing in parts - it is better to use
higher acceleration value instead.
2. Increase `max_accel_to_decel` by issuing the following command:
`SET_VELOCITY_LIMIT ACCEL_TO_DECEL=7000`
3. Disable Pressure Advance: `SET_PRESSURE_ADVANCE ADVANCE=0`
4. If you have already added `[input_shaper]` section to the printer.cfg,
execute `SET_INPUT_SHAPER SHAPER_FREQ_X=0 SHAPER_FREQ_Y=0` command. If you
get "Unknown command" error, you can safely ignore it at this point and
continue with the measurements.
5. Execute the command:
`TUNING_TOWER COMMAND=SET_VELOCITY_LIMIT PARAMETER=ACCEL START=1500 STEP_DELTA=500 STEP_HEIGHT=5`
Basically, we try to make ringing more pronounced by setting different large
values for acceleration. This command will increase the acceleration every
5 mm starting from 1500 mm/sec^2: 1500 mm/sec^2, 2000 mm/sec^2, 2500 mm/sec^2
and so forth up until 7000 mm/sec^2 at the last band.
6. Print the test model sliced with the suggested parameters.
7. You can stop the print earlier if the ringing is clearly visible and you see
that acceleration gets too high for your printer (e.g. printer shakes too
much or starts skipping steps).
8. Use X and Y marks at the back of the model for reference. The measurements
from the side with X mark should be used for X axis *configuration*, and
Y mark - for Y axis configuration. Measure the distance *D* (in mm) between
several oscillations on the part with X mark, near the notches, preferably
skipping the first oscillation or two. To measure the distance between
oscillations more easily, mark the oscillations first, then measure the
distance between the marks with a ruler or calipers:
|![Mark ringing](img/ringing-mark.jpg)|![Measure ringing](img/ringing-measure.jpg)|
9. Count how many oscillations *N* the measured distance *D* corresponds to.
If you are unsure how to count the oscillations, refer to the picture
above, which shows *N* = 6 oscillations.
10. Compute the ringing frequency of X axis as *V* &middot; *N* / *D* (Hz),
where *V* is the velocity for outer perimeters (mm/sec). For the example
above, we marked 6 oscillations, and the test was printed at 100 mm/sec
velocity, so the frequency is 100 * 6 / 12.14 ≈ 49.4 Hz.
11. Do (8) - (10) for Y mark as well.
Note that ringing on the test print should follow the pattern of the curved
notches, as in the picture above. If it doesn't, then this defect is not really
a ringing and has a different origin - either mechanical, or an extruder issue.
It should be fixed first before enabling and tuning input shapers.
If the measurements are not reliable because, say, the distance
between the oscillations is not stable, it might mean that the printer has
several resonance frequencies on the same axis. One may try to follow the
tuning process described in
[Unreliable measurements of ringing frequencies](#unreliable-measurements-of-ringing-frequencies)
section instead and still get something out of the input shaping technique.
Ringing frequency can depend on the position of the model within the buildplate
and Z height, *especially on delta printers*; you can check if you see the
differences in frequencies at different positions along the sides of the test
model and at different heights. You can calculate the average ringing
frequencies over X and Y axes if that is the case.
If the measured ringing frequency is very low (below approx 20-25 Hz), it might
be a good idea to invest into stiffening the printer or decreasing the moving
mass - depending on what is applicable in your case - before proceeding with
further input shaping tuning, and re-measuring the frequencies afterwards. For
many popular printer models there are often some solutions available already.
Note that the ringing frequencies can change if the changes are made to the
printer that affect the moving mass or change the stiffness of the system,
for example:
* Some tools are installed, removed or replaced on the toolhead that change
its mass, e.g. a new (heavier or lighter) stepper motor for direct extruder
or a new hotend is installed, heavy fan with a duct is added, etc.
* Belts are tightened.
* Some addons to increase frame rigidity are installed.
* Different bed is installed on a bed-slinger printer, or glass added, etc.
If such changes are made, it is a good idea to at least measure the ringing
frequencies to see if they have changed.
### Input shaper configuration
After the ringing frequencies for X and Y axes are measured, you can add the
following section to your `printer.cfg`:
```
[input_shaper]
shaper_freq_x: ... # frequency for the X mark of the test model
shaper_freq_y: ... # frequency for the Y mark of the test model
```
For the example above, we get shaper_freq_x/y = 49.4.
### Choosing input shaper
Klipper supports several input shapers. They differ in their sensitivity to
errors determining the resonance frequency and how much smoothing they cause
in the printed parts. Also, some of the shapers like 2HUMP_EI and 3HUMP_EI
should usually not be used with shaper_freq = resonance frequency - they are
configured from different considerations to reduce several resonances at once.
For most of the printers, either MZV or EI shapers can be recommended. This
section describes a testing process to choose between them, and figure out
a few other related parameters.
Print the ringing test model as follows:
1. Restart the firmware: `RESTART`
2. Prepare for test: `SET_VELOCITY_LIMIT ACCEL_TO_DECEL=7000`
3. Disable Pressure Advance: `SET_PRESSURE_ADVANCE ADVANCE=0`
4. Execute: `SET_INPUT_SHAPER SHAPER_TYPE=MZV`
5. Execute the command:
`TUNING_TOWER COMMAND=SET_VELOCITY_LIMIT PARAMETER=ACCEL START=1500 STEP_DELTA=500 STEP_HEIGHT=5`
6. Print the test model sliced with the suggested parameters.
If you see no ringing at this point, then MZV shaper can be recommended for use.
If you do see some ringing, re-measure the frequencies using steps (8)-(10)
described in [Ringing frequency](#ringing-frequency) section. If the frequencies
differ significantly from the values you obtained earlier, a more complex input
shaper configuration is needed. You can refer to Technical details of
[Input shapers](#input-shapers) section. Otherwise, proceed to the next step.
Now try EI input shaper. To try it, repeat steps (1)-(6) from above, but
executing at step 4 the following command instead:
`SET_INPUT_SHAPER SHAPER_TYPE=EI`.
Compare two prints with MZV and EI input shaper. If EI shows noticeably better
results than MZV, use EI shaper, otherwise prefer MZV. Note that EI shaper will
cause more smoothing in printed parts (see the next section for further
details). Add `shaper_type: mzv` (or ei) parameter to [input_shaper] section,
e.g.:
```
[input_shaper]
shaper_freq_x: ...
shaper_freq_y: ...
shaper_type: mzv
```
A few notes on shaper selection:
* EI shaper may be more suited for bed slinger printers (if the resonance
frequency and resulting smoothing allows): as more filament is deposited
on the moving bed, the mass of the bed increases and the resonance frequency
will decrease. Since EI shaper is more robust to resonance frequency
changes, it may work better when printing large parts.
* Due to the nature of delta kinematics, resonance frequencies can differ a
lot in different parts of the build volume. Therefore, EI shaper can be a
better fit for delta printers rather than MZV or ZV, and should be
considered for the use. If the resonance frequency is sufficiently large
(more than 50-60 Hz), then one can even attempt to test 2HUMP_EI shaper
(by running the suggested test above with
`SET_INPUT_SHAPER SHAPER_TYPE=2HUMP_EI`), but check the considerations in
the [section below](#selecting-max_accel) before enabling it.
### Selecting max_accel
You should have a printed test for the shaper you chose from the previous step
(if you don't, print the test model sliced with the
[suggested parameters](#tuning) with the pressure advance disabled
`SET_PRESSURE_ADVANCE ADVANCE=0` and with the tuning tower enabled as
`TUNING_TOWER COMMAND=SET_VELOCITY_LIMIT PARAMETER=ACCEL START=1500 STEP_DELTA=500 STEP_HEIGHT=5`).
Note that at very high accelerations, depending on the resonance frequency and
the input shaper you chose (e.g. EI shaper creates more smoothing than MZV),
input shaping may cause too much smoothing and rounding of the parts. So,
max_accel should be chosen such as to prevent that. Another parameter that can
impact smoothing is `square_corner_velocity`, so it is not advisable to increase
it above the default 5 mm/sec to prevent increased smoothing.
In order to select a suitable max_accel value, inspect the model for the chosen
input shaper. First, take a note at which acceleration ringing is still small -
that you are comfortable with it.
Next, check the smoothing. To help with that, the test model has a small gap
in the wall (0.15 mm):
![Test gap](img/smoothing-test.png)
As the acceleration increases, so does the smoothing, and the actual gap in
the print widens:
![Shaper smoothing](img/shaper-smoothing.jpg)
In this picture, the acceleration increases left to right, and the gap starts
to grow starting from 3500 mm/sec^2 (5-th band from the left). So the good
value for max_accel = 3000 (mm/sec^2) in this case to avoid the excessive
smoothing.
Note the acceleration when the gap is still very small in your test print.
If you see bulges, but no gap in the wall at all, even at high accelerations,
it may be due to disabled Pressure Advance, especially on Bowden extruders.
If that is the case, you may need to repeat the print with the PA enabled.
It may also be a result of a miscalibrated (too high) filament flow, so it is
a good idea to check that too.
Choose the minimum out of the two acceleration values (from ringing and
smoothing), and put it as `max_accel` into printer.cfg.
As a note, it may happen - especially at low ringing frequencies - that EI
shaper will cause too much smoothing even at lower accelerations. In this case,
MZV may be a better choice, because it may allow higher acceleration values.
At very low ringing frequencies (~25 Hz and below) even MZV shaper may create
too much smoothing. If that is the case, you can also try to repeat the
steps in [Choosing input shaper](#choosing-input-shaper) section with ZV shaper,
by using `SET_INPUT_SHAPER SHAPER_TYPE=ZV` command instead. ZV shaper should
show even less smoothing than MZV, but is more sensitive to errors in measuring
the ringing frequencies.
Another consideration is that if a resonance frequency is too low (below 20-25
Hz), it might be a good idea to increase the printer stiffness or reduce the
moving mass. Otherwise, acceleration and printing speed may be limited due too
much smoothing now instead of ringing.
### Fine-tuning resonance frequencies
Note that the precision of the resonance frequencies measurements using the
ringing test model is sufficient for most purposes, so further tuning is not
advised. If you still want to try to double-check your results (e.g. if you
still see some ringing after printing a test model with an input shaper of
your choice with the same frequencies as you have measured earlier), you can
follow the steps in this section. Note that if you see ringing at different
frequencies after enabling [input_shaper], this section will not help with that.
Assuming that you have sliced the ringing model with suggested
parameters, complete the following steps for each of the axes X and Y:
1. Prepare for test: `SET_VELOCITY_LIMIT ACCEL_TO_DECEL=7000`
2. Make sure Pressure Advance is disabled: `SET_PRESSURE_ADVANCE ADVANCE=0`
3. Execute: `SET_INPUT_SHAPER SHAPER_TYPE=ZV`
4. From the existing ringing test model with your chosen input shaper select
the acceleration that shows ringing sufficiently well, and set it with:
`SET_VELOCITY_LIMIT ACCEL=...`
5. Calculate the necessary parameters for the `TUNING_TOWER` command to tune
`shaper_freq_x` parameter as follows: start = shaper_freq_x * 83 / 132 and
factor = shaper_freq_x / 66, where `shaper_freq_x` here is the current value
in `printer.cfg`.
6. Execute the command:
`TUNING_TOWER COMMAND=SET_INPUT_SHAPER PARAMETER=SHAPER_FREQ_X START=start FACTOR=factor BAND=5`
using `start` and `factor` values calculated at step (5).
7. Print the test model.
8. Reset the original frequency value:
`SET_INPUT_SHAPER SHAPER_FREQ_X=...`.
9. Find the band which shows ringing the least and count its number from the
bottom starting at 1.
10. Calculate the new shaper_freq_x value via old
shaper_freq_x * (39 + 5 * #band-number) / 66.
Repeat these steps for the Y axis in the same manner, replacing references to X
axis with the axis Y (e.g. replace `shaper_freq_x` with `shaper_freq_y` in
the formulae and in the `TUNING_TOWER` command).
As an example, let's assume you have had measured the ringing frequency for one
of the axis equal to 45 Hz. This gives start = 45 * 83 / 132 = 28.30
and factor = 45 / 66 = 0.6818 values for `TUNING_TOWER` command.
Now let's assume that after printing the test model, the fourth band from the
bottom gives the least ringing. This gives the updated shaper_freq_? value
equal to 45 * (39 + 5 * 4) / 66 ≈ 40.23.
After both new `shaper_freq_x` and `shaper_freq_y` parameters have been
calculated, you can update `[input_shaper]` section in `printer.cfg` with the
new `shaper_freq_x` and `shaper_freq_y` values.
### Pressure Advance
If you use Pressure Advance, it may need to be re-tuned. Follow the
[instructions](Pressure_Advance.md#tuning-pressure-advance) to find
the new value, if it differs from the previous one. Make sure to
restart Klipper before tuning Pressure Advance.
### Unreliable measurements of ringing frequencies
If you are unable to measure the ringing frequencies, e.g. if the distance
between the oscillations is not stable, you may still be able to take advantage
of input shaping techniques, but the results may not be as good as with proper
measurements of the frequencies, and will require a bit more tuning and printing
the test model. Note that another possibility is to purchase and install an
accelerometer and measure the resonances with it (refer to the
[docs](Measuring_Resonances.md) describing the required hardware and the setup
process) - but this option requires some crimping and soldering.
For tuning, add empty `[input_shaper]` section to your
`printer.cfg`. Then, assuming that you have sliced the ringing model
with suggested parameters, print the test model 3 times as
follows. First time, prior to printing, run
1. `RESTART`
2. `SET_VELOCITY_LIMIT ACCEL_TO_DECEL=7000`
3. `SET_PRESSURE_ADVANCE ADVANCE=0`
4. `SET_INPUT_SHAPER SHAPER_TYPE=2HUMP_EI SHAPER_FREQ_X=60 SHAPER_FREQ_Y=60`
5. `TUNING_TOWER COMMAND=SET_VELOCITY_LIMIT PARAMETER=ACCEL START=1500 STEP_DELTA=500 STEP_HEIGHT=5`
and print the model. Then print the model again, but before printing run instead
1. `SET_INPUT_SHAPER SHAPER_TYPE=2HUMP_EI SHAPER_FREQ_X=50 SHAPER_FREQ_Y=50`
2. `TUNING_TOWER COMMAND=SET_VELOCITY_LIMIT PARAMETER=ACCEL START=1500 STEP_DELTA=500 STEP_HEIGHT=5`
Then print the model for the 3rd time, but now run
1. `SET_INPUT_SHAPER SHAPER_TYPE=2HUMP_EI SHAPER_FREQ_X=40 SHAPER_FREQ_Y=40`
2. `TUNING_TOWER COMMAND=SET_VELOCITY_LIMIT PARAMETER=ACCEL START=1500 STEP_DELTA=500 STEP_HEIGHT=5`
Essentially, we are printing the ringing test model with TUNING_TOWER using
2HUMP_EI shaper with shaper_freq = 60 Hz, 50 Hz, and 40 Hz.
If none of the models demonstrate improvements in ringing, then, unfortunately,
it does not look like the input shaping techniques can help with your case.
Otherwise, it may be that all models show no ringing, or some show the ringing
and some - not so much. Choose the test model with the highest frequency that
still shows good improvements in ringing. For example, if 40 Hz and 50 Hz models
show almost no ringing, and 60 Hz model already shows some more ringing, stick
with 50 Hz.
Now check if EI shaper would be good enough in your case. Choose EI shaper
frequency based on the frequency of 2HUMP_EI shaper you chose:
* For 2HUMP_EI 60 Hz shaper, use EI shaper with shaper_freq = 50 Hz.
* For 2HUMP_EI 50 Hz shaper, use EI shaper with shaper_freq = 40 Hz.
* For 2HUMP_EI 40 Hz shaper, use EI shaper with shaper_freq = 33 Hz.
Now print the test model one more time, running
1. `SET_INPUT_SHAPER SHAPER_TYPE=EI SHAPER_FREQ_X=... SHAPER_FREQ_Y=...`
2. `TUNING_TOWER COMMAND=SET_VELOCITY_LIMIT PARAMETER=ACCEL START=1500 STEP_DELTA=500 STEP_HEIGHT=5`
providing the shaper_freq_x=... and shaper_freq_y=... as determined previously.
If EI shaper shows very comparable good results as 2HUMP_EI shaper, stick with
EI shaper and the frequency determined earlier, otherwise use 2HUMP_EI shaper
with the corresponding frequency. Add the results to `printer.cfg` as, e.g.
```
[input_shaper]
shaper_freq_x: 50
shaper_freq_y: 50
shaper_type: 2hump_ei
```
Continue the tuning with [Selecting max_accel](#selecting-max_accel) section.
## Troubleshooting and FAQ
### I cannot get reliable measurements of resonance frequencies
First, make sure it is not some other problem with the printer instead of
ringing. If the measurements are not reliable because, say, the distance
between the oscillations is not stable, it might mean that the printer has
several resonance frequencies on the same axis. One may try to follow the
tuning process described in
[Unreliable measurements of ringing frequencies](#unreliable-measurements-of-ringing-frequencies)
section and still get something out of the input shaping technique. Another
possibility is to install an accelerometer, [measure](Measuring_Resonances.md)
the resonances with it, and auto-tune the input shaper using the results of
those measurements.
### After enabling [input_shaper], I get too smoothed printed parts and fine details are lost
Check the considerations in [Selecting max_accel](#selecting-max_accel) section.
If the resonance frequency is low, one should not set too high max_accel or
increase square_corner_velocity parameters. It might also be better to choose
MZV or even ZV input shapers over EI (or 2HUMP_EI and 3HUMP_EI shapers).
### After successfully printing for some time without ringing, it appears to come back
It is possible that after some time the resonance frequencies have changed.
E.g. maybe the belts tension has changed (belts got more loose), etc. It is a
good idea to check and re-measure the ringing frequencies as described in
[Ringing frequency](#ringing-frequency) section and update your config file
if necessary.
### Is dual carriage setup supported with input shapers?
There is no dedicated support for dual carriages with input shapers, but it does
not mean this setup will not work. One should run the tuning twice for each
of the carriages, and calculate the ringing frequencies for X and Y axes for
each of the carriages independently. Then put the values for carriage 0 into
[input_shaper] section, and change the values on the fly when changing
carriages, e.g. as a part of some macro:
```
SET_DUAL_CARRIAGE CARRIAGE=1
SET_INPUT_SHAPER SHAPER_FREQ_X=... SHAPER_FREQ_Y=...
```
And similarly when switching back to carriage 0.
### Does input_shaper affect print time?
No, `input_shaper` feature has pretty much no impact on the print times by
itself. However, the value of `max_accel` certainly does (tuning of this
parameter described in [this section](#selecting-max_accel)).
## Technical details
### Input shapers
Input shapers used in Klipper are rather standard, and one can find more
in-depth overview in the articles describing the corresponding shapers.
This section contains a brief overview of some technical aspects of the
supported input shapers. The table below shows some (usually approximate)
parameters of each shaper.
| Input <br> shaper | Shaper <br> duration | Vibration reduction 20x <br> (5% vibration tolerance) | Vibration reduction 10x <br> (10% vibration tolerance) |
|:--:|:--:|:--:|:--:|
| ZV | 0.5 / shaper_freq | N/A | ± 5% shaper_freq |
| MZV | 0.75 / shaper_freq | ± 4% shaper_freq | -10%...+15% shaper_freq |
| ZVD | 1 / shaper_freq | ± 15% shaper_freq | ± 22% shaper_freq |
| EI | 1 / shaper_freq | ± 20% shaper_freq | ± 25% shaper_freq |
| 2HUMP_EI | 1.5 / shaper_freq | ± 35% shaper_freq | ± 40 shaper_freq |
| 3HUMP_EI | 2 / shaper_freq | -45...+50% shaper_freq | -50%...+55% shaper_freq |
A note on vibration reduction: the values in the table above are approximate.
If the damping ratio of the printer is known for each axis, the shaper can be
configured more precisely and it will then reduce the resonances in a bit wider
range of frequencies. However, the damping ratio is usually unknown and is hard
to estimate without a special equipment, so Klipper uses 0.1 value by default,
which is a good all-round value. The frequency ranges in the table cover a
number of different possible damping ratios around that value (approx. from 0.05
to 0.2).
Also note that EI, 2HUMP_EI, and 3HUMP_EI are tuned to reduce vibrations to 5%,
so the values for 10% vibration tolerance are provided only for the reference.
**How to use this table:**
* Shaper duration affects the smoothing in parts - the larger it is, the more
smooth the parts are. This dependency is not linear, but can give a sense of
which shapers 'smooth' more for the same frequency. The ordering by
smoothing is like this: ZV < MZV < ZVD EI < 2HUMP_EI < 3HUMP_EI. Also,
it is rarely practical to set shaper_freq = resonance freq for shapers
2HUMP_EI and 3HUMP_EI (they should be used to reduce vibrations for several
frequencies).
* One can estimate a range of frequencies in which the shaper reduces
vibrations. For example, MZV with shaper_freq = 35 Hz reduces vibrations
to 5% for frequencies [33.6, 36.4] Hz. 3HUMP_EI with shaper_freq = 50 Hz
reduces vibrations to 5% in range [27.5, 75] Hz.
* One can use this table to check which shaper they should be using if they
need to reduce vibrations at several frequencies. For example, if one has
resonances at 35 Hz and 60 Hz on the same axis: a) EI shaper needs to have
shaper_freq = 35 / (1 - 0.2) = 43.75 Hz, and it will reduce resonances
until 43.75 * (1 + 0.2) = 52.5 Hz, so it is not sufficient; b) 2HUMP_EI
shaper needs to have shaper_freq = 35 / (1 - 0.35) = 53.85 Hz and will
reduce vibrations until 53.85 * (1 + 0.35) = 72.7 Hz - so this is an
acceptable configuration. Always try to use as high shaper_freq as possible
for a given shaper (perhaps with some safety margin, so in this example
shaper_freq 50-52 Hz would work best), and try to use a shaper with as
small shaper duration as possible.
* If one needs to reduce vibrations at several very different frequencies
(say, 30 Hz and 100 Hz), they may see that the table above does not provide
enough information. In this case one may have more luck with
[scripts/graph_shaper.py](../scripts/graph_shaper.py)
script, which is more flexible.

182
docs/Rotation_Distance.md Normal file
View File

@@ -0,0 +1,182 @@
# Rotation distance
Stepper motor drivers on Klipper require a `rotation_distance`
parameter in each
[stepper config section](Config_Reference.md#stepper). The
`rotation_distance` is the amount of distance that the axis moves with
one full revolution of the stepper motor. This document describes how
one can configure this value.
## Obtaining rotation_distance from steps_per_mm (or step_distance)
The designers of your 3d printer originally calculated `steps_per_mm`
from a rotation distance. If you know the steps_per_mm then it is
possible to use this general formula to obtain that original rotation
distance:
```
rotation_distance = <full_steps_per_rotation> * <microsteps> / <steps_per_mm>
```
Or, if you have an older Klipper configuration and know the
`step_distance` parameter you can use this formula:
```
rotation_distance = <full_steps_per_rotation> * <microsteps> * <step_distance>
```
The `<full_steps_per_rotation>` setting is determined from the type of
stepper motor. Most stepper motors are "1.8 degree steppers" and
therefore have 200 full steps per rotation (360 divided by 1.8 is
200). Some stepper motors are "0.9 degree steppers" and thus have 400
full steps per rotation. Other stepper motors are rare. If unsure, do
not set full_steps_per_rotation in the config file and use 200 in the
formula above.
The `<microsteps>` setting is determined by the stepper motor driver.
Most drivers use 16 microsteps. If unsure, set `microsteps: 16` in the
config and use 16 in the formula above.
Almost all printers should have a whole number for `rotation_distance`
on X, Y, and Z type axes. If the above formula results in a
rotation_distance that is within .01 of a whole number then round the
final value to that whole_number.
## Calibrating rotation_distance on extruders
On an extruder, the `rotation_distance` is the amount of distance the
filament travels for one full rotation of the stepper motor. The best
way to get an accurate value for this setting is to use a "measure and
trim" procedure.
First start with an initial guess for the rotation distance. This may
be obtained from
[steps_per_mm](#obtaining-rotation_distance-from-steps_per_mm-or-step_distance)
or by [inspecting the hardware](#extruder).
Then use the following procedure to "measure and trim":
1. Make sure the extruder has filament in it, the hotend is heated to
an appropriate temperature, and the printer is ready to extrude.
2. Use a marker to place a mark on the filament around 70mm from the
intake of the extruder body. Then use a digital calipers to measure
the actual distance of that mark as precisely as one can. Note this
as `<initial_mark_distance>`.
3. Extrude 50mm of filament with the following command sequence: `G91`
followed by `G1 E50 F60`. Note 50mm as
`<requested_extrude_distance>`. Wait for the extruder to finish the
move (it will take about 50 seconds). It is important to use the
slow extrusion rate for this test as a faster rate can cause high
pressure in the extruder which will skew the results. (Do not use
the "extrude button" on graphical front-ends for this test as they
extrude at a fast rate.)
4. Use the digital calipers to measure the new distance between the
extruder body and the mark on the filament. Note this as
`<subsequent_mark_distance>`. Then calculate:
`actual_extrude_distance = <initial_mark_distance> - <subsequent_mark_distance>`
5. Calculate rotation_distance as:
`rotation_distance = <previous_rotation_distance> * <actual_extrude_distance> / <requested_extrude_distance>`
Round the new rotation_distance to three decimal places.
If the actual_extrude_distance differs from requested_extrude_distance
by more than about 2mm then it is a good idea to perform the steps
above a second time.
Note: Do *not* use a "measure and trim" type of method to calibrate x,
y, or z type axes. The "measure and trim" method is not accurate
enough for those axes and will likely lead to a worse configuration.
Instead, if needed, those axes can be determined by
[measuring the belts, pulleys, and lead screw hardware](#obtaining-rotation_distance-by-inspecting-the-hardware).
## Obtaining rotation_distance by inspecting the hardware
It's possible to calculate rotation_distance with knowledge of the
stepper motors and printer kinematics. This may be useful if the
steps_per_mm is not known or if designing a new printer.
### Belt driven axes
It is easy to calculate rotation_distance for a linear axis that uses
a belt and pulley.
First determine the type of belt. Most printers use a 2mm belt pitch
(that is, each tooth on the belt is 2mm apart). Then count the number
of teeth on the stepper motor pulley. The rotation_distance is then
calculated as:
```
rotation_distance = <belt_pitch> * <number_of_teeth_on_pulley>
```
For example, if a printer has a 2mm belt and uses a pulley with 20
teeth, then the rotation distance is 40.
### Axes with a lead screw
It is easy to calculate the rotation_distance for common lead screws
using the following formula:
```
rotation_distance = <screw_pitch> * <number_of_separate_threads>
```
For example, the common "T8 leadscrew" has a rotation distance of 8
(it has a pitch of 2mm and has 4 separate threads).
Older printers with "threaded rods" have only one "thread" on the lead
screw and thus the rotation distance is the pitch of the screw. (The
screw pitch is the distance between each groove on the screw.) So, for
example, an M6 metric rod has a rotation distance of 1 and an M8 rod
has a rotation distance of 1.25.
### Extruder
It's possible to obtain an initial rotation distance for extruders by
measuring the diameter of the "hobbed bolt" that pushes the filament
and using the following formula: `rotation_distance = <diameter> * 3.14`
If the extruder uses gears then it will also be necessary to
[determine and set the gear_ratio](#using-a-gear_ratio) for the
extruder.
The actual rotation distance on an extruder will vary from printer to
printer, because the grip of the "hobbed bolt" that engages the
filament can vary. It can even vary between filament spools. After
obtaining an initial rotation_distance, use the
[measure and trim procedure](#calibrating-rotation_distance-on-extruders)
to obtain a more accurate setting.
## Using a gear_ratio
Setting a `gear_ratio` can make it easier to configure the
`rotation_distance` on steppers that have a gear box (or similar)
attached to it. Most steppers do not have a gear box - if unsure then
do not set `gear_ratio` in the config.
When `gear_ratio` is set, the `rotation_distance` represents the
distance the axis moves with one full rotation of the final gear on
the gear box. If, for example, one is using a gearbox with a "5:1"
ratio, then one could calculate the rotation_distance with
[knowledge of the hardware](#obtaining-rotation_distance-by-inspecting-the-hardware)
and then add `gear_ratio: 5:1` to the config.
For gearing implemented with belts and pulleys, it is possible to
determine the gear_ratio by counting the teeth on the pulleys. For
example, if a stepper with a 16 toothed pulley drives the next pulley
with 80 teeth then one would use `gear_ratio: 80:16`. Indeed, one
could open a common off the shelf "gear box" and count the teeth in it
to confirm its gear ratio.
Note that sometimes a gearbox will have a slightly different gear
ratio than what it is advertised as. The common BMG extruder motor
gears are an example of this - they are advertised as "3:1" but
actually use "50:17" gearing. (Using teeth numbers without a common
denominator may improve overall gear wear as the teeth don't always
mesh the same way with each revolution.) The common "5.18:1 planetary
gearbox", is more accurately configured with `gear_ratio: 57:11`.
If several gears are used on an axis then it is possible to provide a
comma separated list to gear_ratio. For example, a "5:1" gear box
driving a 16 toothed to 80 toothed pulley could use
`gear_ratio: 5:1, 80:16`.
In most cases, gear_ratio should be defined with whole numbers as
common gears and pulleys have a whole number of teeth on them.
However, in cases where a belt drives a pulley using friction instead
of teeth, it may make sense to use a floating point number in the gear
ratio (eg, `gear_ratio: 107.237:16`).

147
docs/SDCard_Updates.md Normal file
View File

@@ -0,0 +1,147 @@
# SDCard updates
Many of today's popular controller boards ship with a bootloader capable of
updating firmware via SD Card. While this is convenient in many
circumstances, these bootloaders typically provide no other way to update
firmware. This can be a nuisance if your board is mounted in a location
that is difficult to access or if you need to update firmware often.
After Klipper has been initially flashed to a controller it is possible to
transfer new firmware to the SD Card and initiate the flashing procedure
via ssh.
## Typical Upgrade Procedure
The procedure for updating MCU firmware using the SD Card is similar to that
of other methods. Instead of using `make flash` it is necessary to run a
helper script, `flash-sdcard.sh`. Updating a BigTreeTech SKR 1.3 might look
like the following:
```
sudo service klipper stop
cd ~/klipper
git pull
make clean
make menuconfig
make
./scripts/flash-sdcard.sh /dev/ttyACM0 btt-skr-v1.3
sudo service klipper start
```
It is up to the user to determine the device location and board name.
If a user needs to flash multiple boards, `flash-sdcard.sh` (or
`make flash` if appropriate) should be run for each board prior to
restarting the Klipper service.
Supported boards can be listed with the following command:
```
./scripts/flash-sdcard.sh -l
```
If you do not see your board listed it may be necessary to add a new
board definition as [described below](#board-definitions).
## Advanced Usage
The above commands assume that your MCU connects at the default baud rate
of 250000 and the firmware is located at `~/klipper/out/klipper.bin`. The
`flash-sdcard.sh` script provides options for changing these defaults.
All options can be viewed by the help screen:
```
./scripts/flash-sdcard.sh -h
SD Card upload utility for Klipper
usage: flash_sdcard.sh [-h] [-l] [-b <baud>] [-f <firmware>]
<device> <board>
positional arguments:
<device> device serial port
<board> board type
optional arguments:
-h show this message
-l list available boards
-b <baud> serial baud rate (default is 250000)
-f <firmware> path to klipper.bin
```
If your board is flashed with firmware that connects at a custom baud
rate it is possible to upgrade by specifying the `-b` option:
```
./scripts/flash-sdcard.sh -b 115200 /dev/ttyAMA0 btt-skr-v1.3
```
If you wish to flash a build of Klipper located somewhere other than
the default location it can be done by specifying the `-f` option:
```
./scripts/flash-sdcard.sh -f ~/downloads/klipper.bin /dev/ttyAMA0 btt-skr-v1.3
```
Note that when upgrading a MKS Robin E3 it is not necessary to manually run
`update_mks_robin.py` and supply the resulting binary to `flash-sdcard.sh`.
This procedure is automated during the upload process.
## Caveats
- As mentioned in the introduction, this method only works for upgrading
firmware. The initial flashing procedure must be done manually per the
instructions that apply to your controller board.
- While it is possible to flash a build that changes the Serial Baud or
connection interface (ie: from USB to UART), verification will always
fail as the script will be unable to reconnect to the MCU to verify
the current version.
- Only boards that use SPI for SD Card communication are supported.
Boards that use SDIO, such as the Flymaker Flyboard and MKS Robin Nano
V1/V2, will not work.
## Board Definitions
Most common boards should be available, however it is possible to add a new
board definition if necessary. Board definitions are located in
`~/klipper/scripts/spi_flash/board_defs.py`. The definitions are stored
in dictionary, for example:
```python
BOARD_DEFS = {
'generic-lpc1768': {
'mcu': "lpc1768",
'spi_bus': "ssp1",
"cs_pin": "P0.6"
},
...<further definitions>
}
```
The following fields may be specified:
- `mcu`: The mcu type. This can be retrevied after configuring the build
via `make menuconfig` by running `cat .config | grep CONFIG_MCU`. This
field is required.
- `spi_bus`: The SPI bus connected to the SD Card. This should be retreived
from the board's schematic. This field is required.
- `cs_pin`: The Chip Select Pin connected to the SD Card. This should be
retreived from the board schematic. This field is required.
- `firmware_path`: The path on the SD Card where firmware should be
transferred. The default is `firmware.bin`.
- `current_firmware_path` The path on the SD Card where the renamed firmware
file is located after a successful flash. The default is `firmware.cur`.
If software SPI is required the `spi_bus` field should be set to `swspi`
and the following additional field should be specified:
- `spi_pins`: This should be 3 comma separated pins that are connected to
the SD Card in the format of `miso,mosi,sclk`.
It should be exceedingly rare that Software SPI is necessary, typically only
boards with design errors will require it. The `btt-skr-pro` board definition
provides an example.
Prior to creating a new board definition one should check to see if an
existing board definition meets the criteria necessary for the new board.
If this is the case, a `BOARD_ALIAS` may be specified. For example, the
following alias may be added to specify `my-new-board` as an alias for
`generic-lpc1768`:
```python
BOARD_ALIASES = {
...<previous aliases>,
'my-new-board': BOARD_DEFS['generic-lpc1768'],
}
```
If you need a new board definition and you are uncomfortable with the
procedure outlined above it is recommended that you request one in
the [Klipper Community Discord](Contact.md#discord).

100
docs/Skew_Correction.md Normal file
View File

@@ -0,0 +1,100 @@
# Skew correction
Software based skew correction can help resolve dimensional inaccuracies
resulting from a printer assembly that is not perfectly square. Note
that if your printer is significantly skewed it is strongly recommended to
first use mechanical means to get your printer as square as possible prior
to applying software based correction.
## Print a Calibration Object
The first step in correcting skew is to print a
[calibration object](https://www.thingiverse.com/thing:2563185/files)
along the plane you want to correct. There is also a
[calibration object](https://www.thingiverse.com/thing:2972743)
that includes all planes in one model. You want the object oriented
so that corner A is toward the origin of the plane.
Make sure that no skew correction is applied during this print. You may
do this by either removing the `[skew_correction]` module from printer.cfg
or by issuing a `SET_SKEW CLEAR=1` gcode.
## Take your measurements
The `[skew_correcton]` module requires 3 measurements for each plane you want
to correct; the length from Corner A to Corner C, the length from Corner B
to Corner D, and the length from Corner A to Corner D. When measuring length
AD do not include the flats on the corners that some test objects provide.
![skew_lengths](img/skew_lengths.png)
## Configure your skew
Make sure `[skew_correction]` is in printer.cfg. You may now use the `SET_SKEW`
gcode to configure skew_correcton. For example, if your measured lengths
along XY are as follows:
```
Length AC = 140.4
Length BD = 142.8
Length AD = 99.8
```
`SET_SKEW` can be used to configure skew correction for the XY plane.
```
SET_SKEW XY=140.4,142.8,99.8
```
You may also add measurements for XZ and YZ to the gcode:
```
SET_SKEW XY=140.4,142.8,99.8 XZ=141.6,141.4,99.8 YZ=142.4,140.5,99.5
```
The `[skew_correction]` module also supports profile management in a manner
similar to `[bed_mesh]`. After setting skew using the `SET_SKEW` gcode,
you may use the `SKEW_PROFILE` gcode to save it:
```
SKEW_PROFILE SAVE=my_skew_profile
```
After this command you will be prompted to issue a `SAVE_CONFIG` gcode to
save the profile to persistent storage. If no profile is named
`my_skew_profile` then a new profile will be created. If the named profile
exists it will be overwritten.
Once you have a saved profile, you may load it:
```
SKEW_PROFILE LOAD=my_skew_profile
```
It is also possible to remove an old or out of date profile:
```
SKEW_PROFILE REMOVE=my_skew_profile
```
After removing a profile you will be prompted to issue a `SAVE_CONFIG` to
make this change persist.
## Verifying your correction
After skew_correction has been configured you may reprint the calibration
part with correction enabled. Use the following gcode to check your
skew on each plane. The results should be lower than those reported via
`GET_CURRENT_SKEW`.
```
CALC_MEASURED_SKEW AC=<ac_length> BD=<bd_length> AD=<ad_length>
```
## Caveats
Due to the nature of skew correction it is recommended to configure skew
in your start gcode, after homing and any kind of movement that travels
near the edge of the print area such as a purge or nozzle wipe. You may
use use the `SET_SKEW` or `SKEW_PROFILE` gcodes to accomplish this. It is
also recommended to issue a `SET_SKEW CLEAR=1` in your end gcode.
Keep in mind that it is possible for `[skew_correction]` to generate a correction
that moves the tool beyond the printer's boundaries on the X and/or Y axes. It
is recommended to arrange parts away from the edges when using
`[skew_correction]`.

89
docs/Slicers.md Normal file
View File

@@ -0,0 +1,89 @@
# Slicers
This document provides some tips for configuring a "slicer"
application for use with Klipper. Common slicers used with Klipper are
Slic3r, Cura, Simplify3D, etc.
## Set the G-Code flavor to Marlin
Many slicers have an option to configure the "G-Code flavor". The
default is frequently "Marlin" and that works well with Klipper. The
"Smoothieware" setting also works well with Klipper.
## Klipper gcode_macro
Slicers will often allow one to configure "Start G-Code" and "End
G-Code" sequences. It is often convenient to define custom macros in
the Klipper config file instead - such as: `[gcode_macro START_PRINT]`
and `[gcode_macro END_PRINT]`. Then one can just run START_PRINT and
END_PRINT in the slicer's configuration. Defining these actions in the
Klipper configuration may make it easier to tweak the printer's start
and end steps as changes do not require re-slicing.
See [sample-macros.cfg](../config/sample-macros.cfg) for example
START_PRINT and END_PRINT macros.
See the [config reference](Config_Reference.md#gcode_macro) for
details on defining a gcode_macro.
## Large retraction settings may require tuning Klipper
The maximum speed and acceleration of retraction moves are controlled
in Klipper by the `max_extrude_only_velocity` and
`max_extrude_only_accel` config settings. These settings have a
default value that should work well on many printers. However, if one
has configured a large retraction in the slicer (eg, 5mm or greater)
then one may find they limit the desired speed of retractions.
If using a large retraction, consider tuning Klipper's
[pressure advance](Pressure_Advance.md) instead. Otherwise, if one
finds the toolhead seems to "pause" during retraction and priming,
then consider explicitly defining `max_extrude_only_velocity` and
`max_extrude_only_accel` in the Klipper config file.
## Do not enable "coasting"
The "coasting" feature is likely to result in poor quality prints with
Klipper. Consider using Klipper's
[pressure advance](Pressure_Advance.md) instead.
Specifically, if the slicer dramatically changes the extrusion rate
between moves then Klipper will perform deceleration and acceleration
between moves. This is likely to make blobbing worse, not better.
In contrast, it is okay (and often helpful) to use a slicer's
"retract" setting, "wipe" setting, and/or "wipe on retract" setting.
## Do not use "extra restart distance" on Simplify3d
This setting can cause dramatic changes to extrusion rates which can
trigger Klipper's maximum extrusion cross-section check. Consider
using Klipper's [pressure advance](Pressure_Advance.md) or the regular
Simplify3d retract setting instead.
## Disable "PreloadVE" on KISSlicer
If using KISSlicer slicing software then set "PreloadVE" to
zero. Consider using Klipper's [pressure advance](Pressure_Advance.md)
instead.
## Disable any "advanced extruder pressure" settings
Some slicers advertise an "advanced extruder pressure" capability. It
is recommended to keep these options disabled when using Klipper as
they are likely to result in poor quality prints. Consider using
Klipper's [pressure advance](Pressure_Advance.md) instead.
Specifically, these slicer settings can instruct the firmware to make
wild changes to the extrusion rate in the hope that the firmware will
approximate those requests and the printer will roughly obtain a
desirable extruder pressure. Klipper, however, utilizes precise
kinematic calculations and timing. When Klipper is commanded to make
significant changes to the extrusion rate it will plan out the
corresponding changes to velocity, acceleration, and extruder
movement - which is not the slicer's intent. The slicer may even
command excessive extrusion rates to the point that it triggers
Klipper's maximum extrusion cross-section check.
In contrast, it is okay (and often helpful) to use a slicer's
"retract" setting, "wipe" setting, and/or "wipe on retract" setting.

40
docs/Sponsors.md Normal file
View File

@@ -0,0 +1,40 @@
# Sponsors
Klipper is Free Software. We depend on the generous support from
sponsors. Please consider sponsoring Klipper or supporting our
sponsors.
## BIGTREETECH
[<img src="./img/sponsors/BTT_BTT.png" width="200" />](https://bigtree-tech.com/collections/all-products)
BIGTREETECH is the official mainboard sponsor of Klipper. BIGTREETECH
is committed to developing innovative and competitive products to
serve the 3D printing community better. Follow them on
[Facebook](https://www.facebook.com/BIGTREETECH) or
[Twitter](https://twitter.com/BigTreeTech).
## Klipper Developers
### Kevin O'Connor
Kevin is the original author and current maintainer of Klipper. Kevin
has a Patreon page at:
[https://www.patreon.com/koconnor](https://www.patreon.com/koconnor)
### Eric Callahan
Eric is the author of bed_mesh, spi_flash, and several other Klipper
modules. Eric has a donations page at:
[https://ko-fi.com/arksine](https://ko-fi.com/arksine)
## Related Klipper Projects
Klipper is frequently used with other Free Software. Consider using or
supporting these projects.
* [Moonraker](https://github.com/Arksine/moonraker)
* [Mainsail](https://github.com/mainsail-crew/mainsail)
* [Fluidd](https://github.com/fluidd-core/fluidd)
* [OctoPrint](https://octoprint.org/)
* [KlipperScreen](https://github.com/jordanruthe/KlipperScreen)

472
docs/Status_Reference.md Normal file
View File

@@ -0,0 +1,472 @@
# Status reference
This document is a reference of printer status information available
in Klipper [macros](Command_Templates.md),
[display fields](Config_Reference.md#display), and via the
[API Server](API_Server.md).
The fields in this document are subject to change - if using an
attribute be sure to review the
[Config Changes document](Config_Changes.md) when upgrading the
Klipper software.
## angle
The following information is available in
[angle some_name](Config_Reference.md#angle) objects:
- `temperature`: The last temperature reading (in Celsius) from a
tle5012b magnetic hall sensor. This value is only available if the
angle sensor is a tle5012b chip and if measurements are in progress
(otherwise it reports `None`).
## bed_mesh
The following information is available in the
[bed_mesh](Config_Reference.md#bed_mesh) object:
- `profile_name`, `mesh_min`, `mesh_max`, `probed_matrix`,
`mesh_matrix`: Information on the currently active bed_mesh.
- `profiles`: The set of currently defined profiles as setup
using BED_MESH_PROFILE.
## configfile
The following information is available in the `configfile` object
(this object is always available):
- `settings.<section>.<option>`: Returns the given config file setting
(or default value) during the last software start or restart. (Any
settings changed at run-time will not be reflected here.)
- `config.<section>.<option>`: Returns the given raw config file
setting as read by Klipper during the last software start or
restart. (Any settings changed at run-time will not be reflected
here.) All values are returned as strings.
- `save_config_pending`: Returns true if there are updates that a
`SAVE_CONFIG` command may persist to disk.
- `save_config_pending_items`: Contains the sections and options that
were changed and would be persisted by a `SAVE_CONFIG`.
- `warnings`: A list of warnings about config options. Each entry in
the list will be a dictionary containing a `type` and `message`
field (both strings). Additional fields may be available depending
on the type of warning.
## display_status
The following information is available in the `display_status` object
(this object is automatically available if a
[display](Config_Reference.md#display) config section is defined):
- `progress`: The progress value of the last `M73` G-Code command (or
`virtual_sdcard.progress` if no recent `M73` received).
- `message`: The message contained in the last `M117` G-Code command.
## endstop_phase
The following information is available in the
[endstop_phase](Config_Reference.md#endstop_phase) object:
- `last_home.<stepper name>.phase`: The phase of the stepper motor at
the end of the last home attempt.
- `last_home.<stepper name>.phases`: The total number of phases
available on the stepper motor.
- `last_home.<stepper name>.mcu_position`: The position (as tracked by
the micro-controller) of the stepper motor at the end of the last
home attempt. The position is the total number of steps taken in a
forward direction minus the total number of steps taken in the
reverse direction since the micro-controller was last restarted.
## exclude_object
The following information is available in the
[exclude_object](Exclude_Object.md) object:
- `objects`: An array of the known objects as provided by the
`EXCLUDE_OBJECT_DEFINE` command. This is the same information provided by
the `EXCLUDE_OBJECT VERBOSE=1` command. The `center` and `polygon` fields will
only be present if provided in the original `EXCLUDE_OBJECT_DEFINE`
Here is a JSON sample:
```
[
{
"polygon": [
[ 156.25, 146.2511675 ],
[ 156.25, 153.7488325 ],
[ 163.75, 153.7488325 ],
[ 163.75, 146.2511675 ]
],
"name": "CYLINDER_2_STL_ID_2_COPY_0",
"center": [ 160, 150 ]
},
{
"polygon": [
[ 146.25, 146.2511675 ],
[ 146.25, 153.7488325 ],
[ 153.75, 153.7488325 ],
[ 153.75, 146.2511675 ]
],
"name": "CYLINDER_2_STL_ID_1_COPY_0",
"center": [ 150, 150 ]
}
]
```
- `excluded_objects`: An array of strings listing the names of excluded objects.
- `current_object`: The name of the object currently being printed.
## fan
The following information is available in
[fan](Config_Reference.md#fan),
[heater_fan some_name](Config_Reference.md#heater_fan) and
[controller_fan some_name](Config_Reference.md#controller_fan)
objects:
- `speed`: The fan speed as a float between 0.0 and 1.0.
- `rpm`: The measured fan speed in rotations per minute if the fan has
a tachometer_pin defined.
## filament_switch_sensor
The following information is available in
[filament_switch_sensor some_name](Config_Reference.md#filament_switch_sensor)
objects:
- `enabled`: Returns True if the switch sensor is currently enabled.
- `filament_detected`: Returns True if the sensor is in a triggered
state.
## filament_motion_sensor
The following information is available in
[filament_motion_sensor some_name](Config_Reference.md#filament_motion_sensor)
objects:
- `enabled`: Returns True if the motion sensor is currently enabled.
- `filament_detected`: Returns True if the sensor is in a triggered
state.
## firmware_retraction
The following information is available in the
[firmware_retraction](Config_Reference.md#firmware_retraction) object:
- `retract_length`, `retract_speed`, `unretract_extra_length`,
`unretract_speed`: The current settings for the firmware_retraction
module. These settings may differ from the config file if a
`SET_RETRACTION` command alters them.
## gcode_macro
The following information is available in
[gcode_macro some_name](Config_Reference.md#gcode_macro) objects:
- `<variable>`: The current value of a
[gcode_macro variable](Command_Templates.md#variables).
## gcode_move
The following information is available in the `gcode_move` object
(this object is always available):
- `gcode_position`: The current position of the toolhead relative to
the current G-Code origin. That is, positions that one might
directly send to a `G1` command. It is possible to access the x, y,
z, and e components of this position (eg, `gcode_position.x`).
- `position`: The last commanded position of the toolhead using the
coordinate system specified in the config file. It is possible to
access the x, y, z, and e components of this position (eg,
`position.x`).
- `homing_origin`: The origin of the gcode coordinate system (relative
to the coordinate system specified in the config file) to use after
a `G28` command. The `SET_GCODE_OFFSET` command can alter this
position. It is possible to access the x, y, and z components of
this position (eg, `homing_origin.x`).
- `speed`: The last speed set in a `G1` command (in mm/s).
- `speed_factor`: The "speed factor override" as set by an `M220`
command. This is a floating point value such that 1.0 means no
override and, for example, 2.0 would double requested speed.
- `extrude_factor`: The "extrude factor override" as set by an `M221`
command. This is a floating point value such that 1.0 means no
override and, for example, 2.0 would double requested extrusions.
- `absolute_coordinates`: This returns True if in `G90` absolute
coordinate mode or False if in `G91` relative mode.
- `absolute_extrude`: This returns True if in `M82` absolute extrude
mode or False if in `M83` relative mode.
## hall_filament_width_sensor
The following information is available in the
[hall_filament_width_sensor](Config_Reference.md#hall_filament_width_sensor)
object:
- `is_active`: Returns True if the sensor is currently active.
- `Diameter`: The last reading from the sensor in mm.
- `Raw`: The last raw ADC reading from the sensor.
## heater
The following information is available for heater objects such as
[extruder](Config_Reference.md#extruder),
[heater_bed](Config_Reference.md#heater_bed), and
[heater_generic](Config_Reference.md#heater_generic):
- `temperature`: The last reported temperature (in Celsius as a float)
for the given heater.
- `target`: The current target temperature (in Celsius as a float) for
the given heater.
- `power`: The last setting of the PWM pin (a value between 0.0 and
1.0) associated with the heater.
- `can_extrude`: If extruder can extrude (defined by `min_extrude_temp`),
available only for [extruder](Config_Reference.md#extruder)
## heaters
The following information is available in the `heaters` object (this
object is available if any heater is defined):
- `available_heaters`: Returns a list of all currently available
heaters by their full config section names, e.g. `["extruder",
"heater_bed", "heater_generic my_custom_heater"]`.
- `available_sensors`: Returns a list of all currently available
temperature sensors by their full config section names,
e.g. `["extruder", "heater_bed", "heater_generic my_custom_heater",
"temperature_sensor electronics_temp"]`.
## idle_timeout
The following information is available in the
[idle_timeout](Config_Reference.md#idle_timeout) object (this object
is always available):
- `state`: The current state of the printer as tracked by the
idle_timeout module. It is one of the following strings: "Idle",
"Printing", "Ready".
- `printing_time`: The amount of time (in seconds) the printer has
been in the "Printing" state (as tracked by the idle_timeout
module).
## led
The following information is available for each `[led led_name]`,
`[neopixel led_name]`, `[dotstar led_name]`, `[pca9533 led_name]`, and
`[pca9632 led_name]` config section defined in printer.cfg:
- `color_data`: A list of color lists containing the RGBW values for a
led in the chain. Each value is represented as a float from 0.0 to
1.0. Each color list contains 4 items (red, green, blue, white) even
if the underyling LED supports fewer color channels. For example,
the blue value (3rd item in color list) of the second neopixel in a
chain could be accessed at
`printer["neopixel <config_name>"].color_data[1][2]`.
## manual_probe
The following information is available in the
`manual_probe` object:
- `is_active`: Returns True if a manual probing helper script is currently
active.
- `z_position`: The current height of the nozzle (as the printer currently
understands it).
- `z_position_lower`: Last probe attempt just lower than the current height.
- `z_position_upper`: Last probe attempt just greater than the current height.
## mcu
The following information is available in
[mcu](Config_Reference.md#mcu) and
[mcu some_name](Config_Reference.md#mcu-my_extra_mcu) objects:
- `mcu_version`: The Klipper code version reported by the
micro-controller.
- `mcu_build_versions`: Information on the build tools used to
generate the micro-controller code (as reported by the
micro-controller).
- `mcu_constants.<constant_name>`: Compile time constants reported by
the micro-controller. The available constants may differ between
micro-controller architectures and with each code revision.
- `last_stats.<statistics_name>`: Statistics information on the
micro-controller connection.
## motion_report
The following information is available in the `motion_report` object
(this object is automatically available if any stepper config section
is defined):
- `live_position`: The requested toolhead position interpolated to the
current time.
- `live_velocity`: The requested toolhead velocity (in mm/s) at the
current time.
- `live_extruder_velocity`: The requested extruder velocity (in mm/s)
at the current time.
## output_pin
The following information is available in
[output_pin some_name](Config_Reference.md#output_pin) objects:
- `value`: The "value" of the pin, as set by a `SET_PIN` command.
## palette2
The following information is available in the
[palette2](Config_Reference.md#palette2) object:
- `ping`: Amount of the last reported Palette 2 ping in percent.
- `remaining_load_length`: When starting a Palette 2 print, this will
be the amount of filament to load into the extruder.
- `is_splicing`: True when the Palette 2 is splicing filament.
## pause_resume
The following information is available in the
[pause_resume](Config_Reference.md#pause_resume) object:
- `is_paused`: Returns true if a PAUSE command has been executed
without a corresponding RESUME.
## print_stats
The following information is available in the `print_stats` object
(this object is automatically available if a
[virtual_sdcard](Config_Reference.md#virtual_sdcard) config section is
defined):
- `filename`, `total_duration`, `print_duration`, `filament_used`,
`state`, `message`: Estimated information about the current print
when a virtual_sdcard print is active.
## probe
The following information is available in the
[probe](Config_Reference.md#probe) object (this object is also
available if a [bltouch](Config_Reference.md#bltouch) config section
is defined):
- `last_query`: Returns True if the probe was reported as "triggered"
during the last QUERY_PROBE command. Note, if this is used in a
macro, due to the order of template expansion, the QUERY_PROBE
command must be run prior to the macro containing this reference.
- `last_z_result`: Returns the Z result value of the last PROBE
command. Note, if this is used in a macro, due to the order of
template expansion, the PROBE (or similar) command must be run prior
to the macro containing this reference.
## quad_gantry_level
The following information is available in the `quad_gantry_level` object
(this object is available if quad_gantry_level is defined):
- `applied`: True if the gantry leveling process has been run and completed
successfully.
## query_endstops
The following information is available in the `query_endstops` object
(this object is available if any endstop is defined):
- `last_query["<endstop>"]`: Returns True if the given endstop was
reported as "triggered" during the last QUERY_ENDSTOP command. Note,
if this is used in a macro, due to the order of template expansion,
the QUERY_ENDSTOP command must be run prior to the macro containing
this reference.
## servo
The following information is available in
[servo some_name](Config_Reference.md#servo) objects:
- `printer["servo <config_name>"].value`: The last setting of the PWM
pin (a value between 0.0 and 1.0) associated with the servo.
## system_stats
The following information is available in the `system_stats` object
(this object is always available):
- `sysload`, `cputime`, `memavail`: Information on the host operating
system and process load.
## temperature sensors
The following information is available in
[bme280 config_section_name](Config_Reference.md#bmp280bme280bme680-temperature-sensor),
[htu21d config_section_name](Config_Reference.md#htu21d-sensor),
[lm75 config_section_name](Config_Reference.md#lm75-temperature-sensor),
and
[temperature_host config_section_name](Config_Reference.md#host-temperature-sensor)
objects:
- `temperature`: The last read temperature from the sensor.
- `humidity`, `pressure`, `gas`: The last read values from the sensor
(only on bme280, htu21d, and lm75 sensors).
## temperature_fan
The following information is available in
[temperature_fan some_name](Config_Reference.md#temperature_fan)
objects:
- `temperature`: The last read temperature from the sensor.
- `target`: The target temperature for the fan.
## temperature_sensor
The following information is available in
[temperature_sensor some_name](Config_Reference.md#temperature_sensor)
objects:
- `temperature`: The last read temperature from the sensor.
- `measured_min_temp`, `measured_max_temp`: The lowest and highest
temperature seen by the sensor since the Klipper host software was
last restarted.
## tmc drivers
The following information is available in
[TMC stepper driver](Config_Reference.md#tmc-stepper-driver-configuration)
objects (eg, `[tmc2208 stepper_x]`):
- `mcu_phase_offset`: The micro-controller stepper position
corresponding with the driver's "zero" phase. This field may be null
if the phase offset is not known.
- `phase_offset_position`: The "commanded position" corresponding to
the driver's "zero" phase. This field may be null if the phase
offset is not known.
- `drv_status`: The results of the last driver status query. (Only
non-zero fields are reported.) This field will be null if the driver
is not enabled (and thus is not periodically queried).
- `run_current`: The currently set run current.
- `hold_current`: The currently set hold current.
## toolhead
The following information is available in the `toolhead` object
(this object is always available):
- `position`: The last commanded position of the toolhead relative to
the coordinate system specified in the config file. It is possible
to access the x, y, z, and e components of this position (eg,
`position.x`).
- `extruder`: The name of the currently active extruder. For example,
in a macro one could use `printer[printer.toolhead.extruder].target`
to get the target temperature of the current extruder.
- `homed_axes`: The current cartesian axes considered to be in a
"homed" state. This is a string containing one or more of "x", "y",
"z".
- `axis_minimum`, `axis_maximum`: The axis travel limits (mm) after
homing. It is possible to access the x, y, z components of this
limit value (eg, `axis_minimum.x`, `axis_maximum.z`).
- `max_velocity`, `max_accel`, `max_accel_to_decel`,
`square_corner_velocity`: The current printing limits that are in
effect. This may differ from the config file settings if a
`SET_VELOCITY_LIMIT` (or `M204`) command alters them at run-time.
- `stalls`: The total number of times (since the last restart) that
the printer had to be paused because the toolhead moved faster than
moves could be read from the G-Code input.
## dual_carriage
The following information is available in
[dual_carriage](Config_Reference.md#dual_carriage)
on a hybrid_corexy or hybrid_corexz robot
- `mode`: The current mode. Possible values are: "FULL_CONTROL"
- `active_carriage`: The current active carriage.
Possible values are: "CARRIAGE_0", "CARRIAGE_1"
## virtual_sdcard
The following information is available in the
[virtual_sdcard](Config_Reference.md#virtual_sdcard) object:
- `is_active`: Returns True if a print from file is currently active.
- `progress`: An estimate of the current print progress (based of file
size and file position).
- `file_path`: A full path to the file of currently loaded file.
- `file_position`: The current position (in bytes) of an active print.
- `file_size`: The file size (in bytes) of currently loaded file.
## webhooks
The following information is available in the `webhooks` object (this
object is always available):
- `state`: Returns a string indicating the current Klipper
state. Possible values are: "ready", "startup", "shutdown", "error".
- `state_message`: A human readable string giving additional context
on the current Klipper state.
## z_tilt
The following information is available in the `z_tilt` object (this
object is available if z_tilt is defined):
- `applied`: True if the z-tilt leveling process has been run and completed
successfully.

557
docs/TMC_Drivers.md Normal file
View File

@@ -0,0 +1,557 @@
# TMC drivers
This document provides information on using Trinamic stepper motor
drivers in SPI/UART mode on Klipper.
Klipper can also use Trinamic drivers in their "standalone mode".
However, when the drivers are in this mode, no special Klipper
configuration is needed and the advanced Klipper features discussed in
this document are not available.
In addition to this document, be sure to review the
[TMC driver config reference](Config_Reference.md#tmc-stepper-driver-configuration).
## Tuning motor current
A higher driver current increases positional accuracy and torque.
However, a higher current also increases the heat produced by the
stepper motor and the stepper motor driver. If the stepper motor
driver gets too hot it will disable itself and Klipper will report an
error. If the stepper motor gets too hot, it loses torque and
positional accuracy. (If it gets very hot it may also melt plastic
parts attached to it or near it.)
As a general tuning tip, prefer higher current values as long as the
stepper motor does not get too hot and the stepper motor driver does
not report warnings or errors. In general, it is okay for the stepper
motor to feel warm, but it should not become so hot that it is painful
to touch.
## Prefer to not specify a hold_current
If one configures a `hold_current` then the TMC driver can reduce
current to the stepper motor when it detects that the stepper is not
moving. However, changing motor current may itself introduce motor
movement. This may occur due to "detent forces" within the stepper
motor (the permanent magnet in the rotor pulls towards the iron teeth
in the stator) or due to external forces on the axis carriage.
Most stepper motors will not obtain a significant benefit to reducing
current during normal prints, because few printing moves will leave a
stepper motor idle for sufficiently long to activate the
`hold_current` feature. And, it is unlikely that one would want to
introduce subtle print artifacts to the few printing moves that do
leave a stepper idle sufficiently long.
If one wishes to reduce current to motors during print start routines,
then consider issuing
[SET_TMC_CURRENT](G-Codes.md#set_tmc_current) commands in a
[START_PRINT macro](Slicers.md#klipper-gcode_macro) to adjust the
current before and after normal printing moves.
Some printers with dedicated Z motors that are idle during normal
printing moves (no bed_mesh, no bed_tilt, no Z skew_correction, no
"vase mode" prints, etc.) may find that Z motors do run cooler with a
`hold_current`. If implementing this then be sure to take into account
this type of uncommanded Z axis movement during bed leveling, bed
probing, probe calibration, and similar. The `driver_TPOWERDOWN` and
`driver_IHOLDDELAY` should also be calibrated accordingly. If unsure,
prefer to not specify a `hold_current`.
## Setting "spreadCycle" vs "stealthChop" Mode
By default, Klipper places the TMC drivers in "spreadCycle" mode. If
the driver supports "stealthChop" then it can be enabled by adding
`stealthchop_threshold: 999999` to the TMC config section.
In general, spreadCycle mode provides greater torque and greater
positional accuracy than stealthChop mode. However, stealthChop mode
may produce significantly lower audible noise on some printers.
Tests comparing modes have shown an increased "positional lag" of
around 75% of a full-step during constant velocity moves when using
stealthChop mode (for example, on a printer with 40mm
rotation_distance and 200 steps_per_rotation, position deviation of
constant speed moves increased by ~0.150mm). However, this "delay in
obtaining the requested position" may not manifest as a significant
print defect and one may prefer the quieter behavior of stealthChop
mode.
It is recommended to always use "spreadCycle" mode (by not specifying
`stealthchop_threshold`) or to always use "stealthChop" mode (by
setting `stealthchop_threshold` to 999999). Unfortunately, the drivers
often produce poor and confusing results if the mode changes while the
motor is at a non-zero velocity.
## TMC interpolate setting introduces small position deviation
The TMC driver `interpolate` setting may reduce the audible noise of
printer movement at the cost of introducing a small systemic
positional error. This systemic positional error results from the
driver's delay in executing "steps" that Klipper sends it. During
constant velocity moves, this delay results in a positional error of
nearly half a configured microstep (more precisely, the error is half
a microstep distance minus a 512th of a full step distance). For
example, on an axis with a 40mm rotation_distance, 200
steps_per_rotation, and 16 microsteps, the systemic error introduced
during constant velocity moves is ~0.006mm.
For best positional accuracy consider using spreadCycle mode and
disable interpolation (set `interpolate: False` in the TMC driver
config). When configured this way, one may increase the `microstep`
setting to reduce audible noise during stepper movement. Typically, a
microstep setting of `64` or `128` will have similar audible noise as
interpolation, and do so without introducing a systemic positional
error.
If using stealthChop mode then the positional inaccuracy from
interpolation is small relative to the positional inaccuracy
introduced from stealthChop mode. Therefore tuning interpolation is
not considered useful when in stealthChop mode, and one can leave
interpolation in its default state.
## Sensorless Homing
Sensorless homing allows to home an axis without the need for a
physical limit switch. Instead, the carriage on the axis is moved into
the mechanical limit making the stepper motor lose steps. The stepper
driver senses the lost steps and indicates this to the controlling MCU
(Klipper) by toggling a pin. This information can be used by Klipper
as end stop for the axis.
This guide covers the setup of sensorless homing for the X axis of
your (cartesian) printer. However, it works the same with all other
axes (that require an end stop). You should configure and tune it for
one axis at a time.
### Limitations
Be sure that your mechanical components are able to handle the load of
the carriage bumping into the limit of the axis repeatedly. Especially
leadscrews might generate a lot of force. Homing a Z axis by bumping
the nozzle into the printing surface might not be a good idea. For
best results, verify that the axis carriage will make a firm contact
with the axis limit.
Further, sensorless homing might not be accurate enough for your
printer. While homing X and Y axes on a cartesian machine can work
well, homing the Z axis is generally not accurate enough and may
result in an inconsistent first layer height. Homing a delta printer
sensorless is not advisable due to missing accuracy.
Further, the stall detection of the stepper driver is dependent on the
mechanical load on the motor, the motor current and the motor
temperature (coil resistance).
Sensorless homing works best at medium motor speeds. For very slow
speeds (less than 10 RPM) the motor does not generate significant back
EMF and the TMC cannot reliably detect motor stalls. Further, at very
high speeds, the back EMF of the motor approaches the supply voltage
of the motor, so the TMC cannot detect stalls anymore. It is advised
to have a look in the datasheet of your specific TMCs. There you can
also find more details on limitations of this setup.
### Prerequisites
A few prerequisites are needed to use sensorless homing:
1. A stallGuard capable TMC stepper driver (tmc2130, tmc2209, tmc2660,
or tmc5160).
2. SPI / UART interface of the TMC driver wired to micro-controller
(stand-alone mode does not work).
3. The appropriate "DIAG" or "SG_TST" pin of TMC driver connected to
the micro-controller.
4. The steps in the [config checks](Config_checks.md) document must be
run to confirm the stepper motors are configured and working
properly.
### Tuning
The procedure described here has six major steps:
1. Choose a homing speed.
2. Configure the `printer.cfg` file to enable sensorless homing.
3. Find the stallguard setting with highest sensitivity that
successfully homes.
4. Find the stallguard setting with lowest sensitivity that
successfully homes with a single touch.
5. Update the `printer.cfg` with the desired stallguard setting.
6. Create or update `printer.cfg` macros to home consistently.
#### Choose homing speed
The homing speed is an important choice when performing sensorless
homing. It's desirable to use a slow homing speed so that the carriage
does not exert excessive force on the frame when making contact with
the end of the rail. However, the TMC drivers can't reliably detect a
stall at very slow speeds.
A good starting point for the homing speed is for the stepper motor to
make a full rotation every two seconds. For many axes this will be the
`rotation_distance` divided by two. For example:
```
[stepper_x]
rotation_distance: 40
homing_speed: 20
...
```
#### Configure printer.cfg for sensorless homing
The `homing_retract_dist` setting must be set to zero in the
`stepper_x` config section to disable the second homing move. The
second homing attempt does not add value when using sensorless homing,
it will not work reliably, and it will confuse the tuning process.
Be sure that a `hold_current` setting is not specified in the TMC
driver section of the config. (If a hold_current is set then after
contact is made, the motor stops while the carriage is pressed against
the end of the rail, and reducing the current while in that position
may cause the carriage to move - that results in poor performance and
will confuse the tuning process.)
It is necessary to configure the sensorless homing pins and to
configure initial "stallguard" settings. A tmc2209 example
configuration for an X axis might look like:
```
[tmc2209 stepper_x]
diag_pin: ^PA1 # Set to MCU pin connected to TMC DIAG pin
driver_SGTHRS: 255 # 255 is most sensitive value, 0 is least sensitive
...
[stepper_x]
endstop_pin: tmc2209_stepper_x:virtual_endstop
homing_retract_dist: 0
...
```
An example tmc2130 or tmc5160 config might look like:
```
[tmc2130 stepper_x]
diag1_pin: ^!PA1 # Pin connected to TMC DIAG1 pin (or use diag0_pin / DIAG0 pin)
driver_SGT: -64 # -64 is most sensitive value, 63 is least sensitive
...
[stepper_x]
endstop_pin: tmc2130_stepper_x:virtual_endstop
homing_retract_dist: 0
...
```
An example tmc2660 config might look like:
```
[tmc2660 stepper_x]
driver_SGT: -64 # -64 is most sensitive value, 63 is least sensitive
...
[stepper_x]
endstop_pin: ^PA1 # Pin connected to TMC SG_TST pin
homing_retract_dist: 0
...
```
The examples above only show settings specific to sensorless
homing. See the
[config reference](Config_Reference.md#tmc-stepper-driver-configuration)
for all the available options.
#### Find highest sensitivity that successfully homes
Place the carriage near the center of the rail. Use the SET_TMC_FIELD
command to set the highest sensitivity. For tmc2209:
```
SET_TMC_FIELD STEPPER=stepper_x FIELD=SGTHRS VALUE=255
```
For tmc2130, tmc5160, and tmc2660:
```
SET_TMC_FIELD STEPPER=stepper_x FIELD=sgt VALUE=-64
```
Then issue a `G28 X0` command and verify the axis does not move at
all. If the axis does move, then issue an `M112` to halt the printer -
something is not correct with the diag/sg_tst pin wiring or
configuration and it must be corrected before continuing.
Next, continually decrease the sensitivity of the `VALUE` setting and
run the `SET_TMC_FIELD` `G28 X0` commands again to find the highest
sensitivity that results in the carriage successfully moving all the
way to the endstop and halting. (For tmc2209 drivers this will be
decreasing SGTHRS, for other drivers it will be increasing sgt.) Be
sure to start each attempt with the carriage near the center of the
rail (if needed issue `M84` and then manually move the carriage to the
center). It should be possible to find the highest sensitivity that
homes reliably (settings with higher sensitivity result in small or no
movement). Note the found value as *maximum_sensitivity*. (If the
minimum possible sensitivity (SGTHRS=0 or sgt=63) is obtained without
any carriage movement then something is not correct with the
diag/sg_tst pin wiring or configuration and it must be corrected
before continuing.)
When searching for maximum_sensitivity, it may be convenient to jump
to different VALUE settings (so as to bisect the VALUE parameter). If
doing this then be prepared to issue an `M112` command to halt the
printer, as a setting with a very low sensitivity may cause the axis
to repeatedly "bang" into the end of the rail.
Be sure to wait a couple of seconds between each homing attempt. After
the TMC driver detects a stall it may take a little time for it to
clear its internal indicator and be capable of detecting another
stall.
During these tuning tests, if a `G28 X0` command does not move all the
way to the axis limit, then be careful with issuing any regular
movement commands (eg, `G1`). Klipper will not have a correct
understanding of the carriage position and a move command may cause
undesirable and confusing results.
#### Find lowest sensitivity that homes with one touch
When homing with the found *maximum_sensitivity* value, the axis
should move to the end of the rail and stop with a "single touch" -
that is, there should not be a "clicking" or "banging" sound. (If
there is a banging or clicking sound at maximum_sensitivity then the
homing_speed may be too low, the driver current may be too low, or
sensorless homing may not be a good choice for the axis.)
The next step is to again continually move the carriage to a position
near the center of the rail, decrease the sensitivity, and run the
`SET_TMC_FIELD` `G28 X0` commands - the goal is now to find the lowest
sensitivity that still results in the carriage successfully homing
with a "single touch". That is, it does not "bang" or "click" when
contacting the end of the rail. Note the found value as
*minimum_sensitivity*.
#### Update printer.cfg with sensitivity value
After finding *maximum_sensitivity* and *minimum_sensitivity*, use a
calculator to obtain the recommend sensitivity as
*minimum_sensitivity + (maximum_sensitivity - minimum_sensitivity)/3*.
The recommended sensitivity should be in the range between the minimum
and maximum, but slightly closer to the minimum. Round the final value
to the nearest integer value.
For tmc2209 set this in the config as `driver_SGTHRS`, for other TMC
drivers set this in the config as `driver_SGT`.
If the range between *maximum_sensitivity* and *minimum_sensitivity*
is small (eg, less than 5) then it may result in unstable homing. A
faster homing speed may increase the range and make the operation more
stable.
Note that if any change is made to driver current, homing speed, or a
notable change is made to the printer hardware, then it will be
necessary to run the tuning process again.
#### Using Macros when Homing
After sensorless homing completes the carriage will be pressed against
the end of the rail and the stepper will exert a force on the frame
until the carriage is moved away. It is a good idea to create a macro
to home the axis and immediately move the carriage away from the end
of the rail.
It is a good idea for the macro to pause at least 2 seconds prior to
starting sensorless homing (or otherwise ensure that there has been no
movement on the stepper for 2 seconds). Without a delay it is possible
for the driver's internal stall flag to still be set from a previous
move.
It can also be useful to have that macro set the driver current before
homing and set a new current after the carriage has moved away.
An example macro might look something like:
```
[gcode_macro SENSORLESS_HOME_X]
gcode:
{% set HOME_CUR = 0.700 %}
{% set driver_config = printer.configfile.settings['tmc2209 stepper_x'] %}
{% set RUN_CUR = driver_config.run_current %}
# Set current for sensorless homing
SET_TMC_CURRENT STEPPER=stepper_x CURRENT={HOME_CUR}
# Pause to ensure driver stall flag is clear
G4 P2000
# Home
G28 X0
# Move away
G90
G1 X5 F1200
# Set current during print
SET_TMC_CURRENT STEPPER=stepper_x CURRENT={RUN_CUR}
```
The resulting macro can be called from a
[homing_override config section](Config_Reference.md#homing_override)
or from a [START_PRINT macro](Slicers.md#klipper-gcode_macro).
Note that if the driver current during homing is changed, then the
tuning process should be run again.
### Tips for sensorless homing on CoreXY
It is possible to use sensorless homing on the X and Y carriages of a
CoreXY printer. Klipper uses the `[stepper_x]` stepper to detect
stalls when homing the X carriage and uses the `[stepper_y]` stepper
to detect stalls when homing the Y carriage.
Use the tuning guide described above to find the appropriate "stall
sensitivity" for each carriage, but be aware of the following
restrictions:
1. When using sensorless homing on CoreXY, make sure there is no
`hold_current` configured for either stepper.
2. While tuning, make sure both the X and Y carriages are near the
center of their rails before each home attempt.
3. After tuning is complete, when homing both X and Y, use macros to
ensure that one axis is homed first, then move that carriage away
from the axis limit, pause for at least 2 seconds, and then start
the homing of the other carriage. The move away from the axis
avoids homing one axis while the other is pressed against the axis
limit (which may skew the stall detection). The pause is necessary
to ensure the driver's stall flag is cleared prior to homing again.
## Querying and diagnosing driver settings
The `[DUMP_TMC command](G-Codes.md#dump_tmc) is a useful tool when
configuring and diagnosing the drivers. It will report all fields
configured by Klipper as well as all fields that can be queried from
the driver.
All of the reported fields are defined in the Trinamic datasheet for
each driver. These datasheets can be found on the
[Trinamic website](https://www.trinamic.com/). Obtain and review the
Trinamic datasheet for the driver to interpret the results of
DUMP_TMC.
## Configuring driver_XXX settings
Klipper supports configuring many low-level driver fields using
`driver_XXX` settings. The
[TMC driver config reference](Config_Reference.md#tmc-stepper-driver-configuration)
has the full list of fields available for each type of driver.
In addition, almost all fields can be modified at run-time using the
[SET_TMC_FIELD command](G-Codes.md#set_tmc_field).
Each of these fields is defined in the Trinamic datasheet for each
driver. These datasheets can be found on the
[Trinamic website](https://www.trinamic.com/).
Note that the Trinamic datasheets sometime use wording that can
confuse a high-level setting (such as "hysteresis end") with a
low-level field value (eg, "HEND"). In Klipper, `driver_XXX` and
SET_TMC_FIELD always set the low-level field value that is actually
written to the driver. So, for example, if the Trinamic datasheet
states that a value of 3 must be written to the HEND field to obtain a
"hysteresis end" of 0, then set `driver_HEND=3` to obtain the
high-level value of 0.
## Common Questions
### Can I use stealthChop mode on an extruder with pressure advance?
Many people successfully use "stealthChop" mode with Klipper's
pressure advance. Klipper implements
[smooth pressure advance](Kinematics.md#pressure-advance) which does
not introduce any instantaneous velocity changes.
However, "stealthChop" mode may produce lower motor torque and/or
produce higher motor heat. It may or may not be an adequate mode for
your particular printer.
### I keep getting "Unable to read tmc uart 'stepper_x' register IFCNT" errors?
This occurs when Klipper is unable to communicate with a tmc2208 or
tmc2209 driver.
Make sure that the motor power is enabled, as the stepper motor driver
generally needs motor power before it can communicate with the
micro-controller.
If this error occurs after flashing Klipper for the first time, then
the stepper driver may have been previously programmed in a state that
is not compatible with Klipper. To reset the state, remove all power
from the printer for several seconds (physically unplug both USB and
power plugs).
Otherwise, this error is typically the result of incorrect UART pin
wiring or an incorrect Klipper configuration of the UART pin settings.
### I keep getting "Unable to write tmc spi 'stepper_x' register ..." errors?
This occurs when Klipper is unable to communicate with a tmc2130 or
tmc5160 driver.
Make sure that the motor power is enabled, as the stepper motor driver
generally needs motor power before it can communicate with the
micro-controller.
Otherwise, this error is typically the result of incorrect SPI wiring,
an incorrect Klipper configuration of the SPI settings, or an
incomplete configuration of devices on an SPI bus.
Note that if the driver is on a shared SPI bus with multiple devices
then be sure to fully configure every device on that shared SPI bus in
Klipper. If a device on a shared SPI bus is not configured, then it
may incorrectly respond to commands not intended for it and corrupt
the communication to the intended device. If there is a device on a
shared SPI bus that can not be configured in Klipper, then use a
[static_digital_output config section](Config_Reference.md#static_digital_output)
to set the CS pin of the unused device high (so that it will not
attempt to use the SPI bus). The board's schematic is often a useful
reference for finding which devices are on an SPI bus and their
associated pins.
### Why did I get a "TMC reports error: ..." error?
This type of error indicates the TMC driver detected a problem and has
disabled itself. That is, the driver stopped holding its position and
ignored movement commands. If Klipper detects that an active driver
has disabled itself, it will transition the printer into a "shutdown"
state.
It's also possible that a **TMC reports error** shutdown occurs due to
SPI errors that prevent communication with the driver (on tmc2130,
tmc5160, or tmc2660). If this occurs, it's common for the reported
driver status to show `00000000` or `ffffffff` - for example: `TMC
reports error: DRV_STATUS: ffffffff ...` OR `TMC reports error:
READRSP@RDSEL2: 00000000 ...`. Such a failure may be due to an SPI
wiring problem or may be due to a self-reset or failure of the TMC
driver.
Some common errors and tips for diagnosing them:
#### TMC reports error: `... ot=1(OvertempError!)`
This indicates the motor driver disabled itself because it became too
hot. Typical solutions are to decrease the stepper motor current,
increase cooling on the stepper motor driver, and/or increase cooling
on the stepper motor.
#### TMC reports error: `... ShortToGND` OR `LowSideShort`
This indicates the driver has disabled itself because it detected very
high current passing through the driver. This may indicate a loose or
shorted wire to the stepper motor or within the stepper motor itself.
This error may also occur if using stealthChop mode and the TMC driver
is not able to accurately predict the mechanical load of the motor.
(If the driver makes a poor prediction then it may send too much
current through the motor and trigger its own over-current detection.)
To test this, disable stealthChop mode and check if the errors
continue to occur.
#### TMC reports error: `... reset=1(Reset)` OR `CS_ACTUAL=0(Reset?)` OR `SE=0(Reset?)`
This indicates that the driver has reset itself mid-print. This may be
due to voltage or wiring issues.
#### TMC reports error: `... uv_cp=1(Undervoltage!)`
This indicates the driver has detected a low-voltage event and has
disabled itself. This may be due to wiring or power supply issues.
### How do I tune spreadCycle/coolStep/etc. mode on my drivers?
The [Trinamic website](https://www.trinamic.com/) has guides on
configuring the drivers. These guides are often technical, low-level,
and may require specialized hardware. Regardless, they are the best
source of information.

View File

@@ -0,0 +1,22 @@
# TSL1401CL filament width sensor
This document describes Filament Width Sensor host module. Hardware used
for developing this host module is based on TSL1401CL linear sensor array
but it can work with any sensor array that has analog output. You can find
designs at [Thingiverse](https://www.thingiverse.com/search?q=filament%20width%20sensor).
To use a sensor array as a filament width sensor, read
[Config Reference](Config_Reference.md#tsl1401cl_filament_width_sensor) and
[G-Code documentation](G-Codes.md#hall_filament_width_sensor).
## How does it work?
Sensor generates analog output based on calculated filament width. Output
voltage always equals to detected filament width (Ex. 1.65v, 1.70v, 3.0v).
Host module monitors voltage changes and adjusts extrusion multiplier.
## Note:
Sensor readings done with 10 mm intervals by default. If necessary you are
free to change this setting by editing ***MEASUREMENT_INTERVAL_MM*** parameter
in **filament_width_sensor.py** file.

69
docs/Using_PWM_Tools.md Normal file
View File

@@ -0,0 +1,69 @@
# Using PWM tools
This document describes how to setup a PWM-controlled laser or spindle
using `output_pin` and some macros.
## How does it work?
With re-purposing the printhead's fan pwm output, you can control
lasers or spindles.
This is useful if you use switchable print heads, for example
the E3D toolchanger or a DIY solution.
Usually, cam-tools such as LaserWeb can be configured to use `M3-M5`
commands, which stand for _spindle speed CW_ (`M3 S[0-255]`),
_spindle speed CCW_ (`M4 S[0-255]`) and _spindle stop_ (`M5`).
**Warning:** When driving a laser, keep all security precautions
that you can think of! Diode lasers are usually inverted.
This means, that when the MCU restarts, the laser will be
_fully on_ for the time it takes the MCU to start up again.
For good measure, it is recommended to _always_ wear appropriate
laser-goggles of the right wavelength if the laser is powered;
and to disconnect the laser when it is not needed.
Also, you should configure a safety timeout,
so that when your host or MCU encounters an error, the tool will stop.
For an example configuration, see [config/sample-pwm-tool.cfg](/config/sample-pwm-tool.cfg).
## Current Limitations
There is a limitation of how frequent PWM updates may occur.
While being very precise, a PWM update may only occur every 0.1 seconds,
rendering it almost useless for raster engraving.
However, there exists an [experimental branch](https://github.com/Cirromulus/klipper/tree/laser_tool) with its own tradeoffs.
In long term, it is planned to add this functionality to main-line klipper.
## Commands
`M3/M4 S<value>` : Set PWM duty-cycle. Values between 0 and 255.
`M5` : Stop PWM output to shutdown value.
## Laserweb Configuration
If you use Laserweb, a working configuration would be:
GCODE START:
M5 ; Disable Laser
G21 ; Set units to mm
G90 ; Absolute positioning
G0 Z0 F7000 ; Set Non-Cutting speed
GCODE END:
M5 ; Disable Laser
G91 ; relative
G0 Z+20 F4000 ;
G90 ; absolute
GCODE HOMING:
M5 ; Disable Laser
G28 ; Home all axis
TOOL ON:
M3 $INTENSITY
TOOL OFF:
M5 ; Disable Laser
LASER INTENSITY:
S

20
docs/_klipper3d/README Normal file
View File

@@ -0,0 +1,20 @@
This directory defines the https://www.klipper3d.org/ website. The
site is hosted using "github pages". The
.github/workflows/klipper3d-deploy.yaml tool uses mkdocs (
https://www.mkdocs.org/ ) to automatically convert the markdown files
in the docs/ directory to html. In addition to the files in this
directory, the docs/CNAME file also controls the website generation.
To test deploy the main English site locally one can use commands
similar to the following:
virtualenv ~/mkdocs-env && ~/python-env/bin/pip install -r ~/klipper/docs/_klipper3d/mkdocs-requirements.txt
cd ~/klipper && ~/mkdocs-env/bin/mkdocs serve --config-file ~/klipper/docs/_klipper3d/mkdocs.yml -a 0.0.0.0:8000
To test deploy the multi-language site locally one can use commands
similar to the following:
virtualenv ~/mkdocs-env && ~/python-env/bin/pip install -r ~/klipper/docs/_klipper3d/mkdocs-requirements.txt
source ~/mkdocs-env/bin/activate
cd ~/klipper && ./docs/_klipper3d/build-translations.sh
cd ~/klipper/site/ && python3 -m http.server 8000

View File

@@ -0,0 +1,84 @@
#!/bin/bash
# This script extracts the Klipper translations and builds multiple
# mdocs sites - one for each supported language. See the README file
# for additional details.
MKDOCS_DIR="docs/_klipper3d/"
WORK_DIR="work/"
TRANS_DIR="${WORK_DIR}klipper-translations/"
TRANS_FILE="${TRANS_DIR}active_translations"
MKDOCS_MAIN="${MKDOCS_DIR}mkdocs-main.yml"
# Fetch translations
git clone --depth 1 https://github.com/Klipper3d/klipper-translations ${TRANS_DIR}
# Create new mkdocs-main.yml with language links
cp ${MKDOCS_DIR}mkdocs.yml ${MKDOCS_MAIN}
while IFS="," read dirname langsite langdesc langsearch; do
sed -i "s%^.*# Alternate language links automatically added here$% - name: ${langdesc}\n link: /${langsite}/\n lang: ${langsite}\n\0%" ${MKDOCS_MAIN}
done < <(egrep -v '^ *(#|$)' ${TRANS_FILE})
# Build main English website
echo "building site for en"
mkdocs build -f ${MKDOCS_MAIN}
# Build each additional language website
while IFS="," read dirname langsite langdesc langsearch; do
new_docs_dir="${WORK_DIR}lang/${langsite}/docs/"
locale_dir="${TRANS_DIR}/docs/locales/${dirname}"
# read toc
title=$(sed -n '1p' ${locale_dir}/Navigation.md)
installation_and_configuration=$(sed -n '3p' ${locale_dir}/Navigation.md)
configuration_reference=$(sed -n '5p' ${locale_dir}/Navigation.md)
bed_level=$(sed -n '7p' ${locale_dir}/Navigation.md)
resonance_compensation=$(sed -n '9p' ${locale_dir}/Navigation.md)
command_template=$(sed -n '11p' ${locale_dir}/Navigation.md)
developer_documentation=$(sed -n '13p' ${locale_dir}/Navigation.md)
device_specific_documents=$(sed -n '15p' ${locale_dir}/Navigation.md)
# Copy markdown files to new_docs_dir
echo "Copying $dirname to $langsite"
mkdir -p "${new_docs_dir}"
cp "${locale_dir}"/*.md "${new_docs_dir}"
echo "copy resources"
cp -r docs/img "${new_docs_dir}"
cp -r docs/prints "${new_docs_dir}"
cp -r docs/_klipper3d "${new_docs_dir}"
# manually replace index.md if a manual-index.md exist
manual_index="${new_docs_dir}manual-index.md"
if [[ -f "${manual_index}" ]]; then
mv -f "${manual_index}" "${new_docs_dir}index.md"
echo "replaced index.md with manual_index.md for $langsite"
else
echo "Manually translated index file for $langsite not found!"
fi
# Create language specific mkdocs-lang-xxx.yml file
echo "create language specific mkdocs configurations for ${langsite}"
new_mkdocs_file="${new_docs_dir}_klipper3d/mkdocs-lang-${langsite}.yml"
cp "${MKDOCS_MAIN}" "${new_mkdocs_file}"
echo "replace search language"
sed -i "s%^ lang: en$% lang: ${langsearch}%" "${new_mkdocs_file}"
echo "replace site language"
sed -i "s%^ language: en$% language: ${langsite}%" "${new_mkdocs_file}"
echo "replace toc"
sed -i "s%Klipper documentation$%${title}%" "${new_mkdocs_file}"
sed -i "s%Installation and Configuration:$%${installation_and_configuration}:%" "${new_mkdocs_file}"
sed -i "s%Configuration Reference:$%${configuration_reference}:%" "${new_mkdocs_file}"
sed -i "s%Bed Level:$%${bed_level}:%" "${new_mkdocs_file}"
sed -i "s%Resonance Compensation:$%${resonance_compensation}:%" "${new_mkdocs_file}"
sed -i "s%Command templates:$%${command_template}:%" "${new_mkdocs_file}"
sed -i "s%Developer Documentation:$%${developer_documentation}:%" "${new_mkdocs_file}"
sed -i "s%Device Specific Documents:$%${device_specific_documents}:%" "${new_mkdocs_file}"
# Build site
echo "building site for ${langsite}"
mkdir -p "${PWD}/site/${langsite}/"
ln -sf "${PWD}/site/${langsite}/" "${WORK_DIR}lang/${langsite}/site"
mkdocs build -f "${new_mkdocs_file}"
done < <(egrep -v '^ *(#|$)' ${TRANS_FILE})

View File

@@ -0,0 +1,16 @@
/* Customization of mkdocs generated site */
[data-md-color-scheme="slate"] {
--md-primary-fg-color: hsla(var(--md-hue),15%,12%,1);
--md-default-bg-color: hsla(var(--md-hue),17%,17%,1);
--md-typeset-a-color: steelblue;
--md-accent-fg-color: lightblue;
}
img {
background-color: white;
}
.center-image {
margin: 0 auto;
display: block;
}

View File

@@ -0,0 +1,10 @@
# Python virtualenv module requirements for mkdocs
jinja2==3.0.3
mkdocs==1.2.3
mkdocs-material==8.1.3
mkdocs-simple-hooks==0.1.3
mkdocs-exclude==1.0.2
mdx-truly-sane-lists==1.2
mdx-breakless-lists==1.0.1
py-gfm==1.0.2
markdown==3.3.7

138
docs/_klipper3d/mkdocs.yml Normal file
View File

@@ -0,0 +1,138 @@
# Main configuration file for mkdocs generation of klipper3d.org website
# Note that the build-translations.sh script expects a certain file
# layout. See that script and the README file for more details.
# Site and directory configuration
site_name: Klipper documentation
repo_url: https://github.com/Klipper3d/klipper
repo_name: Klipper3d/klipper
edit_uri: blob/master/docs/
use_directory_urls: False
docs_dir: '../'
site_dir: '../../site/'
# Custom markdown dialect settings
markdown_extensions:
- toc:
permalink: True
toc_depth: 6
- attr_list
- mdx_partial_gfm
- mdx_truly_sane_lists
- mdx_breakless_lists
plugins:
search:
lang: en
mkdocs-simple-hooks:
hooks:
on_page_markdown: "docs._klipper3d.mkdocs_hooks:transform"
exclude:
glob: "README.md"
# Website layout configuration (using mkdocs-material theme)
theme:
name: material
palette:
- media: "(prefers-color-scheme: light)"
scheme: default
primary: white
accent: blue
toggle:
icon: material/lightbulb
name: Switch to dark mode
- media: "(prefers-color-scheme: dark)"
scheme: slate
primary: grey
accent: light blue
toggle:
icon: material/lightbulb-outline
name: Switch to light mode
logo: img/klipper.svg
favicon: img/favicon.ico
icon:
repo: fontawesome/brands/github
alternate: material/web
features:
#- navigation.tabs
#- navigation.expand
- navigation.top
# if enabled, the TOC doesn't work for some pages
# - toc.integrate
- search.suggest
- search.highlight
- search.share
language: en
extra_css:
- _klipper3d/css/extra.css
# Site usage statistics
extra:
# https://squidfunk.github.io/mkdocs-material/setup/setting-up-site-analytics/#site-search-tracking
analytics:
provider: google
property: UA-138371409-1
# Language Selection
alternate:
- name: English
link: /
lang: en
# Alternate language links automatically added here
# Navigation hierarchy (this should mimic the layout of Overview.md)
nav:
- Overview.md
- Features.md
- FAQ.md
- Releases.md
- Config_Changes.md
- Contact.md
- Installation and Configuration:
- Installation.md
- Configuration Reference:
- Config_Reference.md
- Rotation_Distance.md
- Config_checks.md
- Bed Level:
- Bed_Level.md
- Delta_Calibrate.md
- Probe_Calibrate.md
- BLTouch.md
- Manual_Level.md
- Bed_Mesh.md
- Endstop_Phase.md
- Resonance Compensation:
- Resonance_Compensation.md
- Measuring_Resonances.md
- Pressure_Advance.md
- G-Codes.md
- Command templates:
- Command_Templates.md
- Status_Reference.md
- TMC_Drivers.md
- Multi_MCU_Homing.md
- Slicers.md
- Skew_Correction.md
- Exclude_Object.md
- Using_PWM_Tools.md
- Developer Documentation:
- Code_Overview.md
- Kinematics.md
- Protocol.md
- API_Server.md
- MCU_Commands.md
- CANBUS_protocol.md
- Debugging.md
- Benchmarks.md
- CONTRIBUTING.md
- Packaging.md
- Device Specific Documents:
- Example_Configs.md
- SDCard_Updates.md
- RPi_microcontroller.md
- Beaglebone.md
- Bootloaders.md
- CANBUS.md
- TSL1401CL_Filament_Width_Sensor.md
- Hall_Filament_Width_Sensor.md
- Sponsors.md

View File

@@ -0,0 +1,42 @@
# Tool to customize conversion of markdown files during mkdocs site generation
import re
import logging
# This script translates some github specific markdown formatting to
# improve rendering with mkdocs. The goal is for pages to render
# similarly on both github and the web site. It has three main tasks:
# 1. Convert links outside of the docs directory (any reference
# starting with "../") to an absolute link to the raw file on
# github.
# 2. Convert a trailing backslash on a text line to a "<br>".
# 3. Remove leading spaces from top-level lists so that those lists
# are rendered correctly.
logger = logging.getLogger('mkdocs.mkdocs_hooks.transform')
def transform(markdown: str, page, config, files):
in_code_block = 0
in_list = False
lines = markdown.splitlines()
for i in range(len(lines)):
line_out = lines[i]
in_code_block = (in_code_block +
len(re.findall("\s*[`]{3,}", line_out))) % 2
if not in_code_block:
line_out = line_out.replace('](../',
f"]({config['repo_url']}blob/master/")
line_out = re.sub("\\\s*$", "<br>", line_out)
# check that lists at level 0 are not indented
# (no space before *|-|1.)
if re.match(r"^[^-*0-9 ]", line_out):
in_list = False
elif re.match(r"^(\*|-|\d+\.) ", line_out):
in_list = True
if not in_list:
line_out = re.sub(r"^\s+(\*|-|\d+\.) ", r"\1 ", line_out)
if line_out != lines[i]:
logger.debug((f'[mkdocs_hooks] rewrite line {i+1}: '
f'"{lines[i]}" -> "{line_out}"'))
lines[i] = line_out
output = "\n".join(lines)
return output

View File

@@ -0,0 +1,37 @@
Developer Certificate of Origin
Version 1.1
Copyright (C) 2004, 2006 The Linux Foundation and its contributors.
1 Letterman Drive
Suite D4700
San Francisco, CA, 94129
Everyone is permitted to copy and distribute verbatim copies of this
license document, but changing it is not allowed.
Developer's Certificate of Origin 1.1
By making a contribution to this project, I certify that:
(a) The contribution was created in whole or in part by me and I
have the right to submit it under the open source license
indicated in the file; or
(b) The contribution is based upon previous work that, to the best
of my knowledge, is covered under an appropriate open source
license and I have the right under that license to submit that
work with modifications, whether created in whole or in part
by me, under the same open source license (unless I am
permitted to submit under a different license), as indicated
in the file; or
(c) The contribution was provided directly to me by some other
person who certified (a), (b) or (c) and I have not modified
it.
(d) I understand and agree that this project and the contribution
are public and that a record of the contribution (including all
personal information I submit with it, including my sign-off) is
maintained indefinitely and may be redistributed consistent with
this project or the open source license(s) involved.

Binary file not shown.

After

Width:  |  Height:  |  Size: 207 KiB

BIN
docs/img/adxl345-mount.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 112 KiB

BIN
docs/img/attach-issue.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 10 KiB

202
docs/img/bed_screws.svg Normal file
View File

@@ -0,0 +1,202 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
width="210mm"
height="297mm"
viewBox="0 0 210 297"
version="1.1"
id="svg8"
sodipodi:docname="bed_screws.svg"
inkscape:version="0.92.3 (2405546, 2018-03-11)"
inkscape:export-filename="/home/kevin/src/reprap/firmware/klipper/docs/img/bed_screws.svg.png"
inkscape:export-xdpi="96"
inkscape:export-ydpi="96">
<defs
id="defs2" />
<sodipodi:namedview
id="base"
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1.0"
inkscape:pageopacity="0.0"
inkscape:pageshadow="2"
inkscape:zoom="2.0149341"
inkscape:cx="209.05542"
inkscape:cy="598.47875"
inkscape:document-units="mm"
inkscape:current-layer="layer1"
showgrid="false"
inkscape:window-width="1920"
inkscape:window-height="1030"
inkscape:window-x="0"
inkscape:window-y="0"
inkscape:window-maximized="1" />
<metadata
id="metadata5">
<rdf:RDF>
<cc:Work
rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
<dc:title />
</cc:Work>
</rdf:RDF>
</metadata>
<g
inkscape:label="Layer 1"
inkscape:groupmode="layer"
id="layer1">
<rect
style="opacity:1;fill:#ffffff;fill-opacity:0.96456695;stroke:#ffffff;stroke-width:0.39099997;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
id="rect928"
width="74.716049"
height="98.089432"
x="70.776711"
y="87.033455"
inkscape:export-xdpi="96"
inkscape:export-ydpi="96" />
<rect
style="opacity:1;fill:#c8c8c8;fill-opacity:1;stroke:#030000;stroke-width:0.39099997;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
id="rect815"
width="65.011902"
height="88.446426"
x="75.595238"
y="91.380951"
inkscape:export-xdpi="96"
inkscape:export-ydpi="96" />
<rect
style="opacity:1;fill:#00ff00;fill-opacity:0;stroke:#00ff00;stroke-width:0.39099997;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
id="rect844"
width="0.22808908"
height="92.832253"
x="103.55245"
y="89.324898" />
<g
id="g947"
transform="translate(0,4.4645794)">
<g
transform="translate(8.8954742,-0.79831178)"
id="g848">
<ellipse
style="opacity:1;fill:#fd0000;fill-opacity:0;stroke:#ff0000;stroke-width:0.39099997;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
id="path817"
cx="94.828026"
cy="114.18661"
rx="0.85533404"
ry="0.79831177" />
<ellipse
style="opacity:1;fill:#000000;fill-opacity:0;stroke:#ff0000;stroke-width:0.391;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
id="path817-3"
cx="94.771011"
cy="144.97864"
rx="0.85533404"
ry="0.79831183" />
</g>
<text
inkscape:export-ydpi="96"
inkscape:export-xdpi="96"
id="text858"
y="112.47593"
x="105.26311"
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:2.82222223px;line-height:125%;font-family:sans-serif;-inkscape-font-specification:'sans-serif, Normal';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-feature-settings:normal;text-align:start;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.26458332px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
xml:space="preserve"><tspan
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:2.82222223px;font-family:sans-serif;-inkscape-font-specification:'sans-serif, Normal';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-feature-settings:normal;text-align:start;writing-mode:lr-tb;text-anchor:start;stroke-width:0.26458332px"
y="112.47593"
x="105.26311"
id="tspan856"
sodipodi:role="line">A</tspan><tspan
id="tspan860"
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:2.82222223px;font-family:sans-serif;-inkscape-font-specification:'sans-serif, Normal';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-feature-settings:normal;text-align:start;writing-mode:lr-tb;text-anchor:start;stroke-width:0.26458332px"
y="116.00371"
x="105.26311"
sodipodi:role="line" /></text>
<text
inkscape:export-ydpi="96"
inkscape:export-xdpi="96"
id="text864"
y="142.81177"
x="105.14907"
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:2.82222223px;line-height:125%;font-family:sans-serif;-inkscape-font-specification:'sans-serif, Normal';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-feature-settings:normal;text-align:start;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.26458332px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
xml:space="preserve"><tspan
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:2.82222223px;font-family:sans-serif;-inkscape-font-specification:'sans-serif, Normal';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-feature-settings:normal;text-align:start;writing-mode:lr-tb;text-anchor:start;stroke-width:0.26458332px"
y="142.81177"
x="105.14907"
id="tspan862"
sodipodi:role="line">B</tspan></text>
<g
inkscape:export-ydpi="96"
inkscape:export-xdpi="96"
transform="translate(-42.652658,1.5966236)"
id="g876">
<ellipse
style="opacity:1;fill:#000000;fill-opacity:0;stroke:#ff0000;stroke-width:0.391;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
id="path817-6"
cx="125.56304"
cy="127.41576"
rx="0.85533404"
ry="0.79831183" />
<text
xml:space="preserve"
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:2.82222223px;line-height:125%;font-family:sans-serif;-inkscape-font-specification:'sans-serif, Normal';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-feature-settings:normal;text-align:start;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.26458332px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
x="126.93158"
y="126.5034"
id="text868"><tspan
sodipodi:role="line"
id="tspan866"
x="126.93158"
y="126.5034"
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:2.82222223px;font-family:sans-serif;-inkscape-font-specification:'sans-serif, Normal';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-feature-settings:normal;text-align:start;writing-mode:lr-tb;text-anchor:start;stroke-width:0.26458332px">C</tspan><tspan
sodipodi:role="line"
x="126.93158"
y="130.03117"
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:2.82222223px;font-family:sans-serif;-inkscape-font-specification:'sans-serif, Normal';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-feature-settings:normal;text-align:start;writing-mode:lr-tb;text-anchor:start;stroke-width:0.26458332px"
id="tspan870" /></text>
</g>
</g>
<g
id="g952"
transform="translate(-0.26262232,4.2019571)">
<path
inkscape:export-ydpi="96"
inkscape:export-xdpi="96"
inkscape:transform-center-y="-0.024320163"
inkscape:transform-center-x="-0.059466795"
d="m 138.45007,129.24048 -0.43835,-0.37484 -0.55729,0.14861 0.22103,-0.53273 -0.31355,-0.4841 0.57496,0.0456 0.36351,-0.44779 0.13432,0.56091 0.53821,0.20734 -0.49196,0.30107 z"
inkscape:randomized="0"
inkscape:rounded="0"
inkscape:flatsided="false"
sodipodi:arg2="1.7942231"
sodipodi:arg1="1.1659045"
sodipodi:r2="0.43426865"
sodipodi:r1="0.86853731"
sodipodi:cy="128.44217"
sodipodi:cx="138.10794"
sodipodi:sides="5"
id="path878"
style="opacity:1;fill:#00ff00;fill-opacity:0;stroke:#0000ff;stroke-width:0.39099997;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
sodipodi:type="star" />
<text
inkscape:export-ydpi="96"
inkscape:export-xdpi="96"
id="text882"
y="126.33394"
x="137.52043"
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:2.82222223px;line-height:125%;font-family:sans-serif;-inkscape-font-specification:'sans-serif, Normal';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-feature-settings:normal;text-align:start;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.26458332px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
xml:space="preserve"><tspan
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:2.82222223px;font-family:sans-serif;-inkscape-font-specification:'sans-serif, Normal';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-feature-settings:normal;text-align:start;writing-mode:lr-tb;text-anchor:start;stroke-width:0.26458332px"
y="126.33394"
x="137.52043"
id="tspan880"
sodipodi:role="line">D</tspan></text>
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 11 KiB

BIN
docs/img/bed_screws.svg.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.8 KiB

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 33 KiB

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 38 KiB

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 23 KiB

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 33 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 157 KiB

BIN
docs/img/calibrate-x.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 162 KiB

BIN
docs/img/calibrate-y.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 148 KiB

BIN
docs/img/corner-blob.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.6 KiB

BIN
docs/img/corner-dimple.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.3 KiB

BIN
docs/img/corner-good.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.3 KiB

187
docs/img/corner.svg Normal file
View File

@@ -0,0 +1,187 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
width="54.904114mm"
height="6.0860338mm"
viewBox="0 0 194.54213 21.564687"
id="svg3506"
version="1.1"
inkscape:version="1.1 (c68e22c387, 2021-05-23)"
sodipodi:docname="corner.svg"
inkscape:export-filename="/home/kevin/src/reprap/firmware/klipper/docs/img/corner.svg.png"
inkscape:export-xdpi="89.734001"
inkscape:export-ydpi="89.734001"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns="http://www.w3.org/2000/svg"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:dc="http://purl.org/dc/elements/1.1/">
<defs
id="defs3508">
<marker
inkscape:stockid="DiamondL"
orient="auto"
refY="0"
refX="0"
id="DiamondL"
style="overflow:visible"
inkscape:isstock="true">
<path
id="path4399"
d="M 0,-7.0710768 -7.0710894,0 0,7.0710589 7.0710462,0 0,-7.0710768 Z"
style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1pt;stroke-opacity:1"
transform="scale(0.8,0.8)"
inkscape:connector-curvature="0" />
</marker>
<marker
inkscape:stockid="Arrow2Lend"
orient="auto"
refY="0"
refX="0"
id="Arrow2Lend"
style="overflow:visible"
inkscape:isstock="true">
<path
id="path4341"
style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:0.625;stroke-linejoin:round;stroke-opacity:1"
d="M 8.7185878,4.0337352 -2.2072895,0.01601326 8.7185884,-4.0017078 c -1.7454984,2.3720609 -1.7354408,5.6174519 -6e-7,8.035443 z"
transform="matrix(-1.1,0,0,-1.1,-1.1,0)"
inkscape:connector-curvature="0" />
</marker>
<marker
inkscape:stockid="Arrow1Mend"
orient="auto"
refY="0"
refX="0"
id="marker4596"
style="overflow:visible"
inkscape:isstock="true">
<path
id="path4598"
d="M 0,0 5,-5 -12.5,0 5,5 0,0 Z"
style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1pt;stroke-opacity:1"
transform="matrix(-0.4,0,0,-0.4,-4,0)"
inkscape:connector-curvature="0" />
</marker>
<marker
inkscape:stockid="Arrow1Mend"
orient="auto"
refY="0"
refX="0"
id="Arrow1Mend"
style="overflow:visible"
inkscape:isstock="true">
<path
id="path4329"
d="M 0,0 5,-5 -12.5,0 5,5 0,0 Z"
style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1pt;stroke-opacity:1"
transform="matrix(-0.4,0,0,-0.4,-4,0)"
inkscape:connector-curvature="0" />
</marker>
<marker
inkscape:stockid="Arrow1Mend"
orient="auto"
refY="0"
refX="0"
id="Arrow1Mend-1"
style="overflow:visible"
inkscape:isstock="true">
<path
inkscape:connector-curvature="0"
id="path4329-1"
d="M 0,0 5,-5 -12.5,0 5,5 0,0 Z"
style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1pt;stroke-opacity:1"
transform="matrix(-0.4,0,0,-0.4,-4,0)" />
</marker>
</defs>
<sodipodi:namedview
id="base"
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1.0"
inkscape:pageopacity="1"
inkscape:pageshadow="2"
inkscape:zoom="2.49"
inkscape:cx="94.97992"
inkscape:cy="0"
inkscape:document-units="px"
inkscape:current-layer="layer1"
showgrid="true"
fit-margin-top="0"
fit-margin-left="0"
fit-margin-right="0"
fit-margin-bottom="0"
showborder="false"
inkscape:window-width="1068"
inkscape:window-height="487"
inkscape:window-x="378"
inkscape:window-y="113"
inkscape:window-maximized="0"
inkscape:pagecheckerboard="0">
<inkscape:grid
type="xygrid"
id="grid6021"
spacingx="9.9999997"
spacingy="10.000001"
originx="0.89299989"
originy="-30.954583" />
</sodipodi:namedview>
<metadata
id="metadata3511">
<rdf:RDF>
<cc:Work
rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
</cc:Work>
</rdf:RDF>
</metadata>
<g
inkscape:label="Layer 1"
inkscape:groupmode="layer"
id="layer1"
transform="translate(-253.40821,-436.43703)">
<path
style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:3;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;marker-end:url(#Arrow1Mend)"
d="m 345.38554,440.31401 96.88541,12.96764"
id="path3514"
inkscape:connector-curvature="0"
sodipodi:nodetypes="cc" />
<path
style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:3;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;marker-end:url(#Arrow1Mend-1)"
d="m 253.63788,454.62572 89.78715,-13.91164"
id="path3514-5"
inkscape:connector-curvature="0"
sodipodi:nodetypes="cc" />
<text
xml:space="preserve"
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;line-height:0%;font-family:'DejaVu Sans';-inkscape-font-specification:'DejaVu Sans, Normal';text-align:start;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
x="189.09824"
y="482.48389"
id="text12656-9"
transform="rotate(-9.0348846)"
inkscape:transform-center-x="1.3563414"
inkscape:transform-center-y="-5.7099754"><tspan
sodipodi:role="line"
id="tspan5552"
x="189.09824"
y="482.48389"
style="font-size:11.25px;line-height:1.25">move 1</tspan></text>
<text
xml:space="preserve"
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;line-height:0%;font-family:'DejaVu Sans';-inkscape-font-specification:'DejaVu Sans, Normal';text-align:start;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
x="427.95532"
y="379.5321"
id="text12656-9-8"
transform="rotate(8.3123803)"><tspan
sodipodi:role="line"
id="tspan5554"
x="427.95532"
y="379.5321"
style="font-size:11.25px;line-height:1.25">move 2</tspan></text>
</g>
</svg>

After

Width:  |  Height:  |  Size: 6.8 KiB

BIN
docs/img/corner.svg.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 24 KiB

BIN
docs/img/delta-a-pillar.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 31 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 27 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 24 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 27 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 24 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 19 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 20 KiB

BIN
docs/img/favicon.ico Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.5 KiB

BIN
docs/img/klipper-logo.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 20 KiB

113
docs/img/klipper.svg Normal file
View File

@@ -0,0 +1,113 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
width="100%"
height="100%"
viewBox="0 0 768 624"
version="1.1"
xml:space="preserve"
style="fill-rule:evenodd;clip-rule:evenodd;stroke-linejoin:round;stroke-miterlimit:1.41421;"
id="svg40"
sodipodi:docname="klipper.svg"
inkscape:version="0.92.4 (unknown)"
inkscape:export-filename="/home/kevin/src/reprap/firmware/klipper/logs/logo-20190416/klipper6.svg.png"
inkscape:export-xdpi="96"
inkscape:export-ydpi="96"><metadata
id="metadata46"><rdf:RDF><cc:Work
rdf:about=""><dc:format>image/svg+xml</dc:format><dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" /><dc:title /></cc:Work></rdf:RDF></metadata><defs
id="defs44">
</defs><sodipodi:namedview
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1"
objecttolerance="10"
gridtolerance="10"
guidetolerance="10"
inkscape:pageopacity="0"
inkscape:pageshadow="2"
inkscape:window-width="1920"
inkscape:window-height="1030"
id="namedview42"
showgrid="false"
inkscape:zoom="0.95"
inkscape:cx="327.89418"
inkscape:cy="289.76441"
inkscape:window-x="0"
inkscape:window-y="0"
inkscape:window-maximized="1"
inkscape:current-layer="svg40"
showguides="false"
showborder="false"><inkscape:grid
type="xygrid"
id="grid905" /></sodipodi:namedview>
<path
style="fill:#3c4b5a"
d="m 30,34 v 140 l 260,255 115,-5 h 80 L 730,174 V 34 H 720 L 385,374 40,34 Z"
id="path2"
inkscape:connector-curvature="0"
sodipodi:nodetypes="ccccccccccc" /><path
style="fill:#3c4b5a;stroke-width:1.03280997"
d="m 140,418 -58,57 1,25 v 19 l 57,57 h 27 v -1 L 91,496.5 167,419 v -1 z"
id="path8"
inkscape:connector-curvature="0"
sodipodi:nodetypes="ccccccccccc" /><g
transform="translate(-1.08348e-4,0.048)"
id="g17">
<path
d="m 83.041215,464.92108 h 0.001 l -0.04211,27.03092 h 11 l 73.000005,-74 v 14.301 l -63,64.199 63,65.5 v 14 l -73.000002,-75 h -13 c -2,0 -4,-2 -4,-4 h -2 v -33 h 2 c 0,-1 1,-2 3.00004,-2 1.99996,0 2.99996,1 2.99996,2 z"
style="fill:#b12f35"
id="path15"
inkscape:connector-curvature="0"
sodipodi:nodetypes="cccccccccccccccccc" />
</g><g
id="path839"
transform="matrix(1.03281,0,0,1.0326797,24.31099,-21.921569)">
<rect
x="21"
y="426"
width="30.015202"
height="153"
style="fill:#3c4b5a;fill-rule:nonzero"
id="rect12" />
</g><rect
x="247"
y="469"
width="24"
height="107"
style="fill:#3c4b5a;stroke-width:1.19609642"
id="rect23" /><path
d="m 371.98888,521.45953 c 0,-10.8903 -2.45322,-19.36013 -7.36207,-25.4107 -4.90765,-6.05057 -12.80741,-9.07465 -23.69929,-9.07465 -2.28639,0 -4.6724,0.10081 -7.16044,0.30241 -2.48802,0.20161 -4.94125,0.63842 -7.36207,1.31044 v 60.29926 c 2.15197,1.47844 5.00967,2.85727 8.57188,4.13411 3.56342,1.27684 7.36208,1.91526 11.39597,1.91526 8.87554,0 15.36385,-3.02409 19.46496,-9.07465 4.10111,-6.05057 6.15106,-14.18439 6.15106,-24.40148 z M 397,521.05632 c 0,8.06663 -1.04178,15.46123 -3.12654,22.18261 -2.08476,6.72259 -5.07568,12.50434 -8.97515,17.34409 -3.89947,4.83973 -8.77472,8.60423 -14.62333,11.29351 -5.8498,2.68927 -12.47254,4.0333 -19.86702,4.0333 -4.97606,0 -9.54765,-0.60481 -13.71597,-1.81445 -4.16832,-1.21082 -7.59731,-2.55487 -10.28698,-4.03451 V 611 H 302 V 471.64736 c 4.97486,-1.34524 11.09352,-2.62207 18.35477,-3.83171 C 327.61602,466.60482 335.28055,466 343.34834,466 c 8.33664,0 15.79953,1.27684 22.38866,3.83171 6.58794,2.55487 12.20251,6.21857 16.84131,10.9911 4.6388,4.77253 8.20221,10.5543 10.69024,17.34408 2.48684,6.78859 3.73145,14.4184 3.73145,22.88943 z"
style="fill:#3c4b5a;fill-rule:nonzero;stroke-width:1.20011997"
id="path25"
inkscape:connector-curvature="0" /><path
d="m 492.9892,521.45953 c 0,-10.8903 -2.4544,-19.36013 -7.36198,-25.4107 -4.90759,-6.05057 -12.80725,-9.07465 -23.699,-9.07465 -2.28636,0 -4.67354,0.10081 -7.16034,0.30241 -2.488,0.20161 -4.94119,0.63842 -7.36197,1.31044 v 60.29926 c 2.15074,1.47844 5.00839,2.85727 8.57176,4.13411 3.56337,1.27684 7.36198,1.91526 11.39582,1.91526 8.87423,0 15.36246,-3.02409 19.46352,-9.07465 4.10106,-6.05057 6.15219,-14.18439 6.15219,-24.40148 z M 518,521.05632 c 0,8.06663 -1.04297,15.46123 -3.1265,22.18261 -2.08474,6.72259 -5.07681,12.50434 -8.97624,17.34409 -3.89942,4.83973 -8.77341,8.60423 -14.62314,11.29351 -5.84854,2.68927 -12.47119,4.0333 -19.86677,4.0333 -4.9748,0 -9.54633,-0.60481 -13.7146,-1.81445 -4.16827,-1.21082 -7.59722,-2.55487 -10.28684,-4.03451 V 611 H 423 V 471.64736 c 4.97599,-1.34524 11.09337,-2.62207 18.35454,-3.83171 C 448.61569,466.60482 456.28012,466 464.34782,466 c 8.33773,0 15.80052,1.27684 22.38838,3.83171 6.58905,2.55487 12.20235,6.21857 16.84229,10.9911 4.63875,4.77253 8.20211,10.5543 10.69012,17.34408 2.48679,6.78859 3.73139,14.4184 3.73139,22.88943 z"
style="fill:#3c4b5a;fill-rule:nonzero;stroke-width:1.20011246"
id="path27"
inkscape:connector-curvature="0" /><path
d="m 537,521.00591 c 0,-9.30123 1.37492,-17.45591 4.12595,-24.46521 2.74984,-7.00931 6.40632,-12.83838 10.96942,-17.48839 4.56191,-4.65121 9.79451,-8.15587 15.699,-10.51396 5.90328,-2.3593 11.94191,-3.53835 18.11469,-3.53835 14.49054,0 25.79531,4.51527 33.91308,13.5458 8.11897,9.03174 12.17786,22.51016 12.17786,40.43768 0,1.34749 -0.0335,2.8646 -0.1006,4.54896 -0.0671,1.68555 -0.16768,3.20147 -0.30182,4.55015 h -69.43942 c 0.67068,8.49155 3.65646,15.06171 8.95733,19.71294 5.29967,4.65001 12.98149,6.97562 23.04547,6.97562 5.9033,0 11.30477,-0.5402 16.20202,-1.61818 4.89726,-1.07799 8.75493,-2.22335 11.57304,-3.43729 l 3.22052,20.01612 c -1.34138,0.67495 -3.18699,1.38237 -5.53561,2.12349 -2.34742,0.74112 -5.03139,1.41485 -8.05071,2.02242 -3.01811,0.60637 -6.27217,1.11168 -9.76096,1.51592 -3.4888,0.40425 -7.04467,0.60637 -10.66761,0.60637 -9.25915,0 -17.30985,-1.38116 -24.15211,-4.14471 -6.84346,-2.76354 -12.47968,-6.60507 -16.90744,-11.52457 -4.42778,-4.91951 -7.71537,-10.7161 -9.86278,-17.38854 C 538.0731,536.27095 537,528.95845 537,521.00591 Z m 70.64548,-10.91821 c 0,-3.36991 -0.46948,-6.57138 -1.40846,-9.60442 -0.93897,-3.03303 -2.31508,-5.66063 -4.12595,-7.88517 -1.81207,-2.22335 -4.02535,-3.97627 -6.64226,-5.25638 -2.61689,-1.28131 -5.73561,-1.92137 -9.35855,-1.92137 -3.75708,0 -7.04466,0.70743 -9.86278,2.1235 -2.8181,1.41484 -5.19906,3.26883 -7.14527,5.55956 -1.94501,2.29192 -3.45526,4.92071 -4.52837,7.88516 -1.0731,2.96567 -1.81206,5.99871 -2.21447,9.09912 z"
style="fill:#3c4b5a;fill-rule:nonzero;stroke-width:1.20038378"
id="path29"
inkscape:connector-curvature="0" /><path
d="m 717.7869,492.26931 c -2.00567,-0.67394 -4.78138,-1.38159 -8.32593,-2.12292 -3.54453,-0.74135 -7.65736,-1.11202 -12.33845,-1.11202 -2.67542,0 -5.51799,0.26957 -8.52649,0.80874 -3.0097,0.53915 -5.11684,1.01091 -6.32025,1.41528 V 576 H 658 V 475.28104 c 4.68109,-1.75347 10.53216,-3.40464 17.55439,-4.95472 C 682.57663,468.77504 690.36771,468 698.92762,468 c 1.60574,0 3.47769,0.10109 5.61827,0.30328 2.13938,0.20218 4.27996,0.47176 6.42053,0.80873 2.13939,0.33697 4.2131,0.74255 6.21878,1.21431 2.00687,0.47176 3.6114,0.90983 4.8148,1.3142 z"
style="fill:#3c4b5a;fill-rule:nonzero;stroke-width:1.19865453"
id="path31"
inkscape:connector-curvature="0" /><path
sodipodi:nodetypes="cccccccccccccc"
d="M 259,424 H 360 V 359 L 30,34 H 90 L 385,324 670,34 h 60 L 410,359 v 84.99783 C 410,449 405,454 400,454 H 259 c -12,0 -14,-10 -14,-15 0,-5 2,-15 14,-15 z"
style="fill:#b12f35"
id="path35"
inkscape:connector-curvature="0" />
<rect
id="rect12-6"
style="clip-rule:evenodd;fill:#3c4b5a;fill-rule:nonzero;stroke-width:1.03280997;stroke-linejoin:round;stroke-miterlimit:1.41420996"
height="158"
width="24"
y="418"
x="191" /></svg>

After

Width:  |  Height:  |  Size: 8.0 KiB

208
docs/img/lookahead-slow.svg Normal file
View File

@@ -0,0 +1,208 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
width="97.22496mm"
height="32.550285mm"
viewBox="0 0 344.49789 115.33566"
id="svg2"
version="1.1"
inkscape:version="1.1 (c68e22c387, 2021-05-23)"
sodipodi:docname="lookahead-slow.svg"
inkscape:export-filename="/home/kevin/src/reprap/firmware/klipper/docs/img/lookahead-slow.svg.png"
inkscape:export-xdpi="90"
inkscape:export-ydpi="90"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns="http://www.w3.org/2000/svg"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:dc="http://purl.org/dc/elements/1.1/">
<defs
id="defs4">
<marker
inkscape:stockid="Arrow1Mend"
orient="auto"
refY="0"
refX="0"
id="Arrow1Mend-1"
style="overflow:visible"
inkscape:isstock="true">
<path
inkscape:connector-curvature="0"
id="path4329-1"
d="M 0,0 5,-5 -12.5,0 5,5 0,0 Z"
style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1pt;stroke-opacity:1"
transform="matrix(-0.4,0,0,-0.4,-4,0)" />
</marker>
<marker
inkscape:stockid="Arrow1Mend"
orient="auto"
refY="0"
refX="0"
id="Arrow1Mend"
style="overflow:visible"
inkscape:isstock="true">
<path
id="path4329"
d="M 0,0 5,-5 -12.5,0 5,5 0,0 Z"
style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1pt;stroke-opacity:1"
transform="matrix(-0.4,0,0,-0.4,-4,0)"
inkscape:connector-curvature="0" />
</marker>
</defs>
<sodipodi:namedview
id="base"
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1.0"
inkscape:pageopacity="1"
inkscape:pageshadow="2"
inkscape:zoom="1.15"
inkscape:cx="3.4782609"
inkscape:cy="101.30435"
inkscape:document-units="px"
inkscape:current-layer="layer1"
showgrid="false"
inkscape:window-width="1091"
inkscape:window-height="588"
inkscape:window-x="149"
inkscape:window-y="422"
inkscape:window-maximized="0"
fit-margin-top="0"
fit-margin-left="0"
fit-margin-right="0"
fit-margin-bottom="0"
showborder="false"
inkscape:snap-global="false"
showguides="false"
inkscape:pagecheckerboard="0">
<inkscape:grid
type="xygrid"
id="grid3436" />
</sodipodi:namedview>
<metadata
id="metadata7">
<rdf:RDF>
<cc:Work
rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
</cc:Work>
</rdf:RDF>
</metadata>
<g
inkscape:label="Layer 1"
inkscape:groupmode="layer"
id="layer1"
transform="translate(-135.22429,-249.96955)">
<path
style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
d="m 150,250.23455 1.06383,102.12765 327.12765,-0.53192 -7.97871,5.85107"
id="path3347"
inkscape:connector-curvature="0"
sodipodi:nodetypes="cccc" />
<text
xml:space="preserve"
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;line-height:0%;font-family:'DejaVu Sans';-inkscape-font-specification:'DejaVu Sans, Normal';text-align:start;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
x="434.04257"
y="365.1282"
id="text3349"><tspan
sodipodi:role="line"
id="tspan3351"
x="434.04257"
y="365.1282"
style="font-size:12.5px;line-height:1">time</tspan></text>
<text
xml:space="preserve"
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;line-height:0%;font-family:'DejaVu Sans';-inkscape-font-specification:'DejaVu Sans, Normal';text-align:start;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
x="-313.86618"
y="140.27856"
id="text3353"
transform="rotate(-90.917558)"><tspan
sodipodi:role="line"
id="tspan3355"
x="-313.86618"
y="140.27856"
style="font-size:12.5px;line-height:1.25">velocity</tspan></text>
<path
style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
d="m 150,250.23455 -5.31915,8.51063"
id="path3359"
inkscape:connector-curvature="0" />
<path
style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:0.62366331px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
d="m 179.63013,351.45141 16.05677,-60.94328 43.25999,0 16.53759,47.11348"
id="path3361"
inkscape:connector-curvature="0"
sodipodi:nodetypes="cccc" />
<path
style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:0.7558428px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
d="m 254.72406,337.27551 22.65101,-77.77178 43.89917,0 24.69858,91.73948"
id="path3361-7"
inkscape:connector-curvature="0"
sodipodi:nodetypes="cccc" />
<text
xml:space="preserve"
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;line-height:0%;font-family:'DejaVu Sans';-inkscape-font-specification:'DejaVu Sans, Normal';text-align:start;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
x="195.45749"
y="286.52051"
id="text12656-9"><tspan
sodipodi:role="line"
id="tspan7078"
x="195.45749"
y="286.52051"
style="font-size:11.25px;line-height:1.25">move A</tspan></text>
<text
xml:space="preserve"
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;line-height:0%;font-family:'DejaVu Sans';-inkscape-font-specification:'DejaVu Sans, Normal';text-align:start;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
x="280.5639"
y="254.60564"
id="text12656-9-3"><tspan
sodipodi:role="line"
id="tspan7080"
x="280.5639"
y="254.60564"
style="font-size:11.25px;line-height:1.25">move B</tspan></text>
<path
style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:3;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;marker-end:url(#Arrow1Mend)"
d="m 74.333855,283.02668 -147.83244,52.19984"
id="path3514"
inkscape:connector-curvature="0"
sodipodi:nodetypes="cc" />
<path
style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:3;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;marker-end:url(#Arrow1Mend-1)"
d="m -79.633985,251.6122 154.13499,31.81455"
id="path3514-5"
inkscape:connector-curvature="0"
sodipodi:nodetypes="cc" />
<text
xml:space="preserve"
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;line-height:0%;font-family:'DejaVu Sans';-inkscape-font-specification:'DejaVu Sans, Normal';text-align:start;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
x="36.7374"
y="252.31848"
id="text12656-9-1"
transform="rotate(14.638795)"
inkscape:transform-center-x="-0.91382951"
inkscape:transform-center-y="-4.9145266"><tspan
sodipodi:role="line"
id="tspan7074"
x="36.7374"
y="252.31848"
style="font-size:11.25px;line-height:1.25">move A</tspan></text>
<text
xml:space="preserve"
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;line-height:0%;font-family:'DejaVu Sans';-inkscape-font-specification:'DejaVu Sans, Normal';text-align:start;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
x="-126.26086"
y="304.35226"
id="text12656-9-8"
transform="rotate(-20.215565)"><tspan
sodipodi:role="line"
id="tspan7076"
x="-126.26086"
y="304.35226"
style="font-size:11.25px;line-height:1.25">move B</tspan></text>
</g>
</svg>

After

Width:  |  Height:  |  Size: 9.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 13 KiB

139
docs/img/lookahead.svg Normal file
View File

@@ -0,0 +1,139 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
width="97.22496mm"
height="32.550285mm"
viewBox="0 0 344.49789 115.33566"
id="svg2"
version="1.1"
inkscape:version="1.1 (c68e22c387, 2021-05-23)"
sodipodi:docname="lookahead.svg"
inkscape:export-filename="/home/kevin/src/reprap/firmware/klipper/docs/img/lookahead.svg.png"
inkscape:export-xdpi="89.734001"
inkscape:export-ydpi="89.734001"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns="http://www.w3.org/2000/svg"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:dc="http://purl.org/dc/elements/1.1/">
<defs
id="defs4" />
<sodipodi:namedview
id="base"
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1.0"
inkscape:pageopacity="1"
inkscape:pageshadow="2"
inkscape:zoom="0.94"
inkscape:cx="117.02128"
inkscape:cy="46.276596"
inkscape:document-units="px"
inkscape:current-layer="layer1"
showgrid="false"
inkscape:window-width="1091"
inkscape:window-height="588"
inkscape:window-x="149"
inkscape:window-y="422"
inkscape:window-maximized="0"
fit-margin-top="0"
fit-margin-left="0"
fit-margin-right="0"
fit-margin-bottom="0"
showborder="false"
inkscape:snap-global="false"
showguides="false"
inkscape:pagecheckerboard="0">
<inkscape:grid
type="xygrid"
id="grid3436" />
</sodipodi:namedview>
<metadata
id="metadata7">
<rdf:RDF>
<cc:Work
rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
</cc:Work>
</rdf:RDF>
</metadata>
<g
inkscape:label="Layer 1"
inkscape:groupmode="layer"
id="layer1"
transform="translate(-135.22429,-249.96955)">
<path
style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
d="m 150,250.23455 1.06383,102.12765 327.12765,-0.53192 -7.97871,5.85107"
id="path3347"
inkscape:connector-curvature="0"
sodipodi:nodetypes="cccc" />
<text
xml:space="preserve"
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;line-height:0%;font-family:'DejaVu Sans';-inkscape-font-specification:'DejaVu Sans, Normal';text-align:start;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
x="434.04257"
y="365.1282"
id="text3349"><tspan
sodipodi:role="line"
id="tspan3351"
x="434.04257"
y="365.1282"
style="font-size:12.5px;line-height:1">time</tspan></text>
<text
xml:space="preserve"
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;line-height:0%;font-family:'DejaVu Sans';-inkscape-font-specification:'DejaVu Sans, Normal';text-align:start;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
x="-313.86618"
y="140.27856"
id="text3353"
transform="rotate(-90.917558)"><tspan
sodipodi:role="line"
id="tspan3355"
x="-313.86618"
y="140.27856"
style="font-size:12.5px;line-height:1.25">velocity</tspan></text>
<path
style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
d="m 150,250.23455 -5.31915,8.51063"
id="path3359"
inkscape:connector-curvature="0" />
<path
style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:0.62366331px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
d="m 179.63013,351.45141 16.05677,-60.94328 61.3451,0 4.83546,8.81561"
id="path3361"
inkscape:connector-curvature="0"
sodipodi:nodetypes="cccc" />
<path
style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:0.7558428px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
d="m 261.70791,300.17937 13.5395,-40.67564 59.85662,0 24.69858,91.73948"
id="path3361-7"
inkscape:connector-curvature="0"
sodipodi:nodetypes="cccc" />
<text
xml:space="preserve"
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;line-height:0%;font-family:'DejaVu Sans';-inkscape-font-specification:'DejaVu Sans, Normal';text-align:start;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
x="200.77664"
y="286.52051"
id="text12656-9"><tspan
sodipodi:role="line"
id="tspan5532"
x="200.77664"
y="286.52051"
style="font-size:11.25px;line-height:1.25">move 1</tspan></text>
<text
xml:space="preserve"
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;line-height:0%;font-family:'DejaVu Sans';-inkscape-font-specification:'DejaVu Sans, Normal';text-align:start;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
x="280.5639"
y="255.66946"
id="text12656-9-3"><tspan
sodipodi:role="line"
id="tspan5534"
x="280.5639"
y="255.66946"
style="font-size:11.25px;line-height:1.25">move 2</tspan></text>
</g>
</svg>

After

Width:  |  Height:  |  Size: 5.9 KiB

BIN
docs/img/lookahead.svg.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 40 KiB

209
docs/img/ooze.svg Normal file
View File

@@ -0,0 +1,209 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
width="98.140816mm"
height="63.537022mm"
viewBox="0 0 347.74305 225.13119"
id="svg2"
version="1.1"
inkscape:version="1.1 (c68e22c387, 2021-05-23)"
sodipodi:docname="ooze.svg"
inkscape:export-filename="/home/kevin/src/reprap/firmware/klipper/docs/img/ooze.svg.png"
inkscape:export-xdpi="90"
inkscape:export-ydpi="90"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns="http://www.w3.org/2000/svg"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:dc="http://purl.org/dc/elements/1.1/">
<defs
id="defs4" />
<sodipodi:namedview
id="base"
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1.0"
inkscape:pageopacity="1"
inkscape:pageshadow="2"
inkscape:zoom="0.94"
inkscape:cx="198.93617"
inkscape:cy="59.042553"
inkscape:document-units="px"
inkscape:current-layer="layer1"
showgrid="false"
inkscape:window-width="1091"
inkscape:window-height="588"
inkscape:window-x="266"
inkscape:window-y="106"
inkscape:window-maximized="0"
fit-margin-top="0"
fit-margin-left="0"
fit-margin-right="0"
fit-margin-bottom="0"
showborder="false"
inkscape:snap-global="false"
showguides="false"
inkscape:pagecheckerboard="0">
<inkscape:grid
type="xygrid"
id="grid3436"
originx="-1.5695746e-05"
originy="109.79552" />
</sodipodi:namedview>
<metadata
id="metadata7">
<rdf:RDF>
<cc:Work
rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
</cc:Work>
</rdf:RDF>
</metadata>
<g
inkscape:label="Layer 1"
inkscape:groupmode="layer"
id="layer1"
transform="translate(-135.22431,-249.96955)">
<path
style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
d="m 150,250.23455 1.06383,102.12765 327.12765,-0.53192 -7.97871,5.85107"
id="path3347"
inkscape:connector-curvature="0"
sodipodi:nodetypes="cccc" />
<text
xml:space="preserve"
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;line-height:0%;font-family:'DejaVu Sans';-inkscape-font-specification:'DejaVu Sans, Normal';text-align:start;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
x="-346.84067"
y="139.75046"
id="text3353"
transform="rotate(-90.917558)"><tspan
sodipodi:role="line"
id="tspan12733"
x="-346.84067"
y="139.75046"
style="font-size:12.5px;line-height:1.25">head velocity</tspan></text>
<path
style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
d="m 150,250.23455 -5.31915,8.51063"
id="path3359"
inkscape:connector-curvature="0" />
<path
style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:2.00000024;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
d="m 179.63013,351.45141 16.05677,-60.94328 120.91957,-1.06383 16.53759,62.00711"
id="path3361"
inkscape:connector-curvature="0"
sodipodi:nodetypes="cccc" />
<path
style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:0.78742969px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
d="m 332.99641,351.24986 16.72764,-63.00287 133.24331,0"
id="path3361-7"
inkscape:connector-curvature="0"
sodipodi:nodetypes="ccc" />
<text
xml:space="preserve"
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;line-height:0%;font-family:'DejaVu Sans';-inkscape-font-specification:'DejaVu Sans, Normal';text-align:start;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
x="200.11789"
y="284.45413"
id="text12656"><tspan
sodipodi:role="line"
id="tspan12658"
x="200.11789"
y="284.45413"
style="font-size:11.25px;line-height:1.25">extrude move</tspan></text>
<text
xml:space="preserve"
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;line-height:0%;font-family:'DejaVu Sans';-inkscape-font-specification:'DejaVu Sans, Normal';text-align:start;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
x="356.50089"
y="283.39032"
id="text12660"><tspan
sodipodi:role="line"
id="tspan12662"
x="356.50089"
y="283.39032"
style="font-size:11.25px;line-height:1.25">non-extrude move</tspan></text>
<path
style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
d="m 152.72419,471.73218 1.06383,102.12766 327.12768,-0.53192 -7.97872,5.85107"
id="path3347-0"
inkscape:connector-curvature="0"
sodipodi:nodetypes="cccc" />
<text
xml:space="preserve"
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;line-height:0%;font-family:'DejaVu Sans';-inkscape-font-specification:'DejaVu Sans, Normal';text-align:start;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
x="436.76678"
y="586.62585"
id="text3349-3"><tspan
sodipodi:role="line"
id="tspan3351-4"
x="436.76678"
y="586.62585"
style="font-size:12.5px;line-height:1">time</tspan></text>
<text
xml:space="preserve"
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;line-height:0%;font-family:'DejaVu Sans';-inkscape-font-specification:'DejaVu Sans, Normal';text-align:start;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
x="-551.11292"
y="125.37186"
id="text3353-0"
transform="rotate(-90.917558)"><tspan
sodipodi:role="line"
id="tspan4197"
x="-551.11292"
y="125.37186"
style="font-size:12.5px;line-height:1.25">actual</tspan><tspan
sodipodi:role="line"
id="tspan4199"
x="-551.11292"
y="140.99686"
style="font-size:12.5px;line-height:1.25">filament</tspan></text>
<path
style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
d="m 152.72419,471.73218 -5.31915,8.51063"
id="path3359-9"
inkscape:connector-curvature="0" />
<path
style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:2.00000024;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
d="m 182.35432,572.94905 c 17.46262,-43.80215 52.67413,-56.54375 92.65253,-60.94329 l 48.57915,-1.06383 c 24.916,55.4715 110.00504,59.23318 151.64398,62.00712"
id="path3361-1"
inkscape:connector-curvature="0"
sodipodi:nodetypes="cccc" />
<path
style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
d="m 150.87843,360.66993 1.06383,102.12766 327.12768,-0.53192 -7.97872,5.85107"
id="path3347-8"
inkscape:connector-curvature="0"
sodipodi:nodetypes="cccc" />
<text
xml:space="preserve"
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;line-height:0%;font-family:'DejaVu Sans';-inkscape-font-specification:'DejaVu Sans, Normal';text-align:start;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
x="-444.27307"
y="124.17301"
id="text3353-6"
transform="rotate(-90.917558)"><tspan
sodipodi:role="line"
id="tspan4193"
x="-444.27307"
y="124.17301"
style="font-size:12.5px;line-height:1.25">desired</tspan><tspan
sodipodi:role="line"
id="tspan4195"
x="-444.27307"
y="139.79802"
style="font-size:12.5px;line-height:1.25">filament</tspan></text>
<path
style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
d="m 150.87843,360.66993 -5.31915,8.51063"
id="path3359-8"
inkscape:connector-curvature="0" />
<path
style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:2.00000024;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
d="m 180.50856,461.8868 16.05678,-60.94329 120.91958,-1.06383 16.53759,62.00712"
id="path3361-4"
inkscape:connector-curvature="0"
sodipodi:nodetypes="cccc" />
</g>
</svg>

After

Width:  |  Height:  |  Size: 9.7 KiB

BIN
docs/img/ooze.svg.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 20 KiB

BIN
docs/img/paper-test.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 30 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 24 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 49 KiB

BIN
docs/img/ringing-mark.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 44 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 31 KiB

BIN
docs/img/ringing-test.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 65 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 42 KiB

Some files were not shown because too many files have changed in this diff Show More