Showing posts with label processing. Show all posts
Showing posts with label processing. Show all posts

4.6.09

lets look at the tech

Because I find it all so interesting.

I've spent a lot of time in the project exploring different possible technologies to use, including hacking wiimotes, Arduino, RFID, and colour tracking. I explored all the different strengths and weaknesses of each tech: colour tracking being pap in low light, and interfered with by similarly coloured objects, wiimotes being temperamental little things and prone to errors in Processing in my experience, Arduino being one of the most appealing technologies I looked into, but all the fun components get a little bit expensive on my budget, and RFID only reading tags, not tracking. I'm now going to look into the uses of the two technologies that I have decided to use, and the potential uses of what I have created using them.

When I first started this project I was quite interested in tracking the users around the space, which still interests me, but as I progressed through the project I found myself becoming more interested in creating a tactile interface, and the technologies that were best to create one were what I ended up using - Arduino and RFID tagging. The RFID tagging allowed me to create physical objects that could be recognized by the computer, allowing the real world to interact with the data in the computer. The Lilypad allowed me to create objects that were not only clever and glowy and wow, but allowed me to create objects that the user wants to pick up and interact with. The knitting also helped with that, people seem to be comfortable with the objects and find them familiar because of the way they are made.

"In of itself, I don't find RFID that exciting. When it's connected to a greater network (e.g. a database, the web, other intelligent devices, etc.) , that's when it can get really interesting." - Doria Fan

Doria fan uses RFID tags to create objects that are imbued with personal histories, without overpowering the object with technology. Her RFID enabled medical history bracelets are still bracelets, the technology does not interfere with the practicality of the object.



The tags inside the medical bracelets contain activate a link to the patients online medical history, making it a beautiful but practical object, containing the wearers personal history.

iTea is another RFID tagging system which uses the internet to bring up data.



Dropping your conference pass in a tea cup scans the internet for data about you. Some information is taken off a social network site, some is googled, allowing the user to see their personal profile made by the internet, whether it's true or false.

To sum it up, the wonderful thing about RFID is that it enables an object to be two different things. It remains the object it was or was intended to be, the bracelet is still a bracelet, the big wooly cloud is still a big wooly cloud, but it allows the object to take on a different aspect as well. It becomes an object that can interface with the digital world, and can bring up data that not only relates to the object, but adds to its meaning.

I've looked into the uses of the Arduino lilypad before, so this bit will be a little bit shorter. Basically, after my experimentation and research in my last project, which focused on the lilypad being a technology to create wearable textiles, I found myself wanting to experiment with it more in a different context. I have researched in toy hacking as part of this project, looking into the creations from the mediamatic workshop, which while were brilliant examples of the toys getting new functionalities, the objects lost some of their identities as toys, what with the wires poking out of them. Granted they were prototypes from a workshop, but I wanted to create objects that were still objects. My little wooly friends were designed to be wired up, and buzzing around around the place and blinding people with ultra bright LEDs, but I wanted them to retain the element of familiarity and softness brought about by creating them by knitting, even before i knew I was going to knit them or reminded myself how to knit. By using the lilypad I was able to make them into "shiny wow wow's", but by using soft circuits was able to keep them as approachable objects.

So then, how could what I have made be used? My program, even there are around a thousand lines in it, is rather simplistic. It gets the feed, matches it up with the RFID tag and spits it out to the screen. And makes some swirly animations. All rather nice but the data it's getting, and the way it gets it could be used in other ways. Some examples are in the RFID examples above, using the technology to personalise objects and drag in data from the internet. The use of the weather data itself lends it to be used with a mapping system like google maps, returning the data to it's geographical context, and reminding people who don't have such a detailed map in there heads of where places are in relation to each other. The weather feed could also be used in conjunction with other feeds, perhaps used with flickr, to create a link between a weather state and the most recent and geographically appropriate geotagged photo uploaded, creating a visual representation of the weather that is more closely related to the data than my swirly graphics.

There are many things it could be used for i suppose, now that I've figured out how to do the simpler parts (getting the feed, getting it to the screen, using RFID tags), I plan to keep exploring the possibilities.

2.6.09

animation

Here's a sneaky peek at my animations:

Clouds are surrounded by cotton wool.



Heavy rain is not very impressed by his amazingly colourful background.



code:

// final heavy rain animation

import processing.candy.*;
import processing.xml.*;
float angle;

SVG blob1;
SVG blob2;
SVG blob3;
SVG blob4;
SVG blob5;
SVG bigdrip;

void setup()
{
size(1500, 800);
frameRate(30);
smooth();

blob1 = new SVG(this, "blob_001.svg");
blob2 = new SVG(this, "blob_002.svg");
blob3 = new SVG(this, "blob_003.svg");
blob4 = new SVG(this, "blob_004.svg");
blob5 = new SVG(this, "blob_005.svg");
bigdrip = new SVG(this, "heavy_002.svg");
}

