How to Build a Modern Python Tkinter GUI for Arduino Microcontroller Communication
Microcontrollers development boards such as Arduino have made embedded electronics accessible to everyone. From reading sensors to…
How to Build a Modern Python Tkinter GUI for Arduino Microcontroller Communication
[embed]
Microcontrollers development boards such as Arduino have made embedded electronics accessible to everyone. From reading sensors to controlling motors and automation systems, these small boards can perform powerful real-world tasks.

However, interacting directly with a microcontroller through a simple serial terminal is often inconvenient, especially when building practical applications.

A graphical user interface (GUI) can provide a much better user experience by allowing users to send commands, monitor responses, and control hardware through buttons, menus, and display windows.

In this project, we will build a Python-based desktop GUI application (shown above) that communicates with an Arduino through a USB serial connection (USB Virtual COM Port ).
The application uses:
- Python as the programming language
- Tkinter for GUI development
- ttkbootstrap for modern GUI styling
- PySerial for serial communication with Arduino
Source Codes
All the Python and Arduino Source Codes can be downloaded from our Website using the below link.
Hardware connections
Here we will show the Hardware connections for communicating with an Arduino Board using Python/Tkinter app.

Understanding the System Architecture

The communication process begins when the user enters the required serial communication parameters, such as the COM port number, baud rate, and the data to be transmitted, using the Tkinter Entry widgets and ComboBox controls.
Once the Transmit Data button is clicked, Tkinter transfers control to the button’s event handler function, transmit_data_button_handler().
This function validates the user inputs and then calls the main serial communication routine, serial_arduino_send_receive(), which manages the entire data exchange process.
Inside this function, the program attempts to establish a connection with the selected serial port using PySerial’s serial.Serial() class.
The COM port number and baud rate supplied by the user are used to configure the serial connection.
After the connection is opened successfully, the program configures a read timeout to prevent it from waiting indefinitely for incoming data.
Since opening a serial port through PySerial automatically resets most Arduino boards, the program waits briefly to allow the Arduino to complete its reset sequence and start executing the uploaded sketch.
Next, the data entered by the user is transmitted to the Arduino using the write() method. The Arduino receives the data, processes it according to its firmware, and sends a response back over the same serial connection.
Finally, the Python application reads the incoming data using the readline() method, converts the received bytes into a readable string, and displays the result in the Received Data text box of the Tkinter GUI.
ttkbootstrap GUI Elements used

