Tuesday, November 30, 2010

code for slave arduinos

#include <Wire.h>
#define ADDRESS 65

// these are digital pins (leds)
int led[]={2,3,4,5,6,7,8,9,10,11,12,13,14,15,16};

// these are analog pins (photoresistors and pir)
int photo[] = {0,1,2,3,4,5,6,7,8,9,10,11,12,13,14};
int ambient = 15; // this is used for the comparison of each photoresistor
int light[15];

void setup() {      

  Serial.begin(9600);
  Wire.begin(ADDRESS);
  Wire.onReceive(receiveEvent);
 
  for(int i = 0; i< 15; i++){
    pinMode(led[i],OUTPUT);
  }

  for(int i = 0; i< 15; i++){
    pinMode(photo[i],INPUT);
  }

  pinMode(ambient, INPUT);
  
}


void loop() {
}

void receiveEvent(int val){

while (Wire.available() > 0){
val = Wire.receive();
int compare = analogRead(ambient);
Serial.println(val);

for(int i = 0; i< 15; i++){
 light[i] = analogRead(photo[i]);
}

if (val == 111){

  int delayTime = 250; //the time (in milliseconds) to pause between LEDs
                       //make smaller for quicker switching and larger for slower
 
  for(int i = 0; i < 15; i++){
    int offLED = i - 1;  //Calculate which LED was turned on last time through
    if(i == 0) {         //for i = 1 to 7 this is i minus 1 (i.e. if i = 2 we will
      offLED = 15;        //turn on LED 2 and off LED 1)
    }                    //however if i = 0 we don't want to turn of led -1 (doesn't exist)
                         //instead we turn off LED 7, (looping around)
    digitalWrite(led[i], HIGH);     //turn on LED #i
    digitalWrite(led[offLED], LOW); //turn off the LED we turned on last time
    delay(delayTime);
}
}
else if( val != 0){

// for the control of leds----------------------------------
for(int i = 0; i< 15; i++){
 
   if (light[i] > compare + 10){
      digitalWrite(led[i], HIGH);
   }
  
   else {
   digitalWrite(led[i], LOW);
   }
  
}
}

else if (val == 0){
  for (int i = 0; i< 15; i++){
    digitalWrite(led[i], LOW);
  }
}
}
}

code for master arduino

#include <Wire.h>
int ADDRESS[] = {65,42,43,60,61,62,64,65};

// these are digital pins (leds)
int led[]={2,3,4,5,6,7,8,9,10,11,12,13};

// these are analog pins (photoresistors and pir)
int photo[] = {0,1,2,3,4,5,6,7,8,9,10,11};
int ambient = 15; // this is used for the comparison of each photoresistor
int motion = 14; // pir sensor digital
int motion2 = 13; // second pir sensor
int sound = 12;

int light[12];

void setup() {      

  Serial.begin(9600);
  Wire.begin();
 
  for(int i = 0; i< 12; i++){
    pinMode(led[i],OUTPUT);
  }

  for(int i = 0; i< 12; i++){
    pinMode(photo[i],INPUT);
  }

  pinMode(ambient, INPUT);
  pinMode(motion, INPUT);
  pinMode(motion2, INPUT);
  
}


