Sunday, September 9, 2012

This Here is a home work assignment over the weekend that I had for my device interface class here at UC Berkeley.  The task was to create a simple keyboard using Arduino and additional HW.  I decided to use a 5-key (direction pad) keyboard that displays the letter selected on the computer screen.  

In general, this is a fairly simple task; however, because I wanted to have the computer GUI that talked to the Arduino it made the difficulty level a little harder.  





For the first part, I just used an actual keyboard up, down, left, right arrows and enter to control the Processing GUI.  I will then convert the keyboard input to serial input from the Arduino but it should look very similar.  Here is the initial Processing Code:



//Variables

static final int enterh = 30;

PFont f;

int i, charSelect, col;

color fillUP, fillDOWN, fillLEFT, fillRIGHT, fillENTER;




String words;

String[] keyboard = {"a", "b", "c", "d", "e",

"f", "g", "h", "i", "j", "k",

"l", "m", "n", "o", "p", "q",

"r", "s", "t", "u", "v", "w",

"x", "y", "z", "space"};




//Setup Loop

void setup() {

size(400, 360);

words = "";

charSelect = 0;



col = 0;

background(1);

// Create the font

f = createFont("Ethnocentric", 20);

i=0;

background(0);

}







//Draw loop

void draw() {

background(0);

textAlign(LEFT);

textFont(f,9);

fill(255);

text("a b c d e f g h i j k l m", width/2-4*enterh, height/4);

text("n o p q r s t u v w x y z", width/2-4*enterh, height/4+16);

text("space", width/2-4*enterh, height/4+32);

textFont(f, 30);

strokeWeight(1);

stroke(255, 255, 255);

rectMode(CENTER);

fill(0);

//rect(width/2,40, 90, 40);

rectMode(CORNER);

fill(255, 0, 0);

textAlign(CENTER);

text(keyboard[charSelect], width/2, 50);

strokeWeight(4);

stroke(15, 242, 39);

fill(0);

rect(width/2-4*enterh, height/2-1.5*enterh,enterh*8, enterh*4);

stroke(237, 255, 3);

fill(fillENTER);

rect((width/2)-enterh, height/2, enterh*2, enterh);

fill(fillLEFT);

triangle((width/2)-enterh*1.66, height*.5, (width/2)-enterh*1.66, height*.5+enterh,(width/2)-(enterh*2.5), height*.5+(enterh/2));

fill(fillRIGHT);

triangle((width/2)+enterh*1.66, height*.5, (width/2)+enterh*1.66, height*.5+enterh,(width/2)+(enterh*2.5), height*.5+(enterh/2));

fill(fillUP);

triangle((width/2)-enterh, height*.5-enterh*.333, (width/2)+enterh, height*.5-enterh*.33,(width/2), height*.5-enterh);

fill(fillDOWN);

triangle((width/2)-enterh, height*.5+enterh*1.333, (width/2)+enterh, height*.5+enterh*1.33,(width/2), height*.5+enterh*2);

delay(200);

fillUP = color(0, 0, 0);

fillDOWN = color(0, 0, 0);

fillLEFT = color(0, 0, 0);

fillRIGHT = color(0, 0, 0);

fillENTER = color(0, 0, 0);

textAlign(CENTER);

textFont(f, 16);

fill(237, 255, 3);

text(words, width/2, height*.9);

//println(words);





}




void keyPressed() {

if (key == CODED)

{



if (keyCode == UP)

{

fillUP = color(255, 0, 0);

if(col>0)

col -= 1;

else

col = 2;

if(col == 2)

charSelect = 26;



else{

charSelect -= 13;

}

}

else if (keyCode == DOWN)

{

fillDOWN = color(255, 0, 0);

if(col <2)

col += 1;

else

col = 0;

if(col == 2)

charSelect = 26;

else if(col == 0)

charSelect = 0;

else

charSelect += 13;



}

else if(keyCode == LEFT)

{

fillLEFT= color(255, 0, 0);

if(charSelect>0)

charSelect--;

else

charSelect = keyboard.length-1;

}

else if(keyCode == RIGHT)

{

fillRIGHT= color(255, 0, 0);

if(charSelect<keyboard.length-1)

charSelect++;

else

charSelect = 0;

}

}

else if(key == ENTER)

{

fillENTER = color(255, 0, 0);

if(keyboard[charSelect] == "space")

words = words + " ";

else

words = words + keyboard[charSelect];

}

else

{

fillUP = color(0, 0, 0);

fillDOWN = color(0, 0, 0);

fillLEFT = color(0, 0, 0);

fillRIGHT = color(0, 0, 0);

fillENTER = color(0, 0, 0);

}

if(charSelect < 13)

col = 0;

else if(charSelect <26)

col = 1;

else

col = 2;

println(col + " " + charSelect);

}





Processing is best used with Arduino for receiving serial data.  Here is a Processing example for a simple read over the serial port.

A simple way to test the serial with just your computer is to get 2 USB->Serial connections (RS232), a serial cable and connect them together (USB/Serial-->SerialCable-->Serial/USB) and then you can output and read serial information.  This may help in testing Processing code if an Arduino is not available (as is in my case; waiting for it to arrive, but have an assignment due before then!)  Here is a simple serial read on Processing.

Name

read()

Examples
// Example by Tom Igoe

import processing.serial.*;

Serial myPort;  // The serial port

void setup() {
  // List all the available serial ports
  println(Serial.list());
  // Open the port you are using at the rate you want:
  myPort = new Serial(this, Serial.list()[0], 9600);
}

void draw() {
  while (myPort.available() > 0) {
    int inByte = myPort.read();
    println(inByte);
  }
}

Interacting an Arduino with Processing

Processing is an easy-to-learn language for writing graphics programs based on Java.
You don't have to use Processing in this assignment, but you can.

The basic model to do this is as follows (I'll start with the simple unidirectional case where you are only sending data into Processing):
* You write Arduino code that sends data to an attached PC using the serial port functions.
* You write Processing code that opens the appropriate serial port on the PC and reads the data that your Arduino program sent; it then parses the data and responds appropriately.
* You have to come up with a protocol for your messages so Arduino and Processing agree on the format of the messages. This can be as simple as "send a single number followed by the newline character" and as complex as sending XML or JSON.

This is flexible, but also a lot of work: you have to define the protocol and write two pieces of code. Debugging these setups is also time consuming. In many cases, you only need to read simple analog or digital input pins, and write to output pins.

For this common case, Processing provides a library that consists of 1) A Processing library (called "Arduino") and 2) a special firmware (aka sketch) that you run on your Arduino board (called "Firmata"). Firmata exposes a simple, efficient protocol for reading and writing to pins. The Processing library then creates a wrapper around that protocol with Processing/Java functions that mimc the names of Arduino/C functions.

More information is here: http://www.arduino.cc/playground/Interfacing/Processing