Here we will talk about the various tkinter (ttkbootstrap) GUI element’s that are used in our Python Serial Communication Program.
You can also check out our full Youtube tutorial on using the tkinter/ttkbootstrap GUI elements from here,
[embed]
In this case, we will be using only the GUI element’s listed below so you can just follow along.
Main GUI elements used in our tkinter serial port program are listed below.
- Labels -> ttkbootstrap.Label()
- Buttons -> ttkbootstrap.Button()
- Drop Down List -> ttkbootstrap.Combobox()
- Text Entry Box -> ttkbootstrap.Entry()
- Text Box with Scroll Bars -> ttkbootstrap.ScrolledText()
Opening the Serial Port using tkinter
All the major work like opening the serial port and sending data are done inside the function
def serial_arduino_send_receive():
#code here
Here is a snippet of the code for opening the serial port using Python and PySerial inside a tkinter GUI Window.
try:
serial_port_object = serial.Serial(port_number,baudrate) # open the serial port
serial_port_object.timeout = 3 # Setting Read timeouts here
except serial.SerialException as var :
print('An Exception Occured')
print('Exception Details-> ', var)
Messagebox.show_error(title='Serial Exception Occured', message=f'{var}' )
else:
# proceed to read and write data into the serial port
# ..........
#...........
Since opening a serial port may fail due to various reasons, the operation is enclosed within a try-except block to handle errors gracefully.
serial_port_object = serial.Serial(port_number, baudrate)
This statement creates a Serial object and attempts to open the specified COM port using the user-selected baud rate. If the serial port is opened successfully, the function returns a serial port object, which is stored in the variable serial_port_object.
Immediately after opening the port, the program configures a read timeout.
serial_port_object.timeout = 3
This sets the maximum time that the program will wait for incoming serial data. If no data is received within 3 seconds, the read operation terminates and returns control to the program instead of waiting indefinitely
If an error occurs while opening the serial port, PySerial raises a SerialException. Control immediately jumps to the except block.
except serial.SerialException as var:
The exception object is stored in the variable var, which contains information describing the error.
The else block is executed only if no exception occurs inside the try block.
In other words, the code inside the else block runs only after the serial port has been opened successfully. This is where the program performs the actual serial communication, such as sending data to the Arduino using write() and receiving data using readline().
Writing Data to Serial Port in Tkinter GUI
After successfully opening the serial port, the program is ready to transmit data to the Arduino using the PySerial object’s write() method.
data_to_be_transmited = transmit_data_button_entry_box.get() # get the character to be transmitted from th entry box
data_to_be_transmited = bytearray(data_to_be_transmited, "utf-8") # convert string to byte array as pyserial write() requires byte array
serial_port_object.write(data_to_be_transmited) # send the character to Arduino
The data to be transmitted is first obtained from the Tkinter Entry widget by calling its get() method:
data_to_be_transmited = transmit_data_button_entry_box.get()
The get() method returns the user-entered text as a Python string. However, the write() method provided by the PySerial library cannot transmit Python strings directly; it requires the data to be in byte format.
To convert the string into bytes, the program uses the bytearray() function:
data_to_be_transmited = bytearray(data_to_be_transmited, "utf-8")
Here, "utf-8" specifies the character encoding used to convert the string into its corresponding byte representation. UTF-8 is the standard encoding for serial communication and supports a wide range of characters.
Once the conversion is complete, the byte array is transmitted to the Arduino using the write() method:
serial_port_object.write(data_to_be_transmited)
The write() method sends the bytes through the selected serial (COM) port, where they are received by the Arduino's UART interface for further processing by the Arduino sketch.
Reading Data from Serial Port in Tkinter GUI
After receiving data from the PC, the Arduino processes the incoming character or command and sends an appropriate response back through the serial port.
received_data = serial_port_object.readline() # read the data from serial port
received_data = received_data.decode("utf-8").strip() # readline() returns bytes which we need to be converted back to string
# .strip() removes the \r\n send by the Arduino
print(received_data)
received_data_entry.insert(0,received_data) #display received data
serial_port_object.close() # close the serial port
On the Python side, the Tkinter application reads this response using the PySerial readline() method:
received_data = serial_port_object.readline()
The readline() method reads data from the serial port until it encounters a newline character (\n). Therefore, the Arduino program should terminate each transmitted message with a newline character, typically by using Serial.println(), to ensure that the complete message is received correctly.
Since readline() returns the received data as a sequence of bytes, it must be converted back into a Python string before it can be displayed:
received_data = received_data.decode("utf-8")
The program then uses the strip() method to remove any trailing newline (\n), carriage return (\r), or extra whitespace characters:
received_data = received_data.strip()
The processed string can then be displayed in the Received Data text box or any other widget in the Tkinter application, allowing the user to view the response sent by the Arduino.
메타데이터
- post_id
- 7ab1fa2902b5
- slug
- how-to-build-a-modern-python-tkinter-gui-for-arduino-microcontroller-communication-7ab1fa2902b5
- url
- https://medium.com/@rahulsreedharan/how-to-build-a-modern-python-tkinter-gui-for-arduino-microcontroller-communication-7ab1fa2902b5
- canonical_url
- https://medium.com/@rahulsreedharan/how-to-build-a-modern-python-tkinter-gui-for-arduino-microcontroller-communication-7ab1fa2902b5
- author_url
- https://medium.com/@rahulsreedharan
- status
- ok
- fetched_at
- 2026-09-06 08:08:34