Python Forum
Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
How to solve AttributeError
#1
I am using line chart in tkinter.

First i create button event, then generate number graph & updating graph & working fine.

Now change program & receiving serial data in event & updating line chart.

now error appearing

"AttributeError"

& no lines are drawing on chart.

How to solve this error.

        if (len(data) < 100):
            data = np.append(data, float(dataList[1]))
        else:
            data[0:99] = data[1:100]
            data[99] = float(r1)
        lines.set_xdata(np.arange(0, len(data)))
        lines.set_ydata(dataList[1])
        canvas.draw()
same code is working in button event but not working in serial data event.

Need help.
Reply
#2
Quote:now error appearing "AttributeError"
Please show error traceback, complete and unaltered
Reply
#3
Output:
C:\Users\ROSHAN\AppData\Local\Programs\Python\Python35-32\python.exe "D:/Python/python serial/serialPortMarch2021.py" Error reading COM port: <class 'AttributeError'> Error reading COM port: <class 'AttributeError'> Error reading COM port: <class 'AttributeError'> Error reading COM port: <class 'AttributeError'> Error reading COM port: <class 'AttributeError'> Error reading COM port: <class 'AttributeError'> Error reading COM port: <class 'AttributeError'>
every second i am receiving data then error appears.
when i remove chart plotting code then no error.
Thanks
Reply
#4
Ths error occurs when you read the serial port, not when you plot. This part of the error message gives it away "Error reading COM port:". If you need help finding the error post the code that reads the serial port..
Reply
#5
Here is the code.
I have removed my other logging code & now error changes to
Output:
C:\Python\python.exe C:/Users/ROSHAN/PycharmProjects/untitled/serialPortMarch.py Error reading COM port: <class 'NameError'> Error reading COM port: <class 'NameError'> Error reading COM port: <class 'NameError'> Error reading COM port: <class 'NameError'> Error reading COM port: <class 'NameError'> Error reading COM port: <class 'NameError'> Error reading COM port: <class 'NameError'> Error reading COM port: <class 'NameError'>
code divided in 2 files.
main file has tkinter code &

another file has serial port related code(named serial_rx_tx.py)

data receiving from serial port updating on label successfully.
both code here

main code file
import tkinter as tk
from tkinter import *
import serial
from tkinter import messagebox
from tkinter import ttk
import serial.tools.list_ports as port_list
import serial_rx_tx
import _thread
import time
import webbrowser
from tkinter import messagebox
from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg
from matplotlib.figure import Figure
import numpy as np
import os.path
from datetime import datetime, date
import csv

# globals
serialPort = serial_rx_tx.SerialPort()
fileName = "data.csv"
data = np.array([])
# globaal array variable to hold numbewr of port
portList = []
dataList = []
stringEmpty = StringVar
selectedPort = StringVar
dataToBeWrite = StringVar
file = StringVar
root = tk.Tk();
root.title("My Serial Port")
root.geometry("800x520")

# init graph
fig = Figure(figsize=(5, 4), dpi=100)
ax = fig.add_subplot(111)

ax.set_title("Temperature Data Logger")
ax.set_xlabel("Time in Second")
ax.set_ylabel("Temperature In Degree")
ax.set_xlim(0, 60)
ax.set_ylim(0, 100)
lines = ax.plot([], [])[0]
data = np.array([])
ax.set_axisbelow(True)
ax.minorticks_on()
ax.grid(linestyle='-', linewidth='0.5', color='gray')
# Customize the major grid
ax.grid(which='major', linestyle='-', linewidth='0.5', color='black')
# Customize the minor grid
ax.grid(which='minor', linestyle=':', linewidth='0.5', color='gray')

canvas = FigureCanvasTkAgg(fig, root)
canvas.get_tk_widget().place(x=10, y=10, width=750, height=400)
canvas.draw()


