OSCelleton for Kinect

Start with setting up the OpenNI, OpenNite and sensorkinect. Follow the steps in here: http://tohmjudson.com/?p=30

And this is the simplified version of skeleton tracking. It is using simple ellipses to draw the skeleton.

/*simple processing skeletoon sketch for kinect
Instead of using arraylists, I have done this example by using PVector and ellipses
It works for only one user.
Mustafa Bagdatli, http://www.mustafabagdatli.com
February 28, 2011
*/
import oscP5.*;
import netP5.*;
OscP5 oscP5;
boolean userExist = false;
PVector head = new PVector(0,0,0);
PVector neck = new PVector(0,0,0);
PVector r_collar = new PVector(0,0,0);
PVector r_shoulder = new PVector(0,0,0);
PVector r_elbow = new PVector(0,0,0);
PVector r_wrist = new PVector(0,0,0);
PVector r_hand = new PVector(0,0,0);
PVector r_finger = new PVector(0,0,0);
PVector r_collar2 = new PVector(0,0,0);
PVector l_shoulder = new PVector(0,0,0);
PVector l_elbow = new PVector(0,0,0);
PVector l_wrist = new PVector(0,0,0);
PVector l_hand = new PVector(0,0,0);
PVector l_finger = new PVector(0,0,0);
PVector torso = new PVector(0,0,0);
PVector r_hip = new PVector(0,0,0);
PVector r_knee = new PVector(0,0,0);
PVector r_ankle = new PVector(0,0,0);
PVector r_foot = new PVector(0,0,0);
PVector l_hip = new PVector(0,0,0);
PVector l_knee = new PVector(0,0,0);
PVector l_ankle = new PVector(0,0,0);
PVector l_foot = new PVector(0,0,0);
void setup() {
size(screen.height*4/3, screen.height);    // use OPENGL rendering for bilinear filtering on texture
smooth();
oscP5 = new OscP5(this, “127.0.0.1″, 7110);
// Initialize box2d physics and create the world
}
/* incoming osc message are forwarded to the oscEvent method. */
// Here you can easily see the format of the OSC messages sent. For each user, the joints are named with
// the joint named followed by user ID (head0, neck0 …. r_foot0; head1, neck1…..)
void oscEvent(OscMessage msg) {
if (msg.checkAddrPattern(“/joint”) && msg.checkTypetag(“sifff”)) {
// We have received joint coordinates, let’s find out which skeleton/joint and save the values ;)
Integer id = msg.get(1).intValue();
if (msg.get(0).stringValue().equals(“head”)) {
head = new PVector(msg.get(2).floatValue(),msg.get(3).floatValue(),msg.get(4).floatValue());
}
else if (msg.get(0).stringValue().equals(“neck”)) {
neck = new PVector(msg.get(2).floatValue(),msg.get(3).floatValue(),msg.get(4).floatValue());
}
else if (msg.get(0).stringValue().equals(“r_collar”)) {
r_collar = new PVector(msg.get(2).floatValue(),msg.get(3).floatValue(),msg.get(4).floatValue());
}
else if (msg.get(0).stringValue().equals(“r_shoulder”)) {
r_shoulder = new PVector(msg.get(2).floatValue(),msg.get(3).floatValue(),msg.get(4).floatValue());
}
else if (msg.get(0).stringValue().equals(“r_elbow”)) {
r_elbow = new PVector(msg.get(2).floatValue(),msg.get(3).floatValue(),msg.get(4).floatValue());
}
else if (msg.get(0).stringValue().equals(“r_wrist”)) {
r_wrist = new PVector(msg.get(2).floatValue(),msg.get(3).floatValue(),msg.get(4).floatValue());
}
else if (msg.get(0).stringValue().equals(“r_hand”)) {
r_hand = new PVector(msg.get(2).floatValue(),msg.get(3).floatValue(),msg.get(4).floatValue());
}
else if (msg.get(0).stringValue().equals(“r_finger”)) {
r_finger = new PVector(msg.get(2).floatValue(),msg.get(3).floatValue(),msg.get(4).floatValue());
}
else if (msg.get(0).stringValue().equals(“r_collar”)) {
r_collar2 = new PVector(msg.get(2).floatValue(),msg.get(3).floatValue(),msg.get(4).floatValue());
}
else if (msg.get(0).stringValue().equals(“l_shoulder”)) {
l_shoulder = new PVector(msg.get(2).floatValue(),msg.get(3).floatValue(),msg.get(4).floatValue());
}
else if (msg.get(0).stringValue().equals(“l_elbow”)) {
l_elbow = new PVector(msg.get(2).floatValue(),msg.get(3).floatValue(),msg.get(4).floatValue());
}
else if (msg.get(0).stringValue().equals(“l_wrist”)) {
l_wrist = new PVector(msg.get(2).floatValue(),msg.get(3).floatValue(),msg.get(4).floatValue());
}
else if (msg.get(0).stringValue().equals(“l_hand”)) {
l_hand = new PVector(msg.get(2).floatValue(),msg.get(3).floatValue(),msg.get(4).floatValue());
}
else if (msg.get(0).stringValue().equals(“l_finger”)) {
l_finger = new PVector(msg.get(2).floatValue(),msg.get(3).floatValue(),msg.get(4).floatValue());
}
else if (msg.get(0).stringValue().equals(“torso”)) {
torso = new PVector(msg.get(2).floatValue(),msg.get(3).floatValue(),msg.get(4).floatValue());
}
else if (msg.get(0).stringValue().equals(“r_hip”)) {
r_hip = new PVector(msg.get(2).floatValue(),msg.get(3).floatValue(),msg.get(4).floatValue());
}
else if (msg.get(0).stringValue().equals(“r_knee”)) {
r_knee = new PVector(msg.get(2).floatValue(),msg.get(3).floatValue(),msg.get(4).floatValue());
}
else if (msg.get(0).stringValue().equals(“r_ankle”)) {
r_ankle = new PVector(msg.get(2).floatValue(),msg.get(3).floatValue(),msg.get(4).floatValue());
}
else if (msg.get(0).stringValue().equals(“r_foot”)) {
r_foot = new PVector(msg.get(2).floatValue(),msg.get(3).floatValue(),msg.get(4).floatValue());
}
else if (msg.get(0).stringValue().equals(“l_hip”)) {
l_hip = new PVector(msg.get(2).floatValue(),msg.get(3).floatValue(),msg.get(4).floatValue());
}
else if (msg.get(0).stringValue().equals(“l_knee”)) {
l_knee = new PVector(msg.get(2).floatValue(),msg.get(3).floatValue(),msg.get(4).floatValue());
}
else if (msg.get(0).stringValue().equals(“l_ankle”)) {
l_ankle = new PVector(msg.get(2).floatValue(),msg.get(3).floatValue(),msg.get(4).floatValue());
}
else if (msg.get(0).stringValue().equals(“l_foot”)) {
l_foot = new PVector(msg.get(2).floatValue(),msg.get(3).floatValue(),msg.get(4).floatValue());
}
}
else if (msg.checkAddrPattern(“/new_user”) && msg.checkTypetag(“i”)) {
// A new user is in front of the kinect… Tell him to do the calibration pose!
println(“New user with ID = ” + msg.get(0).intValue());
userExist = true;
}
else if(msg.checkAddrPattern(“/new_skel”) && msg.checkTypetag(“i”)) {
//New skeleton calibrated! Lets create it!
Integer id = msg.get(0).intValue();
}
else if(msg.checkAddrPattern(“/lost_user”) && msg.checkTypetag(“i”)) {
//Lost user/skeleton
userExist = false;
Integer id = msg.get(0).intValue();
println(“Lost user ” + id);
}
}
void draw() {
background(0);
noStroke();
println(userExist);
if(userExist) {
fill(255);
//values that we are receiving are for x,y positions are between 0,1.0
//that’s why I am multiplying them with width and height of the screen.
ellipse(head.x*width,head.y*height,50/head.z,50/head.z);
ellipse(r_collar.x*width,r_collar.y*height,30/r_collar.z,30/r_collar.z);
ellipse(r_shoulder.x*width,r_shoulder.y*height,30/r_shoulder.z, 30/r_shoulder.z);
ellipse( r_elbow.x*width, r_elbow.y*height,30/r_elbow.z,30/r_elbow.z);
ellipse(r_wrist.x*width,r_wrist.y*height,30/r_wrist.z,30/r_wrist.z);
ellipse( r_hand.x*width, r_hand.y*height,30/r_hand.z,30/r_hand.z);
ellipse(r_finger.x*width,r_finger.y*height,30/r_finger.z, 30/r_finger.z);
ellipse(r_collar2.x*width,r_collar2.y*height,30/r_collar2.z, 30/r_collar2.z);
ellipse(l_shoulder.x*width,l_shoulder.y*height,30/l_shoulder.z, 30/l_shoulder.z);
ellipse(l_elbow.x*width,l_elbow.y*height,30/l_elbow.z,30/l_elbow.z);
ellipse(l_wrist.x*width,l_wrist.y*height,30/l_wrist.z, 30/l_wrist.z);
ellipse(l_hand.x*width,l_hand.y*height,30/l_hand.z, 30/l_hand.z);
ellipse(l_finger.x*width,l_finger.y*height,30/l_finger.z,30/l_finger.z);
ellipse(torso.x*width,torso.y*height,30/torso.z,30/torso.z);
ellipse(r_hip.x*width,r_hip.y*height,30/r_hip.z, 30/r_hip.z);
ellipse(r_knee.x*width,r_knee.y*height,30/r_knee.z, 30/r_knee.z);
ellipse(r_ankle.x*width,r_ankle.y*height,30/r_ankle.z, 30/r_ankle.z);
ellipse(r_foot.x*width,r_foot.y*height,30/r_foot.z,30/r_foot.z);
ellipse(l_hip.x*width,l_hip.y*height,30/l_hip.z, 30/l_hip.z);
ellipse(l_knee.x*width,l_knee.y*height,30/l_knee.z,30/l_knee.z);
ellipse(l_ankle.x*width,l_ankle.y*height,30/l_ankle.z, 30/l_ankle.z);
ellipse(l_foot.x*width,l_foot.y*height,30/l_foot.z,30/l_foot.z);
}
}