void draw()
{
background(206, 237, 255);
translate(500, 400); // center animation

pushMatrix();
for (int i=0; i<10; i++) //variable controls how many appear
{
angle += 0.0005; // sets speed
rotate(angle); // rotate it
translate(0, 0); // where it is
blob1.draw( 50, 50, 80, 80); // placement and size
}
popMatrix();


pushMatrix();
for (int i=0; i<10; i++) //variable controls how many appear
{
angle += 0.0005; // sets speed
rotate(angle); // rotate it
translate(0, 0); // where it is
blob5.draw( 100, 100, 90, 90); // placement and size
}
popMatrix();


pushMatrix();
for (int i=0; i<10; i++) //variable controls how many appear
{
angle += 0.0005; // sets speed
rotate(angle); // rotate it
translate(0, 0); // where it is
blob3.draw( 150, 150, 100, 100); // placement and size
}
popMatrix();

pushMatrix();
for (int i=0; i<10; i++) //variable controls how many appear
{
angle += 0.0005; // sets speed
rotate(angle); // rotate it
translate(0, 0); // where it is
blob4.draw( 200, 200, 150, 150); // placement and size
}
popMatrix();

pushMatrix();
for (int i=0; i<10; i++) //variable controls how many appear
{
angle += 0.0005; // sets speed
rotate(angle); // rotate it
translate(0, 0); // where it is
blob2.draw( 250, 250, 200, 200); // placement and size
}
popMatrix();

pushMatrix();
for (int i=0; i<10; i++) //variable controls how many appear
{
angle += 0.0005; // sets speed
rotate(angle); // rotate it
translate(0, 0); // where it is
blob5.draw( 350, 350, 250, 250); // placement and size
}
popMatrix();

bigdrip.draw( -200, -200, 400, 400);

}

22.5.09

RFID controlled weather feed

it works and it's so glorious.

The one thing is that it waits till the feed is brought in again before it tells you the weather feed, it isn't instantaneous. At the moment my feed comes in every five seconds which i thought was quite a lot. It would be nice if i could get it looping rather than just waiting. maybe loop(); will work. starting to think about how it's all going to look visually as well...


//weather for twelve cities!
// now waiting for button presses from lilypad
//trying to make it learn to shut up

// XML stuff
import simpleML.*;

// Serial stuff
// import the serial library:
import processing.serial.*;

Serial myPort; // the serial port you're using
String tagID = ""; // the string for the tag ID

XMLRequest aberdeen;
XMLRequest aberystwyth;
XMLRequest birmingham;
XMLRequest bristol;
XMLRequest dundee;
XMLRequest leeds;
XMLRequest liverpool;
XMLRequest london;
XMLRequest manchester;
XMLRequest newcastle;
XMLRequest oxford;
XMLRequest reading;



int startTime; //create timer
int counter = 0;


void setup() {
size(200,200);


// list all the serial ports:
println(Serial.list());

// based on the list of serial ports printed from the
// previous command, change the 0 to your port's number:
String portnum = Serial.list()[0];
// initialize the serial port:
myPort = new Serial(this, portnum, 9600);
// incoming string from reader will have 16 bytes:
myPort.buffer(16);

// create a font with the second font available to the system:
PFont myFont = createFont(PFont.list()[2], 24);
textFont(myFont);

//create and start up request

aberdeen = new XMLRequest(this,"http://weather.yahooapis.com/forecastrss?p=UKXX0001&u=c");
aberdeen.makeRequest();

aberystwyth = new XMLRequest(this,"http://weather.yahooapis.com/forecastrss?p=UKXX0203&u=c");
aberystwyth.makeRequest();

birmingham = new XMLRequest(this,"http://weather.yahooapis.com/forecastrss?p=UKXX0018&u=c");
birmingham.makeRequest();

bristol = new XMLRequest(this,"http://weather.yahooapis.com/forecastrss?p=UKXX0025&u=c");
bristol.makeRequest();

dundee = new XMLRequest(this,"http://weather.yahooapis.com/forecastrss?p=UKXX0045&u=c");
dundee.makeRequest();

leeds = new XMLRequest(this,"http://weather.yahooapis.com/forecastrss?p=UKXX0078&u=c");
leeds.makeRequest();

liverpool = new XMLRequest(this,"http://weather.yahooapis.com/forecastrss?p=UKXX0083&u=c");
liverpool.makeRequest();

london = new XMLRequest(this,"http://weather.yahooapis.com/forecastrss?p=UKXX0085&u=c");
london.makeRequest();

manchester = new XMLRequest(this,"http://weather.yahooapis.com/forecastrss?p=UKXX0092&u=c");
manchester.makeRequest();

newcastle = new XMLRequest(this,"http://weather.yahooapis.com/forecastrss?p=UKXX0098&u=c");
newcastle.makeRequest();

oxford = new XMLRequest(this,"http://weather.yahooapis.com/forecastrss?p=UKXX0106&u=c");
oxford.makeRequest();

reading = new XMLRequest(this,"http://weather.yahooapis.com/forecastrss?p=UKXX0117&u=c");
reading.makeRequest();
startTime = millis();//more timer stuff



}