# serial data callback function
def OnReceiveSerialData(message):
    global data
    global str_message
    global dataList
    global fileName
    global current_datetime
    global r1
    str_message = message.decode("utf-8")
    dataLabel1.config(text=str_message)
    dataList = str_message.split(",")

    if (len(dataList) > 1):
        if (len(data) < 100):
            data = np.append(data, float(r1))
        else:
            data[0:99] = data[1:100]
            data[99] = float(r1)
        lines.set_xdata(np.arange(0, len(data)))
        lines.set_ydata(data)
        canvas.draw()


# Register the callback above with the serial port object
serialPort.RegisterReceiveCallback(OnReceiveSerialData)


def sdterm_main():
    root.after(200, sdterm_main)  # run the main loop once each 200 ms


def openPort():
    global comport
    global baudrate
    if connectPort.cget("text") == 'Connect':
        comport = "COM3"
        baudrate = 9600
        selectedPort = comboBox.get().split("-")
        # print(" my poorrt:",selectedPort[0])
        serialPort.Open(selectedPort[0], baudrate)
        comboBox.config(state='disabled')
        connectPort.config(text='Disconnect')

    else:
        serialPort.Close()
        connectPort.config(text='Connect')


comboBox = ttk.Combobox(root, value=portList, font=("Helvetica 16"))
comboBox.place(x=450, y=450)

connectPort = Button(root, text="Connect", width=10, font=("Helvetica 16 bold"), command=openPort)
connectPort.place(x=300, y=450)

dataLabel1 = Label(text="Rx Data-1:", font=("Helvetica 12"))
dataLabel1.place(x=10, y=450)

# get list of available com ports
portList = list(port_list.comports())
# yupdate list of available comport in combobox
comboBox['value'] = portList
comboBox.set(portList[0])
root.after(200, sdterm_main)
root.mainloop()
here is file serial_rx_tx.py code
#
# Serial COM Port receive message event handler
# When a line of text arrives from the COM port terminated by a \n character, this module will pass the message to
# the function specified by the instantiator of this class.
#
import serial
import sys
import _thread

class SerialPort:
    def __init__(self):
        self.comportName = ""
        self.baud = 0
        self.timeout = None
        self.ReceiveCallback = None
        self.isopen = False
        self.receivedMessage = None
        self.serialport = serial.Serial()

    def __del__(self):
        try:
            if self.serialport.is_open():
                self.serialport.close()
        except:
            print("Destructor error closing COM port: ", sys.exc_info()[0] )

    def RegisterReceiveCallback(self,aReceiveCallback):
        self.ReceiveCallback = aReceiveCallback
        try:
            _thread.start_new_thread(self.SerialReadlineThread, ())
        except:
            print("Error starting Read thread: ", sys.exc_info()[0])

    def SerialReadlineThread(self):
        while True:
            try:
                if self.isopen:
                    self.receivedMessage = self.serialport.readline()
                    if self.receivedMessage != "":
                        self.ReceiveCallback(self.receivedMessage)
            except:
                print("Error reading COM port: ", sys.exc_info()[0])

    def IsOpen(self):
        return self.isopen

    def Open(self,portname,baudrate):
        if not self.isopen:
            # serialPort = 'portname', baudrate, bytesize = 8, parity = 'N', stopbits = 1, timeout = None, xonxoff = 0, rtscts = 0)
            self.serialport.port = portname
            self.serialport.baudrate = baudrate
            try:
                self.serialport.open()
                self.isopen = True
            except:
                print("Error opening COM port: ", sys.exc_info()[0])


    def Close(self):
        if self.isopen:
            try:
                self.serialport.close()
                self.isopen = False
            except:
                print("Close error closing COM port: ", sys.exc_info()[0])

    def Send(self,message):
        if self.isopen:
            try:
                # Ensure that the end of the message has both \r and \n, not just one or the other
                newmessage = message.strip()
                newmessage += '\r\n'
                self.serialport.write(newmessage.encode('utf-8'))
            except:
                print("Error sending message: ", sys.exc_info()[0] )
            else:
                return True
        else:
            return False
Reply
#6
It would be helpful to temporarily remove the exception handler in SerialReadlineThread().
Reply


Forum Jump:

User Panel Messages

Announcements
Announcement #1 8/1/2020
Announcement #2 8/2/2020
Announcement #3 8/6/2020