Skip to content

12. Machine building

This week I tried to build a machine, you can check out the whole thing in the group page.

The Code

As my team members suggested, we would try to controll two stepper motors trhough serial communication using a USB hub.

# Max Garcia 19.04.2022


import math as m
import serial
import time
from serial.tools import list_ports

motors_com = {
    "X": 'COM1',
    "Y": 'COM2'
}

motors = {
}

values = {
    "total_d": 0,
    "radius": 0,
    "y_gap": 0,
    "n_steps_x": 0,
    "n_steps_y": 0
}

values_f = {
    "placeholder": 14.04
}

pos = {
    "y": values["radius"],
    "x": 0,
    "abs_y": values["radius"],
    "abs_x": values["total_d"]/2
}


def input_d():
    while True:
        text = input()
        if text.strip() == "done":
            break
        else:
            text_1 = text.split(", ")
            print(text_1)
            direction, steps = text_1[0], int(text_1[1])
            move(direction, steps)
            if direction == "R":
                values["n_steps_x"] = values["n_steps_x"] + steps
            elif direction == "L":
                values["n_steps_x"] = values["n_steps_x"] - steps
            elif direction == "U":
                values["n_steps_y"] = values["n_steps_y"] + steps
            elif direction == "D":
                values["n_steps_y"] = values["n_steps_y"] - steps


def calculate():
    values_f["steps_to_d_x"] = values["n_steps_x"] / values["radius"]
    values_f["steps_to_d_y"] = values["n_steps_y"] / (values["radius"] * 2)


def from_angle(angle):
    # First determines position of needle
    # Positive x means going right
    if angle <= 90:
        x = m.cos(m.radians(angle)) * values["radius"]
        y = m.sin(m.radians(angle)) * values["radius"]
        dx = x - pos["x"]
        dy = -(y - pos["y"]) - dx
    else:
        x = - m.cos(m.radians(180-angle)) * values["radius"]
        y = m.sin(m.radians(180 - angle)) * values["radius"]
        dx = x - pos["x"]
        dy = -(y - pos["y"]) - dx
    pos["x"], pos["y"] = x, y
    if dx > 0:
        direction = "R"
    else:
        direction = "L"
    if dy > 0:
        direction = "D"
    else:
        direction = "U"
    steps_x = int(values_f["steps_to_d_x"] * dx)
    steps_y = int(values_f["steps_to_d_y"] * dy)
    move(direction, steps_x)
    move(direction, steps_y)


def calibrate_x():
    """
    :return: number of steps to displacement ratio
    """
    print("What is the distance between the two endpoints of the machine? (cm)")
    values["total_d"] = int(input())
    print("What is the radius of the pointer? (cm)")
    print("      This is the distance between the two attachment points")
    values["radius"] = int(input())
    print("Move to leftmost/lowest point the pointer goes using the format: Direction (U,D,L,R), N_Steps(Integer)")
    print("Examples: \"L, 500\" or \"U, 100\"")
    print("Once finished type: \"done\"")
    input_d()
    print("Now move to the middle/highest point using the same commands as before. (\"done\" to exit")
    input_d()
    calculate()
    print("Calibration finished")


def begin():
    print("What is the COM port for the X motor? e.g. \"COM7\"")
    motors["COM_X"] = input()
    print("What is the COM port for the Y motor? e.g. \"COM7\"")
    motors_com["COM_Y"] = input()
    motors["motor_x"] = serial.Serial(port=motors_com["COM_X"], baudrate=9600, timeout=.1)
    motors["motor_y"] = serial.Serial(port=motors_com["COM_Y"], baudrate=9600, timeout=.1)


def move(direction, steps):
    """
    Discriminates between directions and decides to which motor
    information is to be sent.
    """

    divisions = 25
    if direction == "R" or direction == "L":
        message = ", ".join([direction, str(steps)])
        motors["motor_x"].write(message.encode())
        print(message)
    elif direction == "U" or direction == "D":
        message = ", ".join([direction, str(steps)])
        motors["motor_y"].write(message.encode())
        print(message)


if __name__ == "__main__":
    begin()
    calibrate_x()
    from_angle(90)

Files

The code


Last update: April 19, 2022