a scrappy gimbal that insults you in shakespearean english
1import board
2import time
3import digitalio
4import supervisor
5
6class MotorState:
7 def __init__(self, step_pin, dir_pin, min_delay=0.001):
8 self.step_pin = step_pin
9 self.dir_pin = dir_pin
10 self.position = 0
11 self.min_delay = min_delay
12
13 def step(self):
14 self.step_pin.value = True
15 time.sleep(self.min_delay)
16 self.step_pin.value = False
17 time.sleep(self.min_delay)
18
19# Define pins for stepper motors
20motor1_step = digitalio.DigitalInOut(board.GP11)
21motor1_step.direction = digitalio.Direction.OUTPUT
22motor1_dir = digitalio.DigitalInOut(board.GP10)
23motor1_dir.direction = digitalio.Direction.OUTPUT
24motor2_step = digitalio.DigitalInOut(board.GP8)
25motor2_step.direction = digitalio.Direction.OUTPUT
26motor2_dir = digitalio.DigitalInOut(board.GP7)
27motor2_dir.direction = digitalio.Direction.OUTPUT
28enable = digitalio.DigitalInOut(board.GP9)
29enable.direction = digitalio.Direction.OUTPUT
30
31# Enable motors
32enable.value = False
33print("Motors enabled")
34
35STEPS_PER_ROT = 200 * 16 # Steps per rotation
36
37motor1 = MotorState(motor1_step, motor1_dir, 0.0001)
38motor2 = MotorState(motor2_step, motor2_dir, 0.0001)
39
40while True:
41 if supervisor.runtime.serial_bytes_available:
42 command = input().strip().lower()
43 parts = command.split()
44
45 if len(parts) != 2:
46 print("Invalid command. Use '[motor#] [position/zero]'")
47 continue
48
49 motor_num = int(parts[0])
50 target = parts[1]
51
52 if motor_num not in [1,2]:
53 print("Invalid motor number. Use 1 or 2")
54 continue
55
56 motor = motor1 if motor_num == 1 else motor2
57
58 try:
59 if target == "zero":
60 motor.position = 0
61 print(f"Motor {motor_num} position zeroed")
62 continue
63
64 target_pos = float(target) * STEPS_PER_ROT
65 steps = int(target_pos - motor.position)
66
67 if steps > 0:
68 motor.dir_pin.value = True
69 else:
70 motor.dir_pin.value = False
71 steps = -steps
72
73 print(f"Moving motor {motor_num} to position {target} rotations...")
74
75 for _ in range(steps):
76 motor.step()
77
78 motor.position = target_pos
79 print(f"Motor {motor_num} movement complete")
80
81 except ValueError:
82 print("Invalid position. Use number or 'zero'")