Electronic Lock System

I am trying to write a code for a FSM.

Basically the idea here is to design an electronic lock system. The lock would open only when (Key2, Key3, Key1, Key2) is pressed in that sequence, so the password is (2,3,1,2).

Now I am a beginner at coding and what I wrote might seem funny to some experts. However, I am trying my best to make the code compile. I wrote a small state code with lots of errors. I also built a circuit on a breadboard. I attached a photo of my breadboard circuit and the sketch that I wrote.

Here is a brief explanations of what I have on my breadboard:

  1. I have 3 10k resistor connected to three buttons.

  2. Four 1k resistors connected to each 4 red LEDs.

  3. A 9v relay, which I will later connect to make a clicking sound which the password is entered correctly.

The Four LED lights purposes is the following:

  1. The 1st LED light on the far left blinks once to show that the system is ready to accept the password.

  2. The 2nd LED light blinks every time the user presses a button. So it is to verify that a button got pressed.

  3. The 3rd LED blinks only when the password(2,3,1,2) is entered correctly. It represents the open lock.

  4. The 4th LED blinks when the user enters a wrong password.

I hope what I wrote gives a good explanation.

Lock.ino (2.82 KB)

.

Thank you larryd. I added jumpers to the lines shown on your image.

(k1(0) + k1(1) + k1(2) these are not functions!

if (cntr2 >= 2) cntr2 = 0;
Suggest you use this format
if (cntr2 >= 2)
{
cntr2 = 0;
}

What do you think is happening here?
if (digitalRead(array{Key2, Key3, Key1, Key2}));

Each { needs a friend }
.

I used your format for this:
if (cntr2 >= 2)
{
cntr2 = 0;
}

larryd for ( (k1(0) + k1(1) + k1(2)) == 0)

I do not know how to create functions on Arduino. I was searching the web from the morning and was not able to solve this error. I am good at building matlab functions because it is easy for me to solve errors there. However, on Arduino I get stuck on errors and when i solve errors i get more errors that were not there before.

Here,

if (digitalRead(array{Key2, Key3, Key1, Key2}));

I am trying to make an if statement for the correct password sequence if that sequence is correct then go to Open (state). If that the password is wrong go to Fail (state).

   k1(cntr2) = digitalRead(Key1);
      k2(cntr2) = digitalRead(Key2);
      k3(cntr2) = digitalRead(Key3);

You probably meant

      k1 = digitalRead(Key1);
      k2 = digitalRead(Key2);
      k3 = digitalRead(Key3);

BTW
cntr2 = cntr2 + 1;
This is the same as:
cntr2++;

if ( (k1(0) + k1(1) + k1(2)) == 0)
Did you mean this?
if (k1 == 0)

if (digitalRead(array{Key2, Key3, Key1, Key2}));
Did you mean this?
if (K1 || K2 || K3);
{
//code
}

As mentioned you need to understand the syntax of C++ before you write code.

.

Thank you very much larryd for your help.

I will search on how to write good syntax for C++.

Wire your switches as S3 is wired in this image
Then use internal pullups:

  pinMode(Key1, INPUT_PULLUP);           // Setting digital inputs.
  pinMode(Key2, INPUT_PULLUP);
  pinMode(Key3, INPUT_PULLUP);

I will search on how to write good syntax for C++.

Go through the examples that come with the IDE to see how things are done.

Edit:

If those are 1,000 or even worse 10,000 ohm LED resistors, you need to reduce the value to 220 to 470.

larryd i wired the buttons as S3 is wired. I attached a image of the breadboard showing the modifications.

I also change the code to use the internal Pullups:

pinMode(Key1, INPUT_PULLUP); // Setting digital inputs.
pinMode(Key2, INPUT_PULLUP);
pinMode(Key3, INPUT_PULLUP);

As you suggested i used cntr2++; instead of cntr2 = cntr2 + 1;

Thank you for your helpful replies larryd. You are a great teacher.

I did not understand why you wrote

if (K1 || K2 || K3);

I wanted to write an if statement for the correct sequence, so the lock opens when the key are pressed in this order (Key2 then Key3 then Key1 Then Key2).

If the buttons are pressed in that sequence. Then go to Open state and open light the "Open" LED. However if any other sequences if pushed, which does not match (Key2 then Key3 then Key1 Then Key2) order. Then go to Fail (state) to turn the fail LED.

I also changed if ( (k1(0) + k1(1) + k1(2)) == 0) to if (k1 == 0) for k1,k2 and k3

I attached the modified sketch code with this post to show my progress.

Thank you again larryd for you help. I really appreciate your comments.

Lock.ino (2.77 KB)

Each { needs an associated closing }

Do all your opening braces have closing braces?

NOTE:
If that relay is going to be used later, it will need and a diode across the coil.
It will also need a transistor driver.

The LEDs resistors look like they are 10K ohm change them to 220 ohms.

These two lines of code are not the same. :slight_smile:
Which one do you think is correct?

State == KeyPress ;
State = KeyPress ;

Once you get into ' case KeyPress: ' how do you get out?

This is still NOT valid syntax:
if (digitalRead(array{Key2, Key3, Key1, Key2}))

What are cntr1 and cntr2 used for?

When you press a key in 'case Ready:' what happens if the button is still pressed when you enter 'case KeyPress' ?

Hint:
Before you go any further, learn how to detect when a switch goes from LOW (pressed) to HIGH (not pressed).
There is a StateChangeDetection example in the IDE examples.

Also, see this example to see how you can use the StateChangeDetection technique:

// This demonstrates how to look for a switch realease condition
// Switches are connected as below
// Arduino pin-----SwitchPin1 -----SwitchPin2-----GND
// Switch press = LOW, release = HIGH
// LarryD
//

#define OFF      HIGH
#define ON       LOW
#define PRESSED  LOW
#define RELEASED HIGH

const byte switch1 = 8;
const byte switch2 = 9;
const byte switch3 = 10;

const byte LED1    = 11;
const byte LED2    = 12;
const byte LED3    = 13;

byte lastSwitch1   = HIGH;
byte lastSwitch2   = HIGH;
byte lastSwitch3   = HIGH;


//***********************************************************
void setup()
{
  pinMode(switch1, INPUT_PULLUP);
  pinMode(switch2, INPUT_PULLUP);
  pinMode(switch3, INPUT_PULLUP);

  pinMode(LED1, OUTPUT);
  pinMode(LED2, OUTPUT);
  pinMode(LED3, OUTPUT);

  digitalWrite(LED1, OFF);
  digitalWrite(LED2, OFF);
  digitalWrite(LED3, OFF);

} //END of             s e t u  p ( )


//***********************************************************
void loop()
{
  //***************
  if (readSwitch(switch1, lastSwitch1) == true)
  {
    //this switch was just released
    //toggle the LED
    digitalWrite(LED1, !digitalRead(LED1));
  }

  //***************
  if (readSwitch(switch2, lastSwitch2) == true)
  {
    //this switch was just released
    //toggle the LED
    digitalWrite(LED2, !digitalRead(LED2));
  }

  //***************
  if (readSwitch(switch3, lastSwitch3) == true)
  {
    //this switch was just released
    //toggle the LED
    digitalWrite(LED3, !digitalRead(LED3));
  }


} //END of            l o o p ( )



//***********************************************************
//Returns true if the switch was released
bool readSwitch( byte button, byte &lastState)
{
  byte currentState = digitalRead(button);

  if (currentState != lastState)
  {
    lastState = currentState;

    if (currentState == RELEASED) 
    {
      //button was just released
      return true;
    }
  }
  return false;

} //END of           r e a d S w i t c h ( )

//***********************************************************

.

Thank you very much LarryD .

You are correct it is State = KeyPress (this way the (State) will be equal to (KeyPress) state)

However, if i used == the left side and the right of the statement side will be equal. For == it is better to equal a number to a statement and not a (state equal to a state).

Also you are correct about the 220 resistor. Because the LED needs (20mA max) and if we use 220 ohm then:

I= (5-0.7)/220 =19.5mA which is good. However, when 1k resisto is used then we only get 5mA through the diode. I hope this is correct.

When I will connect the 9V relay to the circuit. I will do the following relay circuit same as in the figure attached to this post.

I ran your code that you posted and it is nice to see the lights turning ON and OFF when the buttons are pressed.

I attached a photo of the circuits with the lights turned ON. :smiley:

I will study your code and the SwitchChangeDetection sketch and will try to figure this stuff out.

Thank you very much LarryD for your help again. Will keep you updated when I figure it out. Thank you.

Relay Circuit.png

== tests for equality https://www.arduino.cc/en/Reference/If
= set the left side to the right = - Arduino Reference

1K is fine, 10K would be too large.

Relay schematic looks okay.

enum State {Ready, KeyPress, Check, Open, Fail};
int State = Ready;

Change to:

enum MyState {Ready, KeyPress, Check, Open, Fail};
MyState State = Ready;

What is this project for?

.

Hello LarryD,

Thank you for taking the time and interest to help me with my code.

This is a homework problem from my Mechatronics class. The teacher told me that if i could solve this Finite State Machine problem. Then I will be able to build any machine I want.

I did some corrections for if (digitalRead(array{Key2, Key3, Key1, Key2}));

Instead of that I wrote:

  1. before void setup() I wrote:

int password[4] //To set an array of 4 bits

  1. In the void setup() I wrote;

password[0] = Key2; // This is the correct password
password[1] = Key3;
password[2] = Key1;
password[3] = Key2;

  1. In void loop(), I changed [if (digitalRead(array{Key2, Key3, Key1, Key2}))] and instead wrote:

if (digitalRead(password))

I have some questions, which made me get confused. In:

enum MyState {Ready, KeyPress, Check, Open, Fail};
MyState State = Ready;

  1. Why did you write [MyState State = Ready;] for the second line?

  2. Why didn't you write [int MyState = Ready;] instead? Why didn't you use "int" in the beginning of the second line of your code?

  3. Why is MyState is followed by (State) as in MyState State = Ready; . Why not write int MyState = Ready; instead?

Thank you very much for all of your help LarryD. I attached the progress that I made on my code with this reply.

Lock.ino (2.95 KB)

Here is similar code to what you are doing.
Do you understand everything that is happening here and why things are being done as they are?

// This demonstrates how to code a simple electronic lock
// using 3 switches wired as below
// Arduino pin-----SwitchPin1-----SwitchPin2-----GND
// Switch pressed = LOW, released = HIGH
// LarryD
// Version 1.00 16/11/12  code = 1233
//         1.01 17/08/05  added: switch de-bouncing, heartBeatLED stuff
//

#define OFF      HIGH
#define ON       LOW
#define Pressed  LOW
#define Released HIGH

const byte switch1      = 8;
const byte switch2      = 9;
const byte switch3      = 10;

const byte LockedLED    = 11;

const byte HeartBeatLED = 13; //                     1.10
unsigned long lastMillis; 
const unsigned long bounceDelay    = 10ul;  //10ms
unsigned long HeartBeatMillis;
const unsigned long HeartBeatDelay = 500ul; //500ms  1.01

byte lastSwitch1 = HIGH;
byte lastSwitch2 = HIGH;
byte lastSwitch3 = HIGH;

enum MachineStates {ZERO, ONE, TWO, THREE, FOUR, FIVE, SIX};
MachineStates STATE = ZERO;

//                      s e t u  p ( )
//***********************************************************
void setup()
{
  pinMode(switch1, INPUT_PULLUP);
  pinMode(switch2, INPUT_PULLUP);
  pinMode(switch3, INPUT_PULLUP);

  pinMode(HeartBeatLED, OUTPUT);  //       1.01
  pinMode(LockedLED, OUTPUT);

  lastMillis = millis();

} //END of             s e t u  p ( )

//                      l o o p ( )
//***********************************************************
void loop()
{
  //helps check for blocking code
  if (millis() - HeartBeatMillis >= HeartBeatDelay) //            1.01
  {
    //reset timing
    HeartBeatMillis = millis();
    //toggle the HeartBeatLED
    digitalWrite(HeartBeatLED , !digitalRead(HeartBeatLED)); 
  } //                                                            1.01


  switch (STATE)
  {
    //****************
    case ZERO:
      {
        //Lock the device
        digitalWrite(LockedLED, OFF);

        //Proceed
        STATE = ONE;

      }
      break;

    //****************
    case ONE:
      {
        if (readSwitch(switch1, lastSwitch1) == true)
        {
          //Proceed
          STATE = TWO;
        }

        else if (readSwitch(switch2, lastSwitch2) == true)
        {
          //Reset
          STATE = ZERO;
        }

        else if (readSwitch(switch3, lastSwitch3) == true)
        {
          //Reset
          STATE = ZERO;
        }

      }
      break;

    //****************
    case TWO:
      {
        if (readSwitch(switch2, lastSwitch2) == true)
        {
          //Proceed
          STATE = THREE;
        }

        else if (readSwitch(switch1, lastSwitch1) == true)
        {
          //Reset
          STATE = ZERO;
        }

        else if (readSwitch(switch3, lastSwitch3) == true)
        {
          //Reset
          STATE = ZERO;
        }

      }
      break;

    //****************
    case THREE:
      {
        if (readSwitch(switch3, lastSwitch3) == true)
        {
          //Proceed
          STATE = FOUR;
        }

        else if (readSwitch(switch1, lastSwitch1) == true)
        {
          //Reset
          STATE = ZERO;
        }

        else if (readSwitch(switch2, lastSwitch2) == true)
        {
          //Reset
          STATE = ZERO;
        }

      }
      break;

    //****************
    case FOUR:
      {
        if (readSwitch(switch3, lastSwitch3) == true)
        {
          //Proceed with unlocking the device
          STATE = FIVE;
        }

        else if (readSwitch(switch1, lastSwitch1) == true)
        {
          //Reset
          STATE = ZERO;
        }

        else if (readSwitch(switch2, lastSwitch2) == true)
        {
          //Reset
          STATE = ZERO;
        }

      }
      break;

    //****************
    case FIVE:
      {
        //Proceed
        STATE = SIX;
        //Unlock the device
        digitalWrite(LockedLED, ON);

      }
      break;

    //****************
    case SIX:
      {
        //Should we should lock the device
        if (readSwitch(switch1, lastSwitch1) || readSwitch(switch2, lastSwitch2)
            || readSwitch(switch3, lastSwitch3))
        {
          //Reset
          STATE = ZERO;
        }

      }
      break;

      //****************

  } //END of switch/case

} //END of            l o o p ( )

//***********************************************************


//               r e a d S w i t c h ( )
//***********************************************************
//Return 'true' if the switch was released
bool readSwitch(byte button, byte &lastState)
{
  //Handle switch de-bounce                 1.01
  if (millis() - lastMillis < bounceDelay)
  {
    //it is not time yet
    return false;
  }

  //reset timing
  lastMillis = millis(); //                 1.01

  byte currentState = digitalRead(button);

  if (currentState != lastState)
  {
    lastState = currentState;

    if (currentState == Released)
    {
      //button was just released
      return true;
    }
  }
  return false;

} //END of           r e a d S w i t c h ( )



//***********************************************************
//                 E N D   o f   S k e t c h
//***********************************************************

You really need to stop inventing syntax.

Google is great for looking up information.
Enumeration
Enums - C++ Forum!

Pretend that I'm the little man living inside the chip.

I thought there was, now I have to pretend :frowning:

Yes, what Delta_G said X 10

.

Thank you Delta_G and LarryD for the great comments.

I got the code to compile. I went to the library, wrote my idea on a piece of paper and looked at the examples that LarryD provided. They were really helpful. Thank you LarryD for all of your help today and yesterday. I appreciate it. You are a great teacher and a great person.

I attached my code with this reply, incase anyone is interested in trying it out and improve the code. I also attached my notes, which I wrote. The code has many comments to make anyone life's easier to understand what is going on.

I hope none of my classmates find this post today. Since the due date is tonight :smiley: :smiley: :smiley: , this way I get better grades than them :smiley:

Thank you Delta_G for your comments and the "small man" simile. It is a good way to think when you want to write a code.

Thank you guys again for all the of help. Will try to connect a relay tonight to test the code in real life. This is the first time for me to write a code that works.

Lock.ino (5.82 KB)

Notes Page1.pdf (778 KB)

Notes Page2.pdf (644 KB)

Here is the last page of the notes, which i wrote. I couldn't post it with the last reply because of uploading limit reached max.

Notes Page3.pdf (665 KB)

You only read the switches in the setup() function which only runs once at reset.

How do you expect the code to go from one state to the other if you are 'not' updating/reading the switches?

You said you wanted the code to respond to the switch press sequence 2,3,1,2.

This means:
When you press 2 advance to the next state.
When you press 3 advance to the next state.
When you press 1 advance to the next state.
When you press 2 advance to the next state.
Any out of sequence press should therefore set a wrong flag or something similar.

You wanted:

  • When your code is ready to accept a new sequence the ready LED comes on.
  • On each switch press you want the switch pressed LED to flash.
  • On the 4th switch press, if you followed the correct sequence, the unlock LED should come on.
  • If on the 4th switch press the sequence was incorrect, the wrong LED goes on.
    Do the above 4 LEDs work like this?

You talk about flashing what does this mean to you?

delay(1); <-----<<< why do you want to do this?

Hello LarryD thank you for your comment. I spent more time on fixing the code.

Now this time, I not only was able to just compile it. This time I made it run and went through all of the case till case Open.

I also tried {2,3,1,1} and this time because I messed up on the last digit i went to Fail state the Fail LED lit ON.

Also, I was able to make KeyPressLED blink every-time I press a button.

I think this code is now fine. But some time when i press a key the correct sequence {2,3,1,2} nothing happens.

Thank you.

Lock.ino (8.8 KB)