Microcontroller 1
Instructor: Reza Farashahi
The goal of this assignment is to interface an Arduino Uno with a Python script on your computer. You will read the X and Y coordinates from a joystick module using the Arduino's analog-to-digital converter (ADC). These coordinates will then be sent to your computer via the serial port. A Python script will read this serial data and use it to control the position of your mouse pointer on the screen.
This project will teach you about:
analogRead().First, we need to wire the joystick to the Arduino and write a sketch to read its values and send them over the serial port.
Connect your joystick module to the Arduino Uno as shown below. Joystick modules typically have 5 pins:
The Arduino sketch should perform these steps in a loop:
Serial.println().Here is a starter code snippet. You will need to complete it.
// Define the analog pins connected to the joystick
#define VRX_PIN A0 // Joystick X-axis
#define VRY_PIN A1 // Joystick Y-axis
void setup() {
// Initialize serial communication at a 9600 bits-per-second baud rate.
// This rate must match the rate used in your Python script.
Serial.begin(9600);
}
void loop() {
// Read the analog values from the joystick
int xValue = analogRead(VRX_PIN);
int yValue = analogRead(VRY_PIN);
// Print the values to the serial port in a "x,y" format
Serial.print(xValue);
Serial.print(",");
Serial.println(yValue); // println adds a newline character at the end
// A small delay to make the communication stable
delay(50);
}
Upload this code to your Arduino Uno. You can check if it's working by opening the Serial Monitor in the Arduino IDE (Tools > Serial Monitor). Make sure the baud rate is set to 9600. You should see a stream of numbers like 512,511 that change as you move the joystick.
Now we will write a Python script to read the data from the Arduino and move the mouse.
You will need two Python libraries: pyserial to read from the serial port and pyautogui to control the mouse. Open your terminal or command prompt and install them using pip:
pip install pyserial
pip install pyautogui
Before trying to control the mouse, it's very important to confirm that Python can receive data from your Arduino. Use the following test script. This script will simply print whatever it receives from the serial port to your console.
Important: You must find your Arduino's COM port name. On Windows, it looks like COM3, COM4, etc. On macOS or Linux, it's something like /dev/tty.usbmodem14101 or /dev/ttyACM0. You can find this in the Arduino IDE under Tools > Port.
# test_serial.py
import serial
import time
# --- IMPORTANT ---
# CHANGE 'COM3' to your Arduino's port.
# You can find this in the Arduino IDE under Tools > Port.
# For Mac/Linux, it will be something like '/dev/tty.usbmodemXXXX'
ARDUINO_PORT = 'COM3'
BAUD_RATE = 9600
try:
# Establish a serial connection
arduino = serial.Serial(ARDUINO_PORT, BAUD_RATE, timeout=1)
time.sleep(2) # Wait for the connection to establish
print(f"Connected to Arduino on {ARDUINO_PORT}. Reading data...")
print("Move your joystick to see the values change.")
print("Press Ctrl+C to exit.")
while True:
# Read one line of data from the serial port
data = arduino.readline()
# Check if any data was received
if data:
# Decode the bytes into a string and remove leading/trailing whitespace
decoded_data = data.decode('utf-8').strip()
print(f"Received: {decoded_data}")
except serial.SerialException as e:
print(f"Error: Could not open port {ARDUINO_PORT}. {e}")
except KeyboardInterrupt:
print("\nProgram terminated by user.")
finally:
if 'arduino' in locals() and arduino.is_open:
arduino.close()
print("Serial port closed.")
Run this script from your terminal: python test_serial.py. If everything is set up correctly, you should see the same coordinate stream that you saw in the Arduino Serial Monitor.
ARDUINO_PORT is correct and that the BAUD_RATE (9600) matches the one in your Arduino sketch.Once your test script works, you can move on to the main task. You need to modify the script to:
pyautogui.moveTo().Here is a skeleton to guide you. You need to fill in the logic inside the `while` loop.
# joystick_mouse.py
import serial
import pyautogui
import time
# --- Configuration ---
ARDUINO_PORT = 'COM3' # CHANGE THIS to your Arduino's port
BAUD_RATE = 9600
# Get screen dimensions
screenWidth, screenHeight = pyautogui.size()
print(f"Screen size: {screenWidth} x {screenHeight}")
# Establish serial connection
arduino = serial.Serial(ARDUINO_PORT, BAUD_RATE)
time.sleep(2) # Wait for connection
print("Starting mouse control. Move the joystick.")
print("Press Ctrl+C to exit.")
try:
while True:
# 1. Read a line from the Arduino
data = arduino.readline().decode('utf-8').strip()
# 2. Make sure the data is not empty
if data:
try:
# 3. Split the string into two parts and convert to integers
x_str, y_str = data.split(',')
x_val = int(x_str)
y_val = int(y_str)
# 4. Map the joystick values (0-1023) to screen coordinates
# The joystick's X-axis might be inverted, so we map 1023-0 instead of 0-1023.
# You might need to adjust this based on your joystick's orientation.
mouseX = (x_val * screenWidth) / 1023
mouseY = (y_val * screenHeight) / 1023
# 5. Move the mouse to the new coordinates
pyautogui.moveTo(mouseX, mouseY)
except (ValueError, IndexError):
# Handle cases where the data is not in the expected "x,y" format
print(f"Warning: Received malformed data: {data}")
continue
except KeyboardInterrupt:
print("\nProgram terminated.")
finally:
arduino.close()
Please submit the following files in a single ZIP archive named YourName_Assignment2.zip:
.ino)..py).| Criteria | Points | Description |
|---|---|---|
| Arduino Code Correctness | 30 | Sketch correctly reads both X and Y axes and sends them over serial in the specified format. Code is clean and commented. |
| Python Code Correctness | 40 | Script successfully reads from the serial port, parses the data, maps the values correctly, and controls the mouse. Handles potential errors. |
| Functionality & Demonstration | 20 | The project works as intended. The mouse movement is smooth and corresponds to the joystick movement, as shown in the video. |
| Code Style and Comments | 10 | Both Arduino and Python code are well-formatted, readable, and include comments explaining the logic. |
| Total | 100 |