BDSensor – Bed Leveling Sensor installieren
Der BDSensor ist ein Bed Leveling Sensor, der den Abstand der Düse zum Druckbett berührungslos messen kann. Dazu werden Wirbelströme genutzt. Anders als klassischen Bed Leveling Sensoren, muss man mit dieser Art von Sensor nicht an jedem Messpunkt stoppen, sondern man kann das Druckbett in rasender Geschwindigkeit abscannen. Vergleichbare Sensoren sind z.B. der Eddy oder der Beacon. Letzterer verfügt über einen automatischen Z-Stop bei Kollisionserkennung mit der Nozzle. Das hat auch der BDSensor in der aktuellen Version. Und ist dabei deutlich günstiger. Auch der Formfaktor des BDSensor gefällt mir besser, da die PCB und die Messspule entkoppelt sind. So findet man näher an der Düse einen guten Platz.
Den BDSensor gibt es bei PandaPi.
Ich hab für eure eigenen Mounts die Teile nachmodelliert:
https://makerworld.com/en/models/735583
Weitere Features
Der BDSensor kann sogar eine Echtzeit-Z-Korrektur vornehmen, das ist aber Experimentell und ich hab das nicht ausprobiert.
Einschränkungen
Wenn ihr so ein softes Druckbett benutzt, wie ich eigentlich, schlagen Wirbelstromsensoren nicht an. Ich hab also auf Risiko nun auch mal so ein Federstahl-Druckbett gekauft, wo ich nicht ganz sicher bin, ob ich auch kalt drauf drucken kann. Mal gucken 🙂
Installation des BDSensor
Ich verbaue den in meinem alten Ultimaker Original. Der hat ein Uralt Mainboard, das ich nicht ersetzen will, daher möchte ich den Sensor direkt am Raspberry Pi betreiben. Wenn ihr ein neueres Mainboard habt, idealerweise mit einem Port für eine BLTouch, müsst ihr etwas anders vorgehen. Damit wir den BD Sensor direkt am Raspi betreiben können, müssen wir ihn als zweiten (virtuellen) MCU einrichten:
cd ~/klipper/
sudo cp ./scripts/klipper-mcu.service /etc/systemd/system/
sudo systemctl enable klipper-mcu.service
Jetzt müssen wir ggf. noch das PW eingeben.
BDSensor-Packete installieren:
Im nächsten Schritt müssen die notwendigen Files für den Betrieb des Sensor zu Klipper hinzugefügt werden. Dazu navigieren wir ins root Level und clonen uns das repository von GitHub:
cd ~
git clone https://github.com/markniu/Bed_Distance_sensor.git
Dann können wir die Bash-Scripts ausführen:
~/Bed_Distance_sensor/klipper/install_BDsensor.sh
cd ~/klipper/
make menuconfig
Hier kommt nun eine Besonderheit. Wir müssen in der menu config file die MC Architektur als „Linux process“ auswählen. Wenn ihr den BDSensor an eurem Drucker MCU betreibt, müsst ihr hier natürlich die richtigen Werte auswählen.

Das ganze speichern wir mit q und bestätigen mit y. Nun konnt anstelle des make Befehls wieder ein Bash Script:
./make_with_bdsensor.sh
Wer den BD Sensor am Raspi betreibt muss nun den Service von Klipper stoppen und dann können wir die MCU flashen:
sudo service klipper stop
make flash

Um dann im anschluss Klipper wieder zu starten:
sudo service klipper start
Falls es hier eine Fehlermeldung gibt – Ggf. muss man Pi noch als User hinzufügen:
sudo usermod -a -G tty pi
Wie ihr ansonsten die File auf euren MCU flasht, lest ihr in meiner Klipper Installations-Anleitung.
Moonraker Updatemanager
Jetzt haben wir eine custom Klipper Version mit den Paketen für den BD Sensor. Damit wir die auch immer leicht aktualisieren können, empfiehlt es sich, diese auch in den Moonraker Updatemanager hinzuzufügen:
[update_manager BDsensor]
type: git_repo
primary_branch: new
channel: dev
path: ~/Bed_Distance_sensor
origin: https://github.com/markniu/Bed_Distance_sensor.git
install_script: ./klipper/install_BDsensor.sh
is_system_service: False
managed_services: klipper
info_tags:
desc=Bed Distance Sensor

