Разблокировка Arduino Hardlid
Я пытаюсь создать анлокер на своем хардлиде для своего ute. Я заменил механизм ручной разблокировки двумя такими https://www.jaycar.com .au/slave-door-lock-actuator/p/LR8813.
Теперь мой код иногда работает, и я не могу понять, почему. Код должен работать так:
- Нажмите кнопку разблокировки (количество шагов)
- Нажмите кнопку разблокировки еще раз
- Когда count = 2, включите реле на 4 секунды, затем выключите.
- сбросить счетчик до 0
- Если время между нажатиями больше 10 секунд, сбросьте счетчик до 0
Основная схема ниже. Обратите внимание, что кнопка на самом деле подключена к реле, которое срабатывает от пульта дистанционного управления отпиранием автомобиля, а светодиод — это приводы.
Это мой код
int switchPin = 2; // выбираем входной пин (для кнопки)
int relayPin = 4; // выбираем входной пин (для кнопки)
int val = 0; // переменная для чтения состояния пина
int counter = 0;
int currentState = 0;
int previousState = 0;
bool lockOn = false;
unsigned long currentMillis = 0;
unsigned long previousMillis = 0;
unsigned long LockcurrentMillis = 0;
unsigned long LockpreviousMillis = 0;
const long interval = 10000;
const long Lockinterval = 4000;
void setup() {
Serial.begin(9600);
pinMode(switchPin, INPUT); // объявляем кнопку как вход
pinMode(relayPin, OUTPUT); // объявляем кнопку как вход
Serial.println("Ready");
Serial.print("IP address: ");
}
void loop() {
currentMillis = millis();
LockcurrentMillis = millis();
/*
Serial.print("Current ");
Serial.print(currentMillis);
Serial.print(" | Previous ");
Serial.println(previousMillis);
//Serial.println(lockOn);
Serial.print("Lock Current ");
Serial.print(LockcurrentMillis);
Serial.print(" | Lock Previous ");
Serial.println(LockpreviousMillis);
*/
if (lockOn == true){
if (LockcurrentMillis - LockpreviousMillis >= Lockinterval) {
// сохранить время последнего мигания светодиодом
LockpreviousMillis = LockcurrentMillis;
digitalWrite(relayPin, LOW); // выключаем relayPin
lockOn = false;
Serial.println("relay off");
}
}
val = digitalRead(switchPin); // чтение входного значения
if (val == HIGH) { // проверяем, является ли вход ВЫСОКИМ (кнопка отпущена)
currentState = 1;
}
else {
currentState = 0;
}
if (currentState != previousState) {
if (currentState == 1) {
counter = counter + 1;
previousMillis = currentMillis; //сбросить таймер
Serial.println(counter);
}
}
if (counter == 2) {
counter = 0;
digitalWrite(relayPin, HIGH); // включить relayPin
// задержка (4000);
// цифровая запись (relayPin, LOW); // выключаем relayPin
lockOn = true;
LockpreviousMillis = LockcurrentMillis;
Serial.println("relay on");
}
previousState = currentState;
// задержка (250);
if (currentMillis - previousMillis >= interval) {
// сохранить время последнего нажатия кнопки
previousMillis = currentMillis;
//Заблокировать предыдущую Миллис = Блокироватьтекущую Миллис;
//если (счетчик >= 1) {
Serial.println("Took too long reset count");
counter = 0;
lockOn = false;
//}
}
}
Мы будем очень признательны за любую помощь
Спасибо
@Ben, 👍3
Обсуждение1 ответ
Ваш чертеж цепи кажется очень неправильным, но он бесполезен, поскольку, как вы говорите, что это не представляет реальную схему. Пожалуйста, добавьте правильный схема реальной цепи.
Что касается вашей проблемы с надежностью, то я не вникал в логику код, который вы разместили, но я подозреваю, что это может быть вызвано отсутствием устранение дребезга. Вы можете добавить свой собственный код устранения дребезга, но ради простоты, я предлагаю вам вместо этого использовать готовую библиотеку, например Bounce2.
Что касается программы, которую вы пытаетесь написать, я считаю, что логика становится намного легче понять, если вы думаете об этом как о конечном состоянии машина. Это программная конструкция, основанная на идее, что система может находиться в любом из предопределенного набора возможных состояний, и что его поведение и возможные переходы состояний зависят от того, что конкретное состояние, в котором он находится. В этом конкретном случае я бы использовал три состояния:
- В состоянии
LOCKED
крышка заблокирована, и вам нужно нажать кнопку кнопку дважды, чтобы разблокировать его. После того, как вы нажмете кнопку один раз, он переходит в состояниеWAITING
. - В состоянии
WAITING
крышка по-прежнему заблокирована, но первый нажатие кнопки уже зарегистрировано. Если вы нажмете кнопку снова система переходит в состояниеUNLOCKED
. Если не, после тайм-аута он снова переходит в состояниеLOCKED
. - В состоянии
UNLOCKED
крышка разблокирована. После очередного тайм-аута переходит обратно в состояниеLOCKED
.
Записав эту логику, ее можно преобразовать в код на очень простой способ:
#include <Bounce2.h>
const uint8_t switch_pin = 2;
const uint8_t relay_pin = 4;
const uint32_t wait_interval = 10000; // 10 с
const uint32_t lock_interval = 4000; // 4 с
Bounce button;
void setup() {
button.attach(switch_pin, INPUT_PULLUP);
pinMode(relay_pin, OUTPUT);
Serial.begin(9600);
Serial.println("Ready.");
}
void loop() {
static enum { LOCKED, WAITING, UNLOCKED } state = LOCKED;
static uint32_t last_change; // не используется в заблокированном состоянии
button.update();
uint32_t now = millis();
switch (state) {
case LOCKED:
if (button.fell()) {
Serial.println(F("Waiting for second button press."));
state = WAITING;
last_change = now;
}
break;
case WAITING:
if (button.fell()) {
Serial.println(F("Unlocking."));
digitalWrite(relay_pin, HIGH);
state = UNLOCKED;
last_change = now;
} else if (now - last_change >= wait_interval) {
Serial.println(F("Wait time out."));
state = LOCKED;
}
break;
case UNLOCKED:
if (now - last_change >= lock_interval) {
Serial.println(F("Locking."));
digitalWrite(relay_pin, LOW);
state = LOCKED;
}
break;
}
}
Спасибо, Эдгар. Ваш код, безусловно, выглядит намного проще для чтения и выполнения. Я попробую ваш код сейчас и сообщу. Еще раз спасибо, @Ben
Это работает отлично! Я также обновляю схему. Спасибо, @Ben
- Как читать и записывать EEPROM в ESP8266
- Как сделать выводы Tx и Rx на ESP-8266-01 в выводах GPIO?
- Как навсегда изменить скорость передачи данных ESP8266 (12e)?
- Как заставить 5-вольтовое реле работать с NodeMCU
- Как исправить: Invalid conversion from 'const char*' to 'char*' [-fpermissive]
- ESP8266 не подключается к Wi-Fi
- AT-команда не отвечает на последовательный монитор
- Разница между этими двумя платами NodeMCU?
Первое: устраните дребезг кнопки., @Edgar Bonet
Библиотека устранения дребезга кнопок: https://github.com/thomasfredericks/Bounce2, @VE7JRO
Что такое ют? Вы когда-нибудь смотрели фильм «Мой кузен Винни»?, @Delta_G
@Delta_G, лол .... я думал о том же, @jsotola
Уте :) ... https://edge.pxcrush.net/std/car/cil/mxu89gdw4v7sjx3evj47ec64d.jpg?width=900, @Ben