Mind Over Melon
Mind Over Melon is a LVL1 project made by Chris and Brad. It's purpose is simple: Destroy watermelons with your mind. It uses a Star Wars Force Trainer toy attached to an Arduino FIO with Xbee, paired to another Arduino + Xbee, attached to a 200psi Solenoid Valve. The solenoid valve dumps CO2 into the melon when brain activity reaches a certain threshold.
Hardware
The melon fits over a 3/4" copper pipe full of holes. The pipe is fitted to 1/2" tubing, which connects to a solenoid valve. The solenoid valve is directly connected to a CO2 tank, regulated to 200 PSI.
We used this solenoid valve: http://www.ebay.com/itm/ws/eBayISAPI.dll?ViewItem&item=300615692386&ssPageName=ADME:L:OU:US:1123#ht_2096wt_872
Headset
The Force Trainer headset was hacked using instructions from http://frontiernerds.com/brain-hack. An Arduino Fio ties into the headset through a SoftSerial connection. It reads only the attention level and relays the value over the Xbee back to the base station.
Brain library here.
SoftSerial library here.
#include <Brain.h>
#include <NewSoftSerial.h>
// Set up the brain parser, pass it the serial object you want to listen on.
// Create a NewSoftSerial connection, TX on pin 2, and RX on pin 3
// Download the library here: http://arduiniana.org/libraries/NewSoftSerial/
NewSoftSerial softBrain(2, 3);
Brain brain(softBrain);
void setup() {
// Start the hardware serial.
Serial.begin(9600);
}
void loop() {
if (brain.update()) {
Serial.print(brain.readAttention());
}
}
Base Station
The base station consists of an Xbee, 10 LEDs, a relay, and a potentiometer. The relay triggers the solenoid when needed, as the solenoid draws 3A@12v.
The 10 LEDs are attached to D2 - D11 on the Arduino, and are used as an LED bar graph. The relay to fire the melon is on pin D12. The potentiometer acts as a difficulty setting, and is attached to A0. The headset delivers output values ranging from 0-100, so the difficulty knob adjusts the threshold from 0-100 in increments of 10.
Once the threshold is exceeded, the valve is held open for 1 second, then there is a cooldown period of 5 seconds, to allow us to remove the user's headset, so they don't set the machine off again.
The code is below:
void lineGauge(int value);
void lineDDR();
void configureDifficulty();
void explode();
enum state { CONFIG, EXPLODE, DISABLE };
int previousDifficulty;
state melonState;
int brainDifficulty;
int difficultyTimeout;
#define TIMEOUTRESET 2500
#define DISABLEPERIOD 10000
// the setup routine runs once when you press reset:
void setup() {
// initialize the digital pin as an output.
pinMode(led, OUTPUT);
pinMode(12, OUTPUT);
lineDDR();
Serial.begin(9600);
previousDifficulty = analogRead(A0);
lineGauge(0);
}
// the loop routine runs over aand over again forever:
void loop() {
if(analogRead(A0) >= previousDifficulty + 10 || analogRead(A0) <= previousDifficulty - 10)
{
previousDifficulty = analogRead(A0);
melonState = CONFIG;
difficultyTimeout = TIMEOUTRESET;
}
switch(melonState)
{
case CONFIG:
configureDifficulty();
break;
case EXPLODE:
explode();
break;
case DISABLE:
delay(DISABLEPERIOD);
lineGauge(0);
melonState = EXPLODE;
while (Serial.read() >= 0);
break;
}
}
int lineOutput(int input)
{
int difficultyScale = map(input, 0, 100, 0, 255);
int test = map(min((difficultyScale * 10) / brainDifficulty, 255), 0, 255, 1, 10);
return test;
}
void configureDifficulty()
{
int out = map(analogRead(A0), 0, 1023, 0, 9);
lineGauge(1 << out);
difficultyTimeout--;
delay(1);
if(difficultyTimeout <= 0)
{
melonState = EXPLODE;
brainDifficulty = map(analogRead(A0), 0, 1023, 1, 10);
}
}
void explode()
{
int incomingByte;
if (Serial.available() > 0) {
// read the incoming byte:
incomingByte = Serial.read();
Serial.println((int)incomingByte);
int outfactor = lineOutput((int)incomingByte);
lineGauge(pow(2, outfactor));
if(outfactor == 10)
{
digitalWrite(12, HIGH);
delay(1000);
digitalWrite(12, LOW);
melonState = DISABLE;
}
}
}
void lineDDR()
{
pinMode(2, OUTPUT);
pinMode(3, OUTPUT);
pinMode(4, OUTPUT);
pinMode(5, OUTPUT);
pinMode(6, OUTPUT);
pinMode(7, OUTPUT);
pinMode(8, OUTPUT);
pinMode(9, OUTPUT);
pinMode(10, OUTPUT);
pinMode(11, OUTPUT);
}
void lineGauge(int value)
{
unsigned int extraValue = ~value;
byte toPortD = (extraValue & 0b00111111) << 2;
byte toPortB = (extraValue & 0b1111000000) >> 6;
PORTD = toPortD;
PORTB = toPortB;
}