BD-Sensor am Drucker installieren
Natürlich müssen wir den Sensor noch am Drucker installieren. Empfohlen wir ein vertikaler Abstand zur Nozzlespitze von 0.4 bis 2 mm. Der Sensor sollte so nah an der Nozzle sein wie es nur geht. Anders als bei anderen Wirbelstrom Sensoren, ist es dem BD Sensor egal, ob Metall direkt über ihm ist. In der GitHub Repo des Sensors gibt es ein paar .STL Files für die gängigen DIY 3D Drucker. Ich konstruiere mir natürlich eine eigene Halterung für meinen Druckkopf des Ultimakers.
Sidequest: Halterung
Auf thingiverse wurden netterweise auch Coil und das PCB-Housing als .stl zur verfügung gestellt. Auf Basis dieser habe ich mir eine Schraubverbindung überlegt, die ich einfach analog zu den Düsen in die Aluhalterung Schrauben und kontern wollte, allerdings gehen hier meine Kabel hoch und mein Bauteillüfter ist auch im Weg.

Also auf ein neues. Nun sieht mein Konzept so aus:

Aber in der Realität hat es natürlich nicht gepasst:

Der Grund: ich hab nicht die originalen Düsen drin, sondern die kleinen wie am E3D Hot-End. Also drehe ich eine Korrekturschleife, bringe alles etwas weiter nach oben und kann dabei auch den Kabelkanal für das Kabel nochmal anpassen. Das ist am Ende leider immer noch nicht perfekt geworden, da ich die länge nicht genau wusste. Der Clip für die Platine funktioniert eigentlich perfekt, aber ich hab die dann doch mit Kabelbinder fest gemacht, damit das Kabel zur Spule nicht so rumschlackert. Dann hat es gepasst.

Jetzt muss das ganze natürlich noch am Raspi angeschlossen werden. Die Vorgabe ist hier wie folgt:
Raspi | BDsensor
GND --> GND
5V --> 5V
GPIO17 --> CLK/SCL (Input)
GND --> GND
GPIO27 --> SDA (Input/Output)
Wobei für CLK/SCL und SDA eigentlich keine Vorgaben gemacht werden. Also hier gehen auch andere, die wir dann nur in der config file später anpassen müssen.


BDSensor.cfg erstellen:
Wir erstellen uns eine neue .cfg Datei im Webinterface und kopieren folgenden code rein. Bei sda_pin und scl_pin müsst ihr natürlich die richtigen Pins eintragen, an denen ihr den Sensor angesteckt habt.
[BDsensor]
# Don't use aliases for the board pins
#sda_pin: PB1 # example of connecting to main board Creality V4.2.7
#scl_pin: PB0
#scl_pin:MKS_THR:gpio20 # example of connecting to CAN module like MKS THR42
#sda_pin:MKS_THR:gpio11
scl_pin:host:gpio17 # example of connecting to GPIO on RaspberryPi
sda_pin:host:gpio27
delay: 20 # you can set it 10 if the BDsensor version is >=1.2
z_offset: 0 # within -0.6 to 0.6mm
x_offset: -34
y_offset: 0
no_stop_probe: # fast probe that the toolhead will not stop at the probe point,disable it by commenting out.
position_endstop: 1.2 #the triggered position, recommend value is 1~2.8
collision_homing: 0 # set it 1 to enable homing with nozzle collision sensing.
collision_calibrate: 0 # set it 1 to enable auto calibrate BDsensor with nozzle collision sensing.
#QGL_Tilt_Probe: 0 #set 1 to enable probe up and down when do quad_gantry_level
Bei den x und y Offsets muss die Position relativ zur T0 Nozzle eingetragen werden. Ich kann diese bei mir einfach aus dem CAD auslesen:

printer.cfg anpassen
Wir können jetzt noch die BDSensor.cfg mit einem Include zur printer.cfg hinzufügen und dann im Abschnitt für den Z-Motor auf die Probe umstellen.
[include BDSensor.cfg]
[mcu host]
serial: /tmp/klipper_host_mcu
[stepper_z]
endstop_pin: probe:z_virtual_endstop
#position_endstop: 0.5
homing_speed: 5
second_homing_speed: 3 #set this to 3 if homing with collision, otherwise 1
homing_retract_speed: 2
homing_retract_dist:5
[safe_z_home]
home_xy_position: 100,100
# A X, Y coordinate (e.g. 100, 100) where the Z homing should be
# performed. This parameter must be provided.
#speed: 50.0
# Speed at which the toolhead is moved to the safe Z home
# coordinate. The default is 50 mm/s
#z_hop: 5
# Distance (in mm) to lift the Z axis prior to homing. This is
# applied to any homing command, even if it doesn't home the Z axis.
# If the Z axis is already homed and the current Z position is less
# than z_hop, then this will lift the head to a height of z_hop. If
# the Z axis is not already homed the head is lifted by z_hop.
# The default is to not implement Z hop.
#z_hop_speed: 15.0
# Speed (in mm/s) at which the Z axis is lifted prior to homing. The
# default is 15 mm/s.
#move_to_previous: False
# When set to True, the X and Y axes are reset to their previous
# positions after Z axis homing. The default is False.
[bed_mesh]
speed: 120
horizontal_move_z: 1 # 0.7~1.0mm is recommended
mesh_min: 10, 10
mesh_max: 200, 200
probe_count: 5, 5
mesh_pps: 2,2
algorithm: bicubic # this should be bicubic if the bed mesh points count is > 6*6
bicubic_tension: 0.2
zero_reference_position: 100, 100 # Set this value to be the same as home_xy_position that is in the section safe_z_home
....
[force_move]
enable_force_move: true # required by the command SET_KINEMATIC_POSITION in the calibration step below.
...
Achtung: safe z home und homing-override (hatte ich benutzt) sind nicht kompatibel!
Bei mir kam dann folgende Fehlermeldung:

