Skip to content

16. Interface and application programming

May 8

Assignment
  • individual assignment: write an application that interfaces with an input and/or output device that you made
  • group assignment: compare as many tool options as possible among all presented in the lecture

gravacaoFinal from António on Vimeo.

Summary

The upper video shows the steps that show how to start and end the comunication between the A0 sensor data pin in the floating state (tristate) to the browser at a local server. I did this with an Arduino board just to test. I just use an Arduino because I didn’t manage to get the atmega328p on time to use it. I just use it on my final project and after FOUR trials!!! Finnally no YIKES and “Done bootloader” but… when I try to put a file… wrong… I found it was a soldering not well done. This will be implemented on the final project since I want to publish the data from the boat sensors and state.

I found most challenging and rewarding because it was sommething that I didn’t know how to do but now I have same clue to improve it for the final project. Following a tutorial its also chalenging, understanding the design of all the connections its still dificult to remember and understand. Using terminal so often was a usefull moment for practice.

The final Boat Interface can be found at the Interface section but it needs more work, mainly to connect the interface with the data from the board.

For the group assigment we discuss the several processes used at the work done by Mónica at the machine design work and André Rocha work in this same assignment. The processes are very similar to those I showed down on this page and documented at their own pages, but in the case of André Rocha there are other issues and different options that he think about like the security network and the user dashboard. Their work can be found at, Mónica Pedro here) and André Rocha here.

All the EAGLE files can be found here and here.

Todo

  • Program the board
  • test it
  • group assignment
  • implement it in a non-local server

overview

source: https://github.com/sarahgp/p5bots

p5*js

Processing as been substituted by p5.js. But the mission is the same: “Our mission is to promote software literacy within the visual arts, and visual literacy within technology - related fields — and to make these fields accessible to diverse communities. Our goal is to empower people of all interests and backgrounds to learn how to program and make creative work with code, especially those who might not otherwise have access to these tools and resources.” Source: https://processingfoundation.org/.

So, to start I did review this very well written tutorial about processing. The newer P5.js with the bot library, by Sarah is documented here.

I choose processing/p5.js because I’m familiar with it but never mastered it. Everytime I came back to processing its almost as the first time.

what Link
Start with processing/p5.js http://processingjs.org/articles/jsQuickStart.html; http://p5js.org/get-started/
from processing programing to use it on a webpage http://processingjs.org/articles/PomaxGuide.html#pobj
BOT: from the processor to the web page https://github.com/sarahgp/p5bots
Buttons p5.js https://github.com/Lartu/p5.clickable
millions of libraries http://p5js.org/libraries/
millions of examples https://processing.org/examples/
Java mode http://p5js.org/
Python mode https://py.processing.org/
library button https://github.com/Lartu/p5.clickable
library bot https://github.com/sarahgp/p5bots
library BLE
Internal temperature sensor https://harizanov.com/2012/07/using-attiny-84s-internal-temperature-sensor/; https://github.com/mharizanov/TinySensor/blob/master/TinySensor_InternalTemperatureSensor/TinySensor_InternalTemperatureSensor.ino; https://playground.arduino.cc/Main/InternalTemperatureSensor/; https://www.avdweb.nl/arduino/measurement/temperature-measurement

Computer interface and Webpage

This hello world starting point its a way to go in order to start relating webpages and processors: https://github.com/sarahgp/p5bots/blob/master/examples/HelloWorld.md

