A modular, reliable, and easy-to-use stepper motor controller written in Python and Arduino. Control up to 3 stepper motors simultaneously.
The pegasus system allows you to communicate with an Arduino from python to run up to 3 stepper motors, using the Arduino, CNC Motor Shield, and any of the Pololu Stepper Motor Drivers. Displacement and speed feedback is reported to the GUI via an additional Arduino and a rotary encoder.
- Arduino firmware for use with an Arudino Uno
- A python script to test running a motor
- A GUI to run three motors
- Serial Communication utilities
- Unit conversion utilities
- An Arduino Uno (or cheap knockoff)
- Arduino to Computer cable
- CNC Motor Shield for the Arduino
- Pololu Stepper Motor Driver
- Stepper Motor
- [OPTIONAL for use with Rotary Encoder] Stepper motor w/ dual shaft
- Power cable
- Adapter wire
- Optical encoder
- Timing belot pulley
- Timing belt
Setup the hardware by following this instructional video. connect the arduino to your computer, and connect the CNC shield to a power outlet.
Clone or download this repository:
$ git clone https://github.com/sbooeshaghi/pegasus.git
Open up the Arduino IDE and load up motor_serial_com.ino
. Connect to the Arduino that will control the motor, select the right port, and upload the firmware. Load up encoder.ino
, connect to the Arduino that will control the encoder, select the right port, and upload the firmware.
Go to the terminal and run the test script
$ cd tests
$ chmod +x unit_tests.py
$ ./unit_tests.py
The code should do the following:
- Establish a connection with the Arduino,
- Send over "setup" commands,
- Send a Run commend, telling the motor to move,
- Send a Pause command,
- Send a Resume command
- Send a Stop command.
This is the command structure for sending a command from the Python Script to the Arduino :
"<mode,motorID,arg_m1,arg_m2,arg_m3>" # no spaces! the command is a string!
The possible commands are:
Where mode is one of [RUN, STOP, RESUME, PAUSE, SET_SPEED, SET_ACCEL]
motorID is one of int [000, 100, 010, 001, 110, 101, 011, 111]
arg_m1 is [any floating number]
arg_m2 is [any floating number]
arg_m3 is [any floating number]
Go to the terminal and run the GUI
$ cd src/GUI
$ chmod +x pegasus_gui.py
$ ./pegasus_gui.py
A GUI will be launched and you can do the following:
- Make sure both of your Arduinos are plugged in (Motor and Encoder)
- Select the port they are connected to (if you dont see it, try pressing refresh)
- Press connect to connect to the Arduinos.
- Set the units, microstepping, jog delta, and speed.
- Toggle the box associated with the motor you want to run
- Press "JOG +" To see the motor move.
Make sure that the port the code connects to is the correct port. Notice in the following example, my computer connected to the wrong port (Bluetooth port).
$ ./unit_tests.py
---------------- Testing Valid Cmd ----------------
[setup] Connecting to port: /dev/tty.Bluetooth-Incoming-Port
Traceback (most recent call last):
File "./unit_tests.py", line 156, in <module>
main()
File "./unit_tests.py", line 141, in main
test_valid_cmd()
File "./unit_tests.py", line 42, in test_valid_cmd
print(listen(s))
File "pegasus/firmware/serial_comm.py", line 128, in listen
while ord(x) != startMarker:
TypeError: ord() expected a character, but string of length 0 found
If you get the above error then chances are you either 1. don't have the Arduino connected, 2. tried to run the test code while the Arduino firmware was being uploaded to the arduino or 3. the code selected the wrong port programmatically. Check out the port variable that is assigned to populate_ports()[-1]
in the python script. This automatically returns the last port in the list of populate_ports()
ports.
- User flow control: it is possible for you to press buttons in the wrong order that will cause things to break
- Different units: currently only steps/s is supported
- Microstepping: currently only 1/1 microstepping is supported
- Additional encoders: currently only one encoder reports back to the GUI
- Custom acceleration
This work would not have been possible without the help of the wonderful Serial Communications Basics Tutorial by Robin2 at the Arduino Forum and the really awesome AccelStepper Library made by Mike McCauley and the amazing Encoder Library made by Paul Stoffregen. Also a big thank you to Professor Lior Pachter for supporting my work while doing a PhD in his lab at Caltech.