void serialEvent(Serial myPort) {
// get the serial input buffer in a string:
String inputString = myPort.readString();
// filter out the tag ID from the string:
tagID = parseString(inputString);
}

String parseString(String thisString) {
String tagString = ""; // string to put the tag ID into

// first character of the input:
char firstChar = thisString.charAt(0);
// last character of the input:
char lastChar = thisString.charAt(thisString.length() -1);

// if the first char is STX (0x02) and the last char
// is ETX (0x03), then put the next ten bytes
// into the tag string:

if ((firstChar == 0x02) && (lastChar == 0x03)) {
tagString = thisString.substring(1, 11);



}
return tagString;
}

void draw() {
background(0);

//every 5 seconds, make new request
int now = millis();

if (now - startTime > 5000) {
aberdeen.makeRequest();
println("1");
}

if (now - startTime > 5000) {
aberystwyth.makeRequest();
println("2");
}

if (now - startTime > 5000) {
birmingham.makeRequest();
println("3");
}

if (now - startTime > 5000) {
bristol.makeRequest();
println("4");
}

if (now - startTime > 5000) {
dundee.makeRequest();
println("5");
}

if (now - startTime > 5000) {
leeds.makeRequest();
println("6");
}

if (now - startTime > 5000) {
liverpool.makeRequest();
println("7");
}

if (now - startTime > 5001) {
london.makeRequest();
println("8");
}

if (now - startTime > 5000) {
manchester.makeRequest();
println("9");
}

if (now - startTime > 5000) {
newcastle.makeRequest();
println("10");
}

if (now - startTime > 5000) {
oxford.makeRequest();
println("11");
}

if (now - startTime > 5000) {
reading.makeRequest();
println("12");
startTime = now;
}


}


//when request is complete
void netEvent(XMLRequest ml) {

String city = ml.getElementAttributeText("yweather:location", "city");

String temp = ml.getElementAttributeText("yweather:condition", "temp");


String weather = ml.getElementAttributeText("yweather:condition","text");



while(tagID.equals("2100764B24")) { // PARTLY CLOUDY --------------------------------------

if (weather.equals("Partly Cloudy")) {
println("it is partly cloudy in " + city);
break;
}

if (weather.equals("Partly Cloudy/Windy")) {
println("it is partly cloudy and a bit windy in " + city);
break;
}
else {
println("not a little bit cloudy " + city);
break;
}
}

while(tagID.equals("2100766B22")) { // CLOUDY --------------------------------------

if (weather.equals("Cloudy")) {
println("it's cloudy in " + city);
break;
}

if (weather.equals("Mostly Cloudy")) {
println("it's mostly cloudy in " + city);
break;
}

if (weather.equals("Mostly Cloudy/Windy")) {
println("it's mostly cloudy and a bit windy in " + city);
break;
}
else {
println("it's not cloudy in " + city);
break;
}
}

while(tagID.equals("210076572B")) { // LIGHT RAIN --------------------------------------

if (weather.equals("Light Rain")) {
println("it's raining lightly in " + city);

}

if (weather.equals("Light Rain/Wind")) {
println("it's raining lightly and a bit windy in " + city);
break;
}

if (weather.equals("Light Rain Shower")) {
println("there's a light rain shower in " + city);
break;
}

if (weather.equals("Showers in the Vicinity")) {
println("there's some rain showers near " + city);
break;
}
else {
println("it's not raining lightly in " + city);
break;
}

}

while(tagID.equals("21007643E3")) { // RAIN --------------------------------------

if (weather.equals("Rain")) {
println("it's raining in " + city);
break;
}

if (weather.equals("Rain/Wind")) {
println("it's raining and windy in " + city);
break;
}

if (weather.equals("Few Showers")) {
println("there's rain showers in " + city);
break;
}
else {
println("it's not raining in " + city);
break;
}

}
while(tagID.equals("21007683C0")) { // SUNNY --------------------------------------

if (weather.equals("Sunny")) {
println("it's all nice and sunny in " + city);
break;
}

if (weather.equals("Fair")) {
println("it's nice and fair in " + city);
break;
}

if (weather.equals("Moslty Sunny")) {
println("it's mostly sunny in " + city);
break;
}

else {
println("it's not sunny in " + city);
break;
}

}


}

21.5.09

hurrah.



My USB connector for my RFID reader is here, and I've got it working relatively quickly. My reader is an ID-20, slightly different to the reader in "Making Things Talk", which is an ID-12, but the only difference seems to be the range it will read at (the ID-20 is a little stronger). I've used the example code from Making things talk to get it working in Processing, and I've now been able to give the cards their names!!

