y


Paul Gröneveld @ Fab Academy 2016 >>> Interfacing and application programming

<<<< go back

Goal

This week our assignment is about designing a graphical user interface (GUI) on the computer screen. This GUI should show what is happening with the micro controller and the in / output devices. In this case I choose to work with end switches and movement of objects by stepper motors.

Sketch main architecture

Thinking about the main project, I will need to use many stepper motors and end switches to stop the motion from the stepper motors. It would be nice to visualize the sliding of the different drawers from the beehive, until it reaches the end stop. When the end stop is reached, it could give a red flag on the screen.

On the H-bot side also stepper motors and end switches will be necessary to make the movements controllable and save. Red bars can indicate the bottom, top, left and right side. Displaying the direction of the machine head should also be possible, but it needs input from two motors in order to indicate the direction of the movement.

In the hand-sketch below on the left the side view of the beehive is drawn with five drawers underneath each other. Each drawer is activated by a stepper motor. To indicate the beginning and the end of each drawer end switches are used. When the drawer is closed a green flag can indicate the safety of the position. When the drawer is completely open a red flag can indicate it is dangerous because of all the bees flying around. For the H-bot in the right side end switches are used to define the maximum movement. When the movement reached the end position a red bar-flag can indicate this on the screen. The movement can be displayed as well.

y


First test with switch and Adruino

To lock out bugs from the Fabkit I like to start with an Arduino Uno here. A switch was connected with a pull up resistor of 10 kohm. Here I used a video tutorial about serial Communication with Processing. The goal here is to use the input from the switch to change the colour of a rectangular shape in Processing. With Arduino it worked almost immediately. The only change was choosing the right
COM port. This is quite well explained in the video tutorial. So the result is shown in the video below.


y


Second test with switch and Fabkit

The replacement of the Arduino Uno with the Fab kit is almost one to one. However some debugging had to be done:

  1. The solder connection of the pin 4 that I used was not good. Hard to find, easy to solve.
  2. Changing the code back and forward often brings little mistakes when switching between boards. So being very accurate and careful is important.
  3. The serial communication will block the line for other reading. So make sure you have only one line communicating to the right COM-port.


y


Now one switch works well, the next step is using more switches. In this case I connect four switches to the Fabkit. The Switches should indicate start and end positions of the drawers.

Four switches on the Fabkit

Four micro switches are connected with resistors to the Fabkit. Now the serial communication through the FTDI cable should send packages of the four values of the switches through each time to Processing. The code in Processing should receive the sets of four values and do something with it on the screen.

y


Arduino IDE has a solution for this: Serialcallresponse

y


What is happening in this sketch is very well explained in . It is very nice that at the bottom of the Arduino Sketch the code for Processing is available. Just copy it to Processing.

The changes that were made to the code are:
1. removing the analogue sensors
2. adding four digital sensor
3. assigning the sensors to pins from the Fabkit
4. using the map function, which means: when the switch is 0; give a value x and when the switch is 1; give a value y (x and y can be numbers between 0 and 255, grey tones)

After an initial "handshake" the values of the switches will be send though the FTDI cable by using "serial write".

This is the sketch:

/*
  Serial Call and Response
 Language: Wiring/Arduino

 This program sends an ASCII A (byte of value 65) on startup
 and repeats that until it gets some data in.
 Then it waits for a byte in the serial port, and
 sends three sensor values whenever it gets a byte in.

 Thanks to Greg Shakar and Scott Fitzgerald for the improvements

   The circuit:
 * potentiometers attached to analog inputs 0 and 1
 * pushbutton attached to digital I/O 2

 Created 26 Sept. 2005
 by Tom Igoe
 modified 24 April 2012
 by Tom Igoe and Scott Fitzgerald

 This example code is in the public domain.

 http://www.arduino.cc/en/Tutorial/SerialCallResponse

 */

int firstSensor = 0;    // first analog sensor
int secondSensor = 0;   // second analog sensor
int thirdSensor = 0;    // digital sensor
int fourthSensor = 0;    // digital sensor
int inByte = 0;         // incoming serial byte

void setup() {
  // start serial port at 9600 bps:
  Serial.begin(9600);
  while (!Serial) {
    ; // wait for serial port to connect. Needed for native USB port only
  }

  pinMode(2, INPUT);   // digital sensor is on digital pin 2
  establishContact();  // send a byte to establish contact until receiver responds

pinMode(3, INPUT);   // digital sensor is on digital pin 3
  establishContact();  // send a byte to establish contact until receiver responds

pinMode(4, INPUT);   // digital sensor is on digital pin 4
  establishContact();  // send a byte to establish contact until receiver responds

pinMode(5, INPUT);   // digital sensor is on digital pin 5
  establishContact();  // send a byte to establish contact until receiver responds
  
}

