Gabriella Levine

ongoing and past work
ITP

Documentation of Sneel_002

Soon I will make a how-to guide for Sneel_002 on instructables.com, as I did for the first version of Sneel, (i’m working on that) but until then…

Sneel swam in central park

The hardware:

Like a real snakes vertebrates:

I used Arduino Mega with multiple servos attached, using multiple 6V NiMh battery packs, placed along the body, with an xbee mounted on top to control three parameters of wave behavior: period, wavelength, and amplitude.

I taped the bottom of the Arduino so nothing shorted:

First I stuffed the arduino + xbee into a waterproof sac:

Then I decided that was overkill so I just stuffed everything into the tube (as I had sealed each servo motor with epoxy and had a water tight seal on the tube top and bottom)

See the waterproofed servos:

See wires etc. stuffed in the tube:

The Software:

A diagram of the control firmware and the relationship between the classes:

I wrote an Arduino library called ServoWave to control period, amplitude and wavelength of the oscillation for Sneel’s swimming behavior.

Here is it on github.

See how each servo motor oscillates – in the following graph, I print out values of each servo as each motor rotates in a sine wave slightly out of phase from each other. The x axis is time and the y axis is angle, and each colored line is a different motor.

After getting everything packed up in the tube, I tested Sneel_002 on the floor of ITP.

He seemed sort of real:

Sneel in the wild:

Well, Sneel_002 swam pretty well, sort of like a real snake, but there’s much work to be done…

Model shot:

Protei in Ars

Protei got an honorary mention in Ars Electronica!

Protei on Wired!

we got on wired!
“Designing Sailboats to Mop Up Oil Spills”

Progress ON Snake

https://vimeo.com/40613436

a quick start:

questions for consideration:
snake or eel( float or sink)
hydraulic pump?
propeller for forward propagation?
behavioral test – think better about mechanics of aquatic locomotion
______________________________________________________

I got the snake into the tube.

Here are some images of the progress:

I think I’ll bring the boat here:

______________________________________________________________________
my email to the p comp list:

It turns out something weird is happening with my batteries – I can run the lipo batteries I have with two DC motors, giving me a current draw of 1800 mAmps (around there anyway when I tested with the multimeter)m, at around 8 V .

When I try to power solely one servo, the voltage drops immediately to below 2 V. The batteries seem to be fully charged , as indicated by the charger I’m using and when I try to give them voltage from a power supply of 8.4 volts at 0.25 mAmps limit, the power supply shuts to 0 (I think this happens with LI ion batteries, a chip prevents over charging if using a regulated power supply…?)

Anyway, what can possibly be preventing me from running one servo with a current rating of 0.3 Amps peak , but I can run DC motors , with 1800 mAmp peak? ?

I can’t figure out what might be wrong – if the battery was damaged, I thought I’d not be able to use it for the DC motors, but since it works fine that way… what can be the problem?

OK another Totally Weird thing is happening:
when I try to test the amperage on one servo by plugging the multimeter in series between the battery +7.4 V and the servo + power , the servo DOES seem to move a bit (slower than when I use just a 6V non rechargeable battery).

When I but without the multimeter in series I get no motion (immediate voltage drop to 1.5 V from 7.4)

What/??
Also, the multimeter is reading 0 amps even when in series with the battery and Vin on the servo

SO I realized I can’t stack it… UGH. I dont understand why I can’t combine two LI ion batteries to make 7.4 V from 3.2 V. WHy?

And now I am using vivitar batteries from cameras, but my voltage regulator, which brings the voltage down to 5.8 V gets super hot. this scares me.

Also, the small servos get super hot. Especially the Emax MD (i’m also using Emax A ).
SO I think I’ll buy some larger servos now, from servocity , as well as perhaps a 6 V NImh battery. Ugh.

TO REMEMBER:
get bigger servos
get new battery
get charger

tighten screws
put more screws on black servos
put on loctite
test o rings
put dielectric / marine grease
seal with epoxy the rest of the large servos
get more vacuum tubing
figure out battery pack, arduino power, face, etc
glue rubber
pugs
screws

bellflower voltage logging solar panel

logging voltage here: http://www.levinegabriella.com/bellflower/bellflower_dataLog.txt

arduino code here:
https://github.com/gabriella/bellflower

php and more to come…

Protei on Instructables

See the entire instructables here

BLINK detection –> blinding LIGHT

code here

I like the concept of always trying to reach something, or always trying to see something, but you cannot penetrate barrier in order to reach / see it. In a sense, something only occurring when you blink, to me seems like you straddle the threshold of perception… well, i dunno. I have to develop this more and figure out what it actually is I’m trying to see that I never can

Here is a video of me testing my blink mechanism then trying to implement it in the dark, as I thought that would be dramatic. However, there was a delay in the dark, as I guess the camera vision was more difficult.

A few tests with others:

payphone

for the fusebox festival, payphone revival project, in austin texas