Maybe little 21007683C0 will be rain.. I imagine it will be a simple case of replacing the button code I've been working on with the RFID code, and instead of it looking for button presses it will be looking for strings of characters. One thing with the reader is that it can't tell when a card is removed, just when it appears, so any kind of resting state with have to be done with a timer.. if that will work...

10.5.09

from arduino into processing

is not as simple as I first thought it would be. This is for the light sensor I will be using in my final piece.

I've been trying two approaches, the first one getting processing to hijack the serial communication that the lilypad sends to arduino, to see the values the light sensor sends back. This was a bit weird, the values in processing were quite different and didn't make much sense, there didn't seem to be any correlation between the numbers I was seeing and the changes in light.

I've then been looking into firmata, which allows you to program the arduino board from processing itself, but this method recieved even stranger results, this time only printing out 0. It seemed to be receiving a signal from the light sensor but that was only to say that there was no light. I've found someone with a similar problem on the processing forum, so hopefully they'll be able to help me, but it's confusing me at the moment.

8.5.09

weather in twelve cities


//weather for twelve cities!

import simpleML.*;

XMLRequest aberdeen;
XMLRequest aberystwyth;
XMLRequest birmingham;
XMLRequest bristol;
XMLRequest dundee;
XMLRequest leeds;
XMLRequest liverpool;
XMLRequest london;
XMLRequest manchester;
XMLRequest newcastle;
XMLRequest oxford;
XMLRequest reading;



int startTime; //create timer
int counter = 0;


void setup() {
size(200,200);
//create and start up request

aberdeen = new XMLRequest(this,"http://weather.yahooapis.com/forecastrss?p=UKXX0001&u=c");
aberdeen.makeRequest();

aberystwyth = new XMLRequest(this,"http://weather.yahooapis.com/forecastrss?p=UKXX0203&u=c");
aberystwyth.makeRequest();

birmingham = new XMLRequest(this,"http://weather.yahooapis.com/forecastrss?p=UKXX0018&u=c");
birmingham.makeRequest();

bristol = new XMLRequest(this,"http://weather.yahooapis.com/forecastrss?p=UKXX0025&u=c");
bristol.makeRequest();

dundee = new XMLRequest(this,"http://weather.yahooapis.com/forecastrss?p=UKXX0045&u=c");
dundee.makeRequest();

leeds = new XMLRequest(this,"http://weather.yahooapis.com/forecastrss?p=UKXX0078&u=c");
leeds.makeRequest();

liverpool = new XMLRequest(this,"http://weather.yahooapis.com/forecastrss?p=UKXX0083&u=c");
liverpool.makeRequest();

london = new XMLRequest(this,"http://weather.yahooapis.com/forecastrss?p=UKXX0085&u=c");
london.makeRequest();

manchester = new XMLRequest(this,"http://weather.yahooapis.com/forecastrss?p=UKXX0092&u=c");
manchester.makeRequest();

newcastle = new XMLRequest(this,"http://weather.yahooapis.com/forecastrss?p=UKXX0098&u=c");
newcastle.makeRequest();

oxford = new XMLRequest(this,"http://weather.yahooapis.com/forecastrss?p=UKXX0106&u=c");
oxford.makeRequest();

reading = new XMLRequest(this,"http://weather.yahooapis.com/forecastrss?p=UKXX0117&u=c");
reading.makeRequest();
startTime = millis();//more timer stuff



}

void draw() {
background(0);

//every 5 seconds, make new request
int now = millis();

if (now - startTime > 5000) {
aberdeen.makeRequest();
println("1");
}

if (now - startTime > 5000) {
aberystwyth.makeRequest();
println("2");
}

if (now - startTime > 5000) {
birmingham.makeRequest();
println("3");
}

if (now - startTime > 5000) {
bristol.makeRequest();
println("4");
}

if (now - startTime > 5000) {
dundee.makeRequest();
println("5");
}

if (now - startTime > 5000) {
leeds.makeRequest();
println("6");
}

if (now - startTime > 5000) {
liverpool.makeRequest();
println("7");
}

if (now - startTime > 5001) {
london.makeRequest();
println("8");
}

if (now - startTime > 5000) {
manchester.makeRequest();
println("9");
}

if (now - startTime > 5000) {
newcastle.makeRequest();
println("10");
}

if (now - startTime > 5000) {
oxford.makeRequest();
println("11");
}

if (now - startTime > 5000) {
reading.makeRequest();
println("12");
startTime = now;
}


}