void loop() {
  // if we get a valid byte, read analog ins:
  if (Serial.available() > 0) {
    // get incoming byte:
    inByte = Serial.read();
    // read first analog input, divide by 4 to make the range 0-255:
//    firstSensor = analogRead(A0) / 4;
    // delay 10ms to let the ADC recover:
//    delay(10);
    // read second analog input, divide by 4 to make the range 0-255:
//    secondSensor = analogRead(1) / 4;
    // read  switch, map it to 0 or 255L
    firstSensor = map(digitalRead(2), 0, 1, 160, 255);
    // send sensor values:
        secondSensor = map(digitalRead(3), 0, 1, 120, 255);
    // send sensor values:
    thirdSensor = map(digitalRead(4), 0, 1, 80, 255);
    // send sensor values:
    fourthSensor = map(digitalRead(5), 0, 1, 40, 255);
    // send sensor values:
    
    Serial.write(firstSensor);
    Serial.write(secondSensor);
    Serial.write(thirdSensor);
    Serial.write(fourthSensor);
  }
}

void establishContact() {
  while (Serial.available() <= 0) {
    Serial.print('A');   // send a capital A
    delay(300);
  }
}

The processing sketch is shown below.

The changes to the sketch in processing are: - the serialInArray needs to receive 4 values
- new variables defined: fgcolor1, fgcolor2, fgcolor3, fgcolor4
- the COM port is in my case 1
- with "println" the 4 values of the switches are printed on the monitor. Now these numbers can be used in the code. For instance: When it is equal to the value; do something.
- make a block slide with a veriable x +1 or -1, it starts when a value of a switch is not equal to what is read from the micro controller.
- To show the status of the switches I use: If the fgolorx is (not) equal to the default value yy, draw a rectangle on the screen in a certain colour.

//Processing sketch to run with this example:

// This example code is in the public domain.

import processing.serial.*;

int bgcolor; // Background color int fgcolor; // Fill color Serial myPort;                       // The serial port int[] serialInArray = new int[4]; // Where we'll put what we receive int serialCount = 0; // A count of how many bytes we receive int fgcolor1, fgcolor2, fgcolor3, fgcolor4; // Starting position of the ball boolean firstContact = false; // Whether we've heard from the microcontroller

float x = 80;

void setup() {

  size(500, 500); // Stage size   noStroke(); // No border on the next thing drawn

  // Set the starting position of the ball (middle of the stage)

  // Print a list of the serial ports for debugging purposes   // if using Processing 2.1 or later, use Serial.printArray()   println(Serial.list());

  // I know that the first port in the serial list on my mac   // is always my FTDI adaptor, so I open Serial.list()[0].   // On Windows machines, this generally opens COM1.   // Open whatever port is the one you're using.   String portName = Serial.list()[1];   myPort = new Serial(this, portName, 9600); }

void draw() {

  background(bgcolor);   // fill(fgcolor1);

  if (fgcolor1 != 160) {     fill(150);     rect(x, 50, 100, 20);     x = x - 1;   } else {     rect(x, 50, 100, 20);   }

  if (fgcolor2 != 120) {     fill(100);     rect(x, 50, 100, 20);     x = x + 1;   } else {     rect(x, 50, 100, 20);   }

  if (fgcolor1 == 160) {     fill(0, 255, 0);   } else {     fill(255, 0, 0);   }   rect(50, 50, 20, 20);

  if (fgcolor2 == 120) {     fill(0, 255, 0);   } else {     fill(255, 0, 0);   }   rect(400, 50, 20, 20);

  if (fgcolor3 == 80) {     fill(0, 255, 0);   } else {     fill(255, 0, 0);   }   rect(50, 100, 20, 20);

  if (fgcolor4 == 40) {     fill(0, 255, 0);   } else {     fill(255, 0, 0);   }   rect(400, 100, 20, 20);

  // Draw the shape   // background(0); } void serialEvent(Serial myPort) {   // read a byte from the serial port:   int inByte = myPort.read();   // if this is the first byte received, and it's an A,   // clear the serial buffer and note that you've   // had first contact from the microcontroller.   // Otherwise, add the incoming byte to the array:   if (firstContact == false) {     if (inByte == 'A') {       myPort.clear(); // clear the serial port buffer       firstContact = true; // you've had first contact from the microcontroller       myPort.write('A'); // ask for more     }   } else {     // Add the latest byte from the serial port to array:     serialInArray[serialCount] = inByte;     serialCount++;

    // If we have 3 bytes:     if (serialCount > 3 ) {       fgcolor1 = serialInArray[0];       fgcolor2 = serialInArray[1];       fgcolor3 = serialInArray[2];       fgcolor4 = serialInArray[3];       // print the values (for debugging purposes only):       println(fgcolor1 + "\t" + fgcolor2 + "\t" + fgcolor3 + "\t" + fgcolor4);

      // Send a capital A to request new sensor readings:       myPort.write('A');       // Reset serialCount:       serialCount = 0;     }   } }

The code needs some debugging / improvement as you can see in the video below.

Further improvements

For now I understand the basic principles of using Arduino and Processing together by sending through packages of serial information about the status of in/output devices. So far I could show simple things on the screen that indicate the status of switches and the direction of the movement of an object.

To elaborate more into this way of working I seriously need to do more tutorials on programming in Arduino and in Processing.

I intend to do the following tutorials:

< look for tutorials how to do this >