How to Establish Communication Between Python and Arduino

How to Establish Communication Between Python and Arduino

This guide explains how to set up and use the provided Python script to communicate with an Arduino board. It is particularly useful for projects that involve sending commands to control servos, LEDs, or other peripherals, providing a foundation for automation and interactive applications.


Prerequisites
1. Hardware Requirements:
o -Arduino board
o USB cable to connect the Arduino to your computer
o LEDs, servo motor, or other peripherals (depending on the commands used)
2. Software Requirements:
o Python (3.x recommended)
o Arduino IDE for uploading firmware to the Arduino
o pyserial Python library (install using pip install pyserial)


Setting Up the Arduino

  1. Connect the Arduino: Plug the Arduino into your computer using the USB cable.
  2. Upload the Firmware:
    o Open the Arduino IDE.
    o Write or upload the corresponding Arduino sketch that listens for serial commands and controls connected devices (e.g., servos or LEDs).
    o Select the correct COM port and board type in the Arduino IDE.
    o Upload the sketch to the Arduino.
    Example Arduino LED Control Sketch
    Below is an example Arduino sketch (Led_controller.cpp) that handles LED operations. You can find the full Led_controller.cpp here:
#include "Led_controller.h"

CRGB leds[NUM_STRIPS][MAX_NUM_LEDS];  // Array to hold LED data for each strip

int dataPins[NUM_STRIPS] = {9, 10, 11};  // Adjust the data pins according to your setup
int numLeds[NUM_STRIPS] = {30, 30, 30};  // Example: 30 LEDs on each strip

/* Initialization (Default settings) */
void initialize_leds() {
    for (int i = 0; i < NUM_STRIPS; i++) {
        // Initialize each LED strip separately
        if (i == 0) {
            FastLED.addLeds<WS2812B, DATA_PIN_1, RGB>(leds[i], numLeds[i]);
        } else if (i == 1) {
            FastLED.addLeds<WS2812B, DATA_PIN_2, RGB>(leds[i], numLeds[i]);
        } else if (i == 2) {
            FastLED.addLeds<WS2812B, DATA_PIN_3, RGB>(leds[i], numLeds[i]);
        }
    }

    set_all_leds(CRGB::Black);  // Initialize LEDs as off
    FastLED.setBrightness(50);  // Set initial brightness
    FastLED.show();
    delay(500);
}

/* All LED control */
void set_all_leds(CRGB color) {
    for (int i = 0; i < NUM_STRIPS; i++) {
        for (int j = 0; j < numLeds[i]; j++) {
            leds[i][j] = color;
        }
    }
    FastLED.show();
}

/* LED group control */
void set_led_range(int stripIndex, int startLed, int endLed, CRGB color) {
    if (stripIndex < 0 || stripIndex >= NUM_STRIPS) {
        Serial.println("Invalid strip index!");
        return;
    }
    if (startLed < 0 || endLed >= numLeds[stripIndex] || startLed > endLed) {
        Serial.println("Invalid LED range!");
        return;
    }

    for (int i = startLed; i <= endLed; i++) {
        leds[stripIndex][i] = color;
    }
    FastLED.show();
}

/* Load bar control */
void load_bar_range(CRGB color, unsigned long duration, int stripIndex, int startIndex, int endIndex) {
    if (stripIndex < 0 || stripIndex >= NUM_STRIPS) {
        Serial.println("Invalid strip index!");
        return;
    }

    int totalLeds = endIndex - startIndex + 1;
    unsigned long interval = duration / totalLeds;

    for (int i = startIndex; i <= endIndex && i < numLeds[stripIndex]; i++) {
        leds[stripIndex][i] = color;
        FastLED.show();
        delay(interval);
    }

    for (int i = startIndex; i <= endIndex && i < numLeds[stripIndex]; i++) {
        leds[stripIndex][i] = CRGB::Black;
    }
    FastLED.show();
}

Setting Up the Python Script

Script Overview
The Python script facilitates serial communication with the Arduino, sending commands to control peripherals.

Key Functions:

• send_command(command, param): Sends a command with an optional parameter to the Arduino.
• execute_sequence(): Executes a predefined set of commands.
• execute_sequence2(): Executes another predefined set of commands.
Step-by-Step Instructions

  1. Install Dependencies: Ensure that pyserial is installed. You can check this by running pip show pyserial in your terminal or command prompt. If it is not installed, run the following command to install it:
  2. pip install pyserial
  3. Adjust COM Port: Open the script and locate this line:
  4. arduino = serial.Serial(port=‘COM4’, baudrate=9600, timeout=.1)
    Replace ‘COM4’ with the correct COM port where your Arduino is connected. On Windows, you can check this in the Device Manager. On macOS/Linux, use ls /dev/tty.* to find the port.
  5. Run the Script: Save the script as Arduino_communication.py. Run it using:
  6. python Arduino_communication.py

Understanding the Commands

The script supports various commands that are sent to the Arduino. Below is a breakdown:

Command Description:

