You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 

444 lines
17 KiB

#!/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()