I want to read data from my arduino and show it on a tkinter window, it works nicely but when I sent the Data on the arduino faster then every 10ms it resevieses many lines that are not full like this:
'Malik']
⚠️ Invalid line, skipped: ['0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', 'Malik']
⚠️ Invalid line, skipped: ['0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', 'Malik']
⚠️ Invalid line, skipped: ['0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', 'Malik']
⚠️ Invalid line, skipped: ['0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', 'Malik']
⚠️ Invalid line, skipped: ['0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', 'Malik']
⚠️ Invalid line, skipped: ['0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', 'Malik']
⚠️ Invalid line, skipped: ['0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', 'Malik']
⚠️ Invalid line, skipped: ['0', '0', '0', '0', '0', '0', '0', '0', '0', '0', 'Malik']
⚠️ Invalid line, skipped: ['0', '0', '0', '0', '0', '0', '0', '0', '0', '0', 'Malik']
⚠️ Invalid line, skipped: ['0', '0', '0', '0', '0', '0', '0', '0', '0', '0', 'Malik']
⚠️ Invalid line, skipped: ['0', '0', '0', '0', '0', '0', '0', '0', '0', '0', 'Malik']
⚠️ Invalid line, skipped: ['0', '0', '0', '0', '0', '0', '0', '0', '0', '0', 'Malik']
⚠️ Invalid line, skipped: ['0', '0', '0', '0', '0', '0', '0', '0', '0', 'Malik']
⚠️ Invalid line, skipped: ['0', '0', '0', '0', '0', '0', '0', '0', '0', 'Malik']
⚠️ Invalid line, skipped: ['0', '0', '0', '0', '0', '0', '0', '0', '0', 'Malik']
⚠️ Invalid line, skipped: ['0', '0', '0', '0', '0', '0', '0', '0', '0', 'Malik']
The weird thing is when i sent it at 10ms speed it works, just sometimes not when i move the window. Hope somebody can help me here is my code:
def read_Serial_Values(self):
read_Line = ReadLine(ser)
self.raw_Input = read_Line.readline().decode('utf-8').strip()
# if self.is_Data_Here():
# print("!Overload!")
# self.trash = ser.read_all()
self.raw_Listet_Input = [x for x in self.raw_Input.split(",") if x]
if len(self.raw_Listet_Input) < 21:
print("⚠️ Invalid line, skipped:", self.raw_Listet_Input)
return
self.Inp_manager.save_Repeating_Input(self.raw_Listet_Input)
def is_Data_Here(self):
if ser.in_waiting >0:
return True
return False
class ReadLine:
def __init__(self, s):
self.buf = bytearray()
self.s = s
def readline(self):
i = self.buf.find(b"\n")
if i >= 0:
r = self.buf[:i+1]
self.buf = self.buf[i+1:]
return r
while True:
i = max(1, min(2048, self.s.in_waiting))
data = self.s.read(i)
i = data.find(b"\n")
if i >= 0:
r = self.buf + data[:i+1]
self.buf[0:] = data[i+1:]
return r
else:
self.buf.extend(data)
I have tried changing the timeout but that didnt changed anything and I also changed the way the programm recevies the lines.
You're reading data too fast, and the serial input is not guaranteed to end cleanly with \n
before your code tries to process it, and that’s why you are getting incomplete or "corrupted" lines.
Tkinter is single-threaded. If you read from a serial in the same thread as the GUI, the GUI slows down (and vice versa), especially when you move the window.
Run the serial reading in a separate thread, and put the valid data into a queue.Queue()
which the GUI can safely read from.
import threading
import queue
data_queue = queue.Queue()
def serial_read_thread():
read_Line = ReadLine(ser)
while True:
try:
line = read_Line.readline().decode('utf-8').strip()
parts = [x for x in line.split(",") if x]
if len(parts) >= 21:
data_queue.put(parts)
else:
print("⚠️ Invalid line, skipped:", parts)
except Exception as e:
print(f"Read error: {e}")
Start this thread once at the beginning:
t = threading.Thread(target=serial_read_thread, daemon=True)
t.start()
Use after()
in Tkinter to periodically fetch from the queue and update the UI:
def update_gui_from_serial():
try:
while not data_queue.empty():
data = data_queue.get_nowait()
print(data)
except queue.Empty:
pass
root.after(50, update_gui_from_serial)
Please let me know if this works and if you need any further help! :)