Python (pySerial) + Arduino + DC Motor
by thesharanmohan
This quick tutorial shows the simple operation of a DC motor using a Python GUI. To make Python communicate with an Arduino board, the pySerial package will be used. pySerial is a Python library that provides support for serial connections over a variety of different devices.
The setup involves using PyCharm IDE for Python development and the Arduino IDE for the microcontroller programming.
Step 1: Hardware
The required hardware includes:
- Adafruit motor shield
- Arduino board (Mega)
- DC motor
- 1k ohm resistors (2)
- LEDs (2)
- Hook-up wires
- Breadboard
A visual representation shows the Arduino Mega board connected to a motor shield, a DC motor, LEDs, and resistors on a breadboard.
Step 2: Hardware Setup
In this setup:
- Green LED is connected to Pin 30 of the Arduino board.
- Red LED is connected to Pin 32 of the Arduino board.
- DC Motor is connected to Channel 3 (M3) of the motor shield.
A visual representation shows the assembled hardware with the Arduino board, motor shield, DC motor, LEDs, and breadboard.
Step 3: Software - Arduino IDE, PyCharm IDE
This step involves setting up both the Arduino IDE and PyCharm IDE. The Arduino IDE is used to upload code to the Arduino board, while PyCharm IDE is used for writing and running the Python script.
Step 4: Arduino IDE
Connect the Arduino board to a PC. Open the Arduino IDE and select the appropriate COM port and board. The provided code is then uploaded to the Arduino board using the Upload button.
Step 5: Arduino IDE - Code Part 1
This section details the first part of the Arduino code, which includes:
- Including the Adafruit Motor shield library.
- Defining the motor on channel 3.
- Setting up the green and red LED pins as outputs.
- Initializing serial communication at 9600 baud.
- Setting the motor speed to 200 (out of 255).
- Ensuring the motor is initially stopped (RELEASE).
// Adafruit Motor shield library
#include <AFMotor.h>
// Define motor on channel 3
AF_DCMotor motor(3);
const int greenLed = 30;
const int redLed = 32;
int incomingData;
void setup() {
// initialize serial communication
Serial.begin(9600);
// initialize the LED pin as an output
pinMode(greenLed, OUTPUT);
pinMode(redLed, OUTPUT);
// speed
// Valid values for 'speed' are between 0 and 255 with 0 being off and 255 as full throttle
motor.setSpeed(200);
// RELEASE Stop the motor. This removes power from the motor and is equivalent to setSpeed(0)
motor.run(RELEASE);
}
Step 6: Arduino IDE - Code Part 2
This section details the second part of the Arduino code, which handles the motor control based on serial input:
- The
loop()
function continuously checks for incoming serial data. - If 'F' is received, the motor runs FORWARD, and the green LED turns ON.
- If 'R' is received, the motor runs BACKWARD, and the red LED turns ON.
- If 'Q' is received, the motor stops (RELEASE), and both LEDs turn OFF.
void loop() {
// see if there's incoming serial data
if (Serial.available() > 0) {
incomingData = Serial.read();
if (incomingData == 'F') {
motor.run(FORWARD);
digitalWrite(greenLed, HIGH);
digitalWrite(redLed, LOW);
}
if (incomingData == 'R') {
motor.run(BACKWARD);
digitalWrite(greenLed, LOW);
digitalWrite(redLed, HIGH);
}
if (incomingData == 'Q') {
motor.run(RELEASE);
digitalWrite(greenLed, LOW);
digitalWrite(redLed, LOW);
}
}
}
Step 7: Open PyCharm IDE and Click on File -> Settings.
The PyCharm IDE is opened, and the user navigates to 'File' then 'Settings' to configure the project environment.
A screenshot shows the PyCharm IDE interface with the 'Settings' menu open.
Step 8: Under Project, Select Project Interpreter and Click on the “+” Icon.
Within the project settings, the 'Project Interpreter' is selected, and the '+' icon is clicked to add or manage packages.
A screenshot shows the PyCharm project settings, highlighting the 'Project Interpreter' section and the '+' button.
Step 9: In the Search Bar, Type Pyserial and Click on Install Package.
The 'pyserial' package is searched for in the available packages list, and then installed.
A screenshot shows the PyCharm package installation dialog with 'pyserial' being searched and prepared for installation.
Step 10: The Python Code Below Is Run on PyCharm IDE.
The Python script is executed within the PyCharm IDE environment.
A screenshot shows the PyCharm IDE with the Python script open and ready for execution.
Step 11: Python Code - Part 1
This section presents the first part of the Python code. It is crucial to ensure that the COM port number used in the Python code matches the one configured for the Arduino board.
References for pySerial and Tkinter are provided:
- pySerial: https://pyserial.readthedocs.io/en/latest/shortintro.html
- Tkinter: https://docs.python.org/3/library/tkinter.html#tkinter-modules
import serial
import time
import tkinter as tk
window = tk.Tk()
window.configure(background="gray")
window.geometry("330x80")
window.title("MOTOR CTRL PYTHON GUI")
megaBoard = serial.Serial('COM5', 9600)
def motor_control():
print(">>> MOTOR CTRL PROGRAM <<<
")
def forward():
print("CTRL > FORWARD + GREEN LED -> ON")
megaBoard.write(b'F')
def reverse():
print("CTRL -> REVERSE + RED LED -> ON")
megaBoard.write(b'R')
Step 12: Python Code - Part 2
This section completes the Python code, defining the 'quit' function and creating the GUI buttons:
- The
quit()
function closes the serial connection and destroys the GUI window. - Three buttons are created: 'FORWARD', 'REVERSE', and 'EXIT'.
- Each button is configured with specific text, background and foreground colors, and font.
- The buttons are arranged using the
grid
layout manager. - The
window.mainloop()
starts the Tkinter event loop.
def quit():
print("\n** END OF PROGRAM **")
megaBoard.write(b'Q')
megaBoard.close()
window.destroy()
b1 = tk.Button(window, text="FORWARD", command=forward, bg="forest green", fg="gray7", font=("Comic Sans MS", 15))
b2 = tk.Button(window, text="REVERSE", command=reverse, bg="firebrick2", fg="ghost white", font=("Comic Sans MS", 15))
b3 = tk.Button(window, text="EXIT", command=quit, bg="gold", fg="gray7", font=("Comic Sans MS", 15))
bl.grid(row=1, column=0, padx=5, pady=10)
b2.grid(row=1, column=1, padx=5, pady=10)
b3.grid(row=1, column=2, padx=5, pady=10)
window.mainloop()
time.sleep(2)
motor_control()
Step 13: Final
A simple GUI is presented with three buttons: FORWARD, REVERSE, and EXIT. Depending on the motor connection wiring, the motor operates in the selected direction when the FORWARD or REVERSE button is clicked. The EXIT button safely closes the serial port and terminates the program execution.
A screenshot displays the final GUI with the three control buttons.
Step 14: Video
A video demonstration of the project is available at: https://www.youtube.com/watch?v=9xUVIkRJ1rU
The author expresses gratitude for sharing the tutorial.