//when request is complete
void netEvent(XMLRequest ml) {

String city = ml.getElementAttributeText("yweather:location", "city");

String temp = ml.getElementAttributeText("yweather:condition", "temp");


String weather = ml.getElementAttributeText("yweather:condition","text");


if (weather.equals("Partly Cloudy")) {
println("Partly Cloudy" + city);

}

if (weather.equals("Partly Cloudy/Windy")) {
println("Partly Cloudy/Windy" + city);

}

if (weather.equals("Cloudy")) {
println("cloudy" + city);

}

if (weather.equals("Mostly Cloudy")) {
println("Mostly Cloudy" + city);

}

if (weather.equals("Mostly Cloudy/Windy")) {
println("Mostly Cloudy/Windy" + city);

}

if (weather.equals("Light Rain")) {
println("Light Rain" + city);

}

if (weather.equals("Light Rain/Wind")) {
println("Light Rain/Wind" + city);

}

if (weather.equals("Light Rain Shower")) {
println("Light Rain Shower" + city);
}

if (weather.equals("Rain")) {
println("Rain" + city);
}

if (weather.equals("Rain/Wind")) {
println("Rain/Wind" + city);
}

if (weather.equals("Few Showers")) {
println("Few Showers" + city);
}

if (weather.equals("Showers in the Vicinity")) {
println("Showers in the Vicinity" + city);
}

if (weather.equals("Sunny")) {
println("Sunny" + city);
}

if (weather.equals("Fair")) {
println("Fair" + city);
}

if (weather.equals("Moslty Sunny")) {
println("Mostly Sunny" + city);



}

}


Making progress :D

In the final code it will only refresh the RSS feed every few minutes, at the moment I'm keeping it in seconds so it's easier to see what's going on quickly.

i keep winning

It's rather strange. My ideas work. Here's my latest code, pulls in multiple weather feeds, in this case Leeds and London.


//woooooorks. weather in leeds & london

import simpleML.*;

XMLRequest leeds;
XMLRequest london;

int startTime; //create timer
int counter = 0;


void setup() {
size(200,200);
//create and start up request


leeds = new XMLRequest(this,"http://weather.yahooapis.com/forecastrss?p=UKXX0078&u=c");
leeds.makeRequest();
london = new XMLRequest(this,"http://weather.yahooapis.com/forecastrss?p=UKXX0085&u=c");
london.makeRequest();


startTime = millis();//more timer stuff
}

void draw() {
background(0);

//every 5 seconds, make new request
int now = millis();
if (now - startTime > 5000) {
leeds.makeRequest();
println("fio is epic");
}

if (now - startTime > 5001) {
london.makeRequest();
println("fio is awesome");
startTime = now;
}
}

//when request is complete
void netEvent(XMLRequest ml) {

String temp = ml.getElementAttributeText("yweather:condition", "temp");


String weather = ml.getElementAttributeText("yweather:condition","text");


if (weather.equals("Partly Cloudy")) {
println("Partly Cloudy");

}

if (weather.equals("Light Rain Shower")) {
println("Light Rain Shower");
}



}


Now all I need to do is populate the list with cities and different weather conditions.

7.5.09

even more little big win


//woooooorks.

import simpleML.*;


XMLRequest xmlRequest;

int startTime; //create timer
int counter = 0;


void setup() {
size(200,200);
//create and start up request
xmlRequest = new XMLRequest(this,"http://weather.yahooapis.com/forecastrss?p=UKXX0078&u=c");
xmlRequest.makeRequest();
startTime = millis();//more timer stuff
}

void draw() {
background(0);

//every 5 seconds, make new request
int now = millis();
if (now - startTime > 5000) {
xmlRequest.makeRequest();
println("fio is epic");
startTime = now;
}
}

//when request is complete
void netEvent(XMLRequest ml) {

String temp = ml.getElementAttributeText("yweather:condition", "temp");


String weather = ml.getElementAttributeText("yweather:condition","text");


if (weather.equals("Partly Cloudy")) {
println("Partly Cloudy");

}


}


It tells me that I'm epic, and that the weather in Leeds is Partly Cloudy.

little win

After a morning of trying to break HTML requests into strings and then into individual words, I have decided to abandon the BBC RSS feed and instead go with yahoo's less regularly updated one. Because the XML of the yahoo RSS feed looks like this:



Instead of the state of the weather being addressed in the description tag, almost each attribute of the weather is addressed in it's own little tag. Which makes it a lot easier to work with! It's what mister shiffman used in his script as well, so there's some documentation of how to use it well.

dirty XML

I've decided to look again at mister shiffmans simpleML library again, which I looked at briefly in my twitter top project, and found that not only am I a complete berk for not spotting the re-request HTML/XML command which I wanted so desperately and caused me annoyance when I couldn't figure it out myself, but that although it will save my program looking through the whole document, and therefore speed it up, it might still be not as useful as I'd like.

here's the BBC RSS feed for Leeds at the moment:



here's the bit that I'm interested in:



(Temperature: 9°C (48°F), Wind Direction: SW, Wind Speed: 40mph, Relative Humidity: 66%, Pressure: 987mB, rising, Visibility: Good)

