OTTO(Automatic liquid handler)

Hello Dr. Florian,

I attempted to replicate your Otto liquid handler using the information provided on the Open Liquid Handler website. However, I’m encountering issues with the TMC 2260 board and the SPI port communication. Initially, I tried running it with 5 stepper motors, but it didn’t work. I then attempted to run one Stepper motor with TMC 2260 using the SPI connection, but it still didn’t work. Interestingly, when I tried using the TB6600, it worked fine. Could you please help me troubleshoot this issue?..Can I able to use backbox instead of using all these wires and boards?(give me your suggestion).

Thank you.

Hi Kowthaman :wave:

If you are unable to get the SPI communication working, then I strongly recommend selecting a more straightforward stepper driver, like the TB6600. The TMC drivers really just offer quieter operation, which is not necessary for the performance of OTTO.

I do regret not using a more out-of-the-box platform, such as the Blackbox or a stepper motor shield for the publication. As you pointed out, this would significantly cut down on wiring, but I didn’t like the idea of a commercial product that could become obsolete. Also, to actuator the plunger on the pipettor the control system must be able to interface with a fourth motor (most existing solutions are 3-axis only). The new OpenBuilds Blackbox uses an Esp32 microcontroller and likely can be programmed with the Arduino code available on the OpenLiquidHandler website. You can also use the Y2 motor for the pipettor. You will need to identify, which pins on the ESP32 are controlling the Step/Dir signals on the corresponding stepper drivers. Also, if you plan to use the two lasers for checking the tip straightness and floating head, you will need further modifications.

I see that you have reached out to me multiple times over email, website form, Instagram, and this post all within the span of a day. I want to make sure that you have the correct expectations for this DIY project. I can try my best to answer specific question when you provide context (code, wiring diagrams, pictures, etc.), but it will not be possible for me to produce new content for OTTO, including new code for an alternative motion setup or new mechanical designs.

David

Dr. Florian,

Thank you for your response. I am encountering some errors with the Python code you provided. Could you please share an updated version of the OTTO Python file? It would be very helpful.

Thank you!

I have shared the most up-to-date file. Could you please describe the errors you are having?


Hello Dr. Flo,

I hope you are doing well. I have been diligently working on reconstructing your invention, but despite my persistent efforts, I have faced repeated challenges. Unfortunately, I have fried over 20 stepper drivers, and I am struggling to identify the root cause of the issue.

I have attached some reference images for your review. In the first image, you can see that the chip leg responsible for the VS pin is damaged. The second image shows my complete circuit setup. To mitigate noise, I have added a ferrite bead to the VS line, but the problem persists. Could you please give me some tips to over come the issues like to avoid noise, frying stepper driver and voltage fluctuations

Given that I have been working on this for the past six months without a clear resolution, I would greatly appreciate any guidance or suggestions you may have on how to address this electronic issue. Your advice would be invaluable at this stage.

Hi @Kowthaman

As I recommended in July, if you are having issue with the TMC stepper drivers, then go with a simpler and cheaper option: TB6600. There will be no loss in functionality just a bit louder motion.

I would strongly recommend setting up one stepper driver and motor and testing to make sure that you can achieve motion with the Accelstepper library (Run the ConstantSpeed example). After you can get 1 motor to rotate correctly, then add another and another. This is the library that OTTO uses to move the stepper motors.

While not necessarily causing the problem, I am seeing some poor wiring. The Dupont connectors should only be used for breadboard and arduino. Ferrules should be used for screw terminals (like the ones on your stepper driver breakout boards). No connector on the wagos - just bare wire.

If you setup one motor with the TB6600, I can help you troubleshoot further.

hello Dr. Flo,

As per your suggestion, I switched the stepper driver to TB6600. The other three motors are working perfectly fine, but I am encountering an issue with the Y1 and Y2 motors.

When attempting to run Y1 and Y2, they produce loud noise and fail to move properly. Occasionally, the motors move very quickly in one direction and then stop completely. Initially, I had connected the enable, direction, and step pins for Y1 and Y2 together, which caused significant noise. Later, I assigned separate enable pins to each motor, but the issue persists.

Could you please help me diagnose and resolve this problem?

Thank you for your time and assistance.

Hi @Kowthaman

Your connections are looking much better! What is the role of the capacitors between the positive and negative connections? I am worried that their exposed legs could short if they touch the metal enclosure of the stepper driver.

The Y1 and Y2 motors are just sitting out on a desk not coupled to anything correct? If not be sure that they are.

I would remove the enable wire for now. The drivers are enabled by default. When the drives are powered on, are you able to freely spin the motor’s shaft? If so, then there is a wiring issue with the phases. The way you have it wired in the picture, red and blue should have continuity (check with multimeter) and green and yellow should have continuity. If not, determine which wires are continuous and pair them together when wiring to stepper driver (B- B+, and A-, A+).

I often find that if the motor shafts spins quickly when the arduino is turning on but then vibrate and don’t turn when they should that there is a mismatch between the step and direction pins in the code and reality. Can you share your code? Also can you indicate which drivers are your Y1 and Y2 in the image?

Hello Dr. Flo,
Thank you for your prompt response. I have replaced the Y-axis stepper drivers with DM542 drivers, and now all the motors are functioning correctly. For your reference, I am sharing the updated code.

