Gabriella Levine

ongoing and past work
teaching

SKYPE IN THE CLASSROOM

Screen Shot 2013-10-28 at 5.09.46 PM

Screen Shot 2013-10-28 at 5.09.30 PM

Screen Shot 2013-10-28 at 5.12.30 PM

FUELING INNOVATION THROUGH SHARED TECHNOLOGY

Fueling Innovation Through Shared Technology

  • AUTHOR: // CATEGORY: 2013 Event, Blog, Guest, Program, Speakers

    No Comments

    Aug

    arduinoClassINNOVATING BASED ON MODELS

    Technology has always been innovated based on other people’s successes, from the discovery that the earth was round, to the invention of the telephone, steam engine, or airplane. And scientists have found resources in biological systems for technological innovations, for example the development of VELCRO modeled after a Burr plant, or SONAR inspired by the echolocation in bats.

    OPEN HARDWARE MOVEMENT

    oshw-logo-800-pxAlthough patent laws were originally designed to protect inventors’ ideas, patents constrain further innovation. The more that designs and processes can be open and shared, the quicker that innovation can happen.

    There are many examples of successful businesses openly sharing software, such as Mozilla and Linux, but the rise of the Open Hardware trend is just beginning. The Open Hardware definition[1] states that it is any hardware whose documentation is made publicly available for others to use, modify, and distribute. This growing trend is founded in the belief that sharing ideas, designs, and methodologies can bring technological innovation and manufacturing mainstream on local and global scales, making it easier to engineer new solutions to complex problems.

    arduino_due_in_hand

    Open Hardware projects that facilitate free sharing of documentation, source code, and CAD designs, are an approach to proliferate innovation. Arduino, a platform developed for hobbyists to make electronic prototypes, has expanded the world of hardware development from electrical engineers to artists, hobbyists, and even youth. Open Hardware projects range from industrial machines [open source ecology], 3d printers [RepRap], environmental disaster relief efforts [Protei, Open Relief], and underwater robotics [openROV].

    STEALING INFORMATION

    As modern technology and the Internet dissolves boundaries between countries and people, even expensive information is getting easier to steal. Evidence of this can be seen from the recent rise of industrial espionage by mostly Chinese University students gaining access into US University and Library material. The recent NY Times Article on the rise of Cyberattacks [2] cites Bill Mellon of the University of Wisconsin saying, “We get 90,000 to 100,000 attempts per day, from China alone, to penetrate our system”.

    China is a special mecca for hackers. Companies employ hackers to spy on competitors’ trade secrets, and Chinese universities partner with corporations to sponsor hacking competitions that army talent scouts attend. China’s rapidly accelerating economic growth and extreme rate of production, as well as the immense pressure to publish research papers explains the intensity of cyber-hacking in academics and business. For instance, 31% of the publications Journal of Zhejiang University–Science were deemed to be plagiarized[3], .

    SHANZHAI

    0023ae9885da0cb4f9a116A very interesting trend has sprouted from China’s copycat culture, called Shanzhai, literally meaning “Mountain Fortress”[4]. Shanzhai refers to a cluster of about 300 “underground” factories tucked away in the mountains of Shenzhen, China. These factories rapidly produce cheap knock off consumer electronics such as watches and iPhones. Brand names include NOKLA (Nokia knockoffs) and Hi-Phone (iPhone copycats). Although quite secretive and hard to access, Shanzhai is not a small operation: by 2010, Shanzhai cell phones took 20% of the 2G market[5].

    SHANZHAI and OPEN HARDWARE

    There are many similarities between Shanzhai and the Open Hardware community. Both Shanzhai and Open Hardware projects borrow information, tools, source code, CAD files, and techniques; both improve upon other’s work to accelerate development.

    What differentiates Shanzhai from Open Hardware projects is that it doesn’t build upon the work of others for increased innovation, but it exactly copies it and prices it lower.

    BORROWING FROM NATURE : OPEN SOURCING BIOLOGY

    velcro

    Not only does technology proliferate by building upon the innovation of others, but drawing inspiration from biological processes has also refined technological innovation. In contemporary times of extreme technological advancement, social infrastructures (Facebook, Google, Yahoo) are built upon sourcing individual data to inform collective intelligence. Redesigning urban frameworks for efficient transit options is becoming increasingly critical due to growing urban populations. Therefore, looking to biology for influence for organizing emergent intelligent systems is increasingly crucial for design considerations.

    Biomimicry as used in design and engineering takes the form of copying a form and function (like the use of a fin for swimming), modeling principles occurring in nature (such as aerodynamics for flight), or mimicking organizational principles (modeling online social networks on ant colonies). A pivotal example of biomimetic design is the experimental IBM computer chip, released in 2011, that emulates the human brain’s cognition.

    Using complex yet efficient biological systems as a model and a mentor for design and engineering solutions parallels the way that Open Hardware projects can increase innovation potential through building upon effective past work.

    EXPLORING BIOMIMETIC DESIGN: BIOMIMICRY AND OPEN TECHNOLOGY IN ACTION

    I just returned from teaching a 2 week course at CIID (Copenhagen Institute of Interaction Design)[6] in Denmark. With the use of open source electronics boards and modular code libraries shared online through open source communities (such as Adafruit, Sparkfun, and DIYDrones), the students’ projects were able to reach great levels of sophistication, conceptually and technologically, in a short amount of time.

    City Pulse, a final project in the summer course, a data-driven real-time interactive projection based on the people’s motion

    City Pulse, a final project in the summer course, a data-driven real-time interactive projection based on the people’s motion

    This rapid innovation is possible when communities and individuals willingly donate R&D online, making available modular code libraries and hardware toolkits for affordable prices. Through open source sensor distributors, like Sparkfun and Adafruit, the prices of the sensors, (ie for temperature, humidity, acceleration, barometric pressure) are super affordable ($10 – $30USD). In just two weeks, people who had never built electronic circuits, never programmed a microcontroller in the programming language C, or never made real-time interactive computer graphics, were able to map their bike routes with GPS sensors, 3D-print prototypes to manufacture, develop a system for bacteria to harness energy based on people’s twitter feeds, design reactive screen based projections based on sensor data from people’s motion, and prototype robots to collect trash.

    Explore more about the class here.

     

    Sources Cited:

    [1]http://freedomdefined.org/OSHW

    [2]http://www.nytimes.com/2013/07/17/education/barrage-of-cyberattacks-challenges-campus-culture.html

    [3]http://www.nytimes.com/2013/05/23/world/asia/in-china-hacking-has-widespread-acceptance.html

    [4] http://patterns.ideo.com/issue/shanzhai/

    [5] http://uk.finance.yahoo.com/news/bandit-phone-king-has-the-last-laugh-ftimes-34bef9cc11fc.html

    [6] http://ciid.dk/education/summer-school/ciid-summer-school-2013/biomimetic-interfaces/

