Friday, May 4, 2007

Lights, camera, action

Sleep deprived and setting up lights for the video... less than 24 hours to go!



Thursday, May 3, 2007

Wednesday, May 2, 2007

Tuesday, May 1, 2007

Scowling, hard at work

Holy crap! Where'd the time go? Where'd my hair go for that matter?

Monday, April 30, 2007

Probability

Here is the beginning of adding some nuance to my code, rather than just using constant numbers or randoms. I'm working in some probabilities to modulate the motion so that it has a more organic feel.

This function is a loop that slowly moves my cables up and down. Without the probability in the foreloop, the motion looks very machine-like and repetitive. With the addition of the probability, the movement is more fluid. Much more refinement is needed, and I hope to add this sort of logic into other places in my code.

void HoldServo(){

for (int m = 0; m < servo_num; m ++) {
randomNum = random(0,11);
if(randomNum < 1){
speed = 40;
}
else if(randomNum < 9){
speed = 10;
}
else{
speed = 1;
}

rArray[m] = speed;
pulseH[m] = pulseH[m] - (rArray[m] * UorD[m]);

if (millis() - lastPulse[m] >= refreshTime) { // pulse the servo again if the
// refresh time (20 ms) have
// passed:

digitalWrite((2*(m+1)), HIGH); // Turn each motor on, tricky math
// to skip pins, ie 2,4,6,8
delayMicroseconds(pulseH[m]); // Length of the pulse sets the
// motor position
digitalWrite((2*(m+1)), LOW); // Turn the motors off
lastPulse[m] = millis(); // save the time of the last pulse
}

if (pulseH[m] < 1600){ // if it gets too low, flip it so it
UorD[m] = -1; // heads back up
}
else if(pulseH[m] > 2400){ // if it gets too high,flip it so it
UorD[m] = 1; // heads back down
}
}
}

Friday, April 27, 2007

Radio, radio

I feel like I've made great strides in my code. Everything seems to be working with the units talking and listening to each other.

Setting up the radios was a little bit challenging but thanks to the help of Jeff LeBlanc, I got things going. He convinced me to simplify the type of data I was sending, and to forgo sending characters and strings and stick with straight bytes. This made it a lot easier, especially when combined with the packet structure provided by Rob Faludi (a big thanks to him as well.)

My protocol contains 4 bytes, the first being a header, the second being the unit ID number, the third the unit's state, and the fourth an end byte. Given that I'm using the broadcast mode, this protocol makes it easy for each radio to look only for messages intended for it.

When a unit receives a message, it:
1) looks to see if it has the header, if it does it knows it's at the start of a message, and continues reading
2) looks for the unit ID number, if it's from a unit it wants to hear from, it
3) looks for a change in state, causing a reaction in its own state.


Here is the send code: super simple.

void sendData() { // listen to the potentiometer:

// if there's something to send, send it:
//light the tx LED to say you're sending:
digitalWrite(txLed, HIGH); //green LED

Serial.print(255, BYTE); // header byte
Serial.print(1,BYTE); // unit ID number
Serial.print(myState,BYTE); // sends a 1, as this function only runs when
// myState == 1
Serial.print(254,BYTE); // end byte


// turn off the tx LED:
digitalWrite(txLed, LOW); //greenLED

}

Receive code:

void ReadIncoming(){
// listen for incoming serial data:
if (Serial.available() > 3)
{
incomingByte = Serial.read();
if(incomingByte == 255)
{
digitalWrite(rxLed, HIGH); // Yellow LED turn on the RX LED whenever
// you're reading data:
id = Serial.read();
state = Serial.read();
end = Serial.read();
if (id == 2){
digitalWrite(idLED, HIGH); // do we have the right ID?, if so IDLED pin 9
// RED on

if (state == 1){ // is that unit active ?
myState = 2;
}
else {
myState = 0;
}
}
}
else {
// turn off the receive LED when there's no incoming data:
digitalWrite(rxLed, LOW); // yellow LED off
digitalWrite(idLED, LOW); // we don't have the right ID, so IDLED pin 9
// RED off
}
}
}

Round 3

The new and improved prototype went together pretty well—one little snafu with my lasercut file but it was easily solved. In the future I vow to print my CAD files out on paper and cut them out and see how they go together before I commit to cutting plex. It was kind of a shame to have to slice the finger joints that did not join.

Assembly was kind of a pain as it was hard to keep the cables tensioned into the wheels while attaching the wheels to the servo motors. I should have taken this as a bad sign for once the unit was together, I had a lot of problems with the cables staying in the track, and also snaking out of the bottom side of the wheel.

On this prototype I used a hard plastic tube as the cable housing (it creates the 90° transition.) I had suspected that the rubber tubing was too flexible and may have been causing the problems with the cable wrapping on the wheel, and the backside snaking. However this new material was hardly the solution as I continue to have the same issues, in addition to excess noise. I much prefer the quieter rubber tubing, and am planning to return to it for the final project.

Thursday, March 29, 2007

Round 2

Here is the latest functioning prototype, I have a pair working, and am in the process of refining them. They are responding really well, but can use a few tweaks. One thing that's a problem is that the cable jumps out of the track, which prevents it from being pushed out or pulled in. The cable has become fatigued from repeatedly jumping the track while the wheel continues to revolve, resulting in a kink in the cable. This kink causes the problem to occur more often. The other modifications I want to make will allow me to assemble the modules more easily, and to remove the wheel from the bottom.





Video of it in action:


Large format 16.5MB


Medium format 6.5MB


Small format 2MB

Prototypes







Here are some photos of the first round of prototypes. The most promising is on top.

It will have to wait

I was planning on redoing my website and posting my thesis project there, but I recently have come to the realization that with everything I'm working on, the official site will have to wait.

In the meantime, I'll post here.

As an introduction, here's the abstract from my thesis:

Cousteau is a kinetic interactive sculpture, a meditation on the intersection of Nature and Technology. The sculpture’s form is inspired by aquatic life and movements: sea grass swaying in the ocean, the undulating motion of currents, and the hide-and-seek of some sea creatures. The project grew out of my interests in oceanography and design, and the way that we as humans anthropomorphize in order to relate to technology. Cousteau synthesizes these ideas by using simple movements to suggest that technology might possess its own life force; through an array of sensors, the sculpture monitors its surroundings, reacting to ambient activity, and a user’s proximity.

The project is a collection of modules, where each unit acts independently yet still communicates with others. Each module consists of an array of “eels” which grow upward from the base, creating a dynamic field. The “eels” bob back and forth as well as up and down depending on the inputs received from the sensors. For instance, if a user startles Cousteau, the “eels” will seek safety by retracting into the base. Alternatively, if a user waves his hand over a portion of Cousteau, the “eels” may emerge to investigate. Stimulating one module might provoke a neighboring or a remote one to react as well, as if seeking attention or expressing neglect. Cousteau’s animation is contingent upon multiple factors such as noise levels, distance readings and especially frequency of stimuli. Using multiple inputs this way will keep the interaction interesting and ever-evolving, adding a higher degree of unique experiences.