Friday, June 4, 2010

Ifs and Loops

The biggest issue we face now in our intended Smart Systems is configuring a complicated series of loops / 'if' statements that would decide and determine whose light was on and off.

Our original protocol was that if three people had lights on and the fourth person wanted light too, the person who had the most amount of light in their environment (determined by value of LDR) would have their light switched off.


Alternatively, the person whose light had been on for the longest amount of time. We had known from the start that this would be a difficult system to program but decided to pursue it. I devised a diagram to figure out what possible combination of light were possible (15 in total) and wrote a very simple sketch in processing where two ellipses could be made to appear and disappear using the letters 'a' and 's' and only one could be visible at a time.

boolean v1, v2, v3, v4;

void setup(){
background(255);

frameRate(6);

v1=false;
v2=false;
v3=false;
v4=false;

}

void draw (){


if(keyPressed) {

if (key == 'a' || key == 'A') {
if (v1==false) {
v1=true;
v2=false;

} else {
v1=false;
}
}



if (key == 's' || key == 'S') {
if (v2==false) {
v2=true;

v1=false;
} else {
v2=false;
}
}

if (key == 'd' || key == 'D') {

if (v3==false) {
v3=true;
v1=false;

} else {
v3=false;

}
}


if (key == 'f' || key == 'F') {
if (v3==false) {

v4=true;
v1=false;
} else {
v4=false;
}

}

drawEllipse();
}
}

void drawEllipse(){

if (v1==true){
fill(0);
ellipse(30,50,10,10);
} else {
fill(255);
ellipse(30,50,10,10);

}

if (v2==true){
fill(0);
ellipse(50,50,10,10);

} else {
fill(255);
ellipse(50,50,10,10);
}

if (v3==true){
fill(0);

ellipse(70,50,10,10);
} else {

fill(255);
ellipse(70,50,10,10);
}

if (v4==true){
fill(0);

ellipse(90,50,10,10);
} else {
fill(255);
ellipse(90,50,10,10);
}

}

It was only when I tried to implement a third and fourth ellipse I found myself getting a little more confused.

Another stupidly obvious issue we'd overlooked was that if, for example, I switched my dummy switch on then would trigger the servo to switch my real light switch. But if it was my turn to have my light switched off and hence the servo would return the real light switch to an off position, my dummy switch would still remain in the 'on' position, hence messing up the system. We discussed many possible systems we could implement that still incorporated some sensor by which it made as decision as to who would have their lights on or off, hence ensuring it was still a smart system.

The main ideas we were trying to incorporate were use of an LDR to determine level of light an / or a timer to determine how long you've had your light on.

We debate the idea of a shared decision making process where you would push your button if you wanted your light on but it would only send out your 'request' for light if the existing level of light was below a certain threshold. Then a yes / no majority voting system would determine whether you got your light switched on. This was a fairly weak idea as it wasn't particularly 'smart' and again would involve a complicated series of programming loops.


Finally, we scaled it down completely. A very simple idea built from our funadmenta
l idea and mechanics - simple loop where each person reads one other person's feed and their lights is adjusted accordingly, as illustrated below.
It is a simple method based on the idea of only three lights on at one time but it is a fall back which we know more or less is feasible. After setting it up in practice, it went mostly as expected. The only issue we experiences was realising we would need to configure the button to not only send out the data to the feed, but to also control it's own servo so as to actually switch on the light when requested, and even then at the same time, reading the feed to control the servo. A small modification of the code made this possible.

Another alternate method Tapani and Jacques started exploring was implementing use of the Pachuino, a library which makes use of Pachube to provide real time remote sensor data while still sharing local sensor data. They found a different way to approach our idea and their resulting code is as follows:

import eeml.*;
import processing.serial.*;
import cc.arduino.*;
import pachuino.*;


Pachuino p;

float lastUpdate;
float jacquesBtn;
float jacquesLdr;
float tapaniBtn;
float tapaniLdr;
float seamusBtn;

float seamusLdr;
float juditBtn;
float juditLdr;

void setup()
{
p = new Pachuino(this, Arduino.list()[0], 57600);
p.manualUpdate("http://www.pachube.com/api/7584.xml");
p.setKey("API");

p.addRemoteSensor("http://www.pachube.com/api/7344.xml", 0); // jacques button
p.addRemoteSensor("http://www.pachube.com/api/7344.xml", 1); // jacques ldr
p.addRemoteSensor("http://www.pachube.com/api/7339.xml", 0); // tapani button
p.addRemoteSensor("http://www.pachube.com/api/7339.xml", 1); // tapani ldr
p.addRemoteSensor("http://www.pachube.com/api/7472.xml", 0); // seamus button
p.addRemoteSensor("http://www.pachube.com/api/7472.xml", 1); // seamus ldr
p.addRemoteSensor("http://www.pachube.com/api/7584.xml", 0); // judit button
p.addRemoteSensor("http://www.pachube.com/api/7584.xml", 1); // judit ldr

p.addLocalSensor("digital", 0, "button");
p.addLocalSensor("analog", 1, "ldr");
//p.addLocalSensor("digital", 9, "servo");
}

void draw()
{
jacquesBtn = p.remoteSensor[0].value;
jacquesLdr = p.remoteSensor[1].value;
tapaniBtn = p.remoteSensor[2].value;
tapaniLdr = p.remoteSensor[3].value;

seamusBtn = p.remoteSensor[4].value;
seamusLdr = p.remoteSensor[5].value;
juditBtn = p.remoteSensor[6].value;
juditLdr = p.remoteSensor[7].value;

if ((millis() - lastUpdate) > 10000)
{
if (juditBtn == 1.0)

{
p.analogWrite(9, 1);
println("off");
delay(500);
p.analogWrite(9, 0);
lastUpdate = millis();
}
else if (juditBtn == 0.0)
{

if (juditLdr <= jacquesLdr || juditLdr <= tapaniLdr || juditLdr <= seamusLdr) { p.analogWrite(9, 180); println("on"); delay(500); p.analogWrite(9, 0); lastUpdate = millis(); } else { println ("Sorry mate. You've got too much light already."); l astUpdate = millis(); } } else { println ("none"); } } } void onReceiveEEML(DataIn d) { p.updateRemoteSensors(d); } Essentially, it still performs the same operations of reading sensor data and sending it while simultaneously reading data and implementing it. The way they approached the protocol however was that if you pressed your button to try switch your light on, it would then read and compare the other users' LDR readings with their own and if the local LDR value was the greatest, the light would be switched off or remain off.



In theory, it worked. In practise, we encountered lots of error messages which we spent an afternoon trying to trouble shoot. One big issue was the frequency with which we try trying to access and upload data from Pachube, quickly maxing out our API usage allowance.

With time running out, it was coming time to make a decision, find a solution, and actually build the physical component.

No comments:

Post a Comment