Tuesday, September 9, 2008

A piano combination lock

This will probably be the only week with three Phys Comp entries. Following the basic wiring exercise and the earring switch, I present you with a Keyboard Combination Lock! The idea here is to mock up a "lock" where the user must enter a particular "melody" or order of keys to make an LED light up. Along the way, they should get clues that they are on the right track, or failing miserably. This is done with a series of switches, one for each piano key.


The finger from a glove with conductive mesh on the tip, soldered to a wire

The Arduino, all wired up. D1-D7 are inputs, D8 and 9 are outputs

To start with, I found a glove on the Junk shelf, pre-wired with some conductive material on the fingertips, soldered to wires. I cut a finger off and soldered its wire to my incoming power (indirectly wired to 5V on the Arduino Chip). Then I set up seven possible switches, each complete with its own digital input (D1-D7 on the Arduino) and a resistor running to ground for when each individual switch was not in use.


The breadboard, wired up. The red wires on the left go to the Ardrino, the ones on the right go to the keybord

The keyboard - a printout on wood, wires are taped down at the top and bottom

The inputs for the switches were stretched across a printout of a piano keyboard on top of some wood for stability. This gives the user to ability to complete each of the seven switches at will. D8 and D9 were wired to a red and green LED (through protective resistors) to give the user feedback on how they were doing.

The first key (F) being pressed in the correct sequence.

F being pressed out of order. User must start over

The "correct" sequence I chose was pretty arbitrary - an F key followed by a G key. that is, an input into D1 followed by D2. Pressing any other key, including pressing the two correct inputs out of order, causes a red "error" LED to light up briefly. If they get both correct, the green flashing LED of happiness turns on. The green light also blips when the first key is pressed successfully so the user knows they're on the right track. However, if the second key is still incorrect, they'll have to start all over again.


Another key being pressed at any time. User must start over.

The sequence was entered correctly. It's flashing, take my word for it.

Just to be careful, I included a fail-safe to make sure that only one key was being pressed at a time to keep the user from cheating by just pressing down a piece of metal on all the keys at once. There's a small pause after the first key is pressed correctly to give the user time to lift thier finger.

The program is pretty simple. The Arduino watches all the keys waiting for inputs. There are three main possibilities: The first key is pressed (at the right or the wrong time), the second key is pressed (also at the right or the wrong time), and any other key is pressed (always at the wrong time, 'cause they're not part of the sequence). Nested if statements check to make sure those inputs are being triggered in the right sequence, and force the user to start over if they're not. D8 and D9 are designated outputs - they flash a red, green, or a green pulsing pattern to give the user feedback on what's going on.

Here's the code!
/*Piano combination lock.  This code'll strobe a green led until the board is reset if the first switch (in this case and F key) followed by a G key, is pressed in that order.  It will also give a little encouraging green blip if the first key is pressed correctly.  If any other key is pressed for the first selection (including the G key), a red light will blip, and you'll have to start over.  Likewise for the second key.  That's it! */

// declare variables:
int switchPin1 = 1; // digital input pin for switch 1
int switchPin2 = 2;
int switchPin3 = 3;
int switchPin4 = 4;
int switchPin5 = 5;
int switchPin6 = 6;
int switchPin7 = 7;

int greenLEDpin = 8; // digital output pin for an LED
int redLEDpin = 9; // digital output pin for an LED

int switchState1 = 0; // the state of the switch1
int switchState2 = 0;
int switchState3 = 0;
int switchState4 = 0;
int switchState5 = 0;
int switchState6 = 0;
int switchState7 = 0;

int conditionsFilled = 0; //Keeps track of how many conditions so far have been filled
int timer = 0; // Lets us loop if the user is successful

void setup() {
pinMode(switchPin1, INPUT); // set the switch pin to be an input
pinMode(switchPin2, INPUT); // set the switch pin to be an input
pinMode(switchPin3, INPUT); // set the switch pin to be an input
pinMode(switchPin4, INPUT); // set the switch pin to be an input
pinMode(switchPin5, INPUT); // set the switch pin to be an input
pinMode(switchPin6, INPUT); // set the switch pin to be an input
pinMode(switchPin7, INPUT); // set the switch pin to be an input

pinMode(greenLEDpin, OUTPUT); // set the yellow LED pin to be an output
pinMode(redLEDpin, OUTPUT); // set the red LED pin to be an output
}

void loop() {
// read the switch inputs:

switchState1=digitalRead(switchPin1); //Sets the inputs to variables that won't take so long to type
switchState2=digitalRead(switchPin2);
switchState3=digitalRead(switchPin3);
switchState4=digitalRead(switchPin4);
switchState5=digitalRead(switchPin5);
switchState6=digitalRead(switchPin6);
switchState7=digitalRead(switchPin7);

if ((switchState3 + switchState4 + switchState5 + switchState6 + switchState7) != 0) {
//if (switchState3 == 1) {

conditionsFilled = 0; //No matter if it's for the first or second slot, any of these is always wrong. Go back to the beginning

digitalWrite (redLEDpin, 1); //just so they feel really bad about it
delay (500);
digitalWrite (redLEDpin, 0);
}


if (switchState1 == 1) {
// if the correct first switch is closed:

if (conditionsFilled != 0) { //makes sure this is not something they're doing for the second key
// They failed to guess the second or third option, so the entire thing gets reset
//we do not set conditions filled equal to zero, because this could be the start of a new combo too, even if they've pressed it before


digitalWrite (redLEDpin, 1); //just so they feel really bad about it
delay (500);
digitalWrite (redLEDpin, 0);

delay (1000); //a delay so the program doesn't see your ongoing finger pressing the input as an incorrect second input
conditionsFilled = 0;

}

else if (((switchState2 + switchState3 + switchState4 + switchState5 + switchState6 + switchState7) < 1) && (conditionsFilled == 0))
{
//and if this is the first number selected, and if they're not just mashing down all they keys at once
digitalWrite (greenLEDpin, 1);
delay (500);
digitalWrite (greenLEDpin, 0);

conditionsFilled = 1; //let the code know the first condition has been filled
}

}

if (switchState2 == 1) { //if they've selected the second one
//and they're not just mashing down all the keys, and it's the second selection
if (((switchState1 + switchState3 + switchState4 + switchState5 + switchState6 + switchState7 ) < 1) && (conditionsFilled == 1)) {

while(timer < 5000){
digitalWrite(greenLEDpin, 1); // sets the LED on
delay(100); // waits for a second
digitalWrite(greenLEDpin, 0); // sets the LED off
delay(100); // do something repetitive 200 times
timer++;
}

}

else if (conditionsFilled == 0){

digitalWrite (redLEDpin, 1); //just so they feel really bad about it
delay (500);
digitalWrite (redLEDpin, 0);
}

}

}

No comments: