Updated: How to wire correctly (at the end of the blog entry)
Update August 2021: New firmware
available for the board
What is bed leveling and how can it be performed?
What is bed leveling? The idea behind bed leveling is to give a machine (for example
a 3D printer as in the following case, a CNC mill or any other machine) a way to
sense the layout of the machine bed or building plate. When not using bed leveling
one normally assumes a given bed layout - for example on a 3D printer one assumes that
the bed is leveled and perfectly parallel to the 3D printer axis, the same on a mill. It
is also assumed to be at a given z offset relative to the z axis endstops. Zero along
the X and Y axis is normally determined via any other mean (for example using mechanical
endstop switches or inductive, capacitive, ultrasonic or optical sensors). This
raises the requirement for the build plate to be as parallel to the build axis as
possible - which is of course always a good idea if youāre not using one of the infinite
size beds built around tilted conveyor belts. On the other hand there are many machines
where one manipulates the bed - for example on 3D printers one might change the
coating on which on prints, at CNC mills one might add additional clamping mechanisms
although itās normally assumed there that these are precise and that the workpiece is
resting on the build plate itself.
To gain more precision than having a calibrated system one can perform a measurement of
the build surface (and for CNC machines of the workpiece and itās orientation if
one does multiple manufacturing steps on different machines) before each build or on a
periodic schedule. This allows the control software to adjust itself to changes in machine
geometry. Of course this doesnāt mean one should ignore mechanical precision, a machine should
as usual be as precise as possible - but it allows to compensate for different errors
or gain more precision than would be possible with a mechanical solution.
At 3D printers bed leveling is typically performed by a variety of methods:
Manually leveling the bed. This drives the nozzle to well defined points and one
can either adjust the bed or drive the nozzle till one reaches a well defined
height above the surface (normally this is done by sliding some card or other
tool below the nozzle, checking when oneās not capable of moving any more).
Using a capacitive or inductive sensor. This is the second most used method on
current 3D printers. The problem is that there is a offset between the nozzle
and the probe in all three directions - this of course can be measured statically
for the print head and allows measurement in a way that the print head stops
without even touching the bed with the nozzle - which can be quite convenient
because nozzles might be contaminated with plastic remains from the last prints.
The downside is that this method cannot compensate for defects in machine geometry
at which the printing head gets tilted (for example most of the time this happens
with tilted axis). In this case the measurements would look like a tilted bed but
the relation between the distance between build plate and sensor would not be
the same as the relation between build plate and the nozzle. This leads to nozzle
crashing into the build plate or getting too high even when using such probes.
Closing a conductive connection. This is one of the simplest methods. The idea
is to simply check if there is a conductive path between the conductive nozzle
and a conductive build plate. The downside is that one first cannot use this method
on all metal printers (since their parts are normally all pulled to ground potential)
and the nozzle has to be clean. Also one normally uses some kind of non conductive
coating like PEI, Kapton or glass on the heatbeds so there cannot be a conductive path
between the build surface itself and the nozzle.
Mechanically sensing touching. This is the method being described in this article.
The idea is of softly driving the nozzle into the buildplate and sensing the force
in some way. This can be done with a variety of methods like springs and some kind
of switch, piezo sensors, measuring motor current, etc. The largest drawback is that
any remaining plastic from the last print at the nozzle will lead to invalid measurement
results.
Leveling via touch probe (The first try)
Note: This section describes the first try that seemed to work somewhat at
first but had to be modified later on (as described below).
The following article describes some experiments and solutions to do bed leveling
via a touch probe. The basic idea is to sense the contact between the 3D printer nozzle
or a milling tool and the printer bed or machine table. On a 3D printer one cannot use
a simple conductive probe (i.e. sense the contact between the nozzle and a conducting bed)
since one normally uses a non conductive coating as described above. To overcome that
problem one can use pressure sensors. Since they are readily available Iāve tried to
use piezo disks as sensors. They are cheaply available in huge quantities and are
salvageable from electronic waste like watches, cheap microphones, classical guitar
and violin pickups, etc. The are basically manufactured by attaching a layer of piezoelectric
material onto a metal plate and connected on the top of the sandwich as well as on
the metal plate.
The effect being used is the piezoelectric effect. This effect can occur in materials
that change polarization with mechanical stresses (i.e. average charge carriers are
moved inside the material in case of stress changes). The model normally used
to describe the piezoelectric effect assumes that one can calculate the balance point
for positive and negative charges - and as soon as one applies stress to the
material it deforms which leads to the formation or change of the dipole moment
inside the material. Polarization changes then lead to a change in electrical potential
and thus in voltage - which again leads to a small current. The piezoelectric effect
can be used to measure (i.e. mechanical stress leads to induced voltage) or inversely
to induce deformation by applying voltage. The latter method is used in some high
precision machines like scanning tunneling microscopes or high precision mills. Itās
also used in cheap watches to generate the buzzing noises. The direct effect that is
used for bed leveling sensors on the other hand is also used in microphones, accelerometers
and other stuff seen on a day to day basis.
There are two possible placements for the piezo disks. Since the printer Iāve built
already had an finished and not easily changeable printing head Iāve decided to add
the piezo disks below the build surface. This is possible since the build plate is not
too huge - the idea was to put one piezo disk into every corner and rest the whole
weight of the mounting frame for the heatbed onto these disks. Since the disks have
welded and soldered cables on top Iāve added a small spacer (using some cents) above the
piezoelectric layer and put the table on top of them. After that Iāve connected
all four piezo disks in parallel for the easiest and cheapest solution. That might not
be a good idea in every case since - under some circumstances and geometries - itās entirely
possible of occurring voltages to cancel out.
The next problem when connecting piezos to microcontrollers was that they produce positive
and negative voltage depending on the direction of deformation. Since the idea was
to use an single rail ADC for measuring (i.e. the ADC functionality of the AVR itself)
a voltage divider consisting of two $1 M\Omega$ resistors is added. This provides biasing of the
piezo discs such that one can measure positive and negative voltage spikes. One can of
course use different voltage dividers. Lower resistor values lead to higher leakage current
and less sensitivity, higher resistor values to higher sensitivity of the system. One
shouldnāt use that approach when using other piezo sensors - because their voltage spikes
can be way to high for the AVR and itās internal protective circuits to handle - but using
the piezo disks directly with the biasing resistors attached works pretty well.
This way one can simply run normal bed leveling
One just has to tune the thresholds to prevent triggering because of external noise
and vibrations - and to stay sensitive enough for the slow touch during the probing moves.
In case simple thresholding does not work:
One can look at the differentiated signal and perform thresholding there
If this is still not enough one could in theory perform event fitting (i.e. try to fit
an function that models charging and discharging of the circuit during a touch event)
to discriminate touch events a piezo sensor might not be the right choice.
And additional upgrade would be to sample all piezo disks separately. This would
also allow absolute position determination of the touch event.
Update: Increasing sensitivity and working with manufacturing differences
As turned out the system as described above was not nearly as sensitive as it
could be and has a dead section in about 20 percent of the plate. This turned out
to be caused by manufacturing and wiring differences with the piezo disks. To solve
that problem each piezo disk has been attached to itās own analog digital converter.
This has first been tried with an ATMega328P. The system can now also report the
signal shape for all four disks. As one can see the centerline of one of the
piezos is shifted towards lower voltage. This caused the system to oscillate sometimes
and caused the lower voltage disk to be way less sensitive then the other disks.
Running the same system with 4 channels and the same frequency allows more reliable
detection of touch events and being less sensitive to external vibrations like
passing cars or trains.
As one can see the design also has been modified to allow I2C communication for
configuration and calibration as well as reading measurement data and flashing
with an suited I2C bootloader as well as ICSP programming. The board also has an
option to add an local 5V DC-DC regulator as well as an additional input
for a traditional bed leveling sensor. This allows to run detection in coincidence
mode to provide increased noise immunity for larger Z travel distances (i.e.
trigger only whenever the standard z level sensor and the piezo sensors trigger).
One can also support switching between piezo and classical mode.
Some test code for the board presented above using the Arduino IDE (for easy deployment)
has been uploaded as a GIST.
This code does not supply connectivity via I2C.
Update 3: New mount for heatbed
After some months of operation using a rather hackish setup Iāve decided to add
a new mounting frame below my heated bed. This has been done because the load
distribution onto the piezo sensors has not been equal - to counter that Iāve added
an rigid aluminum mounting frame with four M3 screws that allow the frame to rest
directly onto the piezo disks at an adjustable distance. Another additional
feature of the mounting frame is that it solves my previous mounting problem - my
heatbed had just been attached to the table using Kapton tape which has lead to
some problems when unmounting and remounting the heatbed after reapplying the print
surface since the positioning on the piezos is somewhat critical. The only problem
solved currently using Kapton is the mounting of the piezo disks onto the base
table. Since the lower side of the sensors is kept at ground potential Iāve not
added Kapton below the sensors themselves.