#define FLASHCLOCK FSSEL1+((F_CPU/400000L) & 63); // SCLK
#define flash ((unsigned char*)0x1000)
boolean timeToFlash = false;
boolean waitACycle = false;
int counter;
byte wiggleRoom = 25; //the amount + or - of the exact correct push length to pass a lock level, measured in 10ms steps.
byte lockLevel = 1; //Stores what button press the lock is on
boolean open = false;
boolean buttonState;
byte password[4]; //Number of 10ms steps the button should be held down for the first time
//Same, for press two.
//And press 3. So for this setup, we press for 1s, let up, press for 0.5s, let up, press for 1s
void setup(){
Serial.begin(9600);
pinMode(P1_0, OUTPUT);
pinMode(P1_6, OUTPUT);
pinMode(P1_3, INPUT_PULLUP);
for (byte x = 0 ; x < 4 ; x++){
password[x] = (*(flash+x));
delay(10);
}
for (byte x = 0 ; x < 4 ; x++){
Serial.println(password[x]);
delay(10);
}
}
void loop(){
if (!open){ // normal state, red LED on, green LED off.
digitalWrite(P1_0, HIGH); //In this section you would shut the lock, whatever it was.
digitalWrite(P1_6, LOW);
}
else{
digitalWrite(P1_6, HIGH); //Open the lock
digitalWrite(P1_0, LOW);
delay(3000); //Wait a bit.
lockLevel = 1;
open = false; //Set the lock to close next pass through the code.
//Might not be a bad idea to close the lock here too, really.
//That would prevent the button being held down keeping the lock open.
}
buttonState = digitalRead(P1_3);
if (!buttonState){ //Button is pushed
counter = 0; //reset the counter, this is crucial.
while (!buttonState){ //As long as the button is held down, this cycles.
counter++;
delay(10); //10ms per cycle, record the number of cycles.
buttonState = digitalRead(P1_3); //We do need to get out eventually, when the button opens
}
waitACycle = false;
if(counter > 500){
Serial.println("Programming!");
lockLevel = 8;
}
switch (lockLevel){ //Now that we have a press duration, we need to find what level the lock is on
case 1: //If it's the first press, we start here.
if (counter >= password[0] - password[3] && counter <=password[0] + password[3]){
lockLevel = 2; //Adjust password[4] to be the number of 10ms steps you want for wiggle room.
counter = 0; //Right now we get +/- 250ms.
digitalWrite(P1_6, HIGH); //Flash the green LED if the push was successful. Mostly for debugging.
delay(50);
digitalWrite(P1_6, LOW);
}
else{
lockLevel = 1; //If the push is the wrong length, start over.
counter = 0;
}
break;
case 2:
if (counter >= password[1] - password[3] && counter <=password[1] + password[3]){ //Second push, same deal.
lockLevel = 3;
counter = 0;
digitalWrite(P1_6, HIGH);
delay(50);
digitalWrite(P1_6, LOW);
}
else{
lockLevel = 1; //If the push is the wrong length, start over from push 1.
counter = 0;
}
break;
case 3:
if (counter >= password[2] - password[3] && counter <=password[2] + password[3]){
open = true; //Third correct push opens the lock.
counter = 0;
}
else{
lockLevel = 1;
counter = 0;
}
break;
case 8:
lockLevel++;
Serial.println("Lock advanced to 9");
break;
case 9:
if (counter >100){
lockLevel++;
Serial.println("Lock advanced to 10");
}
break;
case 10:
password[0] = counter;
lockLevel++;
Serial.println(password[0]);
break;
case 11:
password[1] = counter;
lockLevel++;
Serial.println(password[1]);
break;
case 12:
password[2] = counter;
lockLevel++;
Serial.println(password[2]);
break;
case 13:
password[3] = counter;
lockLevel = 1;
Serial.println(password[3]);
timeToFlash = true;
break;
}
}
if(timeToFlash){
disableWatchDog(); // Disable WDT
FCTL2 = FWKEY+FLASHCLOCK; // SMCLK/2
FCTL3 = FWKEY; // Clear LOCK
FCTL1 = FWKEY+ERASE; //Enable segment erase
*flash = 0; // Dummy write, erase Segment
FCTL3 = FWKEY+LOCK; // Done, set LOCK
enableWatchDog(); // Enable WDT
disableWatchDog(); // Disable WDT
FCTL2 = FWKEY+FLASHCLOCK; // SMCLK/2
FCTL3 = FWKEY; // Clear LOCK
FCTL1 = FWKEY+WRT; // Enable write
for (byte x = 0 ; x < 4 ; x++){
*(flash+x) = (password[x]);
}
FCTL1 = FWKEY; //Done. Clear WRT
FCTL3 = FWKEY+LOCK; // Set LOCK
enableWatchDog(); // Enable WDT
timeToFlash = false;
Serial.println("Flashed!");
}
}