shahar @ itp

API for the World

I’d like to proudly present to you…. our project for the Techcrunch Disrupt Hackathon!
First, a demo:

Some technical details (pictures to follow soon!):
The key component in the hardware is a SCT-013-000 non-invasive current transformer kindly loaned to us by Tom Igoe, which we’ve also cheaply replicated following this instructable.

Since we were looking to only get an on/off signal, and seeing as we only had around 20 hours, we kept everything as simple as possible. The hardware includes an Arduino, the CT, a voltage divider and an XBee that we used to transparently transmit the on/off signal to a server.

Arduino code:

void setup() {
  pinMode(13, OUTPUT);
  Serial.begin(9600);
}

int numSamples = 0;
long sum = 0;
int mean = 0;

const int NUM_SAMPLES = 2000;
const int ON_THRESHOLD = 50;

int state = -1;

void loop() {
  // read the AC voltage, scaled to 5V and centered at 2.5V
  // 5.0V    _       _       _
  //        / \     / \     / \
  // 2.5V -/   \   /   \   /   \
  //            \ /     \ /
  // 0.0V        -       -
  
  int val = analogRead(1);
  // calculate the running mean
  mean = (mean + val) / 2;

  // substract the average
  val -= mean;
//  Serial.print(val, BYTE);
  
  // square it and add to the sum
  sum += (val * val);
  numSamples++;
  
  if (numSamples == NUM_SAMPLES) {
/////////// DEBUG ONLY: print the values
//    Serial.println((sum/numSamples), DEC);
    boolean newState = ((sum / numSamples) > ON_THRESHOLD);
    digitalWrite(13, newState);
    if (newState != state) {
      Serial.print(newState, BYTE);
      state = newState;
    }
    numSamples = sum = 0;
  }
}

Processing (Proclipsing) server code (you’ll need the Jersey RESTful Web Services Client to run this):

package awpost;

import javax.ws.rs.core.MultivaluedMap;

import processing.core.PApplet;
import processing.serial.*;

import com.sun.jersey.api.client.*;
import com.sun.jersey.api.client.ClientResponse.Status;
import com.sun.jersey.core.util.MultivaluedMapImpl;

public class AWPost extends PApplet {
	Serial myPort;        // The serial port
	int graphXPos = 1;    // the horizontal position of the graph:

	private final String BaseURI = "http://a4w.heroku.com/messages";
	private WebResource wr;
	private int lastVal = 0;
	private boolean report = true;

	public void setup() {
		size(400, 300);        // window size

		Client client = Client.create();
		wr = client.resource(BaseURI);

		// List all the available serial ports
		println(Serial.list());
		// I know that the first port in the serial list on my mac
		// is usually my Arduino module, so I open Serial.list()[0].
		// Open whatever port is the one you're using.
		myPort = new Serial(this, Serial.list()[0], 9600);

		// set inital background:
		background(48,31,65);
	}

	public void draw() {
		background(lastVal == 0 ? 0 : 255);
	}

	public void keyPressed() {
		switch (key) {
		case 'o': // turn reporting on/off
			report = !report;
			println(report ? "will report" : "will NOT report");
			break;
		case 'p':	// panic button
			lastVal = (lastVal == 0) ? 1 : 0;
			report();
			break;
		}
	}

	private void report() {
		MultivaluedMap formData = new MultivaluedMapImpl();
		formData.add("device_id", "1");
		formData.add("status", (lastVal == 0) ? "OFF" : "ON");
		ClientResponse response = wr.type("application/x-www-form-urlencoded").post(ClientResponse.class, formData);
		Status s = response.getClientResponseStatus();
		println(s.getStatusCode() + ": " + s.toString());
	}

	public void serialEvent (Serial myPort) {
		// get the byte:
		lastVal = myPort.read();

		println((lastVal == 0) ? "OFF" : "ON");

		if (report) {
			report();
		}
	}
}

2 Responses to “API for the World”

  1. [...] the arduino code can be downloaded here May 23, 2010 | | Tags: current sensor, hackathon, new york [...]

  2. [...] working on sensor documentation of the project and an instructable, as well as open sourcing the code. Thanks to TechCrunch and the [...]

Leave a Reply