Unfortunately, all the juicy bit I'm interested in is all in the same XML tag, so I can't use simpleML to all it's useful yummyness.

This causes a little problem with the words I'm using in my script. For example, "sunny" and "sunny intervals" both contain the word "sunny" so my script will see "sunny intervals" as "sunny". If that makes sense. The script I'm using at the moment is based on a script I used in my last project:


//pulling in feed of weather in stornoway

String[] tokens; //array
int counter;

void setup() {
size(100, 100);


//load file and split up words
String[] lines = loadStrings("http://news.bbc.co.uk/weather/forecast/373/ObservationsRSS.rss");
String allText = join(lines, " ");
tokens = splitTokens(allText, " ,.?!:;[]-");

}

//so it's now pulling in that sentence and splitting it up.

void draw() {
background(255);
fill(0);

String s = tokens[counter];
counter = (counter +1) % tokens.length;
//look at the words one at a time please



//is the word there?

if (s.equals("sunny")) {
println("sunny");
noLoop(); //DON'T LOOP IT BAHBEE.

}

if (s.equals("white")) {
println("white cloud");
noLoop(); //DON'T LOOP IT BAHBEE.

}

if (s.equals("grey")) {
println("grey cloud");
noLoop(); //DON'T LOOP IT BAHBEE.

}

if (s.equals("light")) {
println("light rain");
noLoop(); //DON'T LOOP IT BAHBEE.

}

if (s.equals("heavy")) {
println("heavy rain");
noLoop(); //DON'T LOOP IT BAHBEE.

}

if (s.equals("clear")) {
println("clear sky (night)");
noLoop(); //DON'T LOOP IT BAHBEE.

}

}


Now i just need to simpleML it up.

5.3.09

i have a vibrating tiger



YEAH.

he's a bit slow though. there seems to be a bit of a delay.

it works by the webcam looking out for something bright orange, and when it sees Terry's glorious orangeness, it sends a signal to the wiimote telling it to vibe. the wiimote is in a little pouch inside Terry.

26.2.09

wii remote

As previously mentioned i have nicked one of my misters wii remotes to play around with. I want to at least research all the different kinds of possible interactions i can get between people, objects, and the floor.

I've got darwiinmote ORC, and i've got the wiimote chatting to the pooter:


That graph alone amuses me.

i'm also going to be looking at what other people have got working. Here's some wiiball:


and here's some wiipaint:


and some more drawing-ish goodness:

25.2.09

it's all coming together

in a way.

I've used everything i've learnt about processing in the past few months to make this code. It imports text from a document (will be replaced with a RSS feed later), splits it into words and looks for a keyword. It also tracks the reddest pixel from a video feed. Once it finds the keyword (in this case, sunny) it looks for the reddest pixel and plonks a big bright sun on the screen.


yes, i'm watching scrubs.

here's the code:


//mushing lasts projects code into this projects colour recognition code to create a program that
//tells you whether it's sunny or not when it sees red.
//background turns yellow

import processing.video.*;
import processing.candy.*;
import processing.xml.*;

Capture video;
SVG yellowsun;

color trackColor;

String[] tokens; //array
int counter;

void setup() {
size(640,480);
video = new Capture(this,width,height,15);
// Start off tracking for red
trackColor = color(255,0,0);

smooth();
yellowsun = new SVG(this, "yellowsun.svg");

String[] lines = loadStrings("feed.txt");
String allText = join(lines, " ");
tokens = splitTokens(allText, " ,.?!:;[]-");
}

void draw() {

if (video.available()) {
video.read();
}

String s = tokens[counter];
counter = (counter +1) % tokens.length;

video.loadPixels();
image(video,0,0);

float worldRecord = 500;

int closestX = 0;
int closestY = 0;

for (int x = 0; x < video.width; x ++ ) {
for (int y = 0; y < video.height; y ++ ) {
int loc = x + y*video.width;
// What is current color
color currentColor = video.pixels[loc];
float r1 = red(currentColor);
float g1 = green(currentColor);
float b1 = blue(currentColor);
float r2 = red(trackColor);
float g2 = green(trackColor);
float b2 = blue(trackColor);

float d = dist(r1,g1,b1,r2,g2,b2);

if (d < worldRecord) {
worldRecord = d;
closestX = x;
closestY = y;
}
}
}

if (worldRecord < 100) {

fill(trackColor);

if (s.equals("sunny")) {
println("sunny");
yellowsun.draw(closestX-100, closestY-100, 100, 100);

} else {
println("not");
}
}
}

10.2.09

play: part one

i've decided to do a series of blog posts about play, because it's what i'm interested in getting people doing. i'm not that interested in trying to find a boring commercial place for my work, so i'm going to justify it's existence by looking at what cool stuff other people are up to.

