16. Interface and application programming¶
This week I worked alongside my group to compare as many tool options as possible. Individually I wrote an application that interfaces with an input &/or output device that I made.
I wanted to create an app and I thought that MIT App Inventor paired with HC-05 seemed like a good place to start. I Read through the guide and tutorials to gain an understanding of the the programming environment and capabilities. I did not read close enough though and soon discovered that it’s only available for android phones and I do not have one.
I decided to switch from AppInventor to Blynk and from HC-05 bluetooth ESP8266- ESP 12E Wifi moduel
The Wifi module will receives input from an app and transmit data to the app from my board.
Schematic¶
Board¶
After I soldered the board I connected it to my computer and the LED did not light up so I returned to the ‘drawing board.’ I used a multimeter to try to diagnose the problem. There was defiantly a connection error but I could not localize where. Then I acknowledged that the reverse side of my board is copper and the connections where coming from my through-hole pin headers. So I did a little bit of a ratchet fix to test if my theory was correct.... IT WAS
Post surgery…LED works!!!
From my research I found tha the ESP-12E is similar to an Arduino itself and I can use the Arduino IDE to upload sketches to it. In the Blynk library, there is a sketch called ESP8266_Standalone that uploads directly to the ESP-12E for basic control. To upload the sketch, I needed to connect the computer to the ESP-12E through a basic serial interface.
#define BLYNK_PRINT Serial #include <ESP8266WiFi.h> #include <BlynkSimpleEsp8266.h> // You should get Auth Token in the Blynk App. // Go to the Project Settings (nut icon). char auth[] = ""; //Token provided by Blynk // Your WiFi credentials. // Set password to "" for open networks. char ssid[] = "ssid"; //I had my ssid here char pass[] = "pass"; // I had my password here void setup() { // Debug console Serial.begin(9600); Blynk.begin(auth, ssid, pass); } void loop() { Blynk.run(); }
When I tried to upload the sketch I received these messages:( Error Message
warning: espcomm_sync failed error: espcomm_open failed error: espcomm_upload_mem failed error: espcomm_upload_mem failed
After troubleshooting I discovered to activate the external device, GPIO0 or GPIO2 must be driven LOW (Active LOW) while GPIO15 must be driven HIGH (Active HIGH). So, I need to connect GPIO0 to low. However when/if I successfully upload code to my board I need to reconnect GPIO0 to high (run mode), to see information on the Arduino IDE serial monitor. After spending hours trying to diagnose this I decided to putt the ESP on hold and try a different approach.
Processing¶
From Arduino…
I started by initiating serial communication from the Arduino to my computer at a baud rate of 9600 and send the string ‘Hello, world!’ over the serial port, over and over (and over).
#include <SoftwareSerial.h> SoftwareSerial mySerial(0, 1); void setup() { //initialize serial communications at a 9600 baud rate mySerial.begin(9600); } void loop() { //send 'Hello, world!' over the serial port mySerial.println("Hello, world!"); //wait 100 milliseconds so we don't drive ourselves crazy delay(100);
…to Processing Next I wanted to see if I detect the ‘Hello, world!’ string sent from Processing.
The software looks very similar to Arduino IDE, which I like. I opened a sketch, and imported the Serial library. This allows Processing to read from my serial port and it adds a first line to the code: import processing.serial.;*
->Import Library->Serial, as shown below:
Next I declared some global variables.
Serial myPort; // Create object from Serial class String val; // Data received from the serial port
Serial myPort allows is a serial object which lets me listen in on a serial port on my computer for any incoming data. String val allows me to receive the actual data coming in. I
For setup() method in Processing, I need to find the serial port my FabISP is connected to and set up the Serial object to listen to that port.
In the draw() loop, I am going to listen in on the Serial port and get something, stick that something in the val variable and print it to the console.
I hit the ‘run’ button with my FabISP plugged in with the code on the previous page loaded, expecting to see a little window pop-up, with Hello, World! appear in the Processing console. However I received this:
There is an issue between my serial connection and I think it has something to do with my Apple computer. I could figure this problem out but decided to continue with processing.
From Processing..
I used the size() command, to produce a little window to click in, which should trigger the sketch to send something over the Serial port to Arduino.
import processing.serial.*; Serial myPort; // Create object from Serial class void setup() { size(200,200); //make the canvas 200 x 200 pixels big String portName = Serial.list()[0]; //change the 0 to a 1 or 2 etc. to match your port myPort = new Serial(this, portName, 9600); } void draw() { if (mousePressed == true) { //if we clicked in the window myPort.write('1'); //send a 1 println("1"); } else { //otherwise myPort.write('0'); //send a 0 } }
When I ran this code, I see a bunch of 1’s appear in the console area whenever I click my mouse in the window. Next I want to look for these 1’s from Arduino. However again I am experiencing serial communication errors. So I decided to go ‘old school’ and complete this assignment using my terminal.
Taking a different route¶
I decided going forward, to refocus this week toward my final project development. I am going to create a GUI with two buttons (forward & reverse) to control my DC Motor board. To do this I will establish a serial connection using python and then develop a GUI using tkinter.
To begin I started testing my code and the serial communication on my board using Arduino IDE. After I established this, I wrote a program for my board to ‘listen,’ if I send an F/f through the serial monitor the motor will rotate and if I send R/r the motor will go in reverse.
#include <SoftwareSerial.h> #define rxPin 1 #define txPin 0 #define button1 9 #define button2 8 #define in1 3 #define in2 2 SoftwareSerial mySerial(rxPin,txPin); //From Greg Buckland Following code adapted from: //https://processing.org/tutorials/electronics/ char val; // Data received from the serial port bool newData = false; // store whether there's new serial data or not void setup() { mySerial.begin(9600); //start serial pinMode(button1, INPUT); pinMode(button2, INPUT); pinMode(in1, OUTPUT); pinMode(in2, OUTPUT); } void loop() { // button conrol if (digitalRead(button1)==0) { digitalWrite(in1,HIGH); digitalWrite(in2,LOW); mySerial.println("button 1"); delay(100); } else if (digitalRead(button2)==0) { digitalWrite(in1,LOW); digitalWrite(in2,HIGH); mySerial.println("button 2"); delay(100); } //serialcontrol if (mySerial.available() > 0) { //if serial buffer has data val = mySerial.read(); // read it and store it in val newData = true; } if (newData) { //if new data is recieved, check what it is if (val == 'F' || val == 'f') { //if an F/f is recived go forward digitalWrite(in1,HIGH); digitalWrite(in2,LOW); mySerial.println("button 1"); delay(100); } else if (val == 'R' || val == 'r') //if an R/r is recived go in reverse { digitalWrite(in1,LOW); digitalWrite(in2,HIGH); mySerial.println("button 2"); delay(100); } else { mySerial.println("invalid"); } } // set motor to braking mode to hold laces digitalWrite(in1,HIGH); digitalWrite(in2,HIGH); newData = false; //reset newData boolean }
Python3¶
Next, I established serial communication with my board and python. To start the python terminal I typed “python” and I received “>>>” now I know I am in the python terminal. First I checked which port my ftdi is connected to.
python >>> import serial >>> s = serial.Serial('/dev/cu.usbserial-FT9P06RD', 9600) >>> s.is_open True >>> s.write('f') 1 >>> s.write('f') 1 >>> s.write('r') 1 >>> s.write('r') 1 >>> s.write('f') 1 >>>
Python Tkinter GUI Development¶¶
I began by testing out a “hello- world” python program.
import tkinter as tk class Application(tk.Frame): def __init__(self, master=None): super().__init__(master) self.master = master self.pack() self.create_widgets() def create_widgets(self): self.hi_there = tk.Button(self) self.hi_there["text"] = "Hello World\n(click me)" self.hi_there["command"] = self.say_hi self.hi_there.pack(side="top") self.quit = tk.Button(self, text="QUIT", fg="red", command=self.master.destroy) self.quit.pack(side="bottom") def say_hi(self): print("hi there, everyone!") root = tk.Tk() app = Application(master=root) app.mainloop()
This worked well, so next I modified this program by adding a forward and reverse button and established a serial communication.
import serial import tkinter as tk s = serial.Serial('/dev/cu.usbserial-FT9P06RD', 9600) class Application(tk.Frame): def __init__(self, master=None): super().__init__(master) self.master = master self.pack() self.create_widgets() def create_widgets(self): self.Forward = tk.Button(self) self.Forward["text"] = "Forward" self.Forward["command"] = self.go_forward self.Forward.pack(side="top") self.Reverse = tk.Button(self) self.Reverse["text"] = "Reverse" self.Reverse["command"] = self.go_reverse self.Reverse.pack(side="top") self.quit = tk.Button(self, text="QUIT", fg="red", command=self.master.destroy) self.quit.pack(side="bottom") def go_forward(self): print("Forward") s.write(str.encode('f')) def go_reverse(self): print("Reverse") s.write(str.encode('r')) root = tk.Tk() app = Application(master=root) app.mainloop()
I know that this is a very basic GUI but I am very happy with the results. I am defiantly going to come back develop this more. I want my self-lacing shoe to have an app control option. I am not sure if I will have enough time to introduce in prototype 1 but defiantly model 2.
You can find files to my board and schematic in week 20