Остановка двигателя постоянного тока с двумя концевыми выключателями

Я пытаюсь построить автоматическую крышу с датчиком дождя. Когда идёт дождь, крыша закрывается, приводимый в движение двигателем постоянного тока по рельсам, и включается зуммер. Когда крыша достигает конечного положения (нажатия концевого выключателя), двигатель останавливается, и зуммер выключается. Когда дождь прекращается, двигатель снова начинает вращаться, открывая крышу, пока не нажмётся второй концевой выключатель, чтобы остановить двигатель постоянного тока.

Я пытался написать собственную программу, но в ней возникла ошибка: при отсутствии дождя мотор вращается, чтобы закрыть крышу, и останавливается при нажатии концевого выключателя (логика LOW). При обнаружении дождя включается зуммер, но мотор не вращается. Вот мой код. Я использую L293D для драйвера мотора и его контакт включения.

void setup() {
  digitalWrite(enable_motor, HIGH);
  digitalWrite(motor_open, LOW);
  digitalWrite(motor_close, LOW);
  digitalWrite(alarm, LOW);
}

void loop() {
  if (analogRead(rainSensor) < 650){
    digitalWrite(alarm, HIGH);
    digitalWrite(motor_close, HIGH);
    digitalWrite(motor_open, LOW);
  }
  else if (digitalRead(stop_close) == LOW){
    digitalWrite(alarm, LOW);
    digitalWrite(enable_motor, LOW);
  }
  else if (analogRead(rainSensor) > 850){
    digitalWrite(alarm, LOW);
    digitalWrite(motor_close, LOW);
    digitalWrite(motor_open, HIGH);
  }
  else if (digitalRead(stop_open) == LOW){
    digitalWrite(alarm, LOW);
    digitalWrite(enable_motor, LOW);
  }
  else {
    digitalWrite(enable_motor, HIGH);
    digitalWrite(alarm, LOW);
  }
}

Можно ли использовать логику If-Else? Или я ошибаюсь?

, 👍0


1 ответ


Лучший ответ:

1

Ваша логика немного не верна. Например, когда идёт дождь и rainSensor < 650, выполняется только эта часть if, а части else if не выполняются.

Можно просто дождаться, пока крыша откроется/закроется в цикле. Кроме того, будет полезно разбить код на более мелкие функции. (Я не уверен, для чего нужен пин enable_motor, так что, возможно, эту часть нужно исправить.)

// Эта функция определяет текущее состояние крыши
enum {OPEN, CLOSED, OPENING, CLOSING, UNKNOWN};
byte get_roof_status()
{
    if (digitalRead(stop_close) == LOW) return CLOSED;
    else if (digitalRead(stop_open) == LOW) return OPEN; // Исправлена опечатка
    else if (digitalRead(motor_open) == HIGH) return OPENING;
    else if (digitalRead(motor_close) == HIGH) return CLOSING;
    return UNKNOWN;
}

// Вспомогательные функции
void open_roof() {
    digitalWrite(alarm, HIGH);
    digitalWrite(enable_motor, HIGH);
    digitalWrite(motor_close, LOW);
    digitalWrite(motor_open, HIGH);
    // Цикл, пока крыша не откроется
    while (OPEN != get_roof_status()) /* NULL */;
    stop();
}
void close_roof() {
    digitalWrite(alarm, HIGH);
    digitalWrite(enable_motor, HIGH);
    digitalWrite(motor_open, LOW);
    digitalWrite(motor_close, HIGH);
    // Цикл, пока крыша не закроется
    while (CLOSED != get_roof_status()) /* NULL */;
    stop();
}
void stop() {
    digitalWrite(alarm, LOW);
    digitalWrite(enable_motor, LOW);
    digitalWrite(motor_open, LOW);
    digitalWrite(motor_close, LOW);
}

void setup() {
  // Установить режимы вывода
  pinMode(enable_motor, OUTPUT);
  pinMode(motor_open, OUTPUT);
  pinMode(motor_close, OUTPUT);
  pinMode(stop_close, INPUT_PULLUP);
  pinMode(stop_open, INPUT_PULLUP);
  pinMode(alarm, OUTPUT);

  digitalWrite(enable_motor, HIGH);
  digitalWrite(motor_open, LOW);
  digitalWrite(motor_close, LOW);
  digitalWrite(alarm, LOW);
}

void loop() {
  // Эта функция теперь намного проще
  if (analogRead(rainSensor) < 650) {
    close_roof();
  }
  else if (analogRead(rainSensor) > 850){
    open_roof();
  }
}
,

enable_motor предназначен для включения двух входов в L293D, поскольку я использую его контакт включения. Я попробовал использовать вашу структуру кода. Она работает для открытия крыши, но когда двигатель начинает вращаться для закрытия крыши и достигает концевого выключателя, двигатель внезапно меняет направление вращения и снова открывает крышу. Я что-то упустил?, @rofimu

В get_roof_status() была опечатка, и логика enable_motor была перевернута. Я исправил эти проблемы. У меня нет запасных моторов, но есть несколько микросхем L293D. Я смоделировал это (со светодиодами и кнопками), и, похоже, всё работает., @Johnny Mopp