Linksprite JPEG Camera tutorial is ready!

I have prepared (thanks to Tom Igoe and Adam Harvey) a tutorial for Linksprite JPEG camera that you can buy from sparkfun.com.

It is really easy to use and actually it could be interesting to play with the image on the Arduino(I haven’t tried it yet).

Anyways, link for the tutorial is here

OLED 128 with Arduino

Here is an updated version of OLED 128 library and a simple sample code.

Jenny already has a good tutorial on connecting screen and Arduino. Check out her blog for information.

My version of the code is working with Arduino 21 and I have tried it only with Arduino Uno.

Here is the result

You can find the sample code in here: http://code.google.com/p/oled128/

I2C tutorial

Here is a tutorial that I prepared for Arduino I2C connection. Arduino.cc has a good tutorial on I2C, I have added my experience on top of what they have to prepare this tutorial. So, you can see some things from Arduino site. I2C lets you communicate between multiple Arduino’s. It works with a master Arduino, and 1 or more Arduino(s), that can be used for input or output.

To make the hardware connection, you need to connect one ground and 5V pins on each Arduino. Also, for data transfer, you need to connect SDA and SCL pins.

I2C is a synchronized communication way between Arduino’s, So, you don’t need to worry about synchronization. We are using 2 pins for I2C. One of them is SDA which is the data line, and the other one is SCL which is the clock line that keeps multiple Arduino’s synchronized according to master.

