Fab Academy 2018

Wk13. Interface & App Programming


Assignment: Write an application that interfaces with an input &/or output device that you made, comparing as many tool options as possible.


This week is all about writing software applications to talk to embedded devices. Software app development is a whole industry and many take degrees in computer science to spend their lives doing just this, but this week serves as an introduction to a number of key principles:

Programming Languages

A program is basically set of repeatable instructions to make a computer do something. In most programming languages, this involves writing “human readable” code instructions that will then be passed to a computer via a compiler. A compiler is basically a translator from human to machine language.

Compiled or “high-level” languages write and read more like the way we humans would give an instruction, eg. “take object A and put it next to object B”. This differs from a low level language such as Assembly language which provide little or no abstraction from a computer’s architecture—commands or functions. We have seen examples of this in our micro-controller data sheets. That said, some languages, like C are both high level and low level which makes the distinction ambiguous.

Here I will do a bit of an overview of the languages Neil mentioned in class which I find both interesting and useful for this week.

Processing

Processing is an open-source programming language and IDE (that is very similar to Arduino in syntax) based on the Java language. It comes with an easy-to-use, creative coding environment or IDE and has fantastic resources. If you are starting out Processing is a great way to learn how to code. And if you like to hallucinate while you learn how code I recommend Daniel Schiffman’s Coding Train.

Grasshopper/FireFly

FireFly is what is called a visual programming add-on for Grasshopper (which works in Rhino CAD) which allows you to interact with the Arduino microcontroller and other input/output devices like web cams, mobile phones, game controllers and more.

Python

Python is a very popular high-level programming language for general-purpose programming created by Guido van Rossum after Monty Python’s Flying Circus. Python is an interpretive language which makes it really fast because it execute instructions directly and freely, but they ten to be slower when compiling low level machine instructions.

JavaScript

JavaScript (“JS” for short) is a full-fledged dynamic programming language that, when applied to an HTML document, can provide dynamic interactivity on websites. It was invented by Brendan Eich, co-founder of the Mozilla project. It has become increasingly popular because of it’s flexibility. Developers have written a large variety of tools such as Node.js which takes Javascript out of the browser.

C

Throughout the FabAcademy, Neil has been using C for his programming examples. C is a low level, general purpose programming language. It can be compiled using the open source compiler GCC to provide low-level access to memory, write complex machine instructions for embedded system applications, and requires minimal run-time support. C is also one of the most widely used programming languages of all time.

AppInventor

MIT App Inventor like Firefly is a visual programming environment that makes it very easy to build fully functional apps for Android smartphones and tablets. They are great for simple programs but start to get unwieldy for more complex programs. The work around, according to Neil, is that you can program conventionally and add them as nodes to the App Inventor to handle complexity.

Talking to Devices

We have been using the FTDI cable to do serial communication between our micro-controllers and our computers via the Universal Serial Bus (USB). Most programming languages have serial libraries that allow you to talk directly via the serial port of your computer (USB is one of many serial protocols). PySerial is the serial library for Python, SerialPort is the same for Node.js. Processing and Arduino also have their respective serial libraries.

Hello Processing

For this week, I decided to start out with Processing as I like it for it’s simplicity and creative visuals. I started by connecting my Hello Board from Wk 7 and see if I can get it to interact with Processing as both an input and output device.

SoftwareSerial

For my first sketch I used the Arduino SoftwareSerial library which allows serial communication to take place on the other digital pins of our Attiny44. As you can see below I include the library and then declare my serial ports to pin 0 and 1 before the void setup()

//HelloBoard and Processing

// Include the SoftwareSerial library to run serial on Attiny44
#include <SoftwareSerial.h>

// declare my serial ports 0 and 1 (RX, TX)
SoftwareSerial mySerial(0, 1);

High-Low Tech explains the ins and outs of programming the Attiny’s with the Arduino IDE. I also highly recommend Serial Communication with the Tiny’s. Basically, my first test was making sure I could press the button on my board and it would send the data out via FTDI USB-serial cable allowing me to read and access it in Precessing. Below the I set my pins, and set a high baud rate seeing as I am using the 20 MHz external clock.