void loop() {

int compare = analogRead(ambient);
int val = analogRead(motion);
int val2 = analogRead(motion2);
int noise = analogRead(sound);
Serial.print(val);
Serial.print(' ');
Serial.print(val2);
Serial.print(' ');
Serial.println(noise);

for(int i = 0; i< 12; i++){
 light[i] = analogRead(photo[i]);
}

int i= 0;
while( i < 8){
 
//Serial.println("val");
int value = ADDRESS[i];
Wire.beginTransmission(value);
//Serial.println(i);
if( val >= val2){
Wire.send(val);
}
else{
  Wire.send(val2);
}
Wire.endTransmission();
i++;
}


if (noise >= 10){
 
  int delayTime = 50; //the time (in milliseconds) to pause between LEDs
                       //make smaller for quicker switching and larger for slower
 
  for(int i = 0; i <= 12; i++){
    int offLED = i - 1;  //Calculate which LED was turned on last time through
    if(i == 0) {         //for i = 1 to 7 this is i minus 1 (i.e. if i = 2 we will
      offLED = 12;        //turn on LED 2 and off LED 1)
    }                    //however if i = 0 we don't want to turn of led -1 (doesn't exist)
                         //instead we turn off LED 7, (looping around)
    digitalWrite(led[i], HIGH);     //turn on LED #i
    digitalWrite(led[offLED], LOW); //turn off the LED we turned on last time
    delay(delayTime);
  }
 
  int i = 0;
  while (i< 8){
  Wire.beginTransmission(ADDRESS[i]);
  int number = 111;
  Wire.send(number);
  Wire.endTransmission();
  delay(150);
  i++;
  }

}


if( val != 0 || val2 != 0){
// for the control of leds----------------------------------
for(int i = 0; i< 12; i++){
 
   if (light[i] > compare + 10){
      digitalWrite(led[i], HIGH);
   }
  
   else {
   digitalWrite(led[i], LOW);
   }
  
}
}

else if (val == 0 && val2 == 0){
  for(int i = 0; i<12; i++){
    digitalWrite(led[i], LOW);
  }
}
}

Friday, November 26, 2010

electromagnets...

So far, the only successful electromagnets that we managed to make were out of transformer coils. Unfortunately we only have enough supplies to make ten for the final project so we spent the majority of the week experimenting with different forms of electromagnets. We finally acquired some enameled wire which greatly helped the process along. Ekta managed to wrap a magnet that caused the ferrofluid to spike:



 

I also tried to make electromagnets that used the ferrofluid as a core so we wouldn't have to worry about sealing the box they are in. These magnets, as seen below, do not spike but form a small bump of ferrofluid. 