Ich hab dann sicherheitshalber nochmal jeweils für den MCU (Arduinoboard im 3D-Drucker) und für den MCU Host kompiliert und neu geflasht. Dann ging es. Natürlich hat dann Klipper beim nächsten Update gemeckert, ich konnte aber mit dem soft-repair ohne weiteres alles wieder fixen.
Testen
Als nächstes müssen wir unser SetUp testen. Dazu müssen wir noch ggf. gpiodetect installieren: Damit kann man checken ob die Pins mit dem Sensor geclaimt wurden. Wir können dies einfach aus der Standard-Packet-Quelle machen:
sudo apt-get install gpiod
gpiodetect
gpioinfo


Soweit, so gut. Dann können wir noch testen ob der Sensor logische Werte bekommt, mit folgenden Befehlen in der Klipper-Konsole:
M102 S-1 # Read sensor information
M102 S-2 # Read one distance value
Und natürlich kommt das nächste Problem:

Ich checke also nochmal alle Anschlüsse, kann ja sein dass ich beim Einbauen was abgezogen hab. Hab ich nicht, aber ich hab SDC und SDA Pins vertauscht. Also einfach in der .cfg angepasst und dann ging alles.
Das sollte euch in der Konsole nun in etwa folgende Antworten zurück geben:

Passt also endlich.
Jetzt sollten wir Nozzle und Druckbett soweit zusammen bringen, dass der BD Sensor anschlägt. Das kann man z.B. auch an der kleinen LED an der Platine erkennen.

Ein blaues Licht. Was kann es? Es leuchtet blau.
Und dann prüfen wir sicherheitshalber noch mit M119 ob auch der virtuelle Endstop funktioniert und dann sind wir good 2 go:

Kalibrieren
Dann müssen wir das Druckbett und die Nozzle soweit zusammen bringen, dass sie sich gerade so berühren. Stichwort: Papertest. Muss aber nicht so genau sein, den Rest machen wir mit Baby Steps später. Oder wenn ihr kaum was am Druckkopf gemacht habt, einfach Z-Homen und G1 Z0 anfahren. Dann kann man den Papertest sparen. Dann starten wir die Kalibrierung mit:
M102 S-6
Der BDSensor fährt nun eine Messreihe ab. Die genauen werte sollten wir uns danach noch anschauen, mit:
M102 S-5
In der aktuellen Firmware werden die aber eh mit ausgegeben:

Wenn der erste Wert nicht größer als 400 ist und der Schritt zum zweiten Wert größer als 10 ist, sind wir good 2 go. Bei mir gibt er aber direkt schon eine Warnung aus.
Edit: Ich hatte vorher alle Achsen gehomed und dann fuhr er zunächst in einen falschen Abstand. Wenn ich direkt nach dem Update der printer.cfg den M106 S-6 eingebe, kommt eine Fehlermeldung, dass force Move fehlte. Hab das also eingetragen, der Druckkopf ist in etwa Mittig über dem Druckbett, Klipper frisch neu gestartet und dann M106 S-6 und nun wird korrekt kalibriert.

Nun lassen wir einmal alle Achsen Homen und fahren dann wieder auf G1 Z0 und machen dann den Papertest. Passt bei mir perfekt. Der erste Layer ist aber etwas dünn für meinen Geschmack. Das ist aber nichts was man mit einem Z-Adjust nicht fixen könnte.
Ein neues Feature ist ja das Collision Homing – das werde ich hier auch noch reinnehmen, jetzt will ich allerdings erstmal ein Mesh fahren, den Z-Abstand tunen und dann mach ich einen One-Layer Druck. Ich hab auch schon einen ohne den BDSensor gemacht (aber schon auf dem PEI Federstahlbett, und ja ich kann kalt drauf Drucken), damit ich die beiden Ergebnisse vergleichen kann.
Erstes MESH
Jetzt können wir unser erstes Mesh erstellen. Dazu gehen wir in den entsprechenden Tab und starten:

