We are building an open micro-manipulator after the amazing design of Diffraction Limited (YouTube). He describes is as:
This project contains an open source low-cost, easy-to-build motorized XYZ Micro-Manipulator motion control platform achieving submicron precision. It's designed for applications such as optical alignment, probing electronic components, and microscopy.
We are building ours for die image stitching and laser alignment needs.
Now pivoting to using the micro-manipulator for a laser fiber alignment. See Optics Lab Notes 2026-09-27 for more :)
Not being able to home in-situ is becoming more and more of an issue.
For reference: The drivers are currently running off 3.5V (lab supply) and idly need about 1.5A.
—
Noticed some clues in setup_guide.md related to our homing troubles: There should be a steel pin limiting the joint motion. We are missing this in our design, probably because of building a partially old revision.
The upstream design uses a 2x8mm steel pin. Our FAFO-joints with the pulleys currently lack the respective bore for them.
Additionally, our initial homing direction was correct; reversing the motors would not have been necessary with this homing approach.
Further attempts at fixing the homing and calibration.
Talk to the device from terminal:
tio -e -m INLCRNL -m ONLCRNL /dev/ttyACM0
By increasing the homing current and reducing homing speed, we managed to get the joints to home more reliably. Had to also add some code so the default retract angle is used for homing (G28).
Also noticed that we are probably homing the wrong direction: With the actual tool head attached, the micro manipulator would self destroy every time during homing as the joints move so far back they force the connecting rods to detach.
Changed the homing direction by plugging in the stepper motors in reverse.
AND IT WORKS!!!
It still self-destructs during homing, but less badly after changing the direction.
We can now use it with the proper host software and started to look at a sample die under a microscope (picture above). Quick setup for the GUI:
git clone https://github.com/0x23/OpenMicroManipulatorGUI cd OpenMicroManipulatorGUI/ uv init uv add -r requirements.txt # Only this command if you already prepared before: uv run source/main.py
For reference: The positive direction of each axis is towards the joint motor of that axis.
Current WIP on YouTube: https://www.youtube.com/watch?v=g0iLpfp9_v4
The code to drive the fafo-flavored circuit board has been pushed to git: https://git.fa-fo.de/fafo/OpenMicroManipulator
We are redesigning the motor horn as the current ones sit so crooked on the too short axles/shafts of the motors that we need to do something about it. Our approach is to use a little trick: Repurpose a GT2 timing belt pulley as an axle adapter as described by @rrmutt on Mastodon:
Design lives in the fafo-hardware branch of https://git.fa-fo.de/fafo/OpenMicroManipulator.
We finished soldering the circuit board and confirmed motors and encoders of all three axis working.
Running calibration on all 3 axes with 27° retration angle (we increased it in an attempt to improve the results).
It does not work reliably yet, neither homing nor calibration yields great results so far. Assuming we will need a combination of improving the encoder to magnet alignment and also tuning software parameters more.
Plotted the encoder values to understand why results do not add up.
The discontinuities look suspicious. Disassembled the encoder from the micromanipulator again and manually played with the magnet array next to it. Figured out where the magnets need to sit in relation to the encoder to produce continuously changing encoder graphs.
We noticed that the version of the stepper motor mount (MotorMount in the FreeCAD assembly) that we printed does not match the latest design. It is missing a mounting hole for the encoder… Printed the new version.
With a properly mounted encoder the measurements look a lot better, but the calibration process was still unhappy with the results. The reason for that was that the magnets were moved out of their linear range when homing. We fixed this by monkey-patching the code to retract 17.5 degrees after homing.
diff --git a/firmware/MotionControllerRP/src/robot_joint/robot_joint.cpp b/firmware/MotionControllerRP/src/robot_joint/robot_joint.cpp index b343a1f..d4263e9 100644 --- a/firmware/MotionControllerRP/src/robot_joint/robot_joint.cpp +++ b/firmware/MotionControllerRP/src/robot_joint/robot_joint.cpp @@ -57,7 +57,7 @@ bool RobotJoint::calibrate(bool print_measurements) { bool homing_ok = homing_controller.run_blocking(servo_controller, -HOMING_VELOCITY, 360.0f*DEG_TO_RAD, HOMING_CURRENT, ENCODER_ANGLE_TO_ROTOR_ANGLE, - 0.0f); + 17.5f*DEG_TO_RAD);
Now the micromanipulator axis is working as intended and can be controlled via G-Code! Success!
After calibrating joints with M56, G0 X0 can be used to move the X-Axis to the center position.
We continued soldering the motor drivers for the remaining axis to the board.
[do not question what the saw is doing on this picture]
Assembly arrived in the lab and we finished assembling it.
The chosen stepper motors have too short of an axle which makes the mating parts not sit straight. The motor coils also have too low resistance which means we cannot drive them at full specified torque. Running at 3V supply for now.
Attached the encoders. They report a “weak” magnetic field (come on, it's at least average!). Patched out the error check for this.
Open loop motion during calibration works, but the closed control loop oscillates heavily. During calibration, motion starts in a weird direction.