Comments

0 Responses to Fueling Innovation Through Shared Technology

Screen Shot 2013-08-06 at 8.14.02 PM

Leave a reply




 

Final Projects CIID

Screen Shot 2013-08-05 at 11.01.58 AM

image_ronny

lP8X2W37B4oNxz-sETYf8rcNoxNq3Al3tJtGDRp5aqE,B12HleIXoJuTDnxxqHoSi5bZpjLT7s8i7TkANvJFRxI

06puCO5j5E9UEyp99vbeaTYjxt7uGtWcgA2dCI6vNvY,UQfWbZd7SL3iSk_TGx_PciCnkrh37hpu7e9-UQjjZGM

yhNoKVPxTVuiWR9ERuxdSKWu9V-_No81mCHPqE4u368,D92Rrsd6DTH5_-l-aziQFdByJAL7hlyptrtkSDlZ5OU

Screen Shot 2013-08-01 at 1.44.55 AM

Teaching at CIID Summer Course 2013: Exploring Biomimetic Interfaces

I just returned from teaching a 2 week summer session course at CIID

It is an amazing place. And it was an intense and fantastic 2 weeks. It was a mix of Human – Based Design Thinking, Biomimetic practices, Programming, creative ideas, interactivity, and stacks of Arduinos. To see some of the course work see this site.

 

 

