on Apr 17th, 2012Wallace Waver
Here’s how to make the Cyborg Ben Wallace Waving Machine
Processing Code (simple frame differencing)
import processing.video.*;
import processing.serial.*; //This allows us to use serial objects
Continue Reading »
Here’s how to make the Cyborg Ben Wallace Waving Machine
Processing Code (simple frame differencing)
import processing.video.*;
import processing.serial.*; //This allows us to use serial objects
Continue Reading »
NO, NOT THAT KIND! THAT KIND MOSTLY ENJOYS SALMON, NOT ELECTRONICS! THIS KIND OF EAGLE:
CadSoft EAGLE PCB is a pretty ok piece of software for drawing up schematics and then laying out a printed circuit board. I say “pretty ok” because its interface and UI consistency leaves a lot to be desired, particularly if you’re used to the relatively sane default behavior of software like Adobe Illustrator. This caveat aside, though, Eagle is kind of amazing: it’s free for educational use (with a limited board size) and does it all. What it lacks in immediate user friendliness it makes up for in extensibility, where any number of people can contribute board shapes for all sorts of components.
This is the real deal! To get started, download the software. Pick the software type that matches your operating system, unless you enjoy fruitless struggle:
We’re also going to need to have some libraries to be sure that we’ve got all the components we want. Sparkfun has a good library, as does lady ada. If you want to save time, though, just grab mine. It’s got all those and more (a bag of chips??):
My thought for today was that we could
While we’ll probably just play around with Eagle during colab this week, Sparkfun’s tutorials for embedded electronics include some decent eagle guides. I’ll link them here for future reference.
Once you’re comfortable building arduino projects with simple sensors and outputs, its fairly soon you find yourself needing more stuff. A basic arduino uno has a limited number of inputs and outputs, for example, and standard inputs tend to limit applications. One way around this is to find sensor and other types of integrated circuit (IC) packages and use them in an arduino-driven project. To do this, it’s necessary to be able to read a datasheet, as well as any schematics found inside them.
Reading schematics
Here’s a handy reference of some common schematic symbols:
This is from Forrest Mims III’s book Radioshack Electronic Sensors Lab, and while some of the parts are specific to this kit (all the cards for example) it’s a decent place to start. There are also many online guides for schematic reference (e.g. here and here). Having a resistor reference is handy. If you’re on a Mac, I like Resistulator.
One of the chips’s we’ll be playing with today has a datasheet circuit that looks like this:
Setting up a breadboard
I’m a huge fan of having a breadboard set up for prototyping that has its own built-in power supply. I know that we don’t all have these, but I feel like it’s worth having on the blog for reference:
This is a breadboard with a standard DC jack, a 7805 power regulator that will give a consistent 5V output, and decoupling capacitors that will keep the current reasonably level. The heatsink is there because regulating 12V to 5V puts off some serious heat.
IC pin orientation
ICs can be read by the “notch” in one end of the chip, or a small depression near one of the pins. The first notes the side that the pin counting starts at, and the second indicates which pin is number 1. Pins on a chip are counted around the IC in a counterclockwise way:
Today’s project(s)
Because this isn’t all that many chips to share, it’s also worthwhile to get the hang of making an Arduino on a breadboard. I have parts enough for at least a couple of those, and I prefer this format of Arduino much more than using a regular Arduino on a PCB because I get much more prototyping space. There are a couple really good pre-built arduino boards that make a breadboard into a decent prototyping platform (e.g. boarduino), but doing it yourself is the gold standard in my book.
Using a in-circuit system programmer (ISP) like the USBtinyISP and a breakout board for the 6 pin programming header, it’s possible to program a breadboard arduino fairly easily.
For this week, we will have a quick glance at the basics of Computer Vision (which is a lofty word). We’ll investigate the algorithms in some basic computer vision projects, such as the Milkscanner, the basic openFrameworks openCV example or the recently completed in-house finger tracking for the kinect.
Yes, we’ll talk a bit about the Kinect too!
Here’s a video of the Milkscanner:
Here’s a video of a structured light 3D scanning approach.
Here’s a homemade facial capture system:
And a full-body mocap solution pre-kinect:
And a more complex algorithm, feature point tracking:
Since we’re all Arduino Masters by now, let’s use all this hardware knowledge to control some software! Instead of writing one big chunk of software, we’ll be learning how to communicate between different programs using a protocol called OSC (short for Open Sound Control).
If you want to know everthing there is to know about OSC, you can go to it’s website here: http://opensoundcontrol.org/introduction-osc
First, you’ll have to install the oscP5 library in Processing.
The library is here: http://www.sojamo.de/libraries/oscP5/
And you want to install/unzip it into your sketchbook folder, in a folder called “libraries” that you’ll have to make. Daniel Shiffman also says so here: http://www.learningprocessing.com/tutorials/libraries/
Next, we’ll use a simple program that reads from Arduino and sends stuff over OSC. We base the program off of Andreas Schegel’s OSC example included in the library.
Before we look at the code, let’s talk a bit about OSC. It’s a neat protocol in that it allows you to send more than just raw bytes, but floats, ints and what have you. The only caveat is that you kindof need to know what you’re looking for on the receiving end.
OSC is basically divided into 2 parts: the address and the data part. In the address, you write stuff that the receiving program will interpret as a string, so it’s convenient to use for communicating what’s going on in the data part. And in the data part you pack your data.
Lots of questions can be resolved once some example code is up and running, so let’s get to it! I will run a program called “Moviesandbox” that you can download from here: http://moviesandbox.net, and that allows me to visualize my sensor inputs using 3D-graphics! It runs on modern Macs and PCs.
I’ll help you set things up in MSB to get your sensor inputs going.
Also, there’s an example MSB project that you can plug your sensors into, that you can download from here:
http://moviesandbox.net/fish.zip
Once downloaded, unzip it to the projects folder in moviesandbox.
Here is the Processing Code (it’s a bit involved, feel free to leave some stuff out):
import oscP5.*;
import netP5.*;
import processing.serial.*;
Serial myPort; // The serial port
//sensors
float inByte1;
float inByte2;
float inByte3;
OscP5 oscP5;
NetAddress myRemoteLocation;
//prefix is the indicator for the sensor number
//int prefix1 = 3;
//flag for the end of the signal
boolean myCatch1 = true;
void setup() {
size(600,400);
frameRate(25);
/* start oscP5, listening for incoming messages at port 12000 */
//we dont really need to listen, so we leave at port 12000
oscP5 = new OscP5(this,12000);
/* myRemoteLocation is a NetAddress. a NetAddress takes 2 parameters,
* an ip address and a port number. myRemoteLocation is used as parameter in
* oscP5.send() when sending osc packets to another computer, device,
* application. usage see below. for testing purposes the listening port
* and the port of the remote location address are the same, hence you will
* send messages back to this sketch.
*/
myRemoteLocation = new NetAddress("127.0.0.1",31841);
// List all the available serial ports
println(Serial.list());
// I know that the first port in the serial list on my mac
// is always my Arduino, so I open Serial.list()[0].
// Open whatever port is the one you're using.
myPort = new Serial(this, Serial.list()[0], 9600);
// don't generate a serialEvent() unless you get a newline character:
myPort.bufferUntil('\n');
}
void serialEvent (Serial myPort) {
// get the ASCII string:
String inString = myPort.readStringUntil(';');
if (inString != null) {
// trim off any whitespace:
inString = trim(inString);
inString=inString.substring(0, inString.length()-1);
// convert to an int and map to the screen height:
inByte1 = float(inString);
inByte1 = map(inByte1, 0, 1023, 0, 1.0);
}
inString = myPort.readStringUntil(';');
if (inString != null) {
// trim off any whitespace:
inString = trim(inString);
inString=inString.substring(0, inString.length()-1);
// convert to an int and map to the screen height:
inByte2 = float(inString);
inByte2 = map(inByte2, 0, 1023, 0, 1.0);
}
inString = myPort.readStringUntil(';');
if (inString != null) {
// trim off any whitespace:
inString = trim(inString);
inString=inString.substring(0, inString.length()-1);
// convert to an int and map to the screen height:
inByte3 = float(inString);
inByte3 = map(inByte3, 0, 1023, 0, 1.0);
}
inString = myPort.readStringUntil('\n');
print(inByte1);
print (" ");
print(inByte2);
print (" ");
print(inByte3);
println(";");
}
void draw() {
background(128);
sendOSC();
}
void sendOSC() {
/* in the following different ways of creating osc messages are shown by example */
// OscMessage myMessage = new OscMessage("/pilot/vector3f/vector3f");
OscMessage myMessage = new OscMessage("/pilot/float/vector3f");
//head
myMessage.add(inByte1); /* add a float value to the osc message */
myMessage.add(0.0); /* add a float value to the osc message */
myMessage.add(0.0); /* add a float value to the osc message */
myMessage.add(inByte1); /* add a float value to the osc message */
/* send the message */
oscP5.send(myMessage, myRemoteLocation);
}
/* incoming osc message are forwarded to the oscEvent method. */
void oscEvent(OscMessage theOscMessage) {
/* print the address pattern and the typetag of the received OscMessage */
print("### received an osc message.");
print(" addrpattern: "+theOscMessage.addrPattern());
println(" typetag: "+theOscMessage.typetag());
}
And we’ll be using this Arduino Code, which is only a slight modification of the Analog Input example by David Cuartielles and Tom Igoe:
int sensorPinOne = A0; // select the input pin for the potentiometer
int sensorPinTwo = A4; // select the input pin for the potentiometer
int sensorPinThree = A2; // select the input pin for the potentiometer
int ledPin = 13; // select the pin for the LED
int sensorValueOne = 0; // variable to store the value coming from the sensor
int sensorValueTwo = 0; // variable to store the value coming from the sensor
int sensorValueThree = 0; // variable to store the value coming from the sensor
void setup() {
// declare the ledPin as an OUTPUT:
pinMode(ledPin, OUTPUT);
Serial.begin(9600);
//set pull up resistors for all three input channels
digitalWrite(14, HIGH); //A0 pullup
digitalWrite(16, HIGH); //A2
digitalWrite(18, HIGH); //A4
}
void loop() {
// read the value from the sensor:
sensorValueOne = analogRead(sensorPinOne);
sensorValueTwo = analogRead(sensorPinTwo);
sensorValueThree = analogRead(sensorPinThree);
Serial.print(sensorValueOne);
Serial.print(";");
Serial.print(sensorValueTwo);
Serial.print(";");
Serial.print(sensorValueThree);
Serial.println(";");
delay(20);
}
From a post by Ben Medler, helped out by the awesomeness of Colab. See the full post here: http://lcc.gatech.edu/~bmedler3/?p=703
In this post I discuss the design philosophies behind folk games like JS Joust and how they relate to game analytics, the process of analyzing game-related data. I argue game analytics is not solely about objectifying games for the sake of data analysis but can provide avenues for players to reflect on their gameplay, which is more aligned with the philosophies behind folk games. Giving an example, I capture player movement data from JS Joust and create visualizations representing the game being played across time. Not for reasons of in-depth analysis but for the fun of being able to spectate players over time.
If Beetles Could Joust
In a recent volume of the Parson’s Journal of Information Mapping, artist and educator Brittany Ransom details a visualization project where she experiments with capturing the travel patterns of bess beetles. These little guys have a number of intriguing attributes which drew Ransom’s attention. Bess Beetles are part of the natural decomposition process, breaking down waste and dead vegetation, and are incredibly strong, able to burrow into wood and pull many times their bodyweight. They live in colonies but pair off into male-female partnerships to take care of larva. Sound is also their main mode of communication (for defense, courtship, etc.) as they live mainly in the dark. But the main reason Ransom wished to experiment with bess beetles is to understand how they navigate their environment, something that we take for granted in our world today with such easy access to GPS and Google Maps.
In order to study bess beetle movement Ransom devised a small tracking backpack a beetle could carry. The backpack consisted of a small LED light and battery component, which is lightly adhered to the back of each beetle in order to allow the beetle to remove the backpack after rubbing against a fixed surface such as wood. Once the beetles are placed back into their natural environment, Ransom uses a number of visualization methods including long-exposure photography to produce images like the one below. Long-exposure photography allows each beetle’s travel path to become illuminated as a single streak of light representing the beetle’s movement data over time. It was these images that drew me to wonder can I treat Doug’s Joust players like Random’s beetles?
Many nuances of Joust gameplay appear in these visualizations. Things like players steadily creeping towards each other before attacking. Players becoming locked in circling motions like a dog chasing its tail. The ill-fated lunges which cause the elimination of both attacker and victim.
Then there are visual records of the funny events which happened during play. The time Bobby ran around the entire play area taking out others as he went. A game that lasted three seconds as three out of the four players all lunged after each other only to each eliminate themselves. Or the sweeping victory dance Andy created after winning a round.
1) Bobby, the pink player, makes a lap around the play area taking out players as he goes (image from an SLR exposure). 2) Three players simultaneously eliminate each other mere seconds into a round. 3) After winning a round, Andy makes a grand victory dance.
So remember the little beetles when playing JS Joust and how we can reflect on their world as we do our own. It’s not always about analyzing the game, it’s sometimes just about the play.
Last week we learned how to make Processing communicate with Arduino. In that lesson, Processing wrote to the serial port and Arduino read that information to light LEDs. But what happens when there needs to be a two-way conversation? This week we will look at handshaking.
Handshaking, or two-way serial communication, requires that the programs communicate in some orderly manner. One way this can be done, and the way we will be doing it, is by waiting for a response from one program before the other does anything. Other ways are adding signatures to communications so that a program only reads certain portions of the serial communications; that is, so each program knows what to read. The advantage of the handshaking method we will be using is the simplicity of the communication channel–one program talks and the other listens, then vice versa.
The code below uses serial communication to draw on the canvas. This certainly does not exploit the full potential of this type of serial communication. For our purposes, the serial communication is simply visually apparent.
Using two potentiometers (or, any type of analog sensor, for that matter) as the knobs, the Arduino program sends X-Y positions to Processing. Processing reads these values, draws the position of the cursor, and then sends a message back to Arduino to indicate it is ready for a new position.
What you need:
1 Arduino
2 Potentiometers (or other analog sensors)
Processing and Arduino (IDEs), installed
USB Serial cable
Various connection cables
What mine looks like:
As you can see, I am using a normal potentiometer for one of my sensors and a hacked potentiometer for my other. The important thing to note is that for three-prong sensors, such as potentiometers, all they do is vary resistance. The outer prongs are interchangeable power and the center is a reading of the current resistance of that power. Servos, when you hack them, have a potentiometer already installed (that is why you can send it values for its motion). If the sensor was a soft pot, the same thing applied. As for two-prong sensors, one prong requires grounding and the other is the sensor reading (that is, it hooks to a pin of number value). So, to mod the physical computing part of this lesson, just make sure to stay aware of what you need: some sort of input pin (pots are great since Etch A Sketches typically have knobs) and power/ground.
We are using pins A0 and A1 as value pins. Just use these and everything will be fine.
Processing Code:
import processing.serial.*;
float xPos = 0;
float yPos = 0;
Serial port;
void setup()
{
size(800, 600);
println(Serial.list());
port = new Serial(this, Serial.list()[1], 9600);
port.bufferUntil('\n');
smooth();
noStroke();
background(255);
}
void draw()
{
fill(0);
ellipse(xPos, yPos, 10, 10);
}
void serialEvent(Serial port)
{
String inString = port.readStringUntil('\n');
inString = trim(inString);
if (inString != null)
{
inString = trim(inString);
float[] pos = float(split(inString, ","));
for (int posNum = 0; posNum < pos.length; posNum++) { print("Sensor " + posNum + ": " + pos[posNum] + "\t"); } println(); if (pos.length >=2)
{
xPos = map(pos[0], 0, 1023, 0, width);
yPos = map(pos[1], 0, 1023, 0, height);
}
}
port.write("A");
}
Arduino code:
/*
Week Two: Arduino to Processing to Arduino
*/
#define xPos A0
#define yPos A1
//#define blue A2
int inByte = 0;
void setup()
{
pinMode(xPos, INPUT);
pinMode(yPos, INPUT);
Serial.begin(9600);
establishContact();
}
void loop()
{
if(Serial.available()>0)
{
inByte = Serial.read();
int x_val = analogRead(xPos);
int y_val = analogRead(yPos);
Serial.print(x_val);
Serial.print(",");
Serial.println(y_val);
delay(100);
}
}
void establishContact()
{
while (Serial.available() <= 0) {
Serial.println("400,300"); // send an initial string
delay(300);
}
}
Goal: To learn how to use serial communication to send information from Processing to Arduino.
Part One: Virtual light switch
Using a virtual button in Processing, an LED can be turned on and off using Arduino. This is done by sending one of two ASCII characters to Arduino through the serial port when a box registers a mouse hover over in the Processing canvas. When an ‘L’ is sent, the LED is off; when an ‘H’ is sent, the LED is on.
Part Two: Physical Mouse Speedometer
Based on the speed of mouse, a series of LEDs acts as a VU meter. This is done by sending various 5 ASCII (‘A’-'E’) characters corresponding to different speed levels. For an alternate project, this basic idea can actuate a Servo motor to produce a more precise speedometer.
What you will need:
Arduino, installed
Processing, installed
5 LEDs (preferably 2 green, 2 yellow, 1 red)
1 Breadboard
1 USB serial cable
Various wires to connect Arduino, LEDs, and breadboard
Part One
Processing
import processing.serial.*; //This allows us to use serial objects
Serial port; // Create object from Serial class
int val; // Data received from the serial port
void setup()
{
size(800, 600);
println(Serial.list()); //This shows the various serial port options
String portName = Serial.list()[1]; //The serial port should match the one the Arduino is hooked to
port = new Serial(this, portName, 9600); //Establish the connection rate
}
void draw()
{
background(255);
if (mouseOverRect() == true)
{ // If mouse is over square,
fill(150); // change color and
port.write('H'); // send an H to indicate mouse is over square
}
else
{ // If mouse is not over square,
fill(0); // change color and
port.write('L'); // send an L otherwise
}
rect(50, 50, 100, 100); // Draw a square
}
boolean mouseOverRect()
{ // Test if mouse is over square
return ((mouseX >= 50) && (mouseX <= 150) && (mouseY >= 50) && (mouseY <= 150));
}
Arduino
#define PIN13 13 //define the pin
char val; // Data received from the serial port
void setup()
{
pinMode(PIN13, OUTPUT); // Set pin as OUTPUT
Serial.begin(9600); // Start serial communication at 9600 bps
}
void loop()
{
if (Serial.available())
{ // If data is available to read,
val = Serial.read(); // read it and store it in val
}
if (val == 'H')
{ // If H was received
digitalWrite(PIN13, HIGH); // turn the LED on
}
else
{
digitalWrite(PIN13, LOW); // Otherwise turn it OFF
}
}
Part Two
Processing
import processing.serial.*; //This allows us to use serial objects
Serial port; // Create object from Serial class
int val; // Data received from the serial port
void setup()
{
size(800, 600);
println(Serial.list()); //This shows the various serial port options
String portName = Serial.list()[1]; //The serial port should match the one the Arduino is hooked to
port = new Serial(this, portName, 9600); //Establish the connection rate
}
void draw()
{
background(255);
char speed = 'E';
if (mouseSpeed()>45)
{
speed = 'A';
}
else if (mouseSpeed()>30)
{
speed = 'B';
}
else if (mouseSpeed()>15)
{
speed = 'C';
}
else if (mouseSpeed()>5)
{
speed = 'D';
}
else
{
speed = 'E';
}
background(mouseSpeed());
println(speed);
port.write(speed);
}
int mouseSpeed()
{
return((int)(abs(mouseX-pmouseX)+abs(mouseY-pmouseY)));
}
Arduino
#define PIN13 13 //define the pin
#define PIN12 12
#define PIN11 11
#define PIN10 10
#define PIN9 9
char val; // Data received from the serial port
void setup()
{
pinMode(PIN13, OUTPUT); // Set pins as OUTPUT
pinMode(PIN12, OUTPUT);
pinMode(PIN11, OUTPUT);
pinMode(PIN10, OUTPUT);
pinMode(PIN9, OUTPUT);
Serial.begin(9600); // Start serial communication at 9600 bps
}
void loop()
{
if (Serial.available())
{ // If data is available to read,
val = Serial.read(); // read it and store it in val
}
switch(val)
{
case 'A':
digitalWrite(PIN13, HIGH);
digitalWrite(PIN12, HIGH);
digitalWrite(PIN11, HIGH);
digitalWrite(PIN10, HIGH);
digitalWrite(PIN9, HIGH);
break;
case 'B':
digitalWrite(PIN13, HIGH);
digitalWrite(PIN12, HIGH);
digitalWrite(PIN11, HIGH);
digitalWrite(PIN10, HIGH);
digitalWrite(PIN9, LOW);
break;
case 'C':
digitalWrite(PIN13, HIGH);
digitalWrite(PIN12, HIGH);
digitalWrite(PIN11, HIGH);
digitalWrite(PIN10, LOW);
digitalWrite(PIN9, LOW);
break;
case 'D':
digitalWrite(PIN13, HIGH);
digitalWrite(PIN12, HIGH);
digitalWrite(PIN11, LOW);
digitalWrite(PIN10, LOW);
digitalWrite(PIN9, LOW);
break;
default:
digitalWrite(PIN13, HIGH);
digitalWrite(PIN12, LOW);
digitalWrite(PIN11, LOW);
digitalWrite(PIN10, LOW);
digitalWrite(PIN9, LOW);
break;
}
}
Inspired by Colab’s work with analog inputs and Tom Igoe’s Making Things Talk, I spent a Saturday putting together this networked mat that documents my cats’ unconscious contortions. In household vernacular, we dub these incidents “Kitty Puddles,” and sightings of said puddle right the wrongs of any day.