And although i've already partially defined what i'm doing (an interactive floor), i want to look into as many different interactions i can make between the users and the floor. This all isn't going to be stuff i can necessarily use in my floor, just stuff i like and think is interesting.



this is japanese based interactive music group type thing called d.v.d, causing a bit of a rukus. this performance is called 'flip', and is a pinball game controlled by their drums. i love the chaos in it.



"An audio generating computer and a second one that generates the visuals exchange signals through LAN using OSC. The tracks are played with max/msp. The drum sets are attached with a sensor called trigger and that transmits the vibration of the drums as signals to the midi interface. Those signals are then converted into midi note numbers. That midi data is then sent to the visual PC and creates the actions in the animations generated by processing software." - Jimanica

I want one of these so much it's actually causing me physical pain to watch this video:

tenori-on.
not that i would know what to do with it.

5.2.09

finds big bright red thing right in front of it...

but still seems amazingly clever:



that little red dot is processing going "HEY! that's red!"

Found the code at daniel shiffman's site again. he seems to be the only person in the processing world that tells you how to do things in a simple straightforward way: ie. giving it to you minus the bollocks. YAY.

the lighting in my flat is crap.

30.1.09

brightness / colour tracking in processing

Here i am sitting in the dark waving my phone about:



testing out a brightness tracking script in processing which finds the brightest pixel and puts a huge yellow blob on it. it only seems to work well in the dark, when i tried it out earlier in the day it kept jumping to bright pixels generated by my bright window. might be a bit problematic if i use brightness in my final piece, it'd have to be pretty dark to work.

Whilst researching the BlobDetection library i found puppet show a processing / unreal programmage that uses colour recognition to control a character in an unreal environment.


(you can tell they're cool, they play guitar hero)

here's a video of it in action and how it works:



I'm hoping after some rooting around in their code i'll get colour recognition working.

12.12.08

the final thing



this is what it looks like, and that's what it all means.

final processing code:


//finds a word, sends a signal to the lilypad then stops the loop.

import processing.serial.*;

Serial port;

String[] tokens; //array
int counter;

void setup() {
size(100, 100);

println(Serial.list());
port = new Serial(this,Serial.list()[0], 9600);

//load file and split up words
String[] lines = loadStrings("http://twitter.com/fiowantscoffee");
String allText = join(lines, " ");
tokens = splitTokens(allText, " ,.?!:;[]-");

}

//so it's now pulling in that sentence and splitting it up.

void draw() {
background(255);
fill(0);

String s = tokens[counter];
counter = (counter +1) % tokens.length;
//look at the words one at a time please



// mood uno: cuppa -------------------------------------------------------------------------------


if (s.equals("coffee")) {
println("coffee");
port.write('A');
noLoop(); //DON'T LOOP IT BAHBEE.
}




// mood zwei: love -------------------------------------------------------------------------------

if (s.equals("love")) {
println("love");
port.write('B');
noLoop(); //DON'T LOOP IT BAHBEE.
}


// mood tres: sex -------------------------------------------------------------------------------

if (s.equals("sex")) {
println("sex");
port.write('C');
noLoop(); //DON'T LOOP IT BAHBEE.
}



// mood funf: fail -------------------------------------------------------------------------------

if (s.equals("fail")) {
println("fail");
port.write('D');
noLoop(); //DON'T LOOP IT BAHBEE.
}


// mood six: internet -------------------------------------------------------------------------------



if (s.equals("internet")) {
println("internet");
port.write('E');
noLoop(); //DON'T LOOP IT BAHBEE.
}


// mood seiben: twitter -------------------------------------------------------------------------------


if (s.equals("tweet")) {
println("tweet");
port.write('F');
noLoop(); //DON'T LOOP IT BAHBEE.
}




// mood acht: geeking out -------------------------------------------------------------------------------

if (s.equals("geek")) {
println("geek");
port.write('H');
noLoop(); //DON'T LOOP IT BAHBEE.
}

}


final arduino code:


//getting it to keep one light lit up

int timer = 10000000; // The higher the number, the slower the timing.




// geeking
int geek[] = { 3, 4 };

// fail
int fail[] = { 5, 6 };


//internet
int net[] = { 7, 8 };


//twitter
int twitter[] = { 9, 10 };

// cuppa
int drink[] = { 11, 12,};

// sex
int sex[] = { 13, 14 };

// love
int loves[] = { 15, 16 };







int num_pins = 18; // the number of pins (i.e. the length of the array)
int val;

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

int i;

for (i = 0; i < num_pins; i++) // the array elements are numbered from 0 to num_pins - 1

pinMode(drink[i], OUTPUT);


pinMode(loves[i], OUTPUT);


pinMode(sex[i], OUTPUT);


pinMode(fail[i], OUTPUT);


pinMode(net[i], OUTPUT);


pinMode(twitter[i], OUTPUT);



pinMode(geek[i], OUTPUT);





}