We arrived the first day: CIID Exploring Biomimetic Interfaces and went to the school.

We explored the lab and the equipment. They have a VERSA laser cutter, 3d printer, electronics bench, a woodshop, and a lot of spare materials.
CIID Exploring Biomimetic Interfaces CIID Exploring Biomimetic Interfaces CIID Exploring Biomimetic Interfaces

From there we head to the apartment and wandered the stairs until we were able to find the right apartment :)

d
CIID Exploring Biomimetic Interfaces CIID Exploring Biomimetic Interfaces

We got our bikes!
And the course began
CIID_CALENDAR

 

The first day of class:
Design Challenge: raft lanterns
CIID Exploring Biomimetic Interfaces CIID Exploring Biomimetic Interfaces

Design Thinking Crash Course : redesign the playground

 

CIID Exploring Biomimetic Interfaces CIID Exploring Biomimetic Interfaces CIID Exploring Biomimetic Interfaces
Day 2: Arduino Intro and lab #1. hardcore hands on.

 

Screen Shot 2013-08-01 at 1.47.40 AM

And assignment #1: Design solution from the perspective of a non human user
exploring biomimetic design exploring biomimetic design exploring biomimetic design

By day 3 already, we were planning for the final project and doing some analog user testing:
exploring biomimetic design exploring biomimetic design exploring biomimetic design

and analog fabrication, building, designing, planting, creating, conceiving, etc

exploring biomimetic design exploring biomimetic design plant

Screen Shot 2013-08-01 at 1.44.55 AM

 

mid term presentations:
antpres presentation1

AND A LOT OF WORK, late night wine, and planning:
gnight

and some picnics and some drinks: 
Ciid Copenhagen exploring biomimetic interfaces bar Ciid Copenhagen exploring biomimetic interfaces

and fun in chrisitiania
chritiania christ

some citi swimming:
Ciid Copenhagen exploring biomimetic interfaces Ciid Copenhagen exploring biomimetic interfaces

Finally the weekend came. We biked to Louisiana to see Tara Donovan.
gen exploring biomimetic design Ciid and Copenhagen summer 2013 exploring biometric interfaces classexploring biomimetic design bike 

 exploring biomimetic design exploring biomimetic design

 

 

 

Then the work resumed, as the week started back up. 
CIID_summerschool CIID_summerschool CIID_summerschool CIID_summerschool

And the arduino stacks grew:
arduino Ciid summer session