const byte ledPin_1 = 8;  // define LED constant variable
const byte buttonPin = A3; // define button constant variable

void setup() {

  mySerial.begin(115200); // set baud rate to 115200 bits per second
  pinMode(buttonPin, INPUT); // set buttonPin (A2) as INPUT
  pinMode(ledPin_1, OUTPUT);  // set LEDs as outputs

}

void loop() {

  int sensorValue = digitalRead(buttonPin); // read INPUT as sensorValue
  mySerial.print(sensorValue); // serial print sensorValue

  if (digitalRead(buttonPin) == 0) {
    digitalWrite(ledPin_1, HIGH); // turn LED on
  } else {
    digitalWrite(ledPin_1, LOW); // turn LED off
  }

  delay(20);  // Wait 100 milliseconds
} // end Loop

The mySerial.print function allows me to see the SensorValue in the Arduino serial monitor, this is good to check before we move on to Processing.

helloboardsketch

It’s also really good practice if you’re starting out to code to break task down to smaller sizes. Printing info can give you feedback that two or more processors are communicating. Also learn how to comment.

Serial Available

In Processing we have to import the serial library and then use the printArray(Serial.list()); function to figure out which USB port our ATTiny is sending its data through.

Tom Igoe has a neat little sketch that usese the serial.available() function to check your ports and see what is coming in. However, as you can see below, the console was reading every time i pressed the button but the console was giving me values 48 and 49!

Serial

After a bit of research I discovered that this is because the communicating via serial depends on something called a Serial Port Buffer, which is sort of like a bus stop. I discovered more about this in the networking and comms week. The Serial Available function basically tells us how many bytes we have in the serial buffer (which can store up to 64 bytes). Basically, a typed 1 in ASCII is represented as the number 49 in decimal, a 0 is 48.

User Interface

At least now I was getting data into Processing. Now I could go ahead and play around with creating a user interface. My first was very basic again, it played with registering a simple colour every time I pressed the button.


import processing.serial.*; //import serial library

Serial myPort;  // Create object from Serial class
char val;      // Data received from the serial port

void setup()
{
  size(500, 500);
  String portName = Serial.list()[5];
  println(Serial.list());
  myPort = new Serial(this, Serial.list()[5], 115200); // Set baud rate equal to microprocessor
}

void draw()
{
  while ( myPort.available() > 0) {  // If data is available,
    val = myPort.readChar();         // read it and store it in val
   println(val);
  }

  background(255); // Set background to white
  if (val == '1') {              // If the serial value is 0,
    fill(0);                   // set fill to black
  }
  else {                       // If the serial value is not 0,
    fill(204);                 // set fill to light gray
  }
  rect(0, 0, 500, 500);
}
processing

Processing back to ATTiny

Now I wanted to check that I could interface with my Attiny board via Processing. Again, here is my Processing code (this time I tried with a lower Baud rate)

import processing.serial.*;

Serial myPort;  // Create object from Serial class

void setup()
{
  size(200,200); //make our canvas 200 x 200 pixels big
  String portName = Serial.list()[5]; //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
  }   
}

And here is my Arduino setup programmed to receive:

#include <SoftwareSerial.h> // include the Software serial library to run serial on Attiny45
SoftwareSerial mySerial(0, 1); // declare my serial ports 1 and 0 (MISO, MOSI)


char val; // Data received from the serial port
int ledPin = 8; // Set the pin to digital I/O 8

void setup() {
  pinMode(ledPin, OUTPUT); // Set pin as OUTPUT
  mySerial.begin(9600); // Start serial communication at 9600 bps
}

void loop() {
  if (mySerial.available())
  { // If data is available to read,
    val = mySerial.read(); // read it and store it in val
  }
  if (val == '1')
  { // If 1 was received
    digitalWrite(ledPin, HIGH); // turn the LED on
  } else {
    digitalWrite(ledPin, LOW); // otherwise turn it off
  }
  delay(10); // Wait 10 milliseconds for next reading
}
IMG_4472

You can download my Processing code sketches for week 13 from my Gitlab repository. Otherwise, it is all available in the documentation above.