void loop()
{
int i;

if (Serial.available()) {
val = Serial.read();

//cuppa --------------------------------------------------------------------------


if (val == 'A') {
digitalWrite(drink[i], HIGH);
}
else {
digitalWrite(drink[i], LOW);
}



//love --------------------------------------------------------------------------

if (val == 'B') {
digitalWrite(loves[i], HIGH);
}
else {
digitalWrite(loves[i], LOW);
}


//sex --------------------------------------------------------------------------

if (val == 'C') {
digitalWrite(sex[i], HIGH);
}
else {
digitalWrite(sex[i], LOW);
}

//fail --------------------------------------------------------------------------



if (val == 'D') {
digitalWrite(fail[i], HIGH);
}
else {
digitalWrite(fail[i], LOW);
}


//internet----------------------------



if (val == 'E') {
digitalWrite(net[i], HIGH);
}
else {
digitalWrite(net[i], LOW);
}


//twitter --------------------------------------------------------------------------




if (val == 'F') {
digitalWrite(twitter[i], HIGH);
}
else {
digitalWrite(twitter[i], LOW);
}





//geeking out --------------------------------------------------------------------------



if (val == 'H') {
digitalWrite(geek[i], HIGH);
}
else {
digitalWrite(geek[i], LOW);
}


}


}


that's all a lot shorter than i wanted it to be, but oh well.

22.11.08

think i should explain it really...

my boobs lighting up actually has a communicative purpose.

each LED shows when a certain word is found in this twitter feed.



and here's the code controlling it all:

arduino code:


//getting it to keep one light lit up

int timer = 10000000; // The higher the number, the slower the timing.
int happy[] = { 5, 6,}; // an array of pin numbers
int sad[] = { 7, 8 };
int meh[] = { 9, 10 };
int love[] = { 11, 12 };
int fuming[] = { 13, 14 };
int num_pins = 10; // the number of pins (i.e. the length of the array)
int val;

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

int i;

for (i = 0; i < num_pins; i++) // the array elements are numbered from 0 to num_pins - 1
pinMode(happy[i], OUTPUT); // set each pin as an output
pinMode(sad[i], OUTPUT);
pinMode(meh[i], OUTPUT);
pinMode(love[i], OUTPUT);
pinMode(fuming[i], OUTPUT);
}

void loop()
{
int i;

if (Serial.available()) {
val = Serial.read();
if (val == 'A') {
digitalWrite(happy[i], HIGH);
}
else {
digitalWrite(happy[i], LOW);
}


if (val == 'B') {
digitalWrite(sad[i], HIGH);
}
else {
digitalWrite(sad[i], LOW);
}

if (val == 'C') {
digitalWrite(meh[i], HIGH);
}
else {
digitalWrite(meh[i], LOW);
}

if (val == 'D') {
digitalWrite(love[i], HIGH);
}
else {
digitalWrite(love[i], LOW);
}

if (val == 'E') {
digitalWrite(fuming[i], HIGH);
}
else {
digitalWrite(fuming[i], LOW);
}
}


}


and the processing code:


//finds a word, sends a signal to the lilypad then stops the loop.

import processing.serial.*;

Serial port;

String[] tokens; //array
int counter;

void setup() {
size(100, 100);

println(Serial.list());
port = new Serial(this,Serial.list()[0], 9600);

//load file and split up words
String[] lines = loadStrings("http://twitter.com/allemotional");
String allText = join(lines, " ");
tokens = splitTokens(allText, " ,.?!:;[]-");

}

//so it's now pulling in that sentence and splitting it up.

void draw() {
background(255);
fill(0);

String s = tokens[counter];
counter = (counter +1) % tokens.length;
//look at the words one at a time please



//is the word there?
if (s.equals("happy")) {
println("happy");
port.write('A');
noLoop(); //DON'T LOOP IT BAHBEE.


}

if (s.equals("sad")) {
println("sad");
port.write('B');
noLoop(); //DON'T LOOP IT BAHBEE.

}

if (s.equals("meh")) {
println("meh");
port.write('C');
noLoop(); //DON'T LOOP IT BAHBEE.

}

if (s.equals("love")) {
println("love");
port.write('D');
noLoop(); //DON'T LOOP IT BAHBEE.

}

if (s.equals("fuming")) {
println("fuming");
port.write('E');
noLoop(); //DON'T LOOP IT BAHBEE.

}

}


i need to think more about the words that i'm looking for, they really need to reflect what people say in twitter.

20.11.08

my boobs light up!

sheer awesome.



the mister approves.

this is what fail looks like.

trying to sign my processing app in terminal and failing miserably.

following this tutorial.



obviously i've blocked out my name and password because i don't want any of you hacking my mac, but that's what i'm trying to get working. but it wont. i don't know why.

why didn't i just do animation?