On most Arduino boards, SDA (data line) is on analog input pin 4, and SCL (clock line) is on analog input pin 5. On the Arduino Mega, SDA is digital pin 20 and SCL is 21. (got it from http://arduino.cc/en/Reference/Wire)

Functions

Begin:

Wire.begin()

Wire.begin(address)

Description

Initiate the Wire library and join the I2C bus as a master or slave.

Address is the name of the Arduino module, in your conversation between Arduino’s. It is really important to define addresses for each Arduino, because it is the simplest way to identify them. If address is not specified, it can be used as master. For slaves, address should be determined.

Parameters

Address: the 7-bit slave address (0-127).

Returns

None

Example

void setup(){

Wire.begin(4);                // join i2c bus with address #4

}

Wire.requestFrom(address, quantity)

Description

This function is for, when master requests bytes from a slave. You need to define the address of the slave that you are asking bytes, also number of bytes that you are asking from that slave.

The bytes may then be retrieved with the available() and receive() functions.

Parameters

address: the 7-bit address of the device to request bytes from

quantity: the number of bytes to request

Returns

None

Example

for master

// by Nicholas Zambetti <http://www.zambetti.com>
#include <Wire.h>

void setup()
{
Wire.begin();        // join i2c bus (address optional for master)
Serial.begin(9600); // serial connection
}

void loop()
{
Wire.requestFrom(2, 6);    // request 6 bytes from slave device #2

while(Wire.available())    // slave may send less than requested
{
char c = Wire.receive(); // receive a byte as character, you can chance “char” according to what you are sending from your slave (ex: byte, float etc.)
Serial.print(c);         // print the character
}

delay(500);
}

See Also

Wire.beginTransmission(address)

Description

Begin transmitting data to the I2C slave device with the given address. This function calls master device that, you are about to start transmitting data to defined slave. Subsequently, queue bytes for transmission with the send() function and transmit them by calling endTransmission().

Parameters

address: the 7-bit address of the device to transmit to

Returns

None

Example

for master

// by Nicholas Zambetti <http://www.zambetti.com>

#include <Wire.h>

void setup()
{
Wire.begin(); // join i2c bus (address optional for master)
}

byte x = 0; //data to transmit

void loop()
{
Wire.beginTransmission(4); // transmit to device #4
Wire.send(“x is “);        // sends five bytes
Wire.send(x);              // sends one byte
Wire.endTransmission();    // stop transmitting, this function makes the transmission

x++;
delay(500);
}

See Also

Wire.endTransmission()

Description

Ends a transmission to a slave device that was begun by beginTransmission() and actually transmits the bytes that were queued by send().

Parameters

None

Returns

None

See Also

Wire.send(value)

Wire.send(string)

Wire.send(data, quantity)

Description

Sends data from a slave device in response to a request from a master, or queues bytes for transmission from a master to slave device (in-between calls to beginTransmission() and endTransmission()).

Parameters

value: a byte to send (byte)

string: a string to send (char *)

data: an array of data to send (byte *)

quantity: the number of bytes of data to transmit (byte)

Returns

None

See Also

Wire.available()

Description

Returns the number of bytes available for retrieval with receive(). This should be called on a master device after a call to requestFrom() or on a slave inside the onReceive() handler.

Parameters

None

Returns

The number of bytes available for reading.

Example

for master

// by Nicholas Zambetti <http://www.zambetti.com>

void loop()
{
Wire.requestFrom(2, 6);    // request 6 bytes from slave device #2

while(Wire.available())    // slave may send less than requested
{
char c = Wire.receive(); // receive a byte as character
Serial.print(c);         // print the character
}

delay(500);
}

See Also

byte Wire.receive()

Description

Retrieve a byte that was transmitted from a slave device to a master after a call to requestFrom or was transmitted from a master to a slave.

Parameters

None

Returns

The next byte received.

Example

for slave

// by Nicholas Zambetti <http://www.zambetti.com>

void loop()
{
Wire.requestFrom(2, 6);    // request 6 bytes from slave device #2

while(Wire.available())    // slave may send less than requested
{
char c = Wire.receive(); // receive a byte as character
Serial.print(c);         // print the character
}

delay(500);
}

See Also

Wire.onReceive(handler)

Description

Registers a function to be called when a slave device receives a transmission from a master.

Wire.onRecive(handler) should be in setup function. Whenever slave receives a data from master, Wire,onReceive(handler) calls the handler function to handle the receiving process from master.

Parameters

handler: the function to be called when the slave receives data; this should take a single int parameter (the number of bytes received from the master) and return nothing, e.g.: void myHandler(int numBytes)

Example

for slave

// by Nicholas Zambetti <http://www.zambetti.com>
#include <Wire.h>

void setup()
{
Wire.begin(4);                // join i2c bus with address #4
Wire.onReceive(receiveEvent); // register event
Serial.begin(9600);           // start serial for output
}

void loop()
{
delay(100);
}

// function that executes whenever data is received from master
// this function is registered as an event, see setup()
void receiveEvent(int howMany)
{
while(1 < Wire.available()) // loop through all but the last
{
char c = Wire.receive(); // receive byte as a character
Serial.print(c);         // print the character
}

}

Returns

None

See Also

Wire.onRequest(handler)

Description

Register a function to be called when a master requests data from this slave device.

Wire.onRequest(handler) should be in setup function. Whenever master requests a data from slave, Wire,onRequest(handler) calls the handler function to handle the request process from master.

Parameters

handler: the function to be called, takes no parameters and returns nothing, e.g.: void myHandler()

Returns

None

Example

For slave
// by Nicholas Zambetti <http://www.zambetti.com>

#include <Wire.h>

void setup()
{
Wire.begin(2);                // join i2c bus with address #2
Wire.onRequest(requestEvent); // register event
}

void loop()
{
delay(100);
}

// function that executes whenever data is requested by master
// this function is registered as an event, see setup()
void requestEvent()
{
Wire.send(“hello “); // respond with message of 6 bytes
// as expected by master
}

See Also

TSL 230 R

TSL230R is a programmable light frequency integrated circuit(IC) that gives you pulses which are related to light intensity.

You can find a tutorial for using it in here: http://itp.nyu.edu/physcomp/sensors/Reports/TSL230R

FSR workshop update