initialize_servo Initializes the servo motor.
servo_on Moves the servo to 90 degrees.
servo_off Moves the servo back to 0 degrees.
initialize_leds Initializes the LEDs on the Arduino side by setting them to their default state (off) and configuring brightness.
set_all_leds Sets all LEDs to a specified color (e.g., Red, Blue).
set_strip_leds Sets all LEDs on a specific strip to a specified color.
set_led_range Sets a range of LEDs on a specific strip to a specified color.
load_bar_range Creates a loading bar effect on a range of LEDs with a specified duration.


Example Execution

  1. Sequence 1:
    o Initializes the servo motor and LEDs.
    o Sets all LEDs to red and performs additional LED operations.
    o Moves the servo to different positions.
    Execution code:
    execute_sequence()
  2. Sequence 2:
    o Moves the servo to predefined positions.
    o Performs a loading bar effect on LEDs.
    Execution code:
    execute_sequence2()

Additional Notes

  1. Serial Communication Basics:
    o The Arduino must send back a done message for the Python script to proceed to the next command.
    o Adjust delays (time.sleep()) as needed based on your hardware configuration.
  2. Troubleshooting:
    o Ensure the COM port and baud rate match between the Python script and Arduino sketch.
    o Use a serial monitor (like the one in Arduino IDE) to debug the commands sent and received.

By following this guide, you should be able to establish effective communication between Python and Arduino to control servos, LEDs, and other peripherals. To expand your setup, consider exploring libraries like pyFirmata for additional Arduino control or integrating sensors such as ultrasonic modules for more advanced projects. You may also refer to Arduino’s official documentation and Python community forums for deeper insights. Modify the script as needed to accommodate additional features or devices.


The python code that sends commands to the Arduino:


import serial
import time

# Connect to the Arduino (adjust COM port)
arduino = serial.Serial(port='COM4', baudrate=9600, timeout=.1)  # Adjust COM4 to your port
time.sleep(2)  # Wait for the Arduino to reset
arduino.reset_input_buffer() # Clear serial buffer

def send_command(command, param=""):
    full_command = f"{command} {param}\n"
    arduino.write(full_command.encode())
    print(f"Sent: {full_command.strip()}")
    time.sleep(0.1)  # Add delay before waiting for a response

    while True:
        response = arduino.readline().decode().strip()
        if response == "done":
            print("Arduino: done")
            break
        elif response:
            print(f"Arduino: {response}")

def execute_sequence():
    """Execute a sequence of commands."""

    # Define the sequence of commands to send
    commands = [
        ("initialize_servo", ""),  # Initialize the servo
        ("servo_on", ""),  # Move servo to 90 degrees
        ("initialize_leds", ""),  # Initialize LEDs
        ("set_all_leds", "Red"),  # Set all LEDs to Red
        ("set_strip_leds", "0 Blue"),  # Set LEDs of strip 0 to Blue
        ("set_led_range", "0 0 9 Red"),  # Set LEDs 0-9 on strip 0 to Red
        ("load_bar_range", "Yellow 5000 0 10 20"),  # 5 second Yellow load bar on LEDs 10-20 on strip 0
        ("servo_off", ""),  # Move the servo back to 0 degrees
    ]

    # Send each command in sequence
    for command, param in commands:
        send_command(command, param)

def execute_sequence2():
    """Execute a sequence of commands."""

    # Define the sequence of commands to send
    commands = [
        ("servo_on", ""),  # Move servo to 90 degrees
        ("servo_off", ""),  # Move the servo back to 0 degrees
        ("initialize_leds", ""),  # Initialize LEDs
        ("load_bar_range", "Green 5000 0 0 30"),  # 5 second Green load bar on LEDs 10-20 on strip 0
        ("set_all_leds", "Black")
]
    for command, param in commands:
        send_command(command, param)
#Command breakdown
"""
initialize_servo: Initializes the servo motor.

servo_on: Moves the servo to 90 degrees.

servo_off: Moves the servo back to 0 degrees.

initialize_leds: Initializes the LEDs on the Arduino side.

set_all_leds {color}: Sets all LEDs on all strips to the given color (Red, Blue, etc.).

set_strip_leds {stripIndex} {color}: Sets all LEDs on the given strip index to the specified color.

set_led_range {stripIndex} {startIndex} {endIndex} {color}: Sets a range of LEDs on a specific strip to a color.

load_bar_range {color} {duration} {stripIndex} {startIndex} {endIndex}: Creates a loading bar effect by lighting LEDs from start index to end index on a specific strip with a duration.

# broken blink single {stripIndex} {ledIndex} {color} {speed}: Blinks a single LED on a strip with a specific color and speed.

# broken blink all {stripIndex} {color} {speed}: Blinks all LEDs on a strip with a specified color and speed.

# broken blink range {stripIndex} {startLed} {endLed} {color} {speed}: Blinks a range of LEDs on a strip with a specified color and speed.
"""
if __name__ == "__main__":
    print("Starting the program 1...")
    execute_sequence()
    time.sleep(5)
    print("Starting the program 2 ...")
    execute_sequence2()

    print("Program finished.")