Choose the code editor [open processing] (https://www.openprocessing.org) and start here.

This seems to be good also because it shows the code for the web: https://codepen.io/p5js/pen/wreBKy?editors=1111

For the interface design I used this color pallete: http://paletton.com/#uid=13K0u0kllllaFw0g0qFqFg0w0aF

An the result is this:

Processor programing

At this point I choose to follow other procedure because I found the downward tutorial more easy. Forget the path above, I choose another one.

Assynchronous communication

Serial communication is one of the most common forms of communication between computers and we can get two computers talking to each other using Asynchronous Serial communication. This is not easy to follow because it misses same crucial steps (just two) but the simple changes I found permits to put all in place and working.

Info

Asynchronous serial communication means sending digital pulses between devices througth the serial wire at a rate that needed to be agreed between the devices. So, the name assynchronous, there isn’t a common clock, instead, both devices keep time independently, and either send or listen for new data at an agreed rate.

So, the devices should agreed on: - rate for the read and write; - voltage levels representing a 1 or 0 bit (normally 1, voltage between 3.3 V and 5 V); - and the bit meaning 1, normally means HIGH; 0 means LOW; this is the true logic, there also inverted logic: for instance, the RS232 uses inverted logic.

From the physical point of view there must be: - a common GND for the two devices; - two wires to send and receive data;

For instance, if the rate is 9600 bits/second (9600 baud), in one second 1200 bytes of data can be exchanged, at each 1/9600 part of a second one bit is read (means reading 5 V).

Example

Lets send a 1 and a 2 byte in 8 bit system: 00000001 and 00000010, respectively. On the wire what will happen is a series with a 5 volt peak first and zero voltages next, while the 2, means that is start in 0 V then it apears a peak of 5 V and ended with a series of zero voltage.

This happens in a certain rate, if we have a 9600 baud, the first beat is readed 1/9600 second, the second in 1/9600 later, and so on; so, after 8/9600 the byte is completely readed.

Note

Almost all personal computers do not have an asynchronous serial port, they have USB ports (Universal Serial Bus). It’s a different serial protocol that allows multiple devices to communicate on the same wires (BUS configuration). USB support many different classes of devices: mice, keyboards, hard disks, cameras… etc. Since many devices still use asynchronous serial communication, USB includes a Communications Device Class (CDC) that supports asynchronous serial communication.

💡 Processors with UART have serial buffers, area in memory where they store incoming data from the serial ports. They are called First-In, First-Out or FIFO buffers because they remove the byte from the serial after reading it.

💡 Serial ports can only be controlled by one program at a time which no problem for a processor: the program inside takes control.

Also

The Serial.write() command doesn’t format the bytes as ASCII characters! More on this here

💡 Must see: Node.js is a program that allows serial communication between a processor and a webbrowser: https://itp.nyu.edu/physcomp/labs/labs-serial-communication/lab-serial-communication-with-node-js/

This is an specific example for a serial with ATtiny

Preparing the interaction with a web browser using node.js

Forget what is describe above, I just found a (I think) better tutorial to be used with node.js.

In short all modern browsers include a JavaScript interpreter, which allows the browser to run JavaScript (js) code that’s embedded in a web page. On your personal computer, you run it through the terminal command line interface.

So, after I installed node.js, I followed this tutorial page. I open terminal and type “node -v” and “npm -v” just to see the versions installed.

I created a folder with the name “nodeSerialExample” as the tutorial explained.

Then create a new file index.js with “touch index.js” command and open it with the command “open index.js”. If you write down on that file the text “console.log(“Hello, and welcome to node.”);” and use this command “node index.js” to call the file it will show the text “Hello, and welcome to node.”

Info

Type “pwd” at the command prompt to see in what directory you are at the moment.

Basic commands on MAC terminal: https://macpaw.com/how-to/use-terminal-on-mac

If you have node, use this “node ListPorts.js”

Danger

Install npm (node package manager) in the serialport directory, under this path: /Users/”your_username”/nodeSerialExample/node_modules/serialport

What serials on your computer?

Open the file js we we’ve been using and copy this code:

var serialport = require('serialport');

// list serial ports:
serialport.list(function (err, ports) {
  ports.forEach(function(port) {
    console.log(port.comName);
  });
});

Then, save it and exit and type on the terminl comand line: “node index.html” and it will prompt all the serials available.

Note

To open index.js just type “nano index.js”. nano is an editor previously installed.

You must be in the directory where the file is to use just this command. use “ls” to list whats inside the directory and “cd” to change to the directory where the file is.

Code js on the computer

Danger

I get same error while using the next code, and the solution was that it misses a file called package.json. For that you nee to use npm init and follow the lines. In the end this file will be on the directory. Afetr taht install the serial port libtrary “npm install serialport”

When I put the file index.js working there was an error saying that SerialPort was not defined, so just put this line of code “var SerialPort = serialport;”

Use this next code in the index.js file; save it and type “node index.js” in the terminal to run it. To stop it write in the terminal “CRTL C”. Load on the arduino the example code “AnalogReadSerial” (go to the Arduino IDE, look at file -> examples -> basics). The outcame will be the input at the A0 pin (just to test you don’t need to plug in no sensor, use it in the floating mode, it will give a number in the terminal).

var serialport = require('serialport');// include the library
var SerialPort = serialport;//define SerialPort
var portName = process.argv[2];// get port name from the command line as a variable
var myPort = new SerialPort(portName, 9600);//open the port using new() with baud 9600

var Readline = SerialPort.parsers.Readline; // ASCII-encoded text; make instance of Readline parser [^1]

var parser = new Readline(); // make a new parser to read ASCII lines
myPort.pipe(parser); //pipe the serial stream to the parser

//With a port and a parser you are ready to read serial data comming in.
myPort.on('open', showPortOpen);[^2]
parser.on('data', readSerialData);
myPort.on('close', showPortClose);
myPort.on('error', showError);

// list serial ports:
serialport.list(function (err, ports) {
  ports.forEach(function(port) {
    console.log(port.comName);
  });
});

//callback functions that react to events "open", "data", "close" and "error"
function showPortOpen() {
   console.log('port open. Data rate: ' + myPort.baudRate);
}

function readSerialData(data) {
   console.log(data);
}

function showPortClose() {
   console.log('port closed.');
}

function showError(error) {
   console.log('Serial port error: ' + error);
}

Note

With a port and a parser you are ready to read serial data comming in.

💡 This programing runs througth the terminal This program won’t STOP: you need to use control-C to stop it.

Browser html embeded code

To communicate between node js program and the browser its necessary to define a websocket. Like serial communication this is also a datastreams communication (in which the first byte sent into the stream on one end is the first byte read out on the other end).

There is a node.js library called “ws” from websocket. Install it with the command line at the terminal: “npm install ws”.

The next code completes the code above by connecting the server with the webpage socket. This embeded js program shows in the html browser page connected to the local host the data sended by the arduino to the index.js program file and connected to js embeded in the html web WebSocket.

<!DOCTYPE html>//embedded in the html browser
<html>
<head>
  <meta chartset="utf-8">
  <title>aqua project interface</title>
//library p5.js and p5.dom
  <script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/0.8.0/p5.js"></script>
  <script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/0.8.0/addons/p5.dom.min.js"></script>
  <script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/0.8.0/addons/p5.sound.min.js"></script>

  //<img src="data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7" data-wp-preserve="%$ //no need to use this
<script>
var text;     // variable for the text div you'll create
var socket = new WebSocket("ws://localhost:8081");// local server port

function setup() {

  // The socket connection needs two event listeners:
   socket.onopen = openSocket;
   socket.onmessage = showData;

   // make a new div and position it at 10, 10:
   text = createDiv("Sensor reading:");
   text.position(10,10);
}

function openSocket() {//open websocket
    text.html("Socket open");
    socket.send("Hello server");
  }

function showData(result) {//show data streaming
    // when the server returns, show the result in the div:
    text.html("Pin floating" + result.data);
    xPos = int(result.data);        // convert result to an integer
    text.position(xPos, 10);        // position the text
    c = color('rgb(0,255,0)');//green bar
        fill(c); // Use 'c' as fill colorfill(102);
        noStroke();
        rect(10, 75, xPos, 30);
  }
</script>
</head>
<body>
<p>//comments
Showing the floating pin data.
Testing callback functions, data streams, websocket...
next stop: apply this to the aqua final project.
Fab Academy 2019 student António Gonçalves

</p>
</body>
</html>

To connect node.js program to a web page, the web browser and the node program needs to talk to each other. For this we need webSockets: connections between web clients and servers. Like serials, websockets are data streams: the first byte sent into the stream on one end is the first byte read out on the other end. Data streams connect programs to files, client programs to server programs, or desktop programs to serial or network ports.

node.js to browser

Source: https://itp.nyu.edu/physcomp/wp-content/uploads/workflow.png

To continue, we need to install a websocket library. On terminal write npm install ws (on the directory mentioned above);

Note

There can be multiple webSocket clients at any time, so the server as an array to keep track of all the clients. That array is called connections, and every time a new client connects, the client is added to the array using the .push() function. When a client closes, it’s removed from the array using the .slice() function.

Arduino code

/*
  AnalogReadSerial

  Reads an analog input on pin 0, prints the result to the Serial Monitor.
  Graphical representation is available using Serial Plotter (Tools > Serial Plotter menu).
  Attach the center pin of a potentiometer to pin A0, and the outside pins to +5V and ground.

  This example code is in the public domain.

  http://www.arduino.cc/en/Tutorial/AnalogReadSerial
*/

// the setup routine runs once when you press reset:
void setup() {
  // initialize serial communication at 9600 bits per second:
  Serial.begin(9600);
}

// the loop routine runs over and over again forever:
void loop() {
  // read the input on analog pin 0:
  int sensorValue = analogRead(A0);
  // print out the value you read:
  Serial.println(sensorValue);
  delay(1);        // delay in between reads for stability
}

OR another one to read the internal temperature sensor at the ATtiny44 processor.

void setup()
{
  Serial.begin(9600);
}

void loop()
{
  // Show the temperature in degrees Celsius.
  Serial.println("Sensor");
  Serial.println(ADCH);
  delay(1000);
}


uint8_t ADC_read(uint8_t channel)
{
  ADMUX &= (_BV(REFS1) | _BV(REFS0));    // Clear the ADC Multiplexer
  ADMUX |= channel;                      // Set the ADC multiplexer
  ADCSRA |= ADSC;               // Start an ADC conversion
  while(ADCSRA & _BV(ADSC));    // Wait until conversion is complete
  return (ADCH);                // Return the ADC high register value
}

testing the board

I tested this former programing reporter at the section Browser html embeded code with the board made for the final project. Here just a test with a floating pin:

ATmega328InterfaceFloat from António on Vimeo.

The process of electronic prodution:

BoardElectronicProductionATmega328p from António on Vimeo.

Bootloading and programing are documented on this next videos:

FinalBootLoaderVideo from António on Vimeo.

Yikes

Yikes! We don’t like this ERROR messages. It was a great achievement for me when I did this video! Sucess!!!

Program runing:

SoftwareUpload from António on Vimeo.

The video with all the project his at this final page project here

Interface

I didn’t manage to get this interface running at the local host: need more time of work. This files are at my p5js account:

Boat interface: https://editor.p5js.org/fqantonio/sketches/z4y7rtOwm

HTML server: https://editor.p5js.org/fqantonio/sketches/3MU9QOMOu

The interface can be seen also here

or embeded here:

<!DOCTYPE html>
<html>
  <head>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/0.8.0/p5.js"></script>
     <script language="javascript" type="text/javascript" src="p5.serialport.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/0.8.0/addons/p5.dom.min.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/0.8.0/addons/p5.sound.min.js"></script>
    <link rel="stylesheet" type="text/css" href="style.css">
    <meta charset="utf-8" />

  </head>
  <body>
    <script src="sketch.js"></script>
  </body>
</html>

Group work: other ways to do better

For the group assigment we discuss the several processes used at the work done by Mónica at the machine design work and André Rocha work in this same assignment. The processes are very similar to those I showed down on this page and documented at their own pages, but in the case of André Rocha there are other issues and different options. There work can be found at, Mónica Pedro here) and André Rocha here.

