Как установить время на 15 секунд
Если пользователь использовал один пароль после закрытия сервопривода, пароль будет действителен в течение 15 секунд, а затем не будет работать. Остальные 9 будут аналогичны
Вот код, который мне нужен для установки
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="";
}
}
}
@shiam khan, 👍0
1 ответ
В программировании во многих случаях проектирование структур данных важнее, чем сам код. Если у вас есть структура данных, которая имеет смысл, код работает очень естественно. Я думаю, что это один из тех случаях, поэтому давайте начнем с рассмотрения того, какие данные вам нужно хранить для каждого ваших паролей:
- сам пароль (назовем его кодом)
- использовался ли он когда-либо, и если да, то истек ли срок его действия.
- если он использовался, но срок его действия еще не истек: когда он использовался для первый раз
Это можно сохранить в объекте со следующими полями данных:
const char * const code;
enum { UNUSED, USED, EXPIRED } status;
uint32_t first_use; // действует, если статус == ИСПОЛЬЗУЕТСЯ
Теперь подумайте, какие действия вы хотите выполнить с таким пароль:
- вы хотите иметь возможность проверить, соответствует ли оно какой-либо записи пользователя.
- вы хотите проверить, можно ли его использовать, и если да, то обратите внимание, что это возможно. используется
Исходя из этих требований, я предлагаю следующий класс:
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() { // срок действия истекает, если это необходимо
if (status == USED && millis() - first_use > PASS_LIFE_TIME) {
status = EXPIRED;
}
}
bool use() { // возвращает true в случае успеха
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; // действует, если статус == ИСПОЛЬЗУЕТСЯ
};
Теперь вам нужно хранить все пароли в массиве и пару функции для работы с коллекцией паролей в целом:
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();
}
// Возвращает true в случае успеха и использует соответствующий пароль.
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; // совпадение не найдено
}
Функция update_all_passwords()
предназначена для вызова при каждом
итерация loop()
. Это может показаться лишним, так как пароль обновляется.
всякий раз, когда вы пытаетесь его использовать. Однако без регулярного обновления использованный
пароль можно было повторно использовать через 49,7 дней из-за millis()
опрокидывание.
Теперь в вашей программе вам просто нужно:
- Поместите вызов
update_all_passwords()
в началеloop()
- Замените большое условие, проверяющее действительный пароль, на
if (try_entry(readString.c_str()))
- Использование millis() и micros() внутри процедуры прерывания
- Как сделать очень долгую функцию delay(), несколько часов
- Разница между «time_t» и «DateTime»
- Получение BPM из данного кода
- Как считать время в секундах?
- Создание таймера с использованием часов реального времени с указанием времени начала и остановки
- Arduino непрерывно считывает значение АЦП с помощью прерывания
- Использование TIMER0_COMPB_vect
Хороший ответ! Я бы добавил, что использовать
delay()
не рекомендуется. Думаю, стоит упомянуть, что стиль кодирования из примера BlinkWithoutDelay намного лучше (который вы уже использовали в своем коде, а ОП — нет), и он особенно поможет при добавлении в код дополнительных функций., @chrisl