|
|
- #!/usr/bin/env python3
-
- import sys
- import getopt
- import glob
- import serial
- import struct
- import tkinter
-
- from matplotlib.backends.backend_tkagg import (FigureCanvasTkAgg, NavigationToolbar2Tk)
- # Implement the default Matplotlib key bindings.
- from matplotlib.backend_bases import key_press_handler
- from matplotlib.figure import Figure
-
- import numpy as np
-
- tempe = 0
-
- tSetGlobal = 0.0
-
- controllerDebugWindowOpen = 0
-
- tick = 0
- tickArray = []
-
- tActArray = []
- tSetArray = []
-
- tickDebug = 0
- tickDebugArray = []
-
- tActDebugArray = []
- tSetDebugArray = []
- errDebugArray = []
- errSumDebugArray = []
- outOrigDebugArray = []
- outDebugArray = []
- outAvgDebugArray = []
- sleepCounterDebugArray = []
-
- rxInputBuffer = bytearray()
- rxStatemachine = 0
-
- def serial_ports():
- """ Lists serial port names
-
- :raises EnvironmentError:
- On unsupported or unknown platforms
- :returns:
- A list of the serial ports available on the system
- """
- if sys.platform.startswith('win'):
- ports = ['COM%s' % (i + 1) for i in range(256)]
- elif sys.platform.startswith('linux') or sys.platform.startswith('cygwin'):
- # this excludes your current terminal "/dev/tty"
- ports = glob.glob('/dev/tty[A-Za-z]*')
- elif sys.platform.startswith('darwin'):
- ports = glob.glob('/dev/tty.*')
- else:
- raise EnvironmentError('Unsupported platform')
-
- result = []
- for port in ports:
- try:
- s = serial.Serial(port)
- s.close()
- result.append(port)
- except (OSError, serial.SerialException):
- pass
- return result
-
- #print(serial_ports())
- availableSerialPorts = serial_ports()
-
- print('choose a port:')
- counter = 0
- for port in availableSerialPorts:
- print(' [' + str(counter) + '] ' + port)
- counter += 1
-
- choosenPort = input('(type a number (0)) ')
-
- if choosenPort == '':
- choosenPortNumber = 0
- else:
- choosenPortNumber = int(choosenPort)
-
- counter = 0
-
- #serialPort = '/dev/pts/19'
- serialPort = '/dev/ttyACM0'
-
- serialPort = availableSerialPorts[choosenPortNumber]
-
- try:
- ser = serial.Serial(serialPort, 19200, serial.EIGHTBITS, serial.PARITY_NONE, serial.STOPBITS_ONE, timeout=0, writeTimeout=0)
- except:
- serialPort = '/dev/ttyACM1'
- ser = serial.Serial(serialPort, 19200, serial.EIGHTBITS, serial.PARITY_NONE, serial.STOPBITS_ONE, timeout=0, writeTimeout=0)
-
- def readSerial():
- while True:
- c = ser.read() # attempt to read a character from Serial
-
- #was anything read?
- if len(c) == 0:
- break
- else:
- #print('DATA')
- #log.insert(END, ':' + c.hex())
-
- global rxInputBuffer
- global rxStatemachine
-
- rxInputBuffer.append(c[0])
- if rxStatemachine == 0:
- if rxInputBuffer[0] == 0xff:
- rxStatemachine = 1
- rxInputBuffer = rxInputBuffer[1:]
- elif rxStatemachine == 1:
- if rxInputBuffer[0] == 0xf1:
- rxStatemachine = 2
- else:
- rxStatemachine = 0
- rxInputBuffer = rxInputBuffer[1:]
- elif rxStatemachine == 2:
- if len(rxInputBuffer) >= rxInputBuffer[0] + 1:
- processData(rxInputBuffer[1:rxInputBuffer[0] + 1])
- rxInputBuffer = bytearray()
- rxStatemachine = 0
- else:
- if len(rxInputBuffer) > 256:
- print('rxInputBuffer reset!')
- rxInputBuffer = bytearray()
- rxStatemachine = 0
- root.after(10, readSerial) # check serial again soon
-
- def processData(input):
- global tSetGlobal
-
- print([ "0x%02x" % b for b in input ])
- # ~ print(str([hex(x) for x in input]))
- # ~ if input[0] == 0x11:
- # ~ if input[1] == 100:
- # ~ temperatureString.set(str(round(((input[2] * 256) + input[3]) * 0.4833149757 + 35.1689715661)) + "degC")
- # ~ processControllerDebugData(((input[2] * 256) + input[3]) * 0.4833149757 + 35.1689715661, 20, 10, 0, -10, -20)
- if input[0] == 0x33:
- print("debugDataEnabled")
- tickDebugArray.clear()
- tActDebugArray.clear()
- tSetDebugArray.clear()
- errDebugArray.clear()
- errSumDebugArray.clear()
- outOrigDebugArray.clear()
- outDebugArray.clear()
- outAvgDebugArray.clear()
- sleepCounterDebugArray.clear()
- elif input[0] == 0x34:
- print("debugDataDisabled")
- elif input[0] == 0x8d:
- cartridge_temperature_adc_raw = ((input[1] * 256) + input[2])
- tAct = struct.unpack('>f', input[3:7])[0]
- tSet = struct.unpack('>f', input[7:11])[0]
- err = struct.unpack('>f', input[11:15])[0]
- errSum = struct.unpack('>f', input[15:19])[0]
- outOrig = struct.unpack('>f', input[19:23])[0]
- out = input[23] * 256 + input[24]
- outAvg = input[25] * 256 + input[26]
- sleepCounter = input[27] * 256 + input[28]
- if out > 32767:
- out -= 65536
- tActString.set(str(round(tAct)) + "degC")
- tSetString.set("(" + str(round(tSet)) + "degC)")
- tSetGlobal = tSet
- processTemperatureData(tAct, tSet)
- processControllerDebugData(tAct, tSet, err, errSum, outOrig, out, outAvg, sleepCounter)
- elif input[0] == 0x8c:
- tAct = struct.unpack('>f', input[1:5])[0]
- tSet = struct.unpack('>f', input[5:9])[0]
- tActString.set(str(round(tAct)) + "degC")
- tSetString.set("(" + str(round(tSet)) + "degC)")
- tSetGlobal = tSet
- processTemperatureData(tAct, tSetGlobal)
- # ~ elif input[0] == 0x91:
- # ~ tSet = struct.unpack('>f', input[1:5])[0]
- # ~ tSetString.set("(" + str(round(tSet)) + "degC)")
- # ~ elif input[0] == 0x92:
- # ~ controllerValueKpString.set("Kp: " + str(struct.unpack('>f', input[1:5])[0]))
- # ~ elif input[0] == 0x93:
- # ~ controllerValueKpString.set("Kp: " + str(struct.unpack('>f', input[1:5])[0]))
- # ~ elif input[0] == 0x94:
- # ~ controllerValueKiString.set("Ki: " + str(struct.unpack('>f', input[1:5])[0]))
- # ~ elif input[0] == 0x95:
- # ~ controllerValueKiString.set("Ki: " + str(struct.unpack('>f', input[1:5])[0]))
- # ~ elif input[0] == 0x96:
- # ~ controllerValueKdString.set("Kd: " + str(struct.unpack('>f', input[1:5])[0]))
- # ~ elif input[0] == 0x97:
- # ~ controllerValueKdString.set("Kd: " + str(struct.unpack('>f', input[1:5])[0]))
- # ~ elif input[0] == 0x98:
- # ~ controllerValueKitString.set("Kit: " + str(struct.unpack('>f', input[1:5])[0]))
- # ~ elif input[0] == 0x99:
- # ~ controllerValueKitString.set("Kit: " + str(struct.unpack('>f', input[1:5])[0]))
- elif input[0] == 0xa0:
- controllerValueKpString.set("Kp: " + str(struct.unpack('>f', input[1:5])[0]))
- elif input[0] == 0xa1:
- controllerValueKiString.set("Ki: " + str(struct.unpack('>f', input[1:5])[0]))
- elif input[0] == 0xa2:
- controllerValueKdString.set("Kd: " + str(struct.unpack('>f', input[1:5])[0]))
- elif input[0] == 0xa3:
- controllerValueKitString.set("Kit: " + str(struct.unpack('>f', input[1:5])[0]))
- elif input[0] == 0xf0:
- tSet = struct.unpack('>f', input[1:5])[0]
- controllerKp = struct.unpack('>f', input[5:9])[0]
- controllerKi = struct.unpack('>f', input[9:13])[0]
- controllerKd = struct.unpack('>f', input[13:17])[0]
- controllerKit = struct.unpack('>f', input[17:21])[0]
- tSetString.set("(" + str(round(tSet)) + "degC)")
- tSetGlobal = tSet
- controllerValueKpString.set("Kp: " + str(controllerKp))
- controllerValueKiString.set("Ki: " + str(controllerKi))
- controllerValueKdString.set("Kd: " + str(controllerKd))
- controllerValueKitString.set("Kit: " + str(controllerKit))
-
- def sendSerial(payloadType, payload):
- # ~ print('send ' + str(len(input)) + ' byte(s): ' + str([hex(x) for x in input]))
- data = bytearray([0xff, 0xf1])
- data.append(1 + len(payload))
- data.append(payloadType)
- data.extend(bytearray(payload))
- print("send " + str([ "0x%02x" % b for b in data ]))
- ser.write(data)
-
- def createNewWindow():
- global controllerDebugWindowOpen
-
- newWindow = tkinter.Toplevel(root)
- newWindow.protocol("WM_DELETE_WINDOW", lambda: closeWindow(newWindow))
- # ~ labelExample = tkinter.Label(master=newWindow, text="new window")
- # ~ labelExample.pack()
- canvas2 = FigureCanvasTkAgg(controllerDebugFigure, master=newWindow) # A tk.DrawingArea.
- canvas2.draw()
- canvas2.get_tk_widget().pack()
- controllerDebugWindowOpen = 1
-
- def closeWindow(myVar):
- print("closeWindow " + str(myVar))
- controllerDebugWindowOpen = 0
- myVar.destroy()
-
- def increaseTemperature():
- global tempe, temperatureString
- tempe = tempe + 10
- temperatureString.set(str(tempe) + "degC")
-
- def processTemperatureData(tAct, tSet):
- global tick, tickArray, tActArray, tSetArray
-
- tickArray.append(tick)
- tickArray = tickArray[-30:]
- tick = tick + 1
-
- tActArray.append(tAct)
- tActArray = tActArray[-30:]
- tSetArray.append(tSet)
- tSetArray = tSetArray[-30:]
-
- yMin = tSet - 10
- yMax = tSet + 10
-
- if min(tActArray) < yMin:
- yMin = min(tActArray) - 2
-
- if max(tActArray) > yMax:
- yMax = max(tActArray) + 2
-
- temperatureFigureAxis1.clear()
- temperatureFigureAxis1.plot(tickArray, tActArray, linewidth=1, color="black")
- temperatureFigureAxis1.plot(tickArray, tSetArray, linewidth=1, color="green")
- temperatureFigureAxis1.set_ylim(yMin, yMax)
- # ~ temperatureFigure.tight_layout()
- temperatureFigure.canvas.draw()
-
- def processControllerDebugData(tAct, tSet, err, errSum, outOrig, out, outAvg, sleepCounter):
- # ~ print("processControllerDebugData")
- global tickDebug, tickDebugArray, tActDebugArray, tSetDebugArray, errDebugArray, errSumDebugArray, outOrigDebugArray, outDebugArray, outAvgDebugArray, sleepCounterDebugArray
- global controllerDebugWindowOpen
-
- tickDebugArray.append(tickDebug)
- tickDebugArray = tickDebugArray[-1000:]
- tickDebug = tickDebug + 1
-
- tActDebugArray.append(tAct)
- tActDebugArray = tActDebugArray[-1000:]
- tSetDebugArray.append(tSet)
- tSetDebugArray = tSetDebugArray[-1000:]
- errDebugArray.append(err)
- errDebugArray = errDebugArray[-1000:]
- errSumDebugArray.append(errSum)
- errSumDebugArray = errSumDebugArray[-1000:]
- outOrigDebugArray.append(outOrig)
- outOrigDebugArray = outOrigDebugArray[-1000:]
- outDebugArray.append(out)
- outDebugArray = outDebugArray[-1000:]
- outAvgDebugArray.append(outAvg)
- outAvgDebugArray = outAvgDebugArray[-1000:]
- sleepCounterDebugArray.append(sleepCounter)
- sleepCounterDebugArray = sleepCounterDebugArray[-1000:]
-
- if controllerDebugWindowOpen == 1:
- # ~ ax1.clear()
- # ~ ax1.plot(tickArray, tActArray, linewidth=2, color='black')
- # ~ fig.canvas.draw()
- controllerDebugFigureAxis1.clear()
- controllerDebugFigureAxis1.plot(tickDebugArray, tActDebugArray, linewidth=1, color="black", label="tAct")
- controllerDebugFigureAxis1.plot(tickDebugArray, tSetDebugArray, linewidth=1, color="green", label="tSet")
- controllerDebugFigureAxis1.plot(tickDebugArray, errDebugArray, linewidth=1, color="red", label="err")
- controllerDebugFigureAxis1.plot(tickDebugArray, errSumDebugArray, linewidth=1, color="orange", label="errSum")
- controllerDebugFigureAxis1.plot(tickDebugArray, outOrigDebugArray, linewidth=1, color="royalblue", label="outOrig")
- controllerDebugFigureAxis1.plot(tickDebugArray, outDebugArray, linewidth=1, color="blueviolet", label="out")
- controllerDebugFigureAxis1.plot(tickDebugArray, outAvgDebugArray, linewidth=1, color="blue", label="outAvg")
- controllerDebugFigureAxis1.plot(tickDebugArray, sleepCounterDebugArray, linewidth=1, color="grey", label="sleepCounter")
- controllerDebugFigureAxis1.legend(loc="lower left")
- controllerDebugFigureAxis1.set_ylim(-100, 1000)
- # ~ controllerDebugFigure.tight_layout()
- controllerDebugFigure.canvas.draw()
-
- root = tkinter.Tk()
- root.wm_title("Embedding in Tk")
- root.geometry("320x850")
- # ~ root.protocol("WM_DELETE_WINDOW", lambda: closeWindow(root))
-
- # ~ fig = Figure(figsize=(5, 4), dpi=100)
- # ~ fig2 = Figure(figsize=(5, 4), dpi=100)
- # ~ t = np.arange(0, 3, .01)
- # ~ fig.add_subplot(111).plot(t, 2 * np.sin(2 * np.pi * t))
- # ~ fig2.add_subplot(111).plot(t, 2 * np.cos(2 * np.pi * t))
-
- temperatureFigure = Figure(figsize=(3, 2))
- temperatureFigureAxis1 = temperatureFigure.add_subplot(1, 1, 1)
- temperatureFigureAxis1.yaxis.set_label_position("right")
- temperatureFigureAxis1.yaxis.tick_right()
- temperatureFigure.tight_layout()
-
- controllerDebugFigure = Figure(figsize=(15, 9))
- controllerDebugFigureAxis1 = controllerDebugFigure.add_subplot(1, 1, 1)
- controllerDebugFigureAxis1.yaxis.set_label_position("right")
- controllerDebugFigureAxis1.yaxis.tick_right()
- controllerDebugFigureAxis1.set_ylim(-200, 500)
- controllerDebugFigure.tight_layout()
-
- # ~ canvas = FigureCanvasTkAgg(fig, master=root) # A tk.DrawingArea.
- # ~ canvas.draw()
-
- # pack_toolbar=False will make it easier to use a layout manager later on.
- # ~ toolbar = NavigationToolbar2Tk(canvas, root, pack_toolbar=False)
- # ~ toolbar.update()
-
-
- # ~ canvas.mpl_connect("key_press_event", lambda event: print(f"you pressed {event.key}"))
- # ~ canvas.mpl_connect("key_press_event", key_press_handler)
-
- # ~ btn = tk.Button(root, text="Press", command=lambda: myFunction("See this worked!"))
- # ~ button = tkinter.Button(master=root, text="Quit", command=root.quit)
- buttonNewWindow = tkinter.Button(master=root, text="open controller debug window", command=createNewWindow)
-
- # Packing order is important. Widgets are processed sequentially and if there
- # is no space left, because the window is too small, they are not displayed.
- # The canvas is rather flexible in its size, so we pack it last which makes
- # sure the UI controls are displayed as long as possible.
- # ~ button.pack(side=tkinter.BOTTOM)
- buttonNewWindow.pack(side=tkinter.BOTTOM)
- # ~ toolbar.pack(side=tkinter.BOTTOM, fill=tkinter.X)
- # ~ canvas.get_tk_widget().pack(side=tkinter.TOP, fill=tkinter.BOTH, expand=1)
-
- tkinter.Button(master=root, text="set 330degC", command=lambda: sendSerial(0x91, [0x01, 0x4a])).pack()
- tkinter.Button(master=root, text="set 200degC", command=lambda: sendSerial(0x91, [0x00, 0xc8])).pack()
- tkinter.Button(master=root, text="set 0degC", command=lambda: sendSerial(0x91, [0x00, 0x00])).pack()
-
- tActString = tkinter.StringVar()
- tActString.set("0degC")
- tSetString = tkinter.StringVar()
- tSetString.set("(0degC)")
- controllerValueKpString = tkinter.StringVar()
- controllerValueKpString.set("Kp: 0")
- controllerValueKiString = tkinter.StringVar()
- controllerValueKiString.set("Ki: 0")
- controllerValueKdString = tkinter.StringVar()
- controllerValueKdString.set("Kd: 0")
- controllerValueKitString = tkinter.StringVar()
- controllerValueKitString.set("Kit: 0")
-
- tkinter.Label(master=root, textvariable=tActString, font=("Free Mono", 40)).pack()
- tkinter.Label(master=root, textvariable=tSetString, font=("Free Mono", 20)).pack()
-
- canvas = FigureCanvasTkAgg(temperatureFigure, master=root) # A tk.DrawingArea.
- canvas.draw()
- canvas.get_tk_widget().pack()
-
- # ~ tkinter.Button(master=root, text="Kp +1", command=lambda: sendSerial(0x92, [])).pack()
- tkinter.Label(master=root, textvariable=controllerValueKpString, font=("Free Mono", 20)).pack()
- textValueKp = tkinter.Text(master=root, height=1, width=20)
- textValueKp.pack()
- tkinter.Button(master=root, text="set Kp", command=lambda: sendSerial(0xa0, convertStringToFloatBytearray(textValueKp.get("1.0", "end-1c")))).pack()
- # ~ tkinter.Button(master=root, text="Kp -1", command=lambda: sendSerial(0x93, [])).pack()
- # ~ tkinter.Button(master=root, text="Ki +1", command=lambda: sendSerial(0x94, [])).pack()
- tkinter.Label(master=root, textvariable=controllerValueKiString, font=("Free Mono", 20)).pack()
- textValueKi = tkinter.Text(master=root, height=1, width=20)
- textValueKi.pack()
- tkinter.Button(master=root, text="set Ki", command=lambda: sendSerial(0xa1, convertStringToFloatBytearray(textValueKi.get("1.0", "end-1c")))).pack()
- # ~ tkinter.Button(master=root, text="Ki -1", command=lambda: sendSerial(0x95, [])).pack()
- # ~ tkinter.Button(master=root, text="Kd +1", command=lambda: sendSerial(0x96, [])).pack()
- tkinter.Label(master=root, textvariable=controllerValueKdString, font=("Free Mono", 20)).pack()
- textValueKd = tkinter.Text(master=root, height=1, width=20)
- textValueKd.pack()
- tkinter.Button(master=root, text="set Kd", command=lambda: sendSerial(0xa2, convertStringToFloatBytearray(textValueKd.get("1.0", "end-1c")))).pack()
- # ~ tkinter.Button(master=root, text="Kd -1", command=lambda: sendSerial(0x97, [])).pack()
- # ~ tkinter.Button(master=root, text="Kit +1", command=lambda: sendSerial(0x98, [])).pack()
- tkinter.Label(master=root, textvariable=controllerValueKitString, font=("Free Mono", 20)).pack()
- textValueKit = tkinter.Text(master=root, height=1, width=20)
- textValueKit.pack()
- tkinter.Button(master=root, text="set Kit", command=lambda: sendSerial(0xa3, convertStringToFloatBytearray(textValueKit.get("1.0", "end-1c")))).pack()
- # ~ tkinter.Button(master=root, text="Kit -1", command=lambda: sendSerial(0x99, [])).pack()
-
- tkinter.Button(master=root, text="enable debug data", command=lambda: sendSerial(0x33, [])).pack()
- tkinter.Button(master=root, text="disable debug data", command=lambda: sendSerial(0x34, [])).pack()
-
- # ~ tkinter.Button(master=root, text="init", command=lambda: sendSerial(0xf0, [])).pack()
-
- def convertStringToFloatBytearray(inputString):
- try:
- floatValue = float(inputString)
- byteArrayValue = bytearray(struct.pack('>f', floatValue))
- # ~ print(str(floatValue))
- # ~ print([ "0x%02x" % b for b in byteArrayValue ])
- return byteArrayValue
- except:
- print("can not convert [" + inputString + "] to float!")
- return []
-
- root.after(100, readSerial)
-
- sendSerial(0xf0, [])
-
- tkinter.mainloop()
|