Build your own machine¶
Repo
Download from this site
Firmware¶
Download firmware from repo / from this site
Note
- While holding down the “BOOT” button, connect the USB cable to the PC.
or - Connect the USB cable to the PC.
- Keep holding the BOOT button.
- Press and release the RESET button.
A storage device named “RPI-RP2” will be mounted, just like a USB flash drive.
Drag and drop the .uf2 file into the “RPI-RP2” drive.
Python¶
Python code
The code is designed for Python >= 3.10
Dependencies:
pyserial >= 3.4
cobs >= 1.1
install python
# Check Python version
% python3 --version
Python 3.13.5
# Check pyserial version (if installed)
% python3 -c "import serial; print(serial.__version__)"
3.5
# Install or update pyserial if missing or outdated
% python3 -m pip install --user --upgrade pyserial
# Check cobs version
% python3 -c "import cobs; print(cobs.__version__)"
1.2.1
# Install or update pyserial and cobs if needed
% python3 -m pip install --user --upgrade pyserial cobs
code¶
Serial port
% ls /dev/tty.*
/dev/tty.usbmodem101
% ls /dev/cu.*
/dev/cu.usbmodem101
% ls /dev/*usb*
/dev/cu.usbmodem101 /dev/tty.usbmodem101
Note
Use /dev/cu. instead of /dev/tty. for USB serial devices on macOS.
/dev/cu.* is non-blocking and safer for direct communication with Arduino.
download code
import motor
import time
import random
def goto(m: motor.Motor, x, vel, accel):
# print(m.get_states())
m.set_target_position(x, vel, accel)
# print(m.get_states())
# ... wait while not at point:
while True:
states = m.get_states()
# print(states["position"])
# if states['is_moving'] == 0:
if not states["is_moving"]:
break
# if abs(states["position"] - x) <= 0.01:
# break
def goto_all(m1: motor.Motor, m2: motor.Motor, x1, x2, vel, accel):
m1.set_target_position(x1, vel, accel)
m2.set_target_position(x2, vel, accel)
# ... wait while not at point:
done = False
while not done:
states1 = m1.get_states()
states2 = m2.get_states()
done = states1['is_moving'] == 0 and states2['is_moving'] == 0
def main():
# change to the correct serial port
# m = motor.Motor("COM47")
# Use /dev/cu.* instead of /dev/tty.* for USB serial devices on macOS.
# /dev/cu.* is non-blocking and safer for direct communication with Arduino.
m = motor.Motor("/dev/cu.usbmodem101") # ====================================== here
# turns/sec
vel = 5
# turns/sec²
acc = 30
# 200 steps per turn
steps_per_unit = 200
# 30% current
current = 0.3
m.set_steps_per_unit(steps_per_unit)
m.set_current(current)
goto(m, 2.0, vel, acc)
time.sleep(0.2)
goto(m, 0.0, vel, acc)
m.set_current(0)
if __name__ == "__main__":
main()
% cd path/to/code/python
% tree
.
├── __pycache__
│ ├── cobs_usb_serial.cpython-312.pyc
│ ├── cobs_usb_serial.cpython-313.pyc
│ ├── motor.cpython-312.pyc
│ └── motor.cpython-313.pyc
├── cobs_usb_serial.py
├── main_test.py
└── motor.py
% python3 main_test.py
Two machines¶
% ls /dev/tty.*
/dev/tty.usbmodem101
/dev/tty.usbmodem1101
import motor
import time
import random
def goto(m: motor.Motor, x, vel, accel):
# print(m.get_states())
m.set_target_position(x, vel, accel)
# print(m.get_states())
# ... wait while not at point:
while True:
states = m.get_states()
# print(states["position"])
# if states['is_moving'] == 0:
if not states["is_moving"]:
break
# if abs(states["position"] - x) <= 0.01:
# break
def goto_all(m1: motor.Motor, m2: motor.Motor, x1, x2, vel, accel):
m1.set_target_position(x1, vel, accel)
m2.set_target_position(x2, vel, accel)
# ... wait while not at point:
done = False
while not done:
states1 = m1.get_states()
states2 = m2.get_states()
done = states1['is_moving'] == 0 and states2['is_moving'] == 0
def main():
# change to the correct serial port
#m = motor.Motor("COM47")
m1 = motor.Motor("/dev/tty.usbmodem101")
m2 = motor.Motor("/dev/tty.usbmodem1101")
# turns/sec
vel = 5
# turns/sec²
acc = 30
# 200 steps per turn
steps_per_unit = 200
# 30% current
current = 0.3
m1.set_steps_per_unit(steps_per_unit)
m1.set_current(current)
m2.set_steps_per_unit(steps_per_unit)
m2.set_current(current)
goto_all(m1, m2, 2.0, 2.0, vel, acc)
#goto(m, 2.0, vel, acc)
time.sleep(0.2)
goto_all(m1, m2, 0.0, 0.0, vel, acc)
#goto(m, 0.0, vel, acc)
m1.set_current(0)
m2.set_current(0)
if __name__ == "__main__":
main()