using a mp3 trigger, and getting into the matrix circuit behind the keypad (luckily the phone was OPEN and not locked) we’re going to allow people to pick up the phone

The payphone is so much simpler than I thought! the coin slot is just a bunch of gears, then the circuitry for the buttons and the receiver etc… nice

So I soldered some wires onto the already working switch so when the receiver is picked up a dial tone plays, then working on the matrix to activate different tracks when I button is pressed

cool.

the mp3 trigger is pretty simple with a micro sd card, FAT 16 formatted (<2 gb)- either it can be digitally controlled, by closing the switch on pins 0-17 (which switches between 18 tracks), Or it can interface with arduino serially. [gallery]

transformer

Following the below circuit, I made used a transformer to make a variable voltage DC power supply, from 0-32 V. Here is the link: http://web.mac.com/er0sentha1/NYUBAC/Session_3.html

This was from Eric Rosenthal’s Basic Analog Circuit class

Snake Motion Protei


wireless video from analog security cam

My 2.4 GHz xbee was interfering with my wireless camera, also transmitting at 2.4 gHz. So I wired up my analog security cam to a 950 MHz transmitter, and the receiver displayed on the LCD screen quite nicely.

seeed studio

Thanks for helping support Protei_010 by supplying parts, like servos, microcontrollers, servo brackets, sensors, IOIO boards, etc…

more joint work

To summarize: I started experimenting with making my own joints and ribs, by cutting corrugated plastic ribs, and 3d printing universal joints at AMS. Then, my intention was to use springs and servos to enact articulation.

However, I started using u-joint servo brackets, that are super stable, and I will continue with this. https://github.com/gabriella/Servo_wave
Here is the code I finally got to work. Basically, I am storing a table of values, a formula for a sin wave, and each servo is at a different index along the wave values, oscillating up and down. I can therefore control wavelength, speed of the wave propagation, offset from one servo to another, amplitude of the wave, etc.


int total = int(TWO_PI/0.01);//total number of indexes points, points
//until the amplitude is back to zero

float[] wave = new float[total];//array for the amplitude of the
//object to be drawn betwen 0 and ht

int numBalls = 40;
int[]index= new int[numBalls];// 1 = 0;//
int sp = 1;
float ht=1;
//changer = 10;
void setup() {
size(800, 400);
float a = 0;
for (int i = 0; i < wave.length; i++) {
wave[i] = map(sin(a), -1, 1, 0, 180);
println(wave[i]);
a+=0.05;
}
//print(wave.length);
//print(total);
//print(index.length);
for (int i = 0; i < index.length; i++) {

index[i] = i*5;
}
}

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

for (int i=0;i<numBalls;i++) {
ellipse(i*20, ht*wave[index[i]], 10, 10);
index[i] = (sp*index[i]+1) % wave.length;

}
}

void keyPressed(){
if(key=='a'){
ht=ht+0.5;
}
if(key=='s'){
ht = ht-0.5;
}
if(key=='q'){
sp++;

}
if(key=='w'){
sp--;
}
println(ht);

}

The Human Repeater performance, !s!w at 319 scholes gallery

http://319scholes.org/nsnw3/

snake servos

CNC universal joints to use later

I 3d printed these parts for universal joints, first using the solid white, then I used a blend of black and white (so it was sort of soft)

This is one type of joint that i thought might work for a snake like robot that can be articulated at each joint in more than one axis.

PROTEI ITP winter show and build it yourself…

PROJECT DEVELOPMENT STUDIO

To do:
1.Transpose important elements from the above “map”
I had a very specific topic of interest I would like to explore – the open source hardware system and agent-based software architecture for a universal-joint system for individual units that self-assemble into a biomimetic linear, snakelike robot that is adaptable for different purposes and functions.
However, I would like to instead build a large scale (2 meter?) vertebrate like robot in a finished form. This will be an aesthetic design that stems out of the idea and project, Protei, that I am working on, which is an open source prototype for a fleet of semi-autonomous or remote controlled, segmented, shape shifting, oil-collecting sailboat drone. I would like to create both DIY kits for a fully segmented and articulated robotic snake, with a software package, mechanical designs, and electronic architecture, for a smaller simpler version of this boat, but focus on the large scale model and the concept of biomimicry in science and art.

I believe I have to hone in on the unification of the above utilitarian function and inspiration, while also developing the concept of giving life and autonomy to a machine (that can therefore possess its own life cycle), the transformation of human body/mind by modern technology, beauty in the grotesque, the commodification of technology and body…

So… how can I move forwards and converge all of the above (how can I justify making an “aesthetic object”, with the function only as a prompting driving impulse)

2. 3 developments:
1. Bill of materials; Finish instructables for the DIY kit (as an example):

