0

When user used one password after close the servo the password will valid for 15 seconds then it will not work. Other 9 will be same process

Here is code I need just this to set

int locker = 13;
int lockerState = 0;
const int buzzer = 49;
String readString;

#include <Servo.h>
Servo myservo;
int pos = 0;

void setup() {
  Serial.begin(9600);
  pinMode(locker, OUTPUT);
  pinMode(buzzer, OUTPUT);
  myservo.attach(9);
}

void loop() {
  lockerState = digitalRead(locker);
  while (Serial.available()) {
    delay(3);  
    char c = Serial.read();
    readString += c;
  }

  if (readString.length() >0) {
    Serial.println(readString);
    if ((readString == "2028") || (readString =="1234") || (readString =="1294") || (readString =="4795") || (readString =="5651") || (readString =="7616") || (readString =="5648") || (readString =="1487") || (readString =="7095") || (readString =="2554"))
    {
      digitalWrite(locker, HIGH);
      for (pos = 0; pos <= 180; pos += 1) {
      myservo.write(pos);
      delay(30);
      }
      delay(5000);
      digitalWrite(locker, LOW);
      /* for (pos = 180; pos >= 1; pos -= 1) {
      myservo.write(pos);
      delay(30);
      } */
      readString="";
    }
      /* else if (readString == "proceed") {
        digitalWrite(locker, HIGH);
        for (pos = 0; pos <= 180; pos += 1) {
        myservo.write(pos);
        delay(30);
        }
      digitalWrite(locker, LOW);
      readString="";
      } */
      if (readString == "decline") {
         digitalWrite(locker, HIGH);
         for (pos = 180; pos >= 0; pos -= 1) {
         myservo.write(pos);
         delay(30);
         }
      digitalWrite(locker, LOW);
      readString="";
      }

    else {
      tone(buzzer, 500);
      delay(1000);
      noTone(buzzer);
      delay(1000);
      readString="";
  }
 }
}
2

In programming, there are many cases where designing data structures is more important than the code itself. Once you have a data structure that makes sense, the code flows very naturally. I think this is one of those cases, so let's start by looking at what data you have to store for each of your passwords:

  • the password itself (let's call it the code)
  • whether it has ever been used and, if so, whether it has expired
  • if it has been used but has not expired yet: when it was used for the first time

This can be saved in an object with the following data fields:

const char * const code;
enum { UNUSED, USED, EXPIRED } status;
uint32_t first_use;  // valid if status == USED

Now think about what kind of actions you want to perform on such a password:

  • you want to be able to test whether it matches some user entry
  • you want check whether it can be used and, if so, take note that it is being used

Based on these requirements, I propose the following class:

const uint32_t PASS_LIFE_TIME = 15000;

class Password {
public:
    Password(const char *c)
        : code(c), status(UNUSED) {}
    bool matches(const char *entry) {
        return strcmp(code, entry) == 0;
    }
    void update() {  // expire if it needs to be
        if (status == USED && millis() - first_use > PASS_LIFE_TIME) {
            status = EXPIRED;
        }
    }
    bool use() {  // returns true on success
        if (status == UNUSED) {
            status = USED;
            first_use = millis();
        }
        update();
        return status != EXPIRED;
    }
private:
    const char * const code;
    enum { UNUSED, USED, EXPIRED } status;
    uint32_t first_use;  // valid if status == USED
};

Now you need to store all the passwords in an array, and a couple of functions to operate on the password collection as a whole:

const int PASS_COUNT = 10;

Password passwords[PASS_COUNT] = { "2028", "1234", "1294",
    "4795", "5651", "7616", "5648", "1487", "7095", "2554" };

void update_all_passwords()
{
    for (int i = 0; i < PASS_COUNT; i++)
        passwords[i].update();
}

// Returns true on success, and uses the matching password.
bool try_entry(const char * entry)
{
    for (int i = 0; i < PASS_COUNT; i++)
        if (passwords[i].matches(entry))
            return passwords[i].use();
    return false;  // no match found
}

The function update_all_passwords() is meant to be called on each iteration of loop(). It may seem superfluous, as a password is updated whenever you try to use it. However, without regular updating, a used password could be reused 49.7 days later, because of the millis() rollover.

Now, in your program, you just need to:

  1. Put a call to update_all_passwords() at the beginning of loop()
  2. Replace the big condition that tests for a valid password by if (try_entry(readString.c_str()))
  • Good answer! I would add, that it is not a good practice to use delay(). I think it's worth mentioning, that the coding style from the BlinkWithoutDelay example is way better (which you already used in your code, but the OP didn't), and will help especially when adding more functions to the code. – chrisl Nov 15 '18 at 9:32

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.