Marlin Firmware for Hangprinter
Torbjørn also forked Marlin Firmware and pulled back a lot of stuff into official Marlin feature tree
- G95 (torque mode) - G95 Set servo torque mode status. Accepts 0 or 1
- G96 (zero encoders) - G96 Tell sensor servo to mark its reference point
- G97 (measure) - G97 Get sensor servo length travelled since last G96
Adapted gcodes that still use XYZE parameters:
- G0/G1 (inverse kinematics)
Adapted gcodes that use ABCDE parameters:
Adapted gcodes with other parameters
- M665 (set Hangprinter anchor positions / Auto Calibration Simulation Input Parameters)
- M114 S1 (read encoder mm movement since reference point was marked)
New features that also work on non-Hangprinter machines:
Features that are Hangprinter specific:
XYZfor indexing and initializing arrays that refer to kinematic axes (movement axes on physical machine) rather than the cartesian axes of incoming gcode.
E_AXISfor indexing arrays that refer to cartesian axes of incoming gcode.
Auto Calibration Simulation for Hangprinter (Python script)
The Hangprinter Project has a goal of auto-calibration. That requires locating anchor points by sampling relative line lengths with tight lines at unknown positions. This code tries to optimize the anchor positions to fit the samples of relative line lengths. Note that this code assumes that the B-anchor has a positive x-coordinate. If your machine's B-anchor is negative then your output anchors Bx and Cx will have the wrong signs.
The script will only work if you have closed loop steppers like Smart Stepper or Mechaduino installed. Only with I2C connected hardware a positional feedback is possible to get with M114 S1 command.
Installation on Windows 10 (64 Bit) with Python 3.7.5
Installation on raspbian (Python 2.7)
this does not work with older Python 3.5 which is on Raspbian Stretch (my case), so use old Python 2.7.
Test example (run the script)
How to Collect Data Points?
Data collection depends on Smart Stepper and well calibrated line buildup compensation.
- Go into torque mode on all motors and adjust torque magnitude as you prefer.
- Drag mover to the origin and zero counters:
G92 X0 Y0 Z0
- Mark reference point for all encoders:
G96 A B C D(Stock Marlin accepts
G96as a short hand for
G96 A B C D)
- Repeat 13 - ca 20 times:
- Drag mover to position of data point collection.
- Collect data point:
M114 S1(M114: Get Current Position)
How to Insert Data Points?
Before you run the simulation, open
simulation.py and modify the main function, near the bottom of the file. Replace
?? with data points collected with your Hangprinter.
When values are inserted, run again with
The first block give some stats trying to describe the quality of the parameters that were found
It's recommended to use 13 samples or more. Using fewer samples makes it probable that the solver finds bogus anchor positions that still minimizes cost.
Ideal data points collected on an ideal machine would give
total cost: 0.000000 for any sample size above 10. In real life this does not happen. The
cost per sample value let you compare results from your different data sets of unequal size.
The second block contains the anchor positions that the script found. They are formatted so they can be pasted directly into Marlin's
The gcode line that is the third block can be used to set anchor calibration values on a running Hangprinter without re-uploading firmware.
If you have
EEPROM_SETTINGS enabled you can save these values with
M500. If you don't save them they will be forgotten when you power down your machine.
The script accepts a
--debug flag. It calculates the difference between the output anchor positions and your manually measured ones:
Err_ABCD_XYZ-values to be meaningful you must have inserted your manually measured values into the
anchors array in the script:
The debug check is only relevant if you suspect that the script outputs bogus values. Error larger than ca 100 mm is generally a sign that something's up.
Alternative Optimization Algorithms
The script accepts a
--method argument. Try for example
If you want to use the
PowellDirectionalSolver, you also need Mystic:
For more on usage, try