Реверсирование вращения двигателя постоянного тока с использованием ДВУХ концевых выключателей

Я хотел бы написать код для изменения направления вращения двигателя постоянного тока следующим образом:

  1. Начните вращение двигателя по часовой стрелке (CW).
  2. При достижении концевого выключателя (CW) → двигатель остановится на 5 секунд.
  3. через 5 сек. остановки → двигатель будет вращаться против часовой стрелки (CCW).
  4. При достижении концевого выключателя (CCW) → двигатель остановится на 5 секунд.

и повторите пункты 1, 2, 3 и 4...

На самом деле я написал код для изменения направления вращения двигателя с использованием двух концевых выключателей, и он работает хорошо. Но когда я добавил задержку, двигатель не остановился, используя концевые выключатели, и продолжил вращаться... Если кто-то может помочь... Вот мой код для изменения направления без задержки в 5 сек. Мои предельные SW подключены по нормальному открытому принципу.

int sw1, sw2, sw3;
const int LM1 = 0;
const int LM2 = 1;
const int LM3 = 6;
const int CW = 10;
const int CCW = 9;
const int Buzzer = 7;


void setup() {
  pinMode(LM1, INPUT);
  pinMode(LM2, INPUT);
  pinMode(LM3, INPUT);
  pinMode(CW, OUTPUT);
  pinMode(CCW, OUTPUT);
}

void loop(){
  sw3 = digitalRead(LM3);
  sw1 = digitalRead(LM1);
  sw2 = digitalRead(LM2);

  if (sw1 == LOW && sw2 == HIGH) {
    do {
      digitalWrite(Buzzer, HIGH);
      digitalWrite(CW, HIGH);// изменение направления вращения (движение ВНИЗ)
      digitalWrite(CCW, LOW);

      sw2 = digitalRead(LM2);
    } while (sw2 == HIGH);
  }
  else if (sw1 == HIGH && sw2 == LOW) {
    do {
      digitalWrite(Buzzer, HIGH);
      digitalWrite(CW, LOW);// изменение направления вращения (движение ВВЕРХ)
      digitalWrite(CCW, HIGH);

      sw1= digitalRead(LM1);
    } while (sw1 == HIGH);
  }
}

, 👍1


2 ответа


0

Возможно, код с задержкой в 5 секунд более полезен. Ведь вы говорите нам, что код, который вы сейчас предоставляете, должен работать?

Вероятно, использование delay(5000) сработает?

,

2

Обычно для такого рода программирования используется конечный автомат: у вас есть state переменная, которая запоминает, что вы делаете, и в зависимости от текущее состояние вы решаете, что делать дальше. Ниже приведен пример с двумя состояния. Я вставил несколько предположений о проводке вашего двигателя и ваши переключатели, которые могут быть неправильными, поэтому вам придется проверить код.

void loop() {
    static enum {MOVING_CW, MOVING_CCW} state;

    switch (state) {
    case MOVING_CW:
        if (digitalRead(LM2) == LOW) {  // нажать переключатель
            digitalWrite(CW, LOW);      // остановить
            delay(5000);
            digitalWrite(CCW, HIGH);    // перезапуск
            state = MOVING_CCW;
        }
        break;
    case MOVING_CCW:
        if (digitalRead(LM1) == LOW) {  // нажать переключатель
            digitalWrite(CCW, LOW);     // остановить
            delay(5000);
            digitalWrite(CW, HIGH);     // перезапуск
            state = MOVING_CW;
        }
        break;
    }
}

Это начнется в состоянии MOVING_CW, но вам нужно будет фактически начать движение в setup(). Недостатком является наличие длительных delay() в цикл, что нежелательно, если у вас есть другие задачи для выполнения. Эти задержки можно устранить, «помня», что вы ждете, как два дополнительных говорится:

void loop() {
    static enum {MOVING_CW, MOVING_CCW, STOPPED_CW, STOPPED_CCW} state;
    static unsigned long time_stopped;
    unsigned long now = millis();

    switch (state) {
    case MOVING_CW:
        if (digitalRead(LM2) == LOW) {  // нажать переключатель
            digitalWrite(CW, LOW);      // остановить
            state = STOPPED_CW;
            time_stopped = now;
        }
        break;
    case MOVING_CCW:
        if (digitalRead(LM1) == LOW) {  // нажать переключатель
            digitalWrite(CCW, LOW);     // остановить
            state = STOPPED_CCW;
            time_stopped = now;
        }
        break;
    case STOPPED_CW:
        if (now - time_stopped >= 5000) {
            digitalWrite(CCW, HIGH);    // перезапуск
            state = MOVING_CCW;
        }
        break;
    case STOPPED_CCW:
        if (now - time_stopped >= 5000) {
            digitalWrite(CW, HIGH);     // перезапуск
            state = MOVING_CW;
        }
        break;
    }
}
,