Could you please guide me on how to modify the OTTO G-code and advise on what should be included in the Python code so I can proceed further? I also added a capacitor to reduce noise in my system ,I would also shorten their legs and I successfully synchronized the Y1 and Y2 motors. You were right—I made a mistake in the code by separating the Enable pins instead of the Direction pins, which likely caused the noise and mismatches.

#include <AccelStepper.h>

// Define stepper pins for Z-axis
#define Z_EN_PIN 27
#define Z_STEP_PIN 25
#define Z_DIR_PIN 26

// Define stepper pins for X-axis
#define X_EN_PIN 3
#define X_STEP_PIN 4
#define X_DIR_PIN 5

// Define stepper pins for Y-axis
#define Y_EN_PIN 35
#define Y_STEP_PIN 37
#define Y_DIR_PIN_Y1 36 // Direction for Y1
#define Y_DIR_PIN_Y2 34 // Direction for Y2 (different direction pin for Y2)

// Define stepper pins for P-axis
#define P_EN_PIN 8
#define P_STEP_PIN 9
#define P_DIR_PIN 10

// Configure the stepper for Z, X, Y1, Y2, and P
AccelStepper stepperZ(AccelStepper::DRIVER, Z_STEP_PIN, Z_DIR_PIN);
AccelStepper stepperX(AccelStepper::DRIVER, X_STEP_PIN, X_DIR_PIN);
AccelStepper stepperY1(AccelStepper::DRIVER, Y_STEP_PIN, Y_DIR_PIN_Y1);
AccelStepper stepperY2(AccelStepper::DRIVER, Y_STEP_PIN, Y_DIR_PIN_Y2);
AccelStepper stepperP(AccelStepper::DRIVER, P_STEP_PIN, P_DIR_PIN);

void setup() {
Serial.begin(9600);

// Enable pins (optional)
pinMode(Z_EN_PIN, OUTPUT);
digitalWrite(Z_EN_PIN, LOW); // Enable Z driver

pinMode(X_EN_PIN, OUTPUT);
digitalWrite(X_EN_PIN, LOW); // Enable X driver

pinMode(Y_EN_PIN, OUTPUT);
digitalWrite(Y_EN_PIN, LOW); // Enable Y1 and Y2 drivers

pinMode(P_EN_PIN, OUTPUT);
digitalWrite(P_EN_PIN, LOW); // Enable P driver

// Set up motor parameters
stepperZ.setMaxSpeed(12000); // Set max speed for Z
stepperZ.setAcceleration(5000); // Set acceleration for Z

stepperX.setMaxSpeed(12000); // Set max speed for X
stepperX.setAcceleration(4000); // Set acceleration for X

stepperY1.setMaxSpeed(12000); // Set max speed for Y1
stepperY1.setAcceleration(4000); // Set acceleration for Y1

stepperY2.setMaxSpeed(12000); // Set max speed for Y2
stepperY2.setAcceleration(4000); // Set acceleration for Y2

stepperP.setMaxSpeed(12000); // Set max speed for P
stepperP.setAcceleration(4000); // Set acceleration for P

Serial.println("Setup complete");

}

void loop() {
// Move Z-axis forward
Serial.println(“Moving Z-axis forward 1 full rotation”);
stepperZ.moveTo(3200);
while (stepperZ.distanceToGo() != 0) {
stepperZ.run();
}
delay(500);

// Move X-axis forward
Serial.println("Moving X-axis forward 1 full rotation");
stepperX.moveTo(3200);
while (stepperX.distanceToGo() != 0) {
    stepperX.run();
}
delay(500);

// Move both Y1 and Y2 motors synchronously but in opposite directions
Serial.println("Moving Y1 and Y2 forward (counter directions)");
stepperY1.moveTo(3200); // Move forward 1 full rotation
stepperY2.moveTo(-3200); // Move backward 1 full rotation (opposite direction)
while (stepperY1.distanceToGo() != 0 || stepperY2.distanceToGo() != 0) {
    stepperY1.run();
    stepperY2.run();
}
delay(500);

// Move P-axis forward
Serial.println("Moving P-axis forward 1 full rotation");
stepperP.moveTo(3200);
while (stepperP.distanceToGo() != 0) {
    stepperP.run();
}
delay(500);

// Reverse Z-axis
Serial.println("Reversing Z-axis");
stepperZ.moveTo(0);
while (stepperZ.distanceToGo() != 0) {
    stepperZ.run();
}
delay(500);

// Reverse X-axis
Serial.println("Reversing X-axis");
stepperX.moveTo(0);
while (stepperX.distanceToGo() != 0) {
    stepperX.run();
}
delay(500);

// Reverse both Y1 and Y2 motors
Serial.println("Reversing Y1 and Y2 (counter directions)");
stepperY1.moveTo(0); // Return to start position
stepperY2.moveTo(0); // Return to start position (opposite direction)
while (stepperY1.distanceToGo() != 0 || stepperY2.distanceToGo() != 0) {
    stepperY1.run();
    stepperY2.run();
}
delay(500);

// Reverse P-axis
Serial.println("Reversing P-axis");
stepperP.moveTo(0);
while (stepperP.distanceToGo() != 0) {
    stepperP.run();
}
delay(500);

}

I have attached the limit switch and optocoupler connection details for your review ( I connected all the ground to power supply ground )