The final form of our project will contain magnets which spike (made the same way Ekta made her's). We found a better way to seal the magnets into the acrylic using epoxy clay which passed both water and ferrofluid leak tests which we ran for several consecutive days.

3 boxes

We decided that our final project would be composed of three modules; each responding to either light, sound, or touch. The form was three meter wide vertical boxes, with a viewing window 54" off the ground and extending 18 inches up. One of the boxes was presented in class and was not well received, causing us to reconsider the final form of our project. I wrote and tested programs for all three responses so if we proceed with any of them the coding will be at least partially done.

working module


The requirement for this week was to have a working module of our final project to present. Since we switched our project the previous week we had to come up with a project and get it working in a relatively short amount of time. We presented an array of extended core electromagnets which were turned on in response to changes in light. The magnets were made with lag bolts and the enameled wire coils that were taken out of transformers. Each magnet was paired with a photoresistor and turned on when a shadow was over it. This is a view from the bottom of our module showing the electromagnets and relays:

This is a side view of the fully assembled module with the ferrofluid in it. The spikes are the threads of the lag bolts which were used as the core of the electromagnets.


A spiral of ferrofluid formed by turning on one of the electromagnets:


We had a small problem with leaking ferrofluid since the heat produced by the electromagnet heated the silicone seals we used. We plan on finding a more reliable sealant for the final and using drip pans as backup.


Saturday, November 6, 2010

Movement mechanisms and a new project

It was decided that we needed to further explore movement mechanisms so for the weekend we split up into pairs and each prototyped mechanisms that seemed viable on paper. Unfortunately, paper doesn't always translate well into real life if you don't take the time to work out the mechanics of the system. Here is what resulted (plus one more gear mechanism which is not shown):




Since none of these worked very well, the majority of the group wanted to give up on this project and pursue something which is mechanistically easier and has a higher chance of working well. Now we are making a table which contains ferrofluid which is activated by electromagnets.

Week 6

We received our final 6 week project and were required to make a biomimetic smart surface. The assignment is very open ended which made it difficult to come up with a project as we could take the assignment and our three thousand dollars and go in whichever direction we choose. Our group had several meetings where we each presented our ideas of what direction the project could take. As a result, we came up with a list:

  • sphere that responds to stimuli
  • sea cucumber inspired surface
  • boxes that for furniture
  • collection of surfaces that mimic a shoal of fish
  • blimps that hover by a light 
  • spider web of fiber-optics
  • device that moves on the ground and interacts with people
  • surface that falls apart and rebuilds
  • plants that move toward water
  • fancy coffee maker
  • seeded paper
  • wall of stacked shapes that makes sound
  • anemone surface
  • wall covering that shrinks and expands
Through a series of long discussions it was narrowed down to the collection of surfaces that mimics a shoal of fish and the wall of stacked shapes that make sound. We discussed each project further, took a break for the night, and resumed the next day to make a decision. After much compromise in the form, it was decided that we would go with the collection of surfaces that moved similar to a shoal of fish on a window. There was the possibility of them being autonomous so we decided to explore mechanisms for movement on a track and independently on a grid or mesh which would be placed over the window. Unfortunately, the majority of the mechanisms were never prototyped and we just discussed them on paper resulting in the presentation of only one (wheels on a pipe) presented in class. 


Tuesday, October 19, 2010

Week 5

After the critique of our week 4 solar tracker we decided to focus more on the 2-axis tracker itself and not its application. This resulted in a redesign of the solar tracking mechanism with inspiration coming from the eye. As light enters the eye, it is concentrated to a point where it comes into contact with the retina. The biomimicry aspect of our device comes from how the solar tracker receives the signal to move. Similar to an eye, the light comes through a pinhole and contacts the sensor array (similar to rods and cones in a eye). The light is then read as a number and the device responds by moving towards it. 


 The device consists of a sphere (the eye) fixed at two points to a turntable so it can rotate freely. An arc of pegs (the mohawk) is attached to the bottom of the sphere and meshes with a gear (powered by a servo) that rotates the eye. The image below shows the preliminary sketches for the movement mechanism of our solar tracker.The gear/mohawk mechanism is then attached to another servo that allows the whole eye to rotate on the xy plane by moving  the turntable. The second image is a photograph of one of the joints connecting the turntable and the xy plane servo. The slit in the bar allows the system to adjust in height small amounts to prevent the servo from lifting the lid off the device. 

Below is a video of the partially constructed device that allows you to see the movement on both the xy and yz planes. 


This is an image of our fully functional two-axis solar tracking device. When the pin hole has oriented with a light source, the green led indicator light comes on  and is visible through the front of the acrylic case. 


This is the code used for operating the servos to track a light source. It is very similar to the one used last week but with the light values mapped to 1050 to account for one of the photoresistors being a different type and reading a much higher value.



#include <Servo.h>

Servo zyplane; //servo attached to the base servo rotates on the zy plane (around x axis)
Servo xyplane;
int pos = 90;
int pos2 = 90;

//PhotoResistors (these are all analog pins)
int photo1 = 0; 
int photo2 = 1;
int photo3 = 2;
int photo4 = 3;
int photo5 = 4;

//alignment indicator LED (this is a digital PWM pin)
int ledPin = 5;  

void setup()
{
  pinMode(ledPin, OUTPUT); //sets the led pin to output
  pinMode(photo1, INPUT);
  pinMode(photo2, INPUT);
  pinMode(photo3, INPUT);
  pinMode(photo4, INPUT);
  pinMode(photo5, INPUT);

  zyplane.attach(10);// attach the pin 10 servo to servo object
  xyplane.attach(9);
  Serial.begin(9600); // use the serial port
}

void loop()
{
 //--------------------gives a value for each photoresistor------------------------------
 int light1 = analogRead(photo1); //Read the lightlevel
 light1 = map(light1, 0, 900, 0, 1050); //adjust the value 0 to 900 to span 0 to 1050
 light1 = constrain(light1, 0, 1050);//make sure the value is between 0 and 1050
  
 int light2 = analogRead(photo2); //Read the lightlevel
 light2 = map(light2, 0, 900, 0, 1050); //adjust the value 0 to 900 to span 0 to 1050
 light2 = constrain(light2, 0, 1050);//make sure the value is between 0 and 1050


 int light3 = analogRead(photo3); //Read the lightlevel

 Serial.println(light3);

 int light4 = analogRead(photo4); //Read the lightlevel
 light4 = map(light4, 0, 900, 0, 1050); //adjust the value 0 to 900 to span 0 to 1050
 light4 = constrain(light4, 0, 1050);//make sure the value is between 0 and 255


 int light5 = analogRead(photo5); //Read the lightlevel
 light5 = map(light5, 0, 900, 0, 1050); //adjust the value 0 to 900 to span 0 to 1050
 light5 = constrain(light5, 0, 1050);//make sure the value is between 0 and 1050



//----------------------------------operates xyplane servo---------------------------------//

  if (light1>light3 && light1>light5  && light1>light4  && light1>light2 && pos!=180 ){
      xyplane.write(pos);
  delay(100);
  pos ++;
  }
    
  if (light3>light1 && light3>light5  && light3>light4  && light3>light2 && pos!= 0  ){
      xyplane.write(pos);
  delay(100);
  pos --;
}
//-------------------------------operates zyplane servo----------------------------------------
   //zyplane.attach(10);// attach the pin 10 servo to servo object
  
  if (light2>light4 && light2>light5  && light2>light3  && light2>light1 && pos2!=180 ){ 
  zyplane.write(pos2);
  delay(100);
  pos2 --;
  }
  
  if(light4>light2 && light4>light5  && light4>light1  && light4>light3 && pos2 != 0){
  zyplane.write(pos2); //goes to the position
  delay(100); //this gives the servo time to move
  pos2 ++;
}



//---------------------------operates LED alignment indicator--------------------------------------

 if (light5>light1 && light5>light2 && light5>light3 && light5>light4){

  digitalWrite(ledPin, HIGH);
 }
  else{ 
    digitalWrite(ledPin, LOW);
    
  }





Friday, October 8, 2010

Week 4

The requirements for this week were to create a 2 axis solar tracking biomimetic surface. The design that our group came up with was inspired by the window plant and an eye. The window plant has a relatively flat surface that focuses the light to a central column of oxylic acid where it is channeled downward (similar to fiber optics) to the base of the plant where photosynthesis takes place.


(http://www.asknature.org/strategy/6eb4107cbcdde41d35818191b29f60f5)

The eye works by acting as a spherical lens that focuses light to a single point. Our proposed design consisted of a hemispherical glass dome, which acts as a lens, that focuses light to a point where a solar panel would be placed. This allows for a higher efficiency solar panel to be used since the light would be concentrated. The solar panel would be located just past the center of the sphere as the focal point of a spherical lens is  approximately equal to the radius.  As the sun moves through the sky there will be a small variance in the position of the focus point (it moves over an arc throughout the day) so the solar panel would be located on a solar tracking device to optimize the alignment with the sun. This would be achieved by placing an array of photo resistors under a pinhole in the solar panel. The solar cell would then move in the direction of the light until the central photo resistor receives the most light, at which point the photovoltaic would be aligned and the movement would stop. 


Solar Tracking Code:


#include <Servo.h>
Servo xyplane; //base servo that rotates on the xy plane(around z axis)
int pos = 0;

Servo zyplane; //servo attached to the base servo rotates on the zy plane (around x axis)
int pos2 = 0;


//PhotoResistors (these are all analog pins)
int photo1 = 0;
int photo2 = 1;
int photo3 = 2;
int photo4 = 3;
int photo5 = 4;

//alignment indicator LED (this is a digital PWM pin)
int ledPin = 5;

void setup()
{
  pinMode(ledPin, OUTPUT); //sets the led pin to output
  pinMode(photo1, INPUT);
  pinMode(photo2, INPUT);
  pinMode(photo3, INPUT);
  pinMode(photo4, INPUT);
  pinMode(photo5, INPUT);
  xyplane.attach(9); // attach the pin 9 servo to servo object
  zyplane.attach(10);// attach the pin 10 servo to servo object
}

void loop()
{
 //--------------------gives a value for each photoresistor------------------------------
 int light1 = analogRead(photo1); //Read the lightlevel
 light1 = map(light1, 0, 900, 0, 255); //adjust the value 0 to 900 to span 0 to 255
light1 = constrain(light1, 0, 255);//make sure the value is between 0 and 255


 int light2 = analogRead(photo2); //Read the lightlevel
 light2 = map(light2, 0, 900, 0, 255); //adjust the value 0 to 900 to span 0 to 255
 light2 = constrain(light2, 0, 255);//make sure the value is between 0 and 255


 int light3 = analogRead(photo3); //Read the lightlevel
 light3 = map(light2, 0, 900, 0, 255); //adjust the value 0 to 900 to span 0 to 255
light3 = constrain(light3, 0, 255);//make sure the value is between 0 and 255


 int light4 = analogRead(photo4); //Read the lightlevel
 light4 = map(light4, 0, 900, 0, 255); //adjust the value 0 to 900 to span 0 to 255
 light4 = constrain(light4, 0, 255);//make sure the value is between 0 and 255


 int light5 = analogRead(photo5); //Read the lightlevel
 light5 = map(light5, 0, 900, 0, 255); //adjust the value 0 to 900 to span 0 to 255
 light5 = constrain(light5, 0, 255);//make sure the value is between 0 and 255


//----------------------------------operates xyplane servo---------------------------------//

while ( light5<light1 || light5<light3){

  if (light1>light3 && light1>light5){
  xyplane.write(pos);
  delay(30);
  pos ++;

  }

  if (light3>light1 && light3>light5){
    xyplane.write(pos);  //goes to the position
  delay(30); //this gives the servo time to move
  pos --;
}
light5= analogRead(photo5);
light1= analogRead(photo1);
light3= analogRead(photo3);
}
//-------------------------------operates zyplane servo----------------------------------------

while (light5<light2 || light5<light4){

  if (light2>light4 && light2>light5){
  zyplane.write(pos2);
  delay(30);
  pos2 ++;
  }

  if(light4>light2 && light4>light5){
  zyplane.write(pos2); //goes to the position
  delay(30); //this gives the servo time to move
  pos2 --;
}
light5= analogRead(photo5);
light4= analogRead(photo4);
light2= analogRead(photo3);
}

//---------------------------operates LED alignment indicator--------------------------------------

 if (light5>light1 && light5>light2 && light5>light3 && light5>light4){
  digitalWrite(ledPin, HIGH);
 }
}

Tuesday, October 5, 2010

Week 3

During the third week of the project our group had to take the acrylic and ping-pong ball model and make it into a functioning structure that was representative of an actual implementation of our design. After the initial criticism of our re-design it was determined that aside from the smartness gained from the plants being automatically watered when needed, the structure should interact with people in some way. The use of LEDs and motion sensors provided this (along with additional aesthetic appeal and an element of delight). In order to better visualize the design, we chose to implement it in the Duderstadt atrium (image below). 


For our model, the atrium was constructed out of acrylic and chipboard with the plant holding spheres represented by ping-pong balls. Red, blue, and green LEDs were incorporated within the ping-pong balls to provide the lighting effects. The blue lights were programmed to turn on and fade off in sequence to look like water flowing downward, the green lights lit and faded randomly, and the red lights respond to motion. All three LED sets would only come on when it was dark.  As it was difficult to connect the arduinos without the proper i2c, each set of lights and the pump ran on separate arduinos.  Below is an image of the final model as well as an image of  the wiring and arduinos.  




Tuesday, September 28, 2010

Re-design (week 2)

After the critique of our week 1 project, it was clear that we had reached a dead end with our current design. It was a general consensus  that we needed something entirely new that met the criteria (smart surface, holds, optimally packed spheres) but still retained the properties of the last design that we liked (the different interpretation of optimally packed, aesthetically pleasing).  During the reevaluation of our last design  we determined some of the problems with it were:
  • no purpose/practicality
  • no specific location for it's use
  • the design would be difficult to mechanize
  • 'holds'  was interpreted too literally
  • wasn't scalable
  • weak relation to bio mimicry
  • it didn't "do enough" for the complexity of the design
One of the group members pointed out that some of the smartness of the design could come from the way we use the materials, not just force the materials to represent our idea. Acrylic is translucent, watertight and rigid; chipboard is flexible, and opaque. These properties helped us determine what our final design would be. 


Initially, it was purposed that a cluster of plant holding acrylic spheres could be arranged around a light source.  With this design, the plants would get receive light and soften it so it wasn't as bright in the room (the shadows cast from the plants could also have aesthetic appeal). This design would allow lighting needs to still be met while incorporating good growing conditions for plants into a room. The arduino would be used to take soil moisture readings and water the plants when needed. 

The previously described 'plant sphere lamp' idea was expanded on and the result was a panel system in which clear plant holding spheres were nested. The bottoms of the spheres would be silvered to prevent root rot and make it more aesthetically pleasing. The series of panels would be used to create structures indoors.  These would include dividing walls, partial window coverings, and awning type structures that you could walk through. The use of the ardunio  to provide water would remain the same. The purpose of this design is to allow for plants to be incorporated into well lit, indoor areas in a low maintenance, artistic, and aesthetically pleasing way. 

For the week 2 presentation, our group presented a bent acrylic sheet with laser cut holes that held ping-pong balls that represented the proposed plant holding acrylic ones.



Thursday, September 23, 2010

9/15 to 9/16

When we met to finish our week one project, one of the group members purposed a new interpretation of 'optimally packing' in which the spheres that we made would be stored in a position where they were folded together (a sphere nested within a sphere).  This proposal allowed for all eight of the spheres to pack down to four all while remaining an optimally packed plane. After a long discussion, it was agreed that we would continue with the new interpretation of optimal packing. Ideally, the spheres would un-nest and close by means of a motor but for the purpose of our presentation we manipulated them by hand.




Tuesday, September 14, 2010

9/09-9/14

The criteria that we were given to work with were:
-Smart surface
-Holds
-Optimally packed spheres (with inspiration from the spittle bug http://www.organicgardeninfo.com/images/spittlebugs.jpg)

Initially, the ideas consisted of a structure that was filled with spheres packed in the fcc orientation. The design consisted of chipboard walls with holes cut into them to allow small spheres (ping-pong ball size) to fill it without gaps on the sides. 

Figure 1 is a model made in Rhinoceros that shows how the spheres would protrude from the holes cut into the chipboard. In this design, the chipboard structure optimally holds the spheres.

Figure 1

Figure 2 is a model made in Rhinoceros of the second initial design. It is similar to the one shown in Figure 1 except that there is also a structure on the inside and the spheres fill the area between the two panels of chipboard. Initially, it was thought this was the better of the two as it holds the spheres optimally and can hold something else in the inner compartment. 

Figure 2

After a night it was agreed upon by the group that we had left out the 'smart' portion of our surface. The definition of 'smart' was discussed in depth and it was decided that the surface had to respond to or interact with something.  

Again, two ideas were purposed. One of which was a ramp and basket combination that spheres would roll down and end up in the fcc orientation. The other was a structure consisting of stacked spheres (in fcc orientation) that opened to hold something. Figure 3 is a preliminary sketch of this design. The spheres would be made of leaf-like panels that would open by means of rotating around an axis.


Figure 3

The group split into two in order to more efficiently pursue both design concepts. It was decided that each sphere in the structure should be aprox. 6 inches in diameter and be composed of a rigid hemisphere that was connected to 6 freely moving leafs that would overlap each other. Figure 4 is a model made in Rhinoceros that shows the hemisphere (front of figure) and overlapping panels (back of figure). 

Figure 4

Three chipboard models were made of this design; The second of which was improved to make the final structure more spherical and the third to allow for a better connection between the hemisphere and the panels. Figure 5 shows the first two spheres and Figure 6 shows the third.


Figure 5


Figure 6

There were a few rotation problems with the front panels, so a modification that was two hemispheres (similar to the current back)  one of which slightly smaller than the other that rotate into each other was purposed. One sphere made with the previously mentioned two hemisphere method  and it rotated much better.

The group met as a whole and it was determined that we would all proceed together with the stacked spheres. Gluing the panels, instead of tape, was purposed and found to make the spheres rotate past each other without catching as much. This resulted in making two more spheres were with glue and remaking the original two hemisphere sphere with glue.