lots of late night work [it only doesn't look dark because it got dark aroundplay 10:30 because of the long days]:
class 9390402957_85dc5871cf_o lab

 

 

and a computer disaster disconnecting Genevieve from the rest of the world:
9386324797_df8811d79f_o Ciid summer session 2013

and a field trip to labitat:
CIID_summerschool CIID_summerschool Ciid summer session

And a long week later:
projects and presentations

METADATA : Exemplifying that unwillingly, we are all contributing to Metadata’s collection, but that can either be percieved positive or negative
THE ANTS PROJECT : encouraging recycling based on a point system modeled after ant behaviour
BIIKE – a gps tracker and data logging system to encourage biking in cities
ANTHILL – bringing sharing to mainstream with intelligent share stations setup in local supermarkets
SYMBO – a biomimetic flying trash collecting drone 
CITY PULSE – Urban Data and energy contributing both to information aggregation as well as public art and compelling visualisations

CIID_summerschool CIID_summerschool CIID_summerschool image_ronny arduinophoneCIID_summerschool CIID_summerschool

And the presentations:

CIID_summerschool CIID_summerschool

And FINALLY after an intense and sleepless week, the barbeque of celebration.
CIID_summerschool CIID_summerschool

Unreasonable Morocco: Protei Hackathon

http://unreasonable.is/video/episode-12-proteis-hack-a-thon-in-morocco/

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”

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:

AC DIMMER Circuit!!

I adapted this from info from Dmitri Grinberg’s post on Hackaday, “Lamp Fading and Remote Control for the Lazy”.

I have been trying for a number of weeks to perfect this, as in, find the correct transistor that would not overheat or burn out (one that is rated for a high enough voltage since it’s using AC 120 V). I followed this circuit from Dmitri’s blog, except instead of the IRF 250 I used an IRF730.

At first, I was using the IRF 520, with a 100 V drain source voltage and a 9 amp continuous drain current. It worked fine at first, and then it burnt out (there was connectivity between the gate-source and gate-drain). So I got an IRF540, with a 100 V drain source voltage and a 33 continuous drain current. This similarly worked at first, then burnt out.

Finally, I used the IRF730 which works pretty well so far! And doesn’t burn out – it is rated upto 400 V (which far surpasses the 120 V wall voltage in the US).

It works for a light (a resistive load):

and a fan (an inductive load):

Here is the simple dimming code used with the infrared detection sensor. I used a universal sony remote as the transmitter.

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(" volts");

// 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(" degrees C");

// now convert to Fahrenheight
float temperatureF = (temperatureC * 9.0 / 5.0) + 32.0;
Serial.print(temperatureF); Serial.println(" degrees F");

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 < 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 >= 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 < barPinCount; thisPin++) {
pinMode(barPin[thisPin], OUTPUT);
}
}

