Как мне создать конечный автомат для моей цели?
Я новичок в Arduino.
У меня есть мотор, который приводит в движение раздвижную дверь вперед и назад. Двигатель подключен к H-мосту, который имеет два управляющих контакта (направление, скорость). У меня есть переключатель, который предназначен для активации двигателя на определенное количество секунд, чтобы полностью открыть дверь. Когда переключатель деактивирован, двигатель вращается в обратном направлении в течение той же продолжительности, что и открытие.
Я написал некоторый базовый код, используя аргумент «if», но моя проблема в том, что код под аргументом «if» зацикливается, когда мой переключатель активируется/деактивируется, тогда как я хочу, чтобы он запускался один раз при каждой активации переключателя. Посмотрев в Интернете, я увидел, что конечный автомат может быть моим решением, но из-за отсутствия опыта в программировании я не могу создать конечный автомат. Это мой код:
const int Switch = 2;
const int hbridge1 = 13;
const int hbridge2 = 12;
const int threshold = 400;
int buttonState = 0;
void setup() {
pinMode(hbridge1, OUTPUT);
pinMode(hbridge2, OUTPUT);
pinMode(Switch, INPUT_PULLUP);
Serial.begin(9600);
}
void loop() {
int buttonState = digitalRead(Switch);
Serial.println(buttonState);
if (buttonState == HIGH) {
digitalWrite(hbridge1, HIGH);
digitalWrite(hbridge2, LOW);
delay(4000);
digitalWrite(hbridge1, LOW);
digitalWrite(hbridge2, LOW); //I only need the motor to activate for four seconds, but 'if' loops it infinitely
} else {
digitalWrite(hbridge1, LOW);
digitalWrite(hbridge2, HIGH);
delay(4000);
digitalWrite(hbridge1, LOW);
digitalWrite(hbridge2, LOW); //Same issue here
}
;
delay(1);
}
@Marcus, 👍0
Обсуждение2 ответа
Схема поможет найти решение. Используете ли вы резистор, например 10 кОм, для понижения уровня на выводе переключателя? Если кнопка не нажата и код продолжает повторяться, как будто она нажата, я рекомендую добавить резистор. Возможно, вам придется добавить еще один компонент. Как микропереключатель на раме двери, который срабатывает, когда она закрыта. Или кнопку закрытия двери. Без этого каждый цикл кода будет считать, что переключатель удерживается на низком уровне, и активировать двигатель. Это может привести к перегоранию двигателя или срабатыванию предохранителя.
if(buttonstate == high){
//открыть дверь
}
else{
if(microswitch == high){
//Выводы H-моста low, low
{
else{
//закрываем дверь
{
Спасибо за ваш ответ. Я использую встроенный подтягивающий резистор, чтобы понизить контакт переключателя. Что касается микропереключателя, это хорошая идея, однако для моих целей я хотел бы управлять двигателем, используя фиксированную продолжительность (я засек время, необходимое двигателю для открытия/закрытия двери, с помощью секундомера). Когда переключатель находится в низком состоянии, активируйте контакт HBRIDGE1 на *продолжительность закрытия*, затем остановитесь, пока переключатель не активируется. Когда переключатель находится в высоком состоянии, активируйте контакт HBRIDGE2 на *продолжительность открытия*., @Marcus
каждый раз, когда void loop() зацикливается, он смотрит на переключатель, видит, что он низкий, и активирует цикл else{} if. Таким образом, дверь будет закрыта, и он сделает else{}, вам может понадобиться что-то еще. например если (buttonstate == high){ //открыть //задерживать //закрывать } еще{ //h мост низкий, низкий }, @lineman2208
Я буду делать это, пока не разберусь, как сделать конечный автомат. Спасибо., @Marcus
KISS Keep It Simple Stupid. Я думаю, это самое простое решение. Он откроется, задержится, закроется, затем, если он низкий, он будет сидеть с двигателем в режиме торможения, @lineman2208
В этом может помочь создание нескольких логических переменных.
bool opening = 0
bool closing = 0
const int Switch = 2;
const int hbridge1 = 13;
const int hbridge2 = 12;
const int threshold = 400;
int buttonState = 0;
void setup() {
pinMode(hbridge1, OUTPUT);
pinMode(hbridge2, OUTPUT);
pinMode(Switch, INPUT_PULLUP);
Serial.begin(9600);
}
void loop() {
int buttonState = digitalRead(Switch);
Serial.println(buttonState);
if (buttonState == HIGH && opening == 0) { //проверяется переменная «открытие»
opening == 1 //переменная «открытие» включена
closing == 0 //переменная «закрытие» отключена
digitalWrite(hbridge1, HIGH);
digitalWrite(hbridge2, LOW);
delay(4000);
digitalWrite(hbridge1, LOW);
digitalWrite(hbridge2, LOW);
}
else if (buttonState == Low && closing == 0){ //проверяется переменная "закрытие"
opening == 0 //переменная «открытие» отключена
closing == 1 // переменная «закрытие» включена
digitalWrite(hbridge1, LOW);
digitalWrite(hbridge2, HIGH);
delay(4000);
digitalWrite(hbridge1, LOW);
digitalWrite(hbridge2, LOW); //Та же проблема здесь
}
delay(1000) // задержка в миллисекундах. Итак, 1000 = 1 секунда.
}
Эти новые переменные устанавливаются при первом запуске кода. Поэтому никаких циклов.
- L298N Dual Motor Controller Enable Pin имеет питание, но двигатели не работают
- Две батареи делят землю?
- Как соединить L293D и MPU6050 для совместной работы?
- Изготовление H-моста с транзисторами
- Двигатель постоянного тока с драйвером L289N не может установить обороты ниже 130
- Arduino H-bridge для радиоуправляемого автомобиля
- Управление скоростью вентилятора с помощью библиотеки Arduino PID
- Как устранить шум от вентилятора 12 В с ШИМ-управлением на низкой скорости
чтобы открыть его, когда он включен
....чтобы открыть? ... переключатель?, @jsotolaкод под аргументом 'if' зацикливается бесконечно
..... это неправильно .... код в функцииloop()
зацикливается бесконечно, @jsotolaпосмотрите пример скетча BlinkWithoutDelay... он показывает, как синхронизировать событие.... вам также необходимо сохранить значение buttonState и запускать код только при его изменении (сохранить новое значение buttonState ` в конце кода), @jsotola