On startup, the encoder module will use the on-board RGB LEDs to signal status information. This information can be useful if you are having trouble with an encoder module, and need to diagnose the problem.
The LED will pulse several times in different colours, and information on decoding these pulses is below.
|First||Communication with encoder IC||Red||Failure|
|Second||Saved Settings Found?||Magenta||Not found, reinitialising to defaults|
|Green||Settings found, restored|
|Third||Module I2C Address||Blue||30 (X)|
As an example, a sequence of flashes coloured green, green and blue, would indicate that the encoder IC is working (good), saved settings have been found (so module has been powered and possibly configured before) and is configured with an I2C address of 30 (which is used to represent an X axis encoder).
If the module detects an unrecoverable fault (for instance, if communication with the encoder IC can not be established) then it will stop on that flash and continuously blink.
The encoder module responds to several different I2C commands. The following table details the different commands available.
|0 / Any Undefined||Transmit Report||The module will respond with the travelled distance, transmitted as four bytes that represent a signed long. Magnetic strip strength can be sent instead (see command 3).|
|1||Reset Accumulated Distance||Resets the encoders internal travel distance counter, 'homing' it. This may not be necessary if homing / zero-offset is handled in firmware (as is the case with the Marlin implementation).|
|2||Set I2C Address||The modules I2C address will be set to the next byte received. This change will take effect on the next power-cycle.|
|3||Select Report Information||The following byte will set the modules report mode. '0' (default) and the probe will always report the travelled distance count. '1' will cause it to report magnetic signal strength rating instead.|
|4||Reset to Defaults||The module will 'factory-reset' to default values, undoing any configuration over I2C. Hardware address configuration (cutting traces) will remain however.|
|10||Set LED Mode||Sets the mode of the LED based on the next two bytes received. B1 = LED (0 or 1), B2 = mode (see LED reference).|
|11||Set LED Brightness||Sets the brightness of the LED based on the next two bytes received. B1 = LED (0 or 1), B2 = brightness (0-255).|
|12||Set LED RGB||Sets the RGB value of the LED based on the next three bytes received. LED must be in RGB mode to display value.|
|13||Set LED HSV||Sets the HSV value of the LED based on the next three bytes received. LED must be in HSV mode to display value.|
|14||Set LED Rate||Sets the rate variable of the LED based on the next two bytes received. B1 = LED (0 or 1), B2 = rate (0-255).|
Setting Module Address / Axis
All encoder modules communicate with the printer control board over an I2C bus. Each module needs a unique address on the bus so that the control board can communicate with it. Therefore, if you are using more than one module, you will need to configure the modules with different addresses.
There are two ways in which the address can be changed.
The encoder module has two jumper traces on board, labelled 'Y' and 'Z'. Cutting these traces will change the module's address. The table below indicates the addresses that can be selected. Note that '0' indicates a trace is unchanged, and '1' indicates the trace has been cut.
|'Z'||'Y'||Address (see address reference table)|
|0||0||'X' address (default)|
Configure over I2C
Only four separate modules can be used on one printer through cutting the jumper traces. If you're running more than four modules, you'll need to configure their addresses over I2C.
You will need to have the module communicating with the control board - if it is using the default address, you can disconnect other modules to avoid any conflict.
See the I2C commands section for the command to set the I2C address. After the address has been set, the module must be restarted for the new address to take effect - disconnect the module, then reconnect it. The status LED should indicate a custom address during the startup procedure - see the startup indicators section.
The address can be any value from 0 to 255. However, some default values for axes are established to make it easier to work with the modules.
|30||X Axis||Default Address|
Both LEDs can be configured independently in terms of mode and brightness. This means that one LED can be used as a dimly-lit status indicator, while the other is used as a bright-white illumination LED (for instance). See the I2C commands section for information on how to set the mode, or, if using the Marlin implementation, the section on custom G-Codes.
|Mode Number||Mode Name||Description|
|0||Magnetic Field Strength||Indicates if the encoder is successfully detecting the magnetic strip. Green is good (strip in range), yellow is intermediate (strip on edge of range), red is bad (no strip detected / out of range).|
|1||Solid White||Sets LED to white|
|2||Solid Red||Sets LED to red|
|3||Solid Green||Sets LED to green|
|4||Solid Blue||Sets LED to blue|
|5||RGB||Sets LED to stored RGB value (colour configured over I2C)|
|6||HSV||Sets LED to stored HSV value (colour configured over I2C)|
|7||Party Mode||Sets LED to display a rainbow HSV colour-wheel, colour proportional to axis position. Rate of change / distance set by LED rate variable.|
Using with Marlin
As the encoder modules communicate over I2C, they can be used with any control board and firmware that supports I2C (basically all of them). However, firmware support is needed to actually do anything with that information - a basic closed-loop control system has been implemented in a fork of Marlin, here.
Configuration / Setup
Download the firmware from the repository, and configure it as you otherwise would for your printer. You will find there are several new options in the configuration relating to the encoder modules - these are detailed below:
//=========================================================================== //============================ I2C Encoder Settings ========================= //=========================================================================== #define I2C_ENCODERS_ENABLED
The above line should be un-commented to enable the encoder functionality.
The example configuration has one encoder enabled, for the X axis. See below:
//Enable and configure encoders #define I2C_ENCODER_1_ADDR I2C_ENCODER_PRESET_ADDR_X #define I2C_ENCODER_1_AXIS X_AXIS //#define I2C_ENCODER_1_INVERT
The first line defines the address of the encoder module. This can be any number, provided the encoder is configured with the matching address. Several presets are set for X, Y and Z axes, and the X preset is used here.
The second line defines which axis this encoder represents - here it's the X axis.
The third line - disabled in the example - will invert the direction of travel when un-commented. This may be needed depending on the mounting orientation of the encoder + strip.
To add an encoder for the Y axis, we could add the following lines after the X encoder definition:
#define I2C_ENCODER_2_ADDR I2C_ENCODER_PRESET_ADDR_Y #define I2C_ENCODER_2_AXIS Y_AXIS //#define I2C_ENCODER_2_INVERT
The Z axis could be added likewise.
The steps / mm for the encoder modules can be changed. These modules, paired with the strips we carry, operate at 2048 steps / mm. It is possible that other encoders or strips will be developed in future, so the steps / mm can be adjusted accordingly:
#define ENCODER_TICKS_PER_MM 2048
We also need to configure how error correction will work.
//Configure error correction #define AXIS_ERROR_THRESHOLD_ABORT 100.0 //number of mm error in any given axis after which the printer will abort. Comment out to disable abort behaviour. #define AXIS_ERROR_THRESHOLD_CORRECT 0.050 //number of mm in error above which the printer will attempt to correct the error, errors smaller than this are ignored to avoid measurement noise / latency (filter) #define STABLE_TIME_UNTIL_TRUSTED 10000 //after an encoder fault, there must be no fault for this period (ms) before the encoder is trusted again
#define ERROR_CORRECT_METHOD_1 #define STEPRATE 1 #define BABYSTEPPING
Upload the firmware to your printer. Once done, connect over USB using your favourite host program (the below examples will use Printrun).
On startup, the printer will attempt communication with each module enabled in the printer's firmware. It will report the status of each module, with three possible outcomes. If the module is not connected or cannot be found at the set address, it will report that the encoder module is not detected. If the module is successfully detected, Marlin will check if the encoder is correctly aligned with the magnetic strip - and will report whether or not the strip is detected. This can be seen in the image below.
//marlin start-up image
If a module is not detected, it is likely that it is either not connected correctly, or does not have its address set to the expected value. This is to be expected if this is a first-time configuration with these modules and their addresses have not yet been set.
A custom G-Code command has been added to configure the address of the currently attached module. This command can be used to set the modules addresses one at a time. For a basic XY encoder setup, the X axis encoder already has the correct address (as the default corresponds to the X axis). Therefore we only need to change the address on the Y axis encoder. Disconnect the X axis encoder, and send the command shown below:
This will set the address of the attached module to the default address for the Y axis. If you want to fully specify what is happening, you can do the following:
M864 O030 A031
Where O = Original address = 030 (X), and A = new address = 031 (Y).
It is important that there is only one device on the default address - if you're setting up more than two encoder modules, disconnect every module except for the one you wish to set.
Once each module is being registered, it is important to check that they are mounted correctly in relation to the magnetic strips. There are two ways to do this - the easiest way is to check the readout in the terminal window, where each strip's status is reported. Alternatively, you can check the status LED on each encoder module - after start-up, the status LED will indicate the strip status (see the LED reference section).
After confirming each module is successfully aligned with a magnetic strip, it's handy to make sure that you're not going to run into alignment issues during a print. The G-Code GXXX will move each axis with an enabled encoder from it's minimum position to it's maximum position, monitoring the continuity of the of the magnetic strip. It's probably best to do this one axis at a time when you're first testing:
Check that the output is good, then continue (if needed):
And so on. This may find problems if, for instance, the strips are uneven, or not parallel with the encoder module. If a problem is found, try adjusting the position of the strip and re-running the test. If you want to run the test on all axes, call the command with no axis specified:
Once you've confirmed that the signal between the encoder and the strips is good for each axis, and that the printer is detecting each encoder, you're ready to start printing.
If needed, you can disable error-correction for any axis using the command:
M867 X (to disable for the X axis)
This can be handy if you want to temporarily disable correction - maybe to move an axis around by hand.
|M860||Report Encoder Position||The printer will respond with the current position as given by the selected encoder module.||Axis code (X, Y, Z, etc...) to select module.
Default response is in ticks, add 'U' (units) for reading in mm.
Position includes home offset (if homed), add 'O' for no-offset.
|M860 X U|
|M861||Report Encoder Status||Performs and reports an encoder + magnetic strength test. This indicates whether the module is currently connected, and if it is in range of the magnetic strip.||Axis code (X, Y, Z, etc...) to select module.||M861 Y|
|M862||Perform Axis Test||Performs and reports the result of an axis continuity test. This means the given axis will move from the minimum to maximum bounds while checking the magnetic strip to ensure good contact distance.||Axis code (X, Y, Z, etc...) to select module. If no module is selected, test will be performed for each axis with an active encoder module.||M862 X|
|M863||Calibrate Steps / mm||Performs a short test move to measure the steps / mm for a given axis. The calculated value will be reported, and can be saved to EEPROM.||Axis code (X, Y, Z, etc...) to select module. If no module is selected, calibration will be performed for each axis with an active encoder module.||M863 X|
|M864||Change Module Address||Attempts to communicate with a connected module on the default address, and changes the address to the one specified.||AXXX - selected address. Alternatively, any of the available defaults (X, Y, Z, etc...).
OXXX - select address of module to change (if not default)
|M864 A100 - set address to 100
M864 Y - set address to 'Y'
|M865||Check Module Firmware Version||Checks the firmware version of a module at a given address.||AXXX - selected address. Alternatively, any of the available defaults (X, Y, Z, etc...).||M865 X|
|M866||Report axis error count||Reports the number of errors greater than a set threshold (in firmware config)||Axis code (X, Y, Z, etc...) to select module.
Optionally 'R' to reset error counter
|M867||Toggle error correction||Toggles error correction for the selected axis on/off||Axis code (X, Y, Z, etc...) to select module.||M867 X|
|M868||Error correction threshold||Check or adjust error correction threshold for a given axis||Axis code (X, Y, Z, etc...) to select module.
Optionally 'TX.XX' to set a new threshold
|M868 X T0.50|
Status indicator sometimes displays yellow on direction-change
This can happen if the range to the magnetic strip is on the edge of the green-range. As the axis switches directions, the platform's momentum may angle the encoder slightly resulting in reduced signal strength - this will depend on the mounting solution and range to the strip. This should not be a problem, as long as the status does not indicate the signal strength is red tracking has been maintained.
Unknown I2C address / can't find module on bus
If you set the module to a custom I2C address and don't remember the new address, you can reset the module by shorting the reset jumper. This will re-initialise it to default settings (address will be 'X axis' default).
What does it do?
These modules measure their position along a suitable magnetic strip to a very high degree of precision. When installed on a moving axis on a 3D printer, this allow's the printer to know exactly where the axis is.
What are the advantages of this?
These modules allow existing printers to implement a basic form of closed-loop control. This means that some print problems, such as layer-shifts, can be automatically corrected while a print is in progress - resulting in only a minor surface defect instead of a failed print. This can be particularly useful in larger prints, where a single problem can cost a lot of time and material. It can also allow for significantly smaller / lower-torque stepper motors to be used, or for existing motors to be run at lower power, as it is no longer necessary to torque the motors to cover 100% of potential problems.
There are many other advantages, and the limit of what can be done lies primarily with the printer's firmware. For instance, in the provided fork of Marlin, steps/mm can be automatically calculated for each axis with an encoder present, allowing for faster, easier and more accurate calibration.
What types of printers are supported?
At the moment only XYZ Cartesian printers have been tested with the Marlin firmware. Other geometries (Delta, CoreXY etc.) may be supported, but so far no testing has been done. This is a question of firmware support on the printer control board, and compatibility should become more widespread with time.
Do I have to do this for every axis?
No, these modules allow for a scalable approach - if you only want an encoder on one particular axis, then that is fine. For instance, in a Prusa i3 type printer, you might want encoders on the oft-moving X and Y axes, but nothing on the relatively stationary Z axis.
What is required?
You'll need one of these modules and a suitable magnetic strip for each axis you want to make closed-loop. We carry both in the shop here. Each module comes with a 1m long cable which is suitable for some control boards. In most cases, if you're running more than one module you'll need a splitter or adaptor to connect multiple modules to one plug on the control board. We have a splitter available in the shop, or if you're handy with a soldering iron you can make your own from some spare pin headers and perf-board.
You'll need to update your printer firmware to something that supports these encoder modules. We have a working fork of Marlin detailed here.
Can these be used on an extruder?
The hardware supports this, provided you can find a suitable magnetic disk. However, there is currently no printer firmware support for closed-loop extruder axes - though this is something we want to explore.
Control Board Wiring
The encoder module requires power (5V / 3.3V and ground) and connection to the I2C bus (SDA and SCL). Below are wiring solutions for different control boards.
Printer Mounting Solutions
This is a list of designs and solutions for mounting encoder modules to different printers. If you've come up with a mounting solution and you think it could help someone else out, let us know and we'll add it to the list!
|Printer||Mounting Solution 1||Mounting Solution 2||Mounting Solution 3|
|Aus3D Mark2||X Axis|
Using springs to mount the magnetic strip can make it much easier to fine tune the distance between the strip and encoder.
Source files for the magnetic encoder module can be found on GitHub.