# this software is licensed under the GPL v3 license. # for further information see document GPL v3.txt # include packages import serial import re import math from tkinter import * # create and configure serial port object ser = serial.Serial() ser.port = 'COM3' # e.g. on Windows 'COM3' and on Linux '/dev/ttyUSB0' ser.baudrate = 115200 ser.rtscts = True #print(ser) # debug only: show current serial port configuration try: ser.open() except Exception as ex: print("Failed to open serial port:", type(ex).__name__, "-", ex) exit(1) print('Serial port successfully opened') # create an instance of tkinter frame win = Tk() # define the geometry of window win.geometry("750x500") # set the resizable property to false win.resizable(False, False) # change titel of window win.title('Visualization of azimuth and elevation angles') # create a canvas object c = Canvas(win, width=750, height=350) c.pack() # oval settings rad = 150 pos_1x = 200 pos_1y = 200 pos_2x = pos_1x + 2 * rad + pos_1x - rad + 25 pos_2y = 200 def draw_pointer(angle, x, y): angle_rad = math.radians(angle) side_x = math.cos(angle_rad) * rad side_y = math.sin(angle_rad) * rad c.create_line(x, y, x + side_x, y + side_y, fill="green", width=3) def draw_guideline(angle, x, y, factor, width): angle_rad = math.radians(angle) side_x = math.cos(angle_rad) * rad side_y = math.sin(angle_rad) * rad short_x = side_x * factor short_y = side_y * factor c.create_line(x+short_x, y+short_y, x+side_x, y+side_y, fill="red", width=width) # text labels label_azimuth = Label(win, text='-', bg='white') label_azimuth.place(x=pos_1x-55, y=pos_1y + rad + 55) label_elevation = Label(win, text='-', bg='white') label_elevation.place(x=pos_2x-55, y=pos_2y + rad + 55) label_90_azimuth = Label(win, text='90°', bg='white') label_90_azimuth.place(x=pos_1x + rad + 4, y=pos_1y - 9) label_90_elevation = Label(win, text='90°', bg='white') label_90_elevation.place(x=pos_2x - 7, y=pos_2y - rad - 23) label_0_azimuth = Label(win, text='0°', bg='white') label_0_azimuth.place(x=pos_1x - 4, y=pos_1y - rad - 23) label_0_elevation = Label(win, text='0°', bg='white') label_0_elevation.place(x=pos_2x - rad - 20, y=pos_2y - 9) label_n90_azimuth = Label(win, text='-90°', bg='white') label_n90_azimuth.place(x=pos_1x - rad - 30, y=pos_1y - 9) label_n90_elevation = Label(win, text='-90°', bg='white') label_n90_elevation.place(x=pos_2x - 15, y=pos_2y + rad + 5) # win.mainloop() angle_azimuth = 0 angle_elevation = 0 while True: # draw an oval in the canvas c.create_oval(pos_1x - rad, pos_1y - rad, pos_1x + rad, pos_1y + rad, fill = 'white') c.create_oval(pos_2x - rad, pos_2y - rad, pos_2x + rad, pos_2y + rad, fill = 'white') # draw guidelines in the oval factor = 0.9 for i in range(0, 360, 360//24): draw_guideline(i, pos_1x, pos_1y, factor, 1) draw_guideline(i, pos_2x, pos_2y, factor, 1) factor = 0.7 for i in range(0, 360, 360//8): draw_guideline(i, pos_1x, pos_1y, factor, 2) draw_guideline(i, pos_2x, pos_2y, factor, 2) try: data = ser.readline().decode('utf-8') # built string from byte array except UnicodeDecodeError as ex: # it seems that decode() fails sometimes at startup # to prevent this move the C209 tag for a few seconds before startup # retry to read next data continue m = re.search(r'^\+UUDF:[^,]*,[^,]*,([0-9-]+),([0-9-]+),[^,]*,[^,]*,[^,]*,[^,]*,[^,]*,[^,]*$', data) if m is not None: angle_azimuth, angle_elevation = m.groups() label_azimuth.config(text="Azimuth angle = " + angle_azimuth) label_elevation.config(text="Elevation angle = " + angle_elevation) #print(angle_azimuth, angle_elevation) # debug only: print the azimuth and elevation angles angle_azimuth = int(angle_azimuth) + 270 angle_elevation = int(angle_elevation) + 180 #print(data) # debug only: print the data that we received over the serial port draw_pointer(angle_azimuth, pos_1x, pos_1y) draw_pointer(angle_elevation, pos_2x, pos_2y) win.update_idletasks() win.update() try: c.delete("all") except TclError as ex: # when the window gets closed via X button we get a TclError here # so we exit the main loop break ser.close() print("Serial port successfully closed")