2. write – a description of moving forwards
3. Finish the Arduino “snakeWave” class and implement it with the hardware I have started to use to model the snake with servos; Make a software representation of the wave in processing of the individual segments – Software progress : Servo_wave class for arduino

  • I took down the model snake robot I built last semester but then decided to use five independent servos. So I glued five down in the orientation that I imagine they will be in, as a prototype to use with Arduino Mega.
  • So this:
  • will model this:

  • 3a. Gather research papers :
    1. Application of AI Techniques for Modelling of a Snake’s Motion, Zenon Chaczko, Perez Moses (Australia)
    2. Bio-inspired Agent-based System for Cooperative Decision-making and Control of Unmanned Aerial Vehicles
    3. Software Infrastructure for Wireless Sensor and Actuator Networks
    4. Ant-Based Topology Convergence Algorithms for Resource Management in VANETs
    5. Neuro-Immune-Endocrine (NIE) Models for Emergency Services Interoperatibility

    … and more

    BOOKS I have :
    Neurotechnology for Biomimetic Robots
    Self Reconfigurable Robots
    Autonomous Robots: From Biological Inspiration to Implementation and Control
    Biomechanisms of swimming and flying

    3b. A few artists and pieces to look into for ‘maps’ of inspirations:

    Alexander McQueen, Untitled Spine Corset
    David Cronenberg (and J.G. Ballard), Crash
    Tetsuo, Shin’ya Tsukamoto
    Natalie Jeremijenko, Amphibious Architecture

    U Ram Choe: Custos Cavum
    Interview with the creators project

    4. map one of your inspirations’ projects based on the criteria in the map/brainstorming session.
    URam Choe’s Custos Cavum:
    Categories:
    · Forms (video, sculpture, website, diorama, comic book, collage).
    -sculpture

    · Materials (concrete, plexiglass, living tissue, rice paper, cake)
    -steel, stainless steel, brass, aluminum, resin, CPUs, motors

    · Scale (use analogies: big as a house, small as a marble)
    -as big as a large truck in its entirety, (basically the size of a large seal), but parts of the piece span upwards vertically towards the ceiling and horizontally across the floor

    · Affects/emotions (clumsy, cheerful, morose, businesslike)
    -grandiose, awe-inspiring, courageous, fear inspiring, stoic, cold, uninviting, of fortitude, somber, tranquil, subtle, impressive, magnificient, aggressive, autonomous, iconographic, cosmic, idealic, center, universal, ecstasy, primordial, territorial

    · Verbs (motivate, collapse, upset, tickle, spin, collect, etc)
    -protect, ward off, illuminate, care, defend, shimmer, breathe, live, cycle, guard, idolize, transcend, destroy, gesture, dominate

    · Motivations (why do you want to do/explore this? your reason, underlying impulse, larger aim?)
    -explore the feeling of awe and transcendance that one gets from religion (this piece is inspired by Shiva as the Lord of Dance, in India), ie from going into a church or dominating piece of architecture, through a machine
    -give life and autonomy to a machine – power it on and it has a life of its own.
    -a group of humans come together to give birth to this creation
    – explore religion through an object, through the electromechanical design – give it life, and it surely takes on a life of its own, the sum of which is greater than the parts (many humans from different disciplines come together to make a machine that can be more powerful than humans); This creature protects and dominates over its realm; It eventually decays (rusts, dies)
    -explore the spiritual through a machine creation that resembles life but does not mimic it.

    · Inspirations (projects, people, contexts that inspire you to follow this hunch)
    -Buddhism, life cycle,
    -transformation of human psychology by modern technology
    -beauty in the grotesque
    -Theo Jansen – the fusion of nature and technology with nothing but power from the natural world (wind in some cases)
    -Rube Goldberg, Alexander Calder, Arthur Ganson, Lyman Whitaker, László Moholy-Nagy (and other kinetic sculptors)
    -Tetsuo (metal fetishist)

    · Ideal audiences (be specific: Guyanese senior citizens, tech geeks in Brooklyn or Fukushima, 3-5 yr old Americans, white hipsters, demographic, economic, social circles)
    -Upper west side shrinks, Asian Buddhists and non-Buddhists, Artists and hobbyists fascinated with kiinetics, artists of all sorts, kids, serious people, spiritualists, people who love literature and/or history
    · Context/location (gallery, dark alley, the internet, public park, suburban cul-desac)
    -vast space, atrium, lobby, serene place, gallery or museum or performance space

    Lastly, take your temperature on what you discovered or explored today in class:
    · What are the first steps?
    -firmware (Arduino), hardware model, mechanical platform, hone in on how to talk about the concept of this – unite the functionality of these robots with the aesthetic vision I have
    · Is it big enough to interest you for a whole semester?
    -Yes
    · If it is enormous, what aspect of this core idea can you tackle?
    -It is enormous, so I am tacking not what interests me utmost (the hardware of a joint system for a modular self assembling robot made up of multiple independent units) but the aesthetics of one developed biomimetic snake robot that is a more developed version of smaller open source models and prototype for which I will have DIY kits, for small functioning skeletons of a robotic boat that can do things like: clean up polluted waters, biological sampling, nuclear waste monitoring; larger environmental impacts: crowdsourced oil spill cleanup with swarms of drones…

    The Bellflower Project

    Technical Diagrams

    The Bellflower Project will showcase the potential of sustainable energy sources. By engaging the public in a creative, non-institutional way, we are hoping to show (not tell) the NYU and larger community the benefits of energy harvesting. The Bellflower project is a series of small, public kinetic sculptures that run on solar power. Each “bellflower” biomimetically recreates an opening flower – five petals will slowly open as they collect solar energy, revealing a spiral of musical bars (like large xylophone bars). As the sculpture gathers energy, the bars begin to play, creating unique melodies and chords that vary depending on weather conditions and time of day. Ideally, the project would be embedded in an urban agriculture garden, promoting biodiversity while demonstrating the power of sustainable energy harvesting. Our goal is to aesthetically improve the quotidian life of the community, as well as potentially educating the public about environmentally responsible power consumption.

    Transpiration

    Transpiration is a data-driven, reactive projection in 240 Central Park South. It is demonstrative of the motion of the elevators through the elevator shafts, based on the flux of people in and out of the building. The data is collected using the security cameras deployed in the four elevators.

    tmp36

    I’ve switched over to this sensor as a solid state temperature sensor:
    I will use thermocouples for rapid rate of changes of liquids but for environmental sensing:

    from adafruit:

    temperature from tmp36 sensor: http://www.ladyada.net/learn/sensors/tmp36.html

    0.73 volts
    22.75 degrees C
    72.96 degrees F
    0.73 volts

    //TMP36 Pin Variables
    int sensorPin = 0; //the analog pin the TMP36's Vout (sense) pin is connected to
    //the resolution is 10 mV / degree centigrade with a
    //500 mV offset to allow for negative temperatures
    
    /*
    * setup() - this function runs once when you turn your Arduino on
    * We initialize the serial connection with the computer
    */
    void setup()
    {
    Serial.begin(9600); //Start the serial connection with the computer
    //to view the result open the serial monitor
    }
    
    void loop() // run over and over again
    {
    //getting the voltage reading from the temperature sensor
    int reading = analogRead(sensorPin);
    
    // converting that reading to voltage, for 3.3v arduino use 3.3
    float voltage = reading * 5.0;
    voltage /= 1024.0;
    
    // print out the voltage
    Serial.print(voltage); Serial.println(&amp;amp;quot; volts&amp;amp;quot;);
    
    // now print out the temperature
    float temperatureC = (voltage - 0.5) * 100 ; //converting from 10 mv per degree wit 500 mV offset
    //to degrees ((volatge - 500mV) times 100)
    Serial.print(temperatureC); Serial.println(&amp;amp;quot; degrees C&amp;amp;quot;);
    
    // now convert to Fahrenheight
    float temperatureF = (temperatureC * 9.0 / 5.0) + 32.0;
    Serial.print(temperatureF); Serial.println(&amp;amp;quot; degrees F&amp;amp;quot;);
    
    delay(1000); //waiting a second
    }

    IR proximity sensor

    Here’s the Sharp product i’m using: http://www.sparkfun.com/datasheets/Sensors/Infrared/gp2y0a02yk_e.pdf
    bought from here: http://www.sparkfun.com/products/8958

    This code is simply smoothing an analog input value (0-5V), and it seems to work ok, but I have to see – I’m working on graphing the values (using Excel and CoolTerm) to make sure that my linearizing function I got from here: http://www.acroname.com/robotics/info/articles/irlinear/irlinear.html = has worked correctly

    const int numReadings = 100;
    
    int readings[numReadings]; // the readings from the analog input
    int index = 0; // the index of the current reading
    int total = 0; // the running total
    int average = 0; // the average
    
    int inputPin = A0;
    
    void setup()
    {
    // initialize serial communication with computer:
    Serial.begin(9600);
    // initialize all the readings to 0:
    for (int thisReading = 0; thisReading &amp;amp;lt; numReadings; thisReading++)
    readings[thisReading] = 0;
    }
    
    void loop() {
    // subtract the last reading:
    total= total - readings[index];
    // read from the sensor:
    readings[index] = analogRead(inputPin);
    // add the reading to the total:
    total= total + readings[index];
    // advance to the next position in the array:
    index = index + 1;
    
    // if we're at the end of the array...
    if (index &amp;amp;gt;= numReadings)
    // ...wrap around to the beginning:
    index = 0;
    
    // calculate the average:
    average = total / numReadings;
    // send it to the computer as ASCII digits
    Serial.println(average);
    }
    

    This code also is seems good but I have to check it out more closely:

    int sensorPin = 0; // input pin for the sensor
    int barPin[] = {2, 3, 4, 5, 6, 7, 8, 9, 10, 11};
    int barPinCount = 10;
    int volt = 0; // variable to store the value coming from the sensor
    int zeit = 100; // *10 = Gesamtzeit - total time
    
    void setup() {
    Serial.begin(9600);
    int thisPin;
    // the array elements are numbered from 0 to (pinCount - 1).
    // use a for loop to initialize each pin as an output:
    for (int thisPin = 0; thisPin &amp;amp;lt; barPinCount; thisPin++) {
    pinMode(barPin[thisPin], OUTPUT);
    }
    }
    
    void loop() {
    int volt = 0;
    for(int i=0; i&amp;amp;lt;10; i++)
    {
    volt += analogRead(sensorPin);
    delay(zeit);
    }
    volt /= 10;
    
    Serial.println(volt);
    int litCount = 0;
    if (volt &amp;amp;lt;= 82) {
    // &amp;amp;gt;= 80cm
    litCount = 1;
    } else if (volt &amp;amp;lt;= 92) {
    // &amp;amp;gt;= 70cm
    litCount = 2;
    } else if (volt &amp;amp;lt;= 102) {
    // &amp;amp;gt;= 60cm
    litCount = 3;
    } else if (volt &amp;amp;lt;= 123) {
    // &amp;amp;gt;= 50cm
    litCount = 4;
    } else if (volt &amp;amp;lt;= 154) {
    // &amp;amp;gt;= 40cm
    litCount = 5;
    } else if (volt &amp;amp;lt;= 184) {
    // &amp;amp;gt;= 30cm
    litCount = 6;
    } else if (volt &amp;amp;lt;= 266) {
    // &amp;amp;gt;= 20cm
    litCount = 7;
    } else if (volt &amp;amp;lt;= 328) {
    // &amp;amp;gt;= 15cm
    litCount = 8;
    } else if (volt &amp;amp;lt;= 461) {
    // &amp;amp;gt;= 10cm
    litCount = 9;
    } else if (volt &amp;amp;gt; 461) {
    // &amp;amp;lt; 10cm
    litCount = 10;
    }
    
    for(int b=0; b&amp;amp;lt;10; b++)
    {
    if(b&amp;amp;lt;=litCount)
    digitalWrite(barPin[b], HIGH); // Turn the bar on
    else
    digitalWrite(barPin[b], LOW); // Turn the bar off
    }
    
    }
    

    circuit – SHT11 humidity sensor

    I found a super nice library – https://github.com/practicalarduino/SHT1x – it’s working way better than what I had going before – Thanks!

    I’m using this schematic: using this http://www.parallax.com/dl/docs/prod/acc/SensirionDocs.pdf

    I’m getting legible values :

    Temperature: 25.4199981689C / 77.8459930419F. Humidity: 23.45%
    Temperature: 25.4399948120C / 77.8639984130F. Humidity: 23.45%
    Temperature: 25.4799957275C / 77.7919921875F. Humidity: 25.12%
    Temperature: 25.4599990844C / 77.8999938964F. Humidity: 27.65%
    Temperature: 25.3600006103C / 77.7739944458F. Humidity: 27.87%
    Temperature: 25.5199966430C / 77.9719924926F. Humidity: 26.86%

    Moving onto the mega (++ sensors, no computer, data to the server)

    A note about the Mega and the spi library: (for use with the SD card and ethernet shield)
    On Arduino MEGA, SPI bus uses pins 51 (MOSI), 52(SCK), 50(MISO), and 53(SS)

    Sensors include: humidity, barometric, light, temp, gps, rtc, accelerometer, more to come…

    connects to a graph:
    logs sensor data to a text file which gets written to a server: www.levinegabriella.com/understanding_networks/dataLogger.php
    www.levinegabriella.com/understanding_networks/Temp_applet_js

    &lt;code&gt;/*
    Web client
    
    This sketch connects to a website (http://www.google.com)
    using an Arduino Wiznet Ethernet shield.
    
    Circuit:
    * Ethernet shield attached to pins 10, 11, 12, 13
    
    created 18 Dec 2009
    by David A. Mellis
    
    */
    #include &amp;amp;lt;Wire.h&amp;amp;gt;
    #include &amp;amp;lt;SPI.h&amp;amp;gt;
    #include &amp;amp;lt;Ethernet.h&amp;amp;gt;
    #include &amp;amp;quot;RTClib.h&amp;amp;quot;
    #include &amp;amp;lt;SD.h&amp;amp;gt;
    
    #define BMP085_ADDRESS 0x77 // I2C address of BMP085
    const unsigned char OSS = 0; // Oversampling Setting
    // Calibration values
    int ac1;
    int ac2;
    int ac3;
    unsigned int ac4;
    unsigned int ac5;
    unsigned int ac6;
    int b1;
    int b2;
    int mb;
    int mc;
    int md;
    // b5 is calculated in bmp085GetTemperature(...), this variable is also used in bmp085GetPressure(...)
    // so ...Temperature(...) must be called before ...Pressure(...).
    long b5;
    
    short temperature;
    long pressure;
    
    // Enter a MAC address for your controller below.
    // Newer Ethernet shields have a MAC address printed on a sticker on the shield
    byte mac[] = {
    0x00, 0xAA, 0xBB, 0xCC, 0xDE, 0x03 };
    IPAddress server(69,89,31,63); // my IP server
    const int requestInterval = 30000;
    long lastAttemptTime = 0; // last time you connected to the server, in milliseconds
    boolean requested;
    const int resetLED = 13;
    float temp;
    float voltage;
    // Initialize the Ethernet client library
    // with the IP address and port of the server
    // that you want to connect to (port 80 is default for HTTP):
    
    const int chipSelect = 53;//changed from 8
    const int LOCATION_FILE_NUMBER_LSB = 0x00;
    const int LOCATION_FILE_NUMBER_MSB = 0x01;
    
    File dataFile;
    RTC_DS1307 RTC;
    EthernetClient client;
    DateTime now;
    
    int ledPin = 13; // LED test pin to determine if we are successfully writing gps strings to a text file
    int ledState = LOW;
    
    int rxPin = 0; // RX PIN
    int txPin = 1; // TX TX
    
    void setup() {
    pinMode(ledPin, OUTPUT); // Initialize LED pin
    pinMode(rxPin, INPUT);
    pinMode(txPin, OUTPUT);
    // start the serial library:
    Serial.begin(38400);
    pinMode(A2, OUTPUT);
    pinMode(A3, OUTPUT);
    // A2 is the ground, A3 is the power:
    digitalWrite(A2, LOW);
    digitalWrite(A3, HIGH);
    pinMode(chipSelect, OUTPUT);
    
    if (!SD.begin(chipSelect)) {
    Serial.println(&amp;amp;quot;Card failed, or not present&amp;amp;quot;);
    // don't do anything more:
    
    }
    Serial.println(&amp;amp;quot;card initialized.&amp;amp;quot;);
    
    Wire.begin();
    RTC.begin();
    delay(50);
    bmp085Calibration();
    if (! RTC.isrunning()) {
    Serial.println(&amp;amp;quot;RTC is NOT running!&amp;amp;quot;);
    // following line sets the RTC to the date &amp;amp;amp;amp; time this sketch was compiled
    RTC.adjust(DateTime(__DATE__, __TIME__));
    }
    dataFile = SD.open(&amp;amp;quot;data.txt&amp;amp;quot;, FILE_WRITE);
    delay(500);
    
    // start the Ethernet connection:
    Ethernet.begin(mac);
    if (Ethernet.begin(mac) == 0) {
    Serial.println(&amp;amp;quot;Failed to configure Ethernet using DHCP&amp;amp;quot;);
    // no point in carrying on, so do nothing forevermore:
    // for(;;)
    // ;
    }
    
    // connectToServer();
    // give the Ethernet shield a second to initialize:
    delay(1500);
    blink(resetLED, 3);
    Serial.println(&amp;amp;quot;connecting...&amp;amp;quot;);
    connectToServer();
    }
    
    // Stores all of the bmp085's calibration values into global variables
    // Calibration values are required to calculate temp and pressure
    // This function should be called at the beginning of the program
    void bmp085Calibration()
    {
    ac1 = bmp085ReadInt(0xAA);
    ac2 = bmp085ReadInt(0xAC);
    ac3 = bmp085ReadInt(0xAE);
    ac4 = bmp085ReadInt(0xB0);
    ac5 = bmp085ReadInt(0xB2);
    ac6 = bmp085ReadInt(0xB4);
    b1 = bmp085ReadInt(0xB6);
    b2 = bmp085ReadInt(0xB8);
    mb = bmp085ReadInt(0xBA);
    mc = bmp085ReadInt(0xBC);
    md = bmp085ReadInt(0xBE);
    }
    
    void loop()
    {
    temperature = bmp085GetTemperature(bmp085ReadUT());
    pressure = bmp085GetPressure(bmp085ReadUP());
    now = RTC.now();
    if(client.connected()){
    if(!requested){
    
    requested = makeRequest();
    // Serial.println(&amp;amp;quot;requesting!&amp;amp;quot;);
    }
    if(millis() - lastAttemptTime&amp;amp;gt;requestInterval){
    //if youre not connected and two minutes have passed, attempt to connect again
    client.stop();
    // Serial.println(&amp;amp;quot;stopping and reconnecting!&amp;amp;quot;);
    
    // getData();
    delay(1500);
    //connectToServer();
    }
    // if there are incoming bytes available
    // from the server, read them and print them:
    
    }
    
    if (client.available()) {
    char c = client.read();
    // Serial.print(c);
    }
    
    // if the server's disconnected, stop the client:
    if (!client.connected()) {
    // Serial.println();
    // Serial.println(&amp;amp;quot;disconnecting.&amp;amp;quot;);
    
    client.stop();
    delay(1500);
    if(millis() - lastAttemptTime&amp;amp;gt;requestInterval){
    //if youre not connected and two minutes have passed, attempt to connect again
    connectToServer();
    //try to reconnect here...
    }
    }
    
    }
    
    void getData(){
    voltage = 5 * analogRead(A0) / 1024.0;
    //float temp = 5 * analogRead(A1) / 1024.0;
    temp=(analogRead(A1))/10;
    
    if(Serial.available()&amp;amp;gt;0){
    byte gps=Serial.read(); //echo incoming gps data
    Serial.write(gps);
    
    if (dataFile) {
    digitalWrite(ledPin, HIGH);//turn on the status led
    DateTime now = RTC.now();
    dataFile.write(gps);
    dataFile.print(now.month());
    dataFile.print('/');
    dataFile.print(now.day());
    dataFile.print('/');
    dataFile.print(now.year());
    dataFile.print(F(&amp;amp;quot;,&amp;amp;quot;));
    dataFile.print(now.hour());
    dataFile.print(F(&amp;amp;quot;:&amp;amp;quot;));
    dataFile.print(now.minute());
    dataFile.print(F(&amp;amp;quot;:&amp;amp;quot;));
    dataFile.print(now.second());
    dataFile.print(F(&amp;amp;quot;,&amp;amp;quot;));
    dataFile.print(voltage);
    dataFile.print(F(&amp;amp;quot;,&amp;amp;quot;));
    dataFile.print(temp);
    dataFile.print(temperature);
    dataFile.print(F(&amp;amp;quot;,&amp;amp;quot;));
    dataFile.print(pressure);
    dataFile.println();
    
    }
    
    dataFile.flush();
    }
    else{digitalWrite(ledPin, LOW);}
    
    }
    
    void connectToServer(){
    // Serial.println(&amp;amp;quot;connecting to server...&amp;amp;quot;);
    if (client.connect(server, 80)) {
    requested = false;
    }
    
    lastAttemptTime = millis();
    }
    
    boolean makeRequest() {
    // Serial.println(&amp;amp;quot;requesting&amp;amp;quot;);
    getData();
    // Make a HTTP request:
    
    client.print(&amp;amp;quot;GET /understanding_networks/dataLogger.php?data=&amp;amp;quot;);
    client.print(now.month());
    client.print('/');
    client.print(now.day());
    client.print('/');
    client.print(now.year());
    client.print(F(&amp;amp;quot;,&amp;amp;quot;));
    client.print(now.hour());
    client.print(F(&amp;amp;quot;:&amp;amp;quot;));
    client.print(now.minute());
    client.print(F(&amp;amp;quot;:&amp;amp;quot;));
    client.print(now.second());
    client.print(F(&amp;amp;quot;,&amp;amp;quot;));
    client.print(voltage);
    client.print(F(&amp;amp;quot;,&amp;amp;quot;));
    client.print(temp);
    client.print(F(&amp;amp;quot;,&amp;amp;quot;));
    client.print(temperature);
    client.print(F(&amp;amp;quot;,&amp;amp;quot;));
    client.print(pressure);
    client.println(&amp;amp;quot; HTTP/1.1 &amp;amp;quot;);
    client.println(&amp;amp;quot;HOST: www.levinegabriella.com&amp;amp;quot;);
    
    client.println();
    return true;
    
    }
    
    // Calculate temperature given ut.
    // Value returned will be in units of 0.1 deg C
    short bmp085GetTemperature(unsigned int ut)
    {
    long x1, x2;
    
    x1 = (((long)ut - (long)ac6)*(long)ac5) &amp;amp;gt;&amp;amp;gt; 15;
    x2 = ((long)mc &amp;amp;lt;&amp;amp;lt; 11)/(x1 + md);
    b5 = x1 + x2;
    
    return ((b5 + 8)&amp;amp;gt;&amp;amp;gt;4);
    }
    
    // Calculate pressure given up
    // calibration values must be known
    // b5 is also required so bmp085GetTemperature(...) must be called first.
    // Value returned will be pressure in units of Pa.
    long bmp085GetPressure(unsigned long up)
    {
    long x1, x2, x3, b3, b6, p;
    unsigned long b4, b7;
    
    b6 = b5 - 4000;
    // Calculate B3
    x1 = (b2 * (b6 * b6)&amp;amp;gt;&amp;amp;gt;12)&amp;amp;gt;&amp;amp;gt;11;
    x2 = (ac2 * b6)&amp;amp;gt;&amp;amp;gt;11;
    x3 = x1 + x2;
    b3 = (((((long)ac1)*4 + x3)&amp;amp;lt;&amp;amp;lt;OSS) + 2)&amp;amp;gt;&amp;amp;gt;2;
    
    // Calculate B4
    x1 = (ac3 * b6)&amp;amp;gt;&amp;amp;gt;13;
    x2 = (b1 * ((b6 * b6)&amp;amp;gt;&amp;amp;gt;12))&amp;amp;gt;&amp;amp;gt;16;
    x3 = ((x1 + x2) + 2)&amp;amp;gt;&amp;amp;gt;2;
    b4 = (ac4 * (unsigned long)(x3 + 32768))&amp;amp;gt;&amp;amp;gt;15;
    
    b7 = ((unsigned long)(up - b3) * (50000&amp;amp;gt;&amp;amp;gt;OSS));
    if (b7 &amp;amp;lt; 0x80000000)
    p = (b7&amp;amp;lt;&amp;amp;lt;1)/b4;
    else
    p = (b7/b4)&amp;amp;lt;&amp;amp;lt;1;
    
    x1 = (p&amp;amp;gt;&amp;amp;gt;8) * (p&amp;amp;gt;&amp;amp;gt;8);
    x1 = (x1 * 3038)&amp;amp;gt;&amp;amp;gt;16;
    x2 = (-7357 * p)&amp;amp;gt;&amp;amp;gt;16;
    p += (x1 + x2 + 3791)&amp;amp;gt;&amp;amp;gt;4;
    
    return p;
    }
    
    // Read 1 byte from the BMP085 at 'address'
    char bmp085Read(unsigned char address)
    {
    unsigned char data;
    
    Wire.beginTransmission(BMP085_ADDRESS);
    Wire.write(address);
    Wire.endTransmission();
    
    Wire.requestFrom(BMP085_ADDRESS, 1);
    while(!Wire.available())
    ;
    
    return Wire.read();
    }
    
    // Read 2 bytes from the BMP085
    // First byte will be from 'address'
    // Second byte will be from 'address'+1
    int bmp085ReadInt(unsigned char address)
    {
    unsigned char msb, lsb;
    
    Wire.beginTransmission(BMP085_ADDRESS);
    Wire.write(address);
    Wire.endTransmission();
    
    Wire.requestFrom(BMP085_ADDRESS, 2);
    while(Wire.available()&amp;amp;lt;2)
    ;
    msb = Wire.read();
    lsb = Wire.read();
    
    return (int) msb&amp;amp;lt;&amp;amp;lt;8 | lsb;
    }
    
    // Read the uncompensated temperature value
    unsigned int bmp085ReadUT()
    {
    unsigned int ut;
    
    // Write 0x2E into Register 0xF4
    // This requests a temperature reading
    Wire.beginTransmission(BMP085_ADDRESS);
    Wire.write(0xF4);
    Wire.write(0x2E);
    Wire.endTransmission();
    
    // Wait at least 4.5ms
    delay(5);
    
    // Read two bytes from registers 0xF6 and 0xF7
    ut = bmp085ReadInt(0xF6);
    return ut;
    }
    
    // Read the uncompensated pressure value
    unsigned long bmp085ReadUP()
    {
    unsigned char msb, lsb, xlsb;
    unsigned long up = 0;
    
    // Write 0x34+(OSS&amp;amp;lt;&amp;amp;lt;6) into register 0xF4
    // Request a pressure reading w/ oversampling setting
    Wire.beginTransmission(BMP085_ADDRESS);
    Wire.write(0xF4);
    Wire.write(0x34 + (OSS&amp;amp;lt;&amp;amp;lt;6));
    Wire.endTransmission();
    
    // Wait for conversion, delay time dependent on OSS
    delay(2 + (3&amp;amp;lt;&amp;amp;lt;OSS));
    
    // Read register 0xF6 (MSB), 0xF7 (LSB), and 0xF8 (XLSB)
    Wire.beginTransmission(BMP085_ADDRESS);
    Wire.write(0xF6);
    Wire.endTransmission();
    Wire.requestFrom(BMP085_ADDRESS, 3);
    
    // Wait for data to become available
    while(Wire.available() &amp;amp;lt; 3)
    ;
    msb = Wire.read();
    lsb = Wire.read();
    xlsb = Wire.read();
    
    up = (((unsigned long) msb &amp;amp;lt;&amp;amp;lt; 16) | ((unsigned long) lsb &amp;amp;lt;&amp;amp;lt; 8) | (unsigned long) xlsb) &amp;amp;gt;&amp;amp;gt; (8-OSS);
    
    return up;
    }
    
    void blink(int thisPin, int howManyTimes){
    for (int blinks = 0;blinks&amp;amp;lt;howManyTimes;blinks++){
    digitalWrite(thisPin, HIGH);
    delay(200);
    digitalWrite(thisPin, LOW);
    delay(200);
    }
    }
    
    //questions: what other sensors will be good?
    //what is too much data
    //i seem to be making my request twice
    
    //when my request interval is more than 5000 i get
    //10/13/2011,11:14:56,3.67,15.00
    //10/13/2011,11:15:5,3.65,15.00
    //10/13/2011,11:15:16,0.00,0.00
    //10/13/2011,11:15:44,0.00,0.00
    //why
    
    //can you go back a directory
    
    //try it? overwhelm maybe... w/ gps
    //implem. timer
    &lt;/code&gt;