16. Interface and application programming¶
assignment¶
individual assignment: write an application that interfaces a user with an input &/or output device that you made
group assignment:¶
compare as many tool options as possible
Step 1: group assignment¶
In the group, we tested mainly 2 options:
- The easy way (as I did): using Python with Tkinter and Pyserial.
- And the hard way (as Axel), who worked on an Inkscape plugin using Python, to interface our machine.
Comparing the results, we can highlight several points:
- Tkinter and Pyserial are simple libraries that allow a quick learning curve, and a basic use can be enough to collect or send simple data.
- However, they are limited. As example, Tkinter become quiclky havy and complex if you want more fancy interfaces. For example, here is the interface that I obtained: not fancy at all but functional.
- More, if you want more complex interfaces, for example to control a machine, you’ll need other tools, that become more complicated to use, but allow more possibilities, as Axel did and documented.
Step2 : assignment¶
making an interface¶
Goal¶
making an interface to see information between my board for my final project and a pc using ftdi cable
To do this code, here are the libraries that I used:
- Pyserial for the communication
- Tkinter for the interface
- Matplotlib for the data visualisation
- Numpy because you need Numpy
And the tutorials that I followed:
- Pyserial and Arduino
- matplotlib and real time plotting
- Good practice for Serial communication
- Neil’s example, for the structure of the code
creation of the interface¶
making my own interface uning python and TkInter
You can see here my interface created by python but it is not connected yet to my board
Debug mode¶
i realized that my interface was not able to recive the information so let search
witch port was used and baudrate
ser = serial.Serial('COM6' , 115200) actuay in my code but for my computer it is ser = serial.Serial('COM8' , 9600)
and verrify all my variables if its correct
# # Global variables # temperatureL=[] #List of the received temperature values timeL=[] #List of time stamp received outL=[] plot_data=False steinhart=0 # received temperature data time=0.0 # real time out=0 # # check command line arguments to define the serial port used for the communication # def idle(parent): # # idle routine # global t, time #Detects the data received on the serial communication start=decode_string() time=decode_float() out=decode_float() steinhart=decode_float() timeInt=decode_float() time=float(timeInt/1000)
code¶
from tkinter import * import serial import time ser = serial.Serial('COM8' , 9600) from matplotlib.backends.backend_tkagg import (FigureCanvasTkAgg, NavigationToolbar2Tk) from matplotlib.backend_bases import key_press_handler from matplotlib.figure import Figure import matplotlib.pyplot as plt import numpy as np from datetime import datetime import os # # Global variables # temperatureL=[] #List of the received temperature values timeL=[] #List of time stamp received outL=[] plot_data=False steinhart=0 # received temperature data time=0.0 # real time out=0 # # check command line arguments to define the serial port used for the communication # def idle(parent): # # idle routine # global t, time #Detects the data received on the serial communication start=decode_string() time=decode_float() out=decode_float() steinhart=decode_float() timeInt=decode_float() time=float(timeInt/1000) #Update the variable labels of the interface val_h.set(h) val_t.set(t) # Add the received values to the lists if(h>=0 and time>=0): #Ensure that all the data were cotrrectly received outL.append(h) temperatureL.append(t) timeL.append(time) save_csv() #Save at each step the values in a csv file else: print("Data missed") #Update the plots if(plot_data==True): try: update_graphs(a,l) except: print("Reinitialisation of the data required") parent.after_idle(idle,parent) # # Update data graphs # def update_graphs(a,l): """ Update the graph real time """ global outL, temperatureL, timeL, out, steinhart, time update_single_graph(timeL, outL, l_h) update_single_graph(timeL, temperatureL, l_t) a.set_xlim(timeL[-1]-60, timeL[-1]+10) #number of seconds before and after the last element of the time list canvas.draw() # # Update one graph # def update_single_graph(x,y,l): """x, y: python lists of the same size""" X=np.array(x) Y=np.array(y) l.set_data(X, Y) def decode_float(): """Reads a float sent by the arduino as a string and terminated by a '\n'""" global serial try: ser_bytes = ser.readline() decoded_bytes = (ser_bytes[0:len(ser_bytes)-2].decode("utf-8")) return(float(decoded_bytes)) except: print("An error occurred on the float serial transmission") return(-1.0) # # set up GUI # master = Tk() master.title(' Project pla ') master['bg']='white' master.bind('q','exit') # Create labels to display pid and temperature # # labels # fr_legends=Frame(master,borderwidth=2,width=30,relief=RAISED) fr_legends.pack(side=LEFT) fr_labels=Frame(fr_legends,borderwidth=2,relief=RAISED) fr_labels.pack(side=TOP) fr_label_h=Frame(fr_labels,borderwidth=2,relief=FLAT) fr_label_h.pack() label_h=Label(fr_label_h, width=20,text="pid =") label_h.pack(side=LEFT) val_h = StringVar() val_h.set("0.00") label_v_h=Label(fr_label_h, width=10, textvariable=val_h ) label_v_h.pack(side=LEFT) fr_label_t=Frame(fr_labels,borderwidth=2,relief=FLAT) fr_label_t.pack() label_t=Label(fr_label_t, width=20,text="Temperature (C) =") label_t.pack(side=LEFT) val_t = StringVar() val_t.set("0.00") label_v_t=Label(fr_label_t, width=10, textvariable=val_t) label_v_t.pack(side=LEFT) fr_legend_graph=Frame(fr_legends,borderwidth=2,relief=RAISED) fr_legend_graph.pack() l=Label(fr_legend_graph, width=30, text="pid", fg="blue") l.pack(side=TOP) l=Label(fr_legend_graph, width=30, text="temperature", fg="green") l.pack(side=TOP) # # canvas and figures # plt.ion() fig = Figure(figsize=(5, 4), dpi=100) a =fig.add_subplot(111) a.set_ylim(0, 100) a.set_xlabel('Time (s)') a.set_ylabel('Measures') #a.grid() l_h, =a.plot(0,0, 'b') l_t, =a.plot(0,0, 'g') canvas = FigureCanvasTkAgg(fig, master=master) # A tk.DrawingArea. canvas.draw() canvas.get_tk_widget().pack(side=TOP, fill=BOTH, expand=1) toolbar = NavigationToolbar2Tk(canvas, master) toolbar.update() canvas.get_tk_widget().pack(side=TOP, fill=BOTH, expand=1) # # start idle loop # master.after(100,idle,master) master.mainloop()
Now it is time to racord my board
now it is time to open my interface with pythonhon
open cmd and use the command below
- with tis command : python interface.py
everything seems to be fine my board seems to send the data and my interface seems to work.
Here you can see the results