In the case of Mónica work she used RaspPi ARM board with Python IDLE on a IOS Raspbian environment. She also use the same process as I did but in her case the procedures are a little bit diferent and resumed here. He also use an acess to Raspi using terminal.

In the case of André Rocha, his option was more soficiscated and use NODE with the ESP12 board, resumed here. Instead of BLE he tried WIFI in this low-cost Wi-Fi microchip with full TCP/IP stack and microcontroller capability produced by manufacturer Espressif Systems, allowing to access same nice features: 11 GPIO pins, one analog-to-digital converter (ADC) with a 10 bit resolution. He implementesd a headless procedure, meaning that there no need to having plug in a monitor, keyboard or even a mouse. All we need to do is get our Pi set up with the right WiFi credentials and we’ll be able to remotely access it through a terminal program and the SDcard: remotely access it through a terminal program, as if we were using the terminal Pi’s own desktop. New here to me was the SSH, a secure protocol to work over an insegure network. He also uses Eclipse Mosquitto™, the MQTT protocol that provides a lightweight method of carrying out messaging using a publish/subscribe model. Finnally, a very easy way to get things done in a practical and comprehensible prototype is to use node-red dashboard.

General issue: reading data from the serial:

https://editor.p5js.org/dano/sketches/SJq0FKc97 https://itp.nyu.edu/physcomp/labs/labs-serial-communication/lab-serial-input-to-the-p5-js-ide/

