|
|
- #!/usr/bin/env python3
-
- import sys
- import getopt
- import glob
- import serial
- import struct
- from tkinter import *
-
- import matplotlib.figure as figure
- from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg
-
- from datetime import datetime
-
- 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)
-
- #ser = serial.Serial()
- #ser.port = "/dev/pts/19"
- #ser.baudrate = 9600
- #ser.bytesize = serial.EIGHTBITS
- #ser.parity = serial.PARITY_NONE
- #ser.stopbits = serial.STOPBITS_ONE
- #ser.timeout = None #block read
- #ser.timeout = 1 #non-block read
- #ser.timeout = 2 #timeout block read
- #ser.xonxoff = False #disable software flow control
- #ser.rtscts = False #disable hardware (RTS/CTS) flow control
- #ser.dsrdtr = False #disable hardware (DSR/DTR) flow control
- #ser.writeTimeout = 2 #timeout for write
-
- #try:
- # ser.open()
- #except Exception as e:
- # print('error open serial port: ' + str(e))
- # exit()
-
- #ser.open()
-
- #ser.write('hello world!')
- #values = bytearray([4, 9, 62, 144, 56, 30, 147, 3, 210, 89, 111, 78, 184, 151, 17, 129])
- #ser.write(values)
-
- #while True:
- # print(ser.readline())
-
- #from serial import *
- #from Tkinter import *
-
- #serialPort = "/dev/ttyACM0"
- #baudRate = 9600
- #ser = Serial(serialPort , baudRate, timeout=0, writeTimeout=0) #ensure non-blocking
-
- logEnable = 0;
-
- #~ temps = [20, 40, 60, 80, 100, 120, 140, 160, 180, 200, 220]
- temps = []
- tick = 0
- #~ tickArray = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
- tickArray = []
-
- tActArray = []
- tSetArray = []
- errArray = []
- errSumArray = []
- outOrigArray = []
- outArray = []
-
- def functionLog():
- global logEnable
-
- if logEnable == 1:
- sendSerial([0xa3])
- app.after(1000, functionLog)
-
- def sendSerial(input):
- print('send ' + str(len(input)) + ' byte(s): ' + str([hex(x) for x in input]))
- data = bytearray([0xff, 0xf1])
- data.append(len(input))
- data.extend(bytearray(input))
- ser.write(data)
-
- def processData(input):
- global logEnable
- global w
- global temps
- global tick
- global tickArray
- global tActArray
- global tSetArray
- global errArray
- global errSumArray
- global outOrigArray
- global outArray
-
- print(str([hex(x) for x in input]))
- if input[0] == 0xa0:
- if input[1] == 0x00:
- log.insert(END, '> temp sensor 0 status: ' + str.join(':', ('%02x' % x for x in input[2:])) + '\n')
- elif input[1] == 0x01:
- log.insert(END, '> temp sensor 1 status: ' + str.join(':', ('%02x' % x for x in input[2:])) + '\n')
- elif input[0] == 0x10:
- if input[1] == 0x00:
- log.insert(END, '> adc: wrong channel\n')
- elif input[1] == 0x01:
- log.insert(END, '> adc: start cartridge resistance measurement\n')
- elif input[1] == 0x02:
- log.insert(END, '> adc: start cartridge current measurement\n')
- elif input[1] == 0x03:
- log.insert(END, '> adc: start cartridge temperature measurement\n')
- elif input[1] == 0x04:
- log.insert(END, '> adc: start input voltage measurement\n')
- elif input[1] == 0xff:
- log.insert(END, '> adc: pending measurement\n')
- elif input[0] == 0x11:
- if input[1] == 0x01:
- log.insert(END, '> raw_adc_cartridge_resistance: ' + str(((input[2] * 256) + input[3])) + '\n')
- elif input[1] == 0x02:
- log.insert(END, '> raw_adc_cartridge_current: ' + str(((input[2] * 256) + input[3])) + '\n')
- elif input[1] == 0x03:
- log.insert(END, '> raw_adc_cartridge_temperature: ' + str(((input[2] * 256) + input[3])) + '\n')
- elif input[1] == 0x04:
- log.insert(END, '> raw_adc_v_in: ' + str(((input[2] * 256) + input[3])) + '\n')
- elif input[1] == 100:
- # log.insert(END, '> raw_adc_cartridge_temperature_cycle: ' + str(((input[2] * 256) + input[3])) + '\n')
- log.insert(END, '> raw_adc_cartridge_temperature_cycle: ' + str(round(((input[2] * 256) + input[3]) * 0.4833149757 + 35.1689715661)) + ' degC\n')
- #~ tick = tick + 1
- #~ tickArray.append(tick)
- #~ temps.append(((input[2] * 256) + input[3]) * 0.4833149757 + 35.1689715661)
- #~ tickArray = tickArray[-200:]
- #~ temps = temps[-200:]
- #~ ax1.clear()
- #~ ax1.set_ylim(0, 400)
- #~ ax1.plot(tickArray, temps, linewidth=2, color='black')
- #~ fig.canvas.draw()
- elif input[0] == 0x20:
- if input[1] == 0x00:
- log.insert(END, '> cartridge resistance measure disabled\n')
- elif input[1] == 0x01:
- log.insert(END, '> cartridge resistance measure enabled\n')
- elif input[0] == 0x21:
- if input[1] == 0x00:
- log.insert(END, '> power-mosfet disabled\n')
- elif input[1] == 0x01:
- log.insert(END, '> power-mosfet enabled\n')
- elif input[0] == 0x8d:
- cartridge_temperature_adc_raw = ((input[1] * 256) + input[2])
- tAct = struct.unpack('>f', input[3:7])
- tSet = struct.unpack('>f', input[7:11])
- err = struct.unpack('>f', input[11:15])
- errSum = struct.unpack('>f', input[15:19])
- outOrig = struct.unpack('>f', input[19:23])
- out = input[23] * 256 + input[24]
- if out > 32767:
- out -= 65536
- log.insert(END, 'tAct: ' + str(tAct) + 'tSet: ' + str(tSet) + 'err: ' + str(err) + 'errSum: ' + str(errSum) + 'outOrig: ' + str(outOrig) + 'out: ' + str(out) + '\n')
- #~ tActArray.append(tAct)
- #~ tActArray = tActArray[-200:]
- #~ ax1.clear()
- #~ ax1.plot(tickArray, tActArray, linewidth=2, color='black')
- #~ fig.canvas.draw()
- else:
- log.insert(END, '> ' + str.join(':', ('%02x' % x for x in input)) + '\n')
- log.see("end")
-
- def btnClearAction():
- log.delete(1.0,END)
- log.insert(END, str(datetime.now()) + '\n')
-
- def btnGetRawAdcCartridgeResistanceAction():
- sendSerial([0x10, 0x01])
-
- def btnGetRawAdcCartridgeCurrentAction():
- sendSerial([0x10, 0x02])
-
- def btnGetRawAdcCartridgeTemperatureAction():
- sendSerial([0x10, 0x03])
-
- def btnGetRawAdcInputVoltageAction():
- sendSerial([0x10, 0x04])
-
- def btnSetCartridgeResistanceMosfetOnAction():
- sendSerial([0x20, 0x01])
-
- def btnSetCartridgeResistanceMosfetOffAction():
- sendSerial([0x20, 0x00])
-
- def btnSetPowerMosfetOnAction():
- sendSerial([0x91, 0x01, 0x18])
-
- def btnSetPowerMosfetOffAction():
- sendSerial([0x91, 0x00, 0x00])
-
- def btnGetTempSensor0DegCAction():
- sendSerial([0xa2, 0x00])
-
- def btnGetTempSensor1DegCAction():
- sendSerial([0xa2, 0x01])
-
- def btnGetTempSensorsDegCAction():
- sendSerial([0xa3])
-
- def btnStartLogAction():
- global logEnable
- global w
-
- w = open('reflow_oven_temperature_log', 'w')
- logEnable = 1
- w.write('time;seconds;status;temperature;tAct;tSet;err;errSum;outOrig;out\n')
- sendSerial([0xa5])
- #functionLog()
-
- def btnStopLogAction():
- global logEnable
- global w
-
- sendSerial([0xa4, 0x00])
- logEnable = 0
- w.close()
-
- def btnDisablePwmAction():
- sendSerial([0xb0, 0x00, 0x00])
-
- def btnSetTemperature0Action():
- sendSerial([0xb1, 0x00])
-
- def btnSetTemperature80Action():
- sendSerial([0xb1, 0x50])
-
- def btnSetTemperature150Action():
- sendSerial([0xb1, 0x96])
-
- def btnSetTemperature180Action():
- sendSerial([0xb1, 0xb4])
-
- def btnSetTemperature245Action():
- sendSerial([0xb1, 0xf5])
-
- #make a TkInter Window
- app = Tk()
- app.wm_title("attiny817_solderstation_app")
-
- # Create figure for plotting
- fig = figure.Figure(figsize=(12, 4))
- #~ fig.subplots_adjust(left=0.1, right=0.8)
- ax1 = fig.add_subplot(1, 1, 1)
- ax1.set_ylim(0, 400)
- #~ ax1.set_xlim(0, 20)
- # Create a Tk Canvas widget out of our figure
- canvas = FigureCanvasTkAgg(fig, master=app)
- canvas_plot = canvas.get_tk_widget()
-
- # make a scrollbar
- scrollbar = Scrollbar(app)
- scrollbar.pack(side=RIGHT, fill=Y)
-
- # make a text box to put the serial output
- log = Text (app, width=250, height=20, takefocus=0)
- log.pack()
-
- # attach text box to scrollbar
- log.config(yscrollcommand=scrollbar.set)
- scrollbar.config(command=log.yview)
-
- btnClear = Button(app, text='clear', command=btnClearAction)
- btnGetRawAdcCartridgeResistance = Button(app, text='getRawAdcCartridgeResistance', command=btnGetRawAdcCartridgeResistanceAction)
- btnGetRawAdcCartridgeCurrent = Button(app, text='getRawAdcCartridgeCurrent', command=btnGetRawAdcCartridgeCurrentAction)
- btnGetRawAdcCartridgeTemperature = Button(app, text='getRawAdcCartridgeTemperature', command=btnGetRawAdcCartridgeTemperatureAction)
- btnGetRawAdcInputVoltage = Button(app, text='getRawAdcInputVoltage', command=btnGetRawAdcInputVoltageAction)
- btnSetCartridgeResistanceMosfetOn = Button(app, text='setCartridgeResistanceMosfetOn', command=btnSetCartridgeResistanceMosfetOnAction)
- btnSetCartridgeResistanceMosfetOff = Button(app, text='setCartridgeResistanceMosfetOff', command=btnSetCartridgeResistanceMosfetOffAction)
- btnSetPowerMosfetOn = Button(app, text='setPowerMosfetOn', command=btnSetPowerMosfetOnAction)
- btnSetPowerMosfetOff = Button(app, text='setPowerMosfetOff', command=btnSetPowerMosfetOffAction)
- btnGetTempSensor0DegC = Button(app, text='getTempSensor0DegC', command=btnGetTempSensor0DegCAction)
- btnGetTempSensor1DegC = Button(app, text='getTempSensor1DegC', command=btnGetTempSensor1DegCAction)
- btnGetTempSensorsDegC = Button(app, text='getTempSensorsDegC', command=btnGetTempSensorsDegCAction)
- btnStartLog = Button(app, text='startLog', command=btnStartLogAction)
- btnStopLog = Button(app, text='stopLog', command=btnStopLogAction)
- btnDisablePwm = Button(app, text='STOP', command=btnDisablePwmAction)
- btnSetTemperature0 = Button(app, text='setTemperature0', command=btnSetTemperature0Action)
- btnSetTemperature80 = Button(app, text='setTemperature80', command=btnSetTemperature80Action)
- btnSetTemperature150 = Button(app, text='setTemperature150', command=btnSetTemperature150Action)
- btnSetTemperature180 = Button(app, text='setTemperature180', command=btnSetTemperature180Action)
- btnSetTemperature245 = Button(app, text='setTemperature245', command=btnSetTemperature245Action)
-
- btnClear.pack()
- canvas_plot.pack()
- btnGetRawAdcCartridgeResistance.pack()
- btnGetRawAdcCartridgeCurrent.pack()
- btnGetRawAdcCartridgeTemperature.pack()
- btnGetRawAdcInputVoltage.pack()
- btnSetCartridgeResistanceMosfetOn.pack()
- btnSetCartridgeResistanceMosfetOff.pack()
- btnSetPowerMosfetOn.pack()
- btnSetPowerMosfetOff.pack()
-
- #make our own buffer
- #useful for parsing commands
- #Serial.readline seems unreliable at times too
-
- rxInputBuffer = bytearray()
- rxStatemachine = 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
- app.after(1, readSerial) # check serial again soon
-
-
- # after initializing serial, an arduino may need a bit of time to reset
- app.after(100, readSerial)
-
- app.mainloop()
|