Как мне создать конечный автомат для моей цели?

Я новичок в 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);
}

, 👍0

Обсуждение

чтобы открыть его, когда он включен ....чтобы открыть? ... переключатель?, @jsotola

код под аргументом 'if' зацикливается бесконечно ..... это неправильно .... код в функции loop() зацикливается бесконечно, @jsotola

посмотрите пример скетча BlinkWithoutDelay... он показывает, как синхронизировать событие.... вам также необходимо сохранить значение buttonState и запускать код только при его изменении (сохранить новое значение buttonState ` в конце кода), @jsotola


2 ответа


0

Схема поможет найти решение. Используете ли вы резистор, например 10 кОм, для понижения уровня на выводе переключателя? Если кнопка не нажата и код продолжает повторяться, как будто она нажата, я рекомендую добавить резистор. Возможно, вам придется добавить еще один компонент. Как микропереключатель на раме двери, который срабатывает, когда она закрыта. Или кнопку закрытия двери. Без этого каждый цикл кода будет считать, что переключатель удерживается на низком уровне, и активировать двигатель. Это может привести к перегоранию двигателя или срабатыванию предохранителя.

if(buttonstate == high){
//открыть дверь
}
else{
if(microswitch == high){
//Выводы H-моста low, low
{
else{
//закрываем дверь
{

schematic

,

Спасибо за ваш ответ. Я использую встроенный подтягивающий резистор, чтобы понизить контакт переключателя. Что касается микропереключателя, это хорошая идея, однако для моих целей я хотел бы управлять двигателем, используя фиксированную продолжительность (я засек время, необходимое двигателю для открытия/закрытия двери, с помощью секундомера). Когда переключатель находится в низком состоянии, активируйте контакт HBRIDGE1 на *продолжительность закрытия*, затем остановитесь, пока переключатель не активируется. Когда переключатель находится в высоком состоянии, активируйте контакт HBRIDGE2 на *продолжительность открытия*., @Marcus

каждый раз, когда void loop() зацикливается, он смотрит на переключатель, видит, что он низкий, и активирует цикл else{} if. Таким образом, дверь будет закрыта, и он сделает else{}, вам может понадобиться что-то еще. например если (buttonstate == high){ //открыть //задерживать //закрывать } еще{ //h мост низкий, низкий }, @lineman2208

Я буду делать это, пока не разберусь, как сделать конечный автомат. Спасибо., @Marcus

KISS Keep It Simple Stupid. Я думаю, это самое простое решение. Он откроется, задержится, закроется, затем, если он низкий, он будет сидеть с двигателем в режиме торможения, @lineman2208


1

В этом может помочь создание нескольких логических переменных.

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 секунда.
}

Эти новые переменные устанавливаются при первом запуске кода. Поэтому никаких циклов.

,