0

I'm designing a safe lock of 4 digits, but the password is in terms of colors, I have 3 colors. we are obliged to use a grayscale sensor (SKU: SEN0147).

The assignment is as follows:

Write a program on Arduino that will be used as a safe lock. Consider having 3 colors black white and grey. Black = 0, Red = 1 and White = 2.

• When the microcontroller is turned on, the safe is locked. The Serial Monitor should display: “System is online.”

• The combination lock should be saved in an array of integers called arr_code.

• The user has 3 trials to open the safe

• The system will wait for the user to enter 4 colors. To enter a color, the grayscale sensor should be place on top of the desired color. Once ready the push button is pressed. Once released, the color is saved in another array called arr_user_code.

• Once 4 colors are entered, the system should test automatically if the code entered by
the user is equal to the code saved in arr_code.

• If the wrong code is entered, the serial monitor displays: “Wrong Code. Try Again.”

• If the user enters the wrong code 3 times in a row the system is locked and a message is
displayed: “System Locked.”

• If the correct code is inserted, the Led on pin 13 is turned on.

• The combinations entered by the user should be displayed on the Serial Monitor. The Arduino program should be clear, separated into functions and documented.

The program I wrote is the following:

char led_pin = 13;
char pb_pin = 2;
int gs_pin = A0;
//the brightness of the flash light im using is giving 894 value so im using it for testing purpose
int arr_code[4] = { 894, 894, 894, 894 };
int arr_user_code[4];

int counter;
int Lock_Interval = 2500;

char trigger = false;
bool equal = true;
char led_state = false;

int Array_Compare(int *a, int *b) {
  for (int i = 0; i < 4; i++) {
    if (a[i] != b[i]) return 0;
    else return 1;
  }
}

void Button_Wait(int buttonPin) {//function to sense if button is pressed
  int curr_state;
  int prev_state;

  while (1) {
    prev_state = curr_state;
    curr_state = digitalRead(buttonPin);
    if (curr_state != prev_state) {
      if (curr_state == false) {
        delay(10);
        return;
      }
    }
  }
}

int GS_Value(int gsPin) {
  int gs_value = analogRead(gs_pin);
  return gs_value;
}

void setup() {
  // put your setup code here, to run once:
  pinMode(led_pin, OUTPUT);
  pinMode(pb_pin, INPUT);
  Serial.begin(9600);
  digitalWrite(led_pin, false);
}

void loop() {
  // put your main code here, to run repeatedly:

  Serial.println("System Online");
  Serial.println("Please Enter Passcode:");

  for (counter = 0; counter < 3; counter++) {
    for (int i = 0; i < 4; i++) {//uploading user array with gs values
      Button_Wait(pb_pin);
      arr_user_code[i] = analogRead(gs_pin);
      Serial.print(analogRead(gs_pin));//printing values on monitor
      Serial.print(" ");
    }

    Serial.println(" ");

    for (int i = 0; i < 4 && equal; i++) {//testing if passcode is true
      if (arr_user_code[i] != arr_code[i]) {
        equal = false;
      }
      else equal = true;
    }
    if (equal == true) {
      Serial.println("System Unlocked");
      digitalWrite(led_pin, true);
    }

    else if (equal == false) {
      Serial.println("Wrong Passcode. Try Again");
    }
  }

  /*Array_Compare( arr_user_code, arr_code);
  if (Array_Compare) Serial.println("System UNLOCKED");
  else Serial.println("Wrong Passcode. Try Again");
  */
  if (trigger == false) {//for locking the system
    Serial.println("System LOCKED!");
    while (1) {
      Lock_Interval = Lock_Interval * 2;//CHANGE TO MINUTES LATER ON!!
      delay(Lock_Interval);
      return;
    }
  }
  delay(100);
}

I'm sorry for having a lot of functions not used and a lot of canceled algorithms by remarks but its my scratch. the issue is that my program is always giving me a wrong passcode even if its correct. Can you help me find the problem please? Thank you in advance.

9
  • Are the values you see printed over Serial correct? – RamblinRose Feb 10 '19 at 13:57
  • yes i set the password according to them – Rayan Hamadeh Feb 10 '19 at 14:03
  • 1
    Since you have else return 1; in Array_Compare this will terminate always after the first iteration.. A return 1; must be placed after the for loop. – Maximilian Gerhardt Feb 10 '19 at 14:14
  • @MaximilianGerhardt you are correct, but the code isn't calling the function. – RamblinRose Feb 10 '19 at 14:47
  • @RamblinRose true. A few more remarks. In the code arr_user_code[i] = analogRead(gs_pin); Serial.print(analogRead(gs_pin)); the value in the array and the one printed out can be different since you're taking 2 different ADC measurements (is that even what you want)? You should print arr_user_code[i]. Also then before comparing it to the other array you should print out its full contents. Then you'll see if there is a difference in the values. – Maximilian Gerhardt Feb 10 '19 at 14:58
1

Since you are trying to distinguish tree different colours, I assume you are using SEN0147 in analog mode. That means the sensor output is between 0-5V. I do not believe that this will always be exactly a value of 894.

I suggest to change your comparison check in a way not to check if values are identical but to check if values are in a certain range. (additionally to all the answers @RamblinRose already suggested)

Here is a modification of the comparison loop of @RamblinRose with the change I propose. Check with different values of threshold, starting from high to lower values.

// returns 1 if equal, 0 otherwise.
int Array_Compare(int *a, int *b) {

   int threshold = 500;
   int temp;
   for (int i = 0; i < 4; i++) {
       temp = a[i] - b[i];
       if (abs(temp) > threshold)
       return 0;
   }
   return 1;
}
0

Your program has a lot of issues, but the main problem revolves around

if (trigger == false) 

The code initializes this to false and the logic never alters the value, thus the program will always indicate "System LOCKED!"

It looks like you've mixed the variables trigger and equal. Get rid of the trigger variable and use equal.

if (equal == false) {//for locking the system
    Serial.println("System LOCKED!");
    while (1) {
      Lock_Interval = Lock_Interval * 2;//CHANGE TO MINUTES LATER ON!!
      delay(Lock_Interval);
      return;
    }
  }

I recommend a different variable name to equal, such as "unlock", as it makes clear the use of the variable. Also, initialize variables such as "equal" at the beginning of loop(). Good luck.

EDIT

Your comparison check in loop() is valid. However if you have to use Array_Compare, here is the fix.

// returns 1 if equal, 0 otherwise.
int Array_Compare(int *a, int *b) {
   for (int i = 0; i < 4; i++) {
       if (a[i] != b[i])
          return 0;
   }
   return 1;
}

Then in loop, remove your local comparison loop with

//for (int i = 0; i < 4 && equal; i++) {//testing if passcode is true
//  if (arr_user_code[i] != arr_code[i]) {
//      equal = false;
//  }
//  else equal = true;
//}

equal = Array_Compare(arr_user_code, arr_code);

I'm not comfortable writing your program for you, this is not a coding service.

2
  • but this doesn't solve the issue concerning comparing arr_user_code and arr_code – Rayan Hamadeh Feb 10 '19 at 15:39
  • @RayanHamadeh the code is comparing the arrays in the loop() function, and altering the 'equal' variable according to the comparisons made. – RamblinRose Feb 10 '19 at 15:51

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.