Monday, June 7, 2010

Penalties

After another round of discussion and brainstorm, we finally seemed to have found a feasible solution. Combining the successful mechanism and serial communication achieved by myself and Seamus (bypassing the use of Firmata using the Handshake method) and the successful protocol of comparing LDR readings figured out by Tapani and Jacques, it suddenly started to make sense.



Use of the button had become redundant so we removed it completely, hence the system would be completely autonomous making decisions for itself based on a combination of LDR readings and time. Essentially, each user receives a penalty for how much light they have and how long they've had it on for. For example:


- Seamus has quite a dim light reading around 300 so each second he has his light on, he receives a penalty of 1, plus a 1% value of his LDR reading. So each second, he accumulates 1.3 points.

- Tapani has a really bright light reading around 1000 so each second his light is on, he received a penalty of 1, plus a 1% value of his LDR reading. So each second, he accumulates 2 points.

These penalty values from each user are uploaded to a Pachube feed and each other users' values are retrieved. The values are compared locally and whoever has the highest penalty points has their light switched off.

Furthermore, Jacques had his light switched off so his LDR reading is below a set minimum threshold of 100 so he stops accruing penalty points.


So, essentially:


The process of sending & receiving from Pachube is taken from the method we tried using Pachuino but using instead a further adaptation of the handshake code.

Arduino takes care of the penalty calculation and timer which it then sends to serial:

/*
Sensor Reader
Language: Wiring/Arduino

Reads two analog inputs and one digital input
and outputs their values.
Connections:
analog sensors on analog input pins 0 and 1
switch on digital I/O pin 2
*/

float timer, LDRvalue, scaledLDR;

int sensorValue = 0; // reading from the sensor
int servoControl;

#include
Servo myservo;
//int pos = 0;

void setup() {
// configure the serial connection:
Serial.begin(9600);
// configure the digital input:

myservo.attach(9);

establishContact();
}


void loop() {

// read the sensor:
LDRvalue = analogRead(1);

if (LDRvalue > 100){
scaledLDR = LDRvalue/100;
timer = timer + scaledLDR;
delay(1000);

}


if (Serial.available() > 0) {
// read the incoming byte:
int inByte = Serial.read();
Serial.println(timer);

if(inByte == 66){
myservo.write(180);
}

if(inByte == 67){
myservo.write(0);
}
}
}

void establishContact() {
while (Serial.available() <= 0) { Serial.println("hello"); // send a starting message delay(300); } }


Processing reads the value from serial as a string, converts it to an integer and then uploads it to Pachube. Simultaneously it also reads the value from the three other feeds and compares the value. Once it has compared the values, it adjusts the state of the servo by sending back to Arduino through serial a 'B' or a 'C'.

/*
Serial String Reader
Language: Processing

Reads in a string of characters from a serial port until
it gets a linefeed (ASCII 10). Then splits the string into
sections separated by commas. Then converts the sections to ints,
and prints them out.

Original code by Tom Igoe
*/

import processing.serial.*; // import the Processing serial library
Serial myPort; // The serial port

boolean firstContact = false; // Whether we've heard from the microcontroller
boolean controlServo = false;

//setup for pachube recieving
import eeml.*;
DataIn dIn;
float myVariable;

//setup for pachube sending
DataOut dOut;
float lastUpdate;
int buttonState =0;


void setup() {

// List all the available serial ports
println(Serial.list());
myPort = new Serial(this, Serial.list()[0], 9600);
myPort.bufferUntil('\n');


dIn = new DataIn(this,"http://www.pachube.com/api/feeds/7472.xml",
"API", 7000);


dOut = new DataOut(this, "http://www.pachube.com/api/feeds/7584.xml",
"7495f20ef1f5da0b1a40dae277c042c33018cf26cb16c33a3be4e3cf789d9c39");
dOut.addData(2,"button");

}

void draw() {
background(255);
}



void serialEvent(Serial myPort) {
// read the serial buffer:
String myString = myPort.readStringUntil('\n');
// if you got any bytes other than the linefeed:
if (myString != null) {

myString = trim(myString);

// if you haven't heard from the microncontroller yet, listen:
if (firstContact == false) {
if (myString.equals("hello")) {
myPort.clear(); // clear the serial port buffer
firstContact = true; // you've had first contact from the microcontroller
myPort.write('A'); // ask for more
//println(firstContact);
}
}
// if you have heard from the microcontroller, proceed:
else {

float recievedData = new Float(myVariable);
float myData = new Float(myString);

//println(recievedData);
//println(myData);
if (myData > recievedData){
myPort.write("B");
println("Judit");
} else {
myPort.write("C");
println("Seamus");
}


//send data to pachube
if ((millis() - lastUpdate) > 7000){


println("ready to POST: ");
dOut.update(0, myString); // update the datastream
int response = dOut.updatePachube(); // updatePachube() updates by an authenticated PUT HTTP request
println(response); // should be 200 if successful; 401 if unauthorized; 404 if feed doesn't exist
lastUpdate = millis();
}
}
}


// when you've parsed the data you have, ask for more:
myPort.write("A");
}

void onReceiveEEML(DataIn d){
myVariable = d.getValue(4); // get the value of the stream 1

}

When we set this up with two of us, it seemed to work so the next step is to set it up with all four of us. If this too runs successfully, we are ready to run it off site.

Finally, the other obstacle we've had to overcome has been in regards to API usage. The limits of Pachube only enable data to be accessed (sent or received) 50 times every 3 minutes (on average once every 3.6 seconds). We felt extremely limited by this as it meant that the more feeds we were accessing, the longer delay we'd have to implement. Many times we received warnings that we'd exceeded this limit so we sent a request to be whitelisted to allow for greater usage allowance. Amazingly, this was granted!

No comments:

Post a Comment