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; }