16. Interface and application programming (CLS Students)¶
Group 1: Nick, Jack, Jada, Aarush¶
Interfacing 1: Unity Engine (From Nick)¶
The Unity engine which Nick used is incredibly powerful. He managed to connect a soil moisture sensor to a child board to a USB-plugged SamD chip which was then read throguh a program called CoolTerm into a text file which was then opened, parsed, and math modified to become understandable as a percentage in Unity. It was then displayed in a bar and as a text object and depending on the moisture level the sensor detected the in-engine world would rain at different amounts.
Here is a video of the sensor interacting with Unity:
Unity as a tool has tons of benefits:
- Can build to almost any device
- Tons of builtin components (Physics, particles, lighting, 3D or 2D, etc.)
However the programs it builds requires somewhat powerful hardware to run, but overall it has tons of features and capabilities to fit tons of needs.
Group 2: Alaric, Aaron, Andrew and Pari¶
Interface 1: Processing (From Aaron)¶
Aaron wanted to use his RFID sensor with the Processing Interface. He wanted the screen to read, “no card avalible” if their wasn’t a card being read. However, if their was a card, then the screen would display the ID string. Their was a lot of troubleshooting with null data types but overall, it was an easy application to use. It works well with Arduino and the language used for Processing may have some differences, but the concepts are the same for each IDE.
The final video of the interface working is below.
Interface 2: Python (From Alaric)¶
To compare python’s tkinter library with processing, Alaric used Aaron’s RFID sensor and wrote a similar interfact using tkinter to better compare the 2 languages keeping the sensor constant. He learned tkinter using this site and learned pyserial with a combination of referencing Dr. Gershenfeld’s code and this site.
He got it working with the following code:
import serial from time import sleep from tkinter import * __name__ = 'main' def idle(ser, root, text, readings): data = '' if ser.in_waiting != 0: data = str(ser.readline()) readings.append(True) if data is None: return if len(readings) > 10: del readings else: readings.append(False) del readings numTrue = 0 for reading in readings: if reading: numTrue += 1 if numTrue >= 5: text.config(text='Your card ID is: ' + data) root.config(bg='green') else: root.config(bg='red') text.config(text='No Card Available') sleep(0.01) root.after_idle(idle, ser, root, text, readings) if __name__ == 'main': readings =  ser = serial.Serial('COM14', 9600) ser.setDTR() root = Tk() root.geometry('1000x500') root.config(bg='red') text = Label(root, text='No Card Available') text.place(x=320, y=250) root.after(10, idle, ser, root, text, readings) root.mainloop()
A couple things of note that Alaric found were that the delay parameter in the root.after method is a one time delay of how long to wait until continually running the idle function with the inputed arguments and that version 3.3 must be used for pyserial by running the following commands, which he learned from this stackoverflow response:
pip uninstall serial pip uninstall pyserial pip install pyserial=3.3
Since python is a general purpose language that gives full control of program control flow unlike processing where it will automatically call setup() then call draw() in an infinite loop, python with tkinter would be preferable to processing in cases where this needs to be managed and if you want to stick to common programming conventions. Python also has a plethora of different libraries to use for different functions if needed, which can be extremely useful and may not be available in processing. On the other hand, the way the widget objects work in tkinter is a bit more confusing than the simple drawing of processing, and with a many widgets, the arguments passed to the root.after method can become quite numerous and result in a massive line of code that may not be very elegant.