void loop() {
int volt = 0;
for(int i=0; i<10; i++)
{
volt += analogRead(sensorPin);
delay(zeit);
}
volt /= 10;

Serial.println(volt);
int litCount = 0;
if (volt <= 82) {
// >= 80cm
litCount = 1;
} else if (volt <= 92) {
// >= 70cm
litCount = 2;
} else if (volt <= 102) {
// >= 60cm
litCount = 3;
} else if (volt <= 123) {
// >= 50cm
litCount = 4;
} else if (volt <= 154) {
// >= 40cm
litCount = 5;
} else if (volt <= 184) {
// >= 30cm
litCount = 6;
} else if (volt <= 266) {
// >= 20cm
litCount = 7;
} else if (volt <= 328) {
// >= 15cm
litCount = 8;
} else if (volt <= 461) {
// >= 10cm
litCount = 9;
} else if (volt > 461) {
// < 10cm
litCount = 10;
}

for(int b=0; b<10; b++)
{
if(b<=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%

circuit – 2 axis parallax accelerometer

This is on the arduino side:

int pinX = 3;
int pinY = 2;
unsigned long serialTimer = millis();
unsigned long xAcc = 0;
unsigned long yAcc = 0;
boolean flipflop;

void setup()
{
pinMode(pinX, INPUT);
pinMode(pinY, INPUT);
Serial.begin(115200);
}

void loop()
{
if (flipflop == true) {
xAcc = pulseIn(pinX, HIGH);
flipflop = false;
} else {
yAcc = pulseIn(pinY, HIGH);
flipflop = true;
}

if ((millis() - serialTimer) > 50 ) {
Serial.print("X ");
Serial.println(xAcc);
// Serial.print(" ");
Serial.print("Y ");
Serial.println(yAcc);
}
}

to visualize it:
in processing:

import processing.serial.*;

Serial port; // Create object from Serial class
int val; // Data received from the serial port
int xAngle;
int yAngle;

void setup()
{
println ( Serial.list());
size(200, 200,P3D);
frameRate(10);
// Open the port that the board is connected to and use the same speed (9600 bps)
port = new Serial(this, Serial.list()[0],115200);
port.bufferUntil(13);
lights();

}

void draw()
{
background(0);
directionalLight(51, 102, 126, 0, 0, -1);
translate(100,100,0);
rotateX(map(xAngle,3800,6300,-1 * HALF_PI,HALF_PI));
rotateY(map(yAngle,3800,6300,-1 * HALF_PI,HALF_PI));
translate(-50,-50,0);
rect(0,0,100,100);

}

void serialEvent(Serial p) {
String msg = port.readStringUntil(13);
if (msg != null) readMsg(msg);

}

void readMsg(String msg) {

//remove non printing chars
int badChars = 0;
for (int i = msg.length() -1; i >= 0; i--) {
char c = msg.charAt(i);
if ( c == 10 || c ==13) {
badChars++;
}
}
if (badChars > 0) msg = msg.substring(0,msg.length()-badChars+1);

String[] words = splitTokens(msg);
if (words[0].equals("X")) {

xAngle = int( words[1]);
}
if (words[0].equals("Y")) {
yAngle = int( words[1]);
}

}

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

<code>/*
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 <Wire.h>
#include <SPI.h>
#include <Ethernet.h>
#include "RTClib.h"
#include <SD.h>

#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("Card failed, or not present");
// don't do anything more:

}
Serial.println("card initialized.");

Wire.begin();
RTC.begin();
delay(50);
bmp085Calibration();
if (! RTC.isrunning()) {
Serial.println("RTC is NOT running!");
// following line sets the RTC to the date & time this sketch was compiled
RTC.adjust(DateTime(__DATE__, __TIME__));
}
dataFile = SD.open("data.txt", FILE_WRITE);
delay(500);

// start the Ethernet connection:
Ethernet.begin(mac);
if (Ethernet.begin(mac) == 0) {
Serial.println("Failed to configure Ethernet using DHCP");
// 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("connecting...");
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("requesting!");
}
if(millis() - lastAttemptTime>requestInterval){
//if youre not connected and two minutes have passed, attempt to connect again
client.stop();
// Serial.println("stopping and reconnecting!");

// 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("disconnecting.");

client.stop();
delay(1500);
if(millis() - lastAttemptTime>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()>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(","));
dataFile.print(now.hour());
dataFile.print(F(":"));
dataFile.print(now.minute());
dataFile.print(F(":"));
dataFile.print(now.second());
dataFile.print(F(","));
dataFile.print(voltage);
dataFile.print(F(","));
dataFile.print(temp);
dataFile.print(temperature);
dataFile.print(F(","));
dataFile.print(pressure);
dataFile.println();

}

dataFile.flush();
}
else{digitalWrite(ledPin, LOW);}

}

void connectToServer(){
// Serial.println("connecting to server...");
if (client.connect(server, 80)) {
requested = false;
}

lastAttemptTime = millis();
}

boolean makeRequest() {
// Serial.println("requesting");
getData();
// Make a HTTP request:

client.print("GET /understanding_networks/dataLogger.php?data=");
client.print(now.month());
client.print('/');
client.print(now.day());
client.print('/');
client.print(now.year());
client.print(F(","));
client.print(now.hour());
client.print(F(":"));
client.print(now.minute());
client.print(F(":"));
client.print(now.second());
client.print(F(","));
client.print(voltage);
client.print(F(","));
client.print(temp);
client.print(F(","));
client.print(temperature);
client.print(F(","));
client.print(pressure);
client.println(" HTTP/1.1 ");
client.println("HOST: www.levinegabriella.com");

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) >> 15;
x2 = ((long)mc << 11)/(x1 + md);
b5 = x1 + x2;

return ((b5 + 8)>>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)>>12)>>11;
x2 = (ac2 * b6)>>11;
x3 = x1 + x2;
b3 = (((((long)ac1)*4 + x3)<<OSS) + 2)>>2;

// Calculate B4
x1 = (ac3 * b6)>>13;
x2 = (b1 * ((b6 * b6)>>12))>>16;
x3 = ((x1 + x2) + 2)>>2;
b4 = (ac4 * (unsigned long)(x3 + 32768))>>15;

b7 = ((unsigned long)(up - b3) * (50000>>OSS));
if (b7 < 0x80000000)
p = (b7<<1)/b4;
else
p = (b7/b4)<<1;

x1 = (p>>8) * (p>>8);
x1 = (x1 * 3038)>>16;
x2 = (-7357 * p)>>16;
p += (x1 + x2 + 3791)>>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()<2)
;
msb = Wire.read();
lsb = Wire.read();

return (int) msb<<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<<6) into register 0xF4
// Request a pressure reading w/ oversampling setting
Wire.beginTransmission(BMP085_ADDRESS);
Wire.write(0xF4);
Wire.write(0x34 + (OSS<<6));
Wire.endTransmission();

// Wait for conversion, delay time dependent on OSS
delay(2 + (3<<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() < 3)
;
msb = Wire.read();
lsb = Wire.read();
xlsb = Wire.read();

up = (((unsigned long) msb << 16) | ((unsigned long) lsb << 8) | (unsigned long) xlsb) >> (8-OSS);

return up;
}

void blink(int thisPin, int howManyTimes){
for (int blinks = 0;blinks<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
</code>

robot boat with many sensing capabilities


STEP BY STEP HOW TO:
http://levinegabriella.com/teaching/Boat.pdf TUTORIAL and CODE
github.com/gabriella/boat-

Logging data remotely to the web, no computer

So I switched over the client to here: http://levinegabriella.com/understanding_networks/liveApplet/

(I have to figure out why no text is appearing on the graph – i had temperature and light and date markers)

the php server is written here: http://levinegabriella.com/understanding_networks/dataLogger.php

The server reads and writes to a text file here: http://www.levinegabriella.com/understanding_networks/liveApplet/DATAcl.TXT

See code below for Arduino and php and processing

Next step: The day I left NY my dataLogging Arduino “crashed”, after working for a week . It could have been any number of things. The SD card, the server, a short?
Try Pachube, and Watch Dog to restart Arduino if it crashes.
Can i do some virtual debugging?

Also, Arduino UNO ran out of space (the functions include: data logger, ethernet connection to a server, temp sensor, light sensor, real time clock – But there are many more sensors on board (gps, humidity, accelerometer, barometric pressure) so I’ve moved everything over to the MEGA. Had to rearrange the SPI / I2C pin connections, but besides that it’s all good.

(all the code (php, processing, arduino) can also be downloaded here)

More to come…

<?php
// put the name and path of the text file in a variable.
// this is the text file where we'll store the data:
$filename = 'liveApplet/DATAcl.TXT';

//make sure the file is not empty:
if (file_exists($filename)) {
// get the contents of the file
// and put them in a variable called $fileContents:
$fileContents = file_get_contents($filename);

// if there is new data from the client, it'll
// be in a request parameter called "data".
if (isset($_REQUEST['data'])) {
// append what the client sent as 'data' to
// the variable holding the file contents:
$fileContents = $fileContents . "\n". $_REQUEST['data'];
// put the file contents back into the file
// you're overwriting the whole file when you do this:
file_put_contents($filename, $fileContents);
} else {
// there was no data sent in the request
// so show the old stuff:
// echo '<p>' . $fileContents . '</p>';
//split the string of the newLines:
$strings = explode("\n", $fileContents);
//loop over the array of the lines, adding a break at the end of each
foreach ($strings as $thisString){
echo $thisString . "<br/>\n";
}
}
}
?>

Arduino:
[/python]
/*
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
#include
#include
#include “RTClib.h”
#include

// Enter a MAC address for your controller below.
// Newer Ethernet shields have a MAC address printed on a sticker on the shield
byte mac[] = {
0×00, 0xAA, 0xBB, 0xCC, 0xDE, 0×03 };
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 = 4;//changed from 8
const int LOCATION_FILE_NUMBER_LSB = 0×00;
const int LOCATION_FILE_NUMBER_MSB = 0×01;

File dataFile;
RTC_DS1307 RTC;
EthernetClient client;
DateTime now;

void setup() {
// start the serial library:
Serial.begin(9600);
pinMode(A2, OUTPUT);
pinMode(A3, OUTPUT);
// A2 is the ground, A3 is the power:
digitalWrite(A2, LOW);
digitalWrite(A3, HIGH);
pinMode(10, OUTPUT);

if (!SD.begin(chipSelect)) {
Serial.println(“Card failed, or not present”);
// don’t do anything more:

}
Serial.println(“card initialized.”);

Wire.begin();
RTC.begin();
delay(50);
if (! RTC.isrunning()) {
Serial.println(“RTC is NOT running!”);
// following line sets the RTC to the date & time this sketch was compiled
RTC.adjust(DateTime(__DATE__, __TIME__));
}
dataFile = SD.open(“data.txt”, FILE_WRITE);
delay(500);

// start the Ethernet connection:
Ethernet.begin(mac);
if (Ethernet.begin(mac) == 0) {
Serial.println(“Failed to configure Ethernet using DHCP”);
// 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(“connecting…”);
connectToServer();
}

void loop()
{

now = RTC.now();
if(client.connected()){
if(!requested){

requested = makeRequest();
// Serial.println(“requesting!”);
}
if(millis() – lastAttemptTime>requestInterval){
//if youre not connected and two minutes have passed, attempt to connect again
client.stop();
// Serial.println(“stopping and reconnecting!”);

// 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(“disconnecting.”);

client.stop();
delay(1500);
if(millis() – lastAttemptTime>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;

// Serial.print(voltage);
// Serial.print(F(“,”));
// Serial.print(temp);
// Serial.print(F(“,”));
// Serial.println(” “);
//
if (dataFile) {
DateTime now = RTC.now();

dataFile.print(now.month());
dataFile.print(‘/’);
dataFile.print(now.day());
dataFile.print(‘/’);
dataFile.print(now.year());
dataFile.print(F(“,”));
dataFile.print(now.hour());
dataFile.print(F(“:”));
dataFile.print(now.minute());
dataFile.print(F(“:”));
dataFile.print(now.second());
dataFile.print(F(“,”));
dataFile.print(voltage);
dataFile.print(F(“,”));
dataFile.print(temp);
dataFile.println();

}
dataFile.flush();

}

void connectToServer(){
// Serial.println(“connecting to server…”);
if (client.connect(server, 80)) {
requested = false;
}

lastAttemptTime = millis();
}

boolean makeRequest() {
// Serial.println(“requesting”);
getData();
// Make a HTTP request:

client.print(“GET /understanding_networks/dataLogger.php?data=”);
client.print(now.month());
client.print(‘/’);
client.print(now.day());
client.print(‘/’);
client.print(now.year());
client.print(F(“,”));
client.print(now.hour());
client.print(F(“:”));
client.print(now.minute());
client.print(F(“:”));
client.print(now.second());
client.print(F(“,”));
client.print(voltage);
client.print(F(“,”));
client.print(temp);
client.println(” HTTP/1.1 “);
client.println(“HOST: www.levinegabriella.com”);

client.println();
return true;

}

void blink(int thisPin, int howManyTimes){
for (int blinks = 0;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
[/python]

Protei at Open_hardware summit 2011

This was the most inspiring day for me.

Here is a link to my slides.

nice write up on the science american blog

A wireless robotic locomotive doorbell surveillance camera

unfinished…
I started making a wireless doorbell that would make a phone ring

Perhaps the phone no longer requires 20 Hz at 48 to 90 volts AC because it doesn’t have those vintage brass bells but rather a buzzer with a piezo, but I couldn’t figure out how to get the right waveform – then the phone went missing. so… my doorbell is a number of layered moving servos activated by a joystick. There is a wireless camera attached to the top which plays back on a screen (or a computer if I go through a little unit (from GrassValley I have).

Jerky camera robot arm prototype:

Camera mounted:

Testing the servos:

Wirelessly controlling three servos with my joystick:

I used a joystick that I had previously hacked into, for the networked PONG game that is in the hall of ITP.

Here are some photos from the process:

radios

more to come