General issue: writing data to the serial:

https://itp.nyu.edu/physcomp/labs/labs-serial-communication/lab-serial-output-from-p5-js/

Basic avr C: https://exploreembedded.com/wiki/Basics_of_AVR_%27C%27

Library for the ARDUINO but similar to PROCESSING: https://github.com/sarahgp/p5bots#p5serial

Info

Temperature measurement,p128: http://ww1.microchip.com/downloads/en/devicedoc/Atmel-7701_Automotive-Microcontrollers-ATtiny24-44-84_Datasheet.pdf

Internal temperature: https://dev.playground.arduino.cc/Main/ShowInfo; https://microchipdeveloper.com/8avr:avradc https://www.avdweb.nl/arduino/measurement/temperature-measurement https://github.com/mharizanov/TinySensor/blob/master/TinySensor_InternalTemperatureSensor/TinySensor_InternalTemperatureSensor.ino

Datasheet, p.120: The on-chip temperature sensor is selected by writing “100010” to the MUX5..0 bits in the ADMUX register. The ADC is enabled by setting the ADC enable bit (ADEN) in ADCSRA. Voltage reference and input channel selections will not go into effect until ADEN is set. The ADC does not consume power when ADEN is cleared, so it is recommended to switch off the ADC before entering power saving sleep modes.The ADC generates a 10-bit result which is presented in the ADC data registers, ADCH and ADCL. By default, the result is presented right adjusted, but can optionally be presented left adjusted by setting the ADLAR bit in ADCSRB