Zack Error, ich musste bei mir die Werte im Bed-Mesh in der printer.cfg leicht nach unten korrigieren. In der config wird das Offset der Probe nicht automatisch mit einkalkuliert, sondern dass muss man selber tun. Wenn ihr also als minimal Punkte 5 und 5 haben möchtet, muss jeweils das Offset mit einkalkuliert werden – und hier muss man auch gut mit den Vorzeichen aufpassen.
Zum besseren Verständnis: Der Nullpunkt wird ja zur Nozzle referenziert. Mein Bed-Leveling Sensor ist in X -20.4 (also ungefähr 21mm) und in Y +10.4 (also sagen wir 11mm) von Nozzle T0 entfernt. Um meinen Nullpunkt für den BDSensor einzustellen, muss ich also als min werte -21 | 11 eingeben. Und bei Maximum (Bei mir sind die maximalen Dimensionen 203 und 203 mm) ergibt sich dann 182 und 210 mm).
[bed_mesh]
speed: 120
horizontal_move_z: 1
mesh_min: -20, 11
mesh_max: 180, 210
probe_count: 50, 50
mesh_pps: 2,2
algorithm: bicubic
bicubic_tension: 0.2
zero_reference_position: 100,100
Wenn das korrekt eingestellt ist, gibt es interessante Ergebnisse. Und ja, das non-stop-scanning geht verdammt schnell. Es hängt also durch in der Mitte und das hatte ich im Beitrag Klipper Installieren ja schon festgestellt.

Damit das Mesh auch benutzt wird müssen wir unser Print-Start Macro anpassen und den Befehl einfügen:
BED_MESH_PROFILE LOAD="default"

Wenn ihr euer Mesh anders benannt habt, müsst ihr den Namen natürlich anpassen.
Beim Drucken höre ich schon (alte Treiber) das die Z-Achse arbeitet. Wie cool 🙂 Und hier kommt der vergleich. Links das Bett-Mesh ohne BD Sensor, einfach durch mein händisches Bed-Leveling. Rechts mit Bed-Mesh durch den Sensor. Ich hab beide Drucke mal vor meinen Bildschirm gelegt, damit man die Unterschiede besser erkennen kann.

Zu dem Zeitpunkt hatte ich glaube ich noch meine z_offsets vertauscht, wodurch der komische rand ganz rechts zustande kommt. Unten links die verdickung kommt duch Baby Stepping. Also man sieht schon krasse Unterschiede.
Ich hab dann auch mal ein Mesh mit 100×100 punkten erzeugt, weil why not:

Homing durch Kollisionserkennung
Dazu können wir einfach in der BDSensor.cfg bei collision homing und collision calibrate den Wert auf 1 setzen. Außerdem sollte beim Bed-Mesh eine zero_reference_position hinterlegt sein (die mit safe_z_homes x und y koordinate übereinstimmt).
[BDsensor]
scl_pin: host:gpio27
sda_pin: host:gpio17
delay: 10
z_offset:0
x_offset: -21.4
y_offset: 10.8
no_stop_probe:
position_endstop: 2.4
speed:0.8
collision_homing:1
collision_calibrate:1
Durch Homing durch Kollisionserkennung kann man den Temperaturdrift des Sensor ausgleichen. Da die Werte beim Proben alle die gleiche Abweichung haben, ist der für das Mesh-Probing egal, aber eben fürs Homen nicht. Daher ist Kollisionshoming dem Induktiven Homing vorzuziehen, da ja auch empfohlen wird, heiß zu homen, damit kein Filament zwischen Düse und Druckbett ist.
Dann Homen wir die Z-Achse ein paar mal und schauen ob die Messwerte akkurat sind.
Das Kollision-Homing ist nicht ganz Ideal beim Ultimaker, da die Konfiguration mit den zwei Kreuzenden Achsen erst leicht nach gibt. Ich lasse das aber erstmal drin und beobachte dann wie es sich verhält.

Hier gibt es aber die möglichkeit zunächst Kontaktlos zu Homen und dann in den Kollisionsmodus zu wechseln:
KAMP
Ein weiteres tolles Feature was mir jetzt möglich wird ist KAMP (Klipper Adaptive Meshing and Purging). Dazu könnt ihr im nächsten Beitrag was lesen.
Happy Printing!
$ Die mit einem $ gekennzeichneten Links, sind Affiliate Links. Wenn du über diese in den Shop gelangst und etwas kaufst, bekomme ich eine kleine Provision