> For the complete documentation index, see [llms.txt](https://guides.mccaskeyrobotics.org/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://guides.mccaskeyrobotics.org/arduino/passcode-protected-tollbooth.md).

# Passcode Protected Tollbooth

### Introduction Video:

{% embed url="<https://www.youtube.com/watch?v=JGx0VPZQIzo>" %}

### Overview: &#x20;

When you pull up to a many buildings, the gate only opens if you know the passcode. In this project you  will use a 4 by 4 keypad to feed Arduino information. Arduino will keep track of that information and  decide whether or not it matches the pre-determined passcode. If it does, it will send signal to a motor  driver board and open or close the gate. If not, it will ask for new information.

![](/files/ZXtPoGOq7SjqVhviPyAg)![](/files/3FCYPz5Rutbq8Z8P9Ihs)

### Parts: &#x20;

\- 1 L298N Motor Driver Board

\- 1 Arduino Uno

\- 1 Tollbooth Setup

\- 1 4 by 4 keypad

\- 1 9V Battery

\- Assorted Wire

### Wiring:

![](/files/4UoYDB2WweF4ex4LUInu)

![](/files/u69shtxMSYMIyZVhrevg)

### Code:

```cpp
#include <Keypad.h> //library to simplify accepting input from the keypad
const byte ROWS = 4; //four rows
const byte COLS = 4; //four columns
//define the cymbols on the buttons of the keypads
char hexaKeys[ROWS][COLS] = {
  {'1', '2', '3', 'A'},
  {'4', '5', '6', 'B'},
  {'7', '8', '9', 'C'},
  {'*', '0', '#', 'D'}
};
byte rowPins[ROWS] = {9, 8, 7, 6}; //connect to the row pinouts of the keypad
byte colPins[COLS] = {5, 4, 3, 2}; //connect to the column pinouts of the keypad
#define Password_Length 7
char Data[Password_Length]; // 6 is the number of chars it can hold + the null char = 7 
char o_master[Password_Length] = "123456";
char c_master[Password_Length] = "654321";
byte data_count = 0, master_count = 0;
bool Pass_is_good;

// declare the pins for the open/close limit switches
int olim = 11;
int clim = 10;

//declare the pincs for the open/close gate enable pins going to the L298 driver
int ogate = 13;
int cgate = 12;

//initialize an instance of class NewKeypad
Keypad customKeypad = Keypad( makeKeymap(hexaKeys), rowPins, colPins, ROWS, COLS);
void setup() {
  Serial.begin(9600);
  //initialize gate control pins as inputs/outputs
  pinMode(olim, INPUT_PULLUP);
  pinMode(clim, INPUT_PULLUP);
  pinMode(ogate, OUTPUT);
  pinMode(cgate, OUTPUT);
  initialize();
}

// the main loop of the program
void loop() {
  char customKey = customKeypad.getKey();
  //only runs when it receives data from the kaypad
  if (customKey) {
    Serial.print(customKey); //print the current key entry to the serial monitor   
    Data[data_count] = customKey; //place the key entry in the data array  
    data_count ++; // move to the next spot in the array
    // wait till there are 6 positions filled in the array
    if (data_count == Password_Length - 1) {
      //compare the array to the open password, if it's a match, open the gate
      if (!strcmp(Data, o_master)) {
        Serial.println("");
        Serial.println("Correct, you may enter");
        open_gate();
        clear_data();
        initialize();
      }
      //compare the array to the close password, if it's a match, close the gate
      else if (!strcmp(Data, c_master)) {
        Serial.println("");
        Serial.println("Correct, the gate is closing");
        close_gate();
        clear_data();
        initialize();
      }

      //if the password doesn't match either, ask the user to try again.
      else {
        Serial.println("");
        Serial.println("Incorect. Please try again");
        clear_data();
        initialize();
      }
    }
  }
}
//determines where the gate is at and prompts the user to enter a password //if gate isn't at top or bottom, it takes it to the bottom and prompts user to enter password
void initialize() {
  int close_value = digitalRead(clim);
  int open_value = digitalRead(olim);
  if (close_value == LOW ) {
    Serial.println("Please enterthe 6 digit open password");
    return;
  }
  else if (open_value == LOW) {
    Serial.println("Please enter the 6 digit close password");
    return;
  }
  else {
    while (digitalRead(clim) == HIGH) {
      digitalWrite(cgate, HIGH);
      digitalWrite(ogate, LOW);
    }
    digitalWrite(cgate, LOW);
    digitalWrite(ogate, LOW);
    delay(100);
    Serial.println("Please enter the 6 digit open password");
    return;
  }
}

//clears the list of numbers in the keypad array
void clear_data() {
  while (data_count != 0) {
    Data[data_count--] = 0;
  }
  return;
}

// runs the motor in the open direction while the open limit switch is not pressed,
//then turns off the motors before going back to main program
void open_gate() {
  while (digitalRead(olim) == HIGH) {
    digitalWrite(ogate, HIGH);
    digitalWrite(cgate, LOW);
  }
  digitalWrite(ogate, LOW);
  digitalWrite(cgate, LOW);
  delay(100);
  return;
}

// runs motor in close direction while the close limit switch is not pressed,
//then turns off the motors before going back to main program
void close_gate() {
  while (digitalRead(clim) == HIGH) {
    digitalWrite(ogate, LOW);
    digitalWrite(cgate, HIGH);
  }
  digitalWrite(ogate, LOW);
  digitalWrite(cgate, LOW);
  delay(100);
  return;
}
```


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://guides.mccaskeyrobotics.org/arduino/passcode-protected-tollbooth.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