Reading registers (basics): https://exploreembedded.com/wiki/Basics_of_AVR_%27C%27

Solenoid driver: https://www.electronicdesign.com/industrial-automation/what-s-best-way-drive-solenoid

Solenoid datasheet: http://www.farnell.com/datasheets/2286294.pdf

Serial on the ATtiny44: https://www.hackster.io/porrey/easy-serial-on-the-attiny-2676e6

    //Water presente, Solenoid actuator and  Led light,  ATtiny44

    #include <SoftwareSerial.h>

    int LED = 8;
    int button = 7;
    int SOLENOID = 3;

    //RX TX
    #define RX    1   // Pin 2
    #define TX    2   // Pin 1

    //SoftwareSerial Serial(RX, TX);

    // the setup routine runs once when you press reset:
    void setup() {
      // initialize serial communication at 9600 bits per second:
      Serial.begin(9600);
      digitalWrite(SOLENOID,LOW);
      pinMode(8,OUTPUT);
      pinMode(7,INPUT_PULLUP);//condutivity button
      pinMode(3,OUTPUT);//

    //p-channel
    }
    // the loop routine runs over and over again forever:
    void loop() {
      // read the input on analog pin 7:
      int sensorValue = digitalRead(7);
      if (sensorValue == LOW) {
      digitalWrite(LED,HIGH);
      digitalWrite(SOLENOID,HIGH);
      // print out the value you read:
      Serial.println(sensorValue);
      }
      else {
        digitalWrite(LED,LOW);
        digitalWrite(SOLENOID,LOW);
      }
      delay(1);        // delay in between reads for stability
    }

Danger

Last our problems with a MOSFET. On the ruch change for a p-mosfet… WRONG TURN… two hours lost!!! Rechange to the N-MOSFET afer time and time again of debuging: - Checking the software - Checking the pin voltage and the mosfet voltages;

After all a MOSFET that was down!

About interrupt

NEED to read the state of the pin that controll the interrupt, otherwise the processor want know it. Well this next code is not an interrupt; this only works with the default pins,1, and of Arduino.

ADVANCED: https://www.arxterra.com/11-atmega328p-external-interrupts/?v=e71bc9c013d9

const byte ledPin = 5;
boolean interruptPin = 8;
volatile byte state = HIGH;

void setup() {
  pinMode(ledPin, OUTPUT);
  pinMode(interruptPin, INPUT_PULLUP);
  attachInterrupt(digitalPinToInterrupt(interruptPin), blink, LOW);
Serial.begin(9600);
}

void loop() {
  bool state = digitalRead(8);// this is **very important**
  Serial.println("interrupt pi");
  Serial.println(interruptPin);
  Serial.println("state");
  Serial.println(state);
  digitalWrite(ledPin, state);
  delay(1000);
}

void blink() {
  state = !state;
}

browser

https://itp.nyu.edu/physcomp/labs/labs-serial-communication/lab-serial-input-to-the-p5-js-ide/

References:

  1. http://processingjs.org/articles/PomaxGuide.html#pobj

  2. https://stackoverflow.com/questions/31819197/how-do-i-send-data-from-processing-to-an-html-page

  3. https://github.com/processing/p5.js/wiki

  4. https://processing.org/reference/libraries/serial/Serial_readString_.html

  5. https://hackaday.com/2014/02/01/atmega-attiny-core-temperature-sensors/


  1. To read serial data as ASCII-encoded text, line by line, need a parser to tell the serial library how to interpret data coming in and read all as a line of text, and generate a new data event when it sees a newline (“\n”). 

  2. The serialport library is event based, meaning that, when an event is generated the function is called: this functions are named callback functions. So, if the serial port is opened, the showPortOpen function start. When new data arrives, the sendSerialData function will get called… and so on.