Python can read data from an Arduino by opening the serial port that connects them and parsing the incoming bytes as text or numbers

An Arduino sends data through a USB cable as a stream of bytes. Python receives those bytes through the same USB connection by opening what the operating system calls a serial port. On Windows, this appears as COM3 or COM4. On Mac and Linux, it appears as /dev/ttyUSB0 or /dev/ttyACM0. Once Python opens that port, it can read whatever the Arduino is sending — sensor readings, button presses, temperature values — and store or process it.

The most common way to do this is with the PySerial library, a Python package that handles the serial port connection. You install it once, import it into your script, and then use a few lines of code to open the port, read data, and close it when you are done.

Key Takeaways

  • Install PySerial on your computer using pip, then import the serial module into your Python script to access the Arduino's USB connection.
  • Find the correct serial port name by checking your Arduino IDE's Tools menu or by listing connected devices on your operating system.
  • Open the port with the correct baud rate — usually 9600, but check your Arduino sketch to confirm what speed it is sending data.
  • Read data line by line using readline() and decode it from bytes to text, then split or convert it into numbers you can use in calculations.
  • Always close the serial port when your script finishes to avoid locking the connection and preventing other programs from using it.

Install PySerial and identify your Arduino's port

Before you write any code, install PySerial. Open your terminal or command prompt and type pip install pyserial. This downloads and installs the library so Python can talk to serial devices.

Next, find out which port your Arduino is using. The easiest way is to open the Arduino IDE, plug in your Arduino, and look under Tools > Port. You will see a name like COM3 (Windows) or /dev/ttyUSB0 (Mac/Linux). Write this down — you will need it in your Python script.

If you do not have the Arduino IDE open, you can find the port another way. On Windows, open Device Manager and look under Ports (COM & LPT). On Mac, open Terminal and type ls /dev/tty.*. On Linux, type ls /dev/tty*. The Arduino will show up as a new entry when you plug it in.

Write a basic Python script to open the serial port

Create a new Python file and start with these lines:

import serial import time ser = serial.Serial('COM3', 9600, timeout=1) time.sleep(2) while True:   if ser.in_waiting > 0:     line = ser.readline().decode('utf-8').rstrip()     print(line) ser.close()

Replace 'COM3' with your actual port name. The 9600 is the baud rate — the speed at which data travels. Your Arduino sketch must send data at the same speed. If your sketch uses Serial.begin(115200), change 9600 to 115200 in the Python code.

The timeout=1 tells Python to wait up to one second for data before moving on. The time.sleep(2) gives the Arduino time to reset when the connection opens. The while True loop keeps reading data until you stop the script. The ser.in_waiting check prevents the script from hanging if no data has arrived yet.

Decode and parse the incoming data

When the Arduino sends data, it arrives as bytes — raw binary information. The .decode('utf-8') converts those bytes into text you can read. The .rstrip() removes the newline character at the end of each line so you do not get extra blank space.

If your Arduino sends a single number like "42", the script above will print it as is. If it sends multiple values separated by commas, like "23,45,67", you need to split them:

line = ser.readline().decode('utf-8').rstrip() values = line.split(',') temp = int(values[0]) humidity = int(values[1]) pressure = int(values[2]) print(f"Temperature: {temp}, Humidity: {humidity}, Pressure: {pressure}")

The split(',') breaks the line into separate pieces at each comma. Then int() converts each piece from text to a number so you can do math with it. If the values are decimals instead of whole numbers, use float() instead of int().

Handle errors and connection problems

If the port name is wrong, Python will throw a SerialException error and stop. Wrap your code in a try-except block to catch this:

try:   ser = serial.Serial('COM3', 9600, timeout=1) except serial.SerialException:   print("Could not open port. Check the port name and try again.")   exit()

If the baud rate is wrong, the script will read garbage characters instead of real data. Go back to your Arduino sketch, find the Serial.begin() line, and make sure the number matches what you put in the Python code.

If the Arduino resets every time Python connects, that is normal on many boards — the connection triggers a reset. The time.sleep(2) at the start gives the Arduino time to boot. If you need to skip the reset, some Arduino boards have a capacitor you can remove, but that is rarely necessary.

Save data to a file or database

Once you are reading data reliably, you can save it instead of just printing it. This example writes each line to a text file:

with open('sensor_data.txt', 'a') as f:   while True:     if ser.in_waiting > 0:       line = ser.readline().decode('utf-8').rstrip()       f.write(line + '\n')       f.flush()

The 'a' mode appends data to the file instead of overwriting it. The f.flush() forces Python to write the data when ready instead of waiting for the buffer to fill. This matters if you want to see the data in real time while the script is still running.

For larger projects, you might store data in a database like SQLite instead. That lets you query and analyze the data later without parsing a text file by hand.

Test with a straightforward Arduino sketch

If you do not have an Arduino sketch yet, use this one to send test data:

void setup() {   Serial.begin(9600); } void loop() {   int sensorValue = analogRead(A0);   Serial.println(sensorValue);   delay(1000); }

This reads an analog sensor on pin A0 every second and sends the value to Python. Upload it to your Arduino, then run your Python script. You should see numbers appearing in your terminal or being written to your file.

Once this works, you can modify the Arduino sketch to send different data — temperature from a sensor, the state of a button, readings from multiple pins — and adjust your Python code to parse whatever format you choose.

Frequently Asked Questions

What if Python says "port is already in use"?

Another program has the port open. Close the Arduino IDE, any other Python scripts, or serial monitor windows. On Windows, you may need to restart your computer. On Mac or Linux, you can kill the process using the terminal, but closing the IDE usually works.

Why am I reading garbage characters instead of numbers?

The baud rate does not match. Check your Arduino sketch for Serial.begin() and make sure the number is the same in your Python code. The most common rates are 9600 and 115200. If you change it in the Arduino sketch, you must upload the new code before running Python again.

Can I read data from multiple Arduinos at once?

Yes. Open multiple serial connections with different port names, each in its own variable. You can read from all of them in the same loop or in separate threads if you need them to run at different speeds.

How do I know if data is actually arriving?

Add print statements to check ser.in_waiting before you try to read. If it stays at 0, no data is coming through — check that the Arduino is plugged in, the sketch is uploaded, and the baud rate is correct. You can also open the Arduino IDE's serial monitor to see what the Arduino is actually sending.

Do I need to close the port every time?

Yes. If you do not call ser.close(), the port stays locked and other programs cannot use it. If your script crashes, the port may stay locked until you restart your computer. Using a try-finally block ensures the port closes even if an error happens.