Программа работает при использовании Delay(), но та же программа не работает с millis()

Я запускаю двигатель постоянного тока, используя esp32 и MOSFET, снимая показания IR.

Программа работает нормально при использовании delay(), но та же программа не работает при загрузке с использованием millis().

//Это использует фиксированную задержку()

// Определения выводов
const int irSensorPin = 34;  // ИК-датчик подключен к GPIO 2
const int motorPin = 32;     // Двигатель постоянного тока подключен к GPIO 4

// Переменные
bool isObjectDetected = false;

void setup() {
  // Инициализировать последовательную связь
  Serial.begin(9600);

  // Установить режимы вывода
  pinMode(irSensorPin, INPUT);
  pinMode(motorPin, OUTPUT);
}

void loop() {
  // Проверяем, обнаружен ли объект
  if (digitalRead(irSensorPin) == LOW) {
    if (!isObjectDetected) {
      // Объект обнаружен впервые
      isObjectDetected = true;
      Serial.println("Object detected. Stopping motor.");
      digitalWrite(motorPin, LOW);  // Остановить двигатель
      delay(500);                   // Ждем 500 мс
      Serial.println("Resuming motor.");
      digitalWrite(motorPin, HIGH); // Запускаем мотор
    }
  } else {
    if (isObjectDetected) {
      // Объект больше не обнаруживается
      isObjectDetected = false;
    }
  }
}



//Здесь используется millis()

// Определения выводов
const int irSensorPin = 34;  // ИК-датчик подключен к GPIO 34
const int motorPin = 32;     // Двигатель постоянного тока подключен к GPIO 32

// Переменные
bool isObjectDetected = false;
unsigned long motorStopTime = 0;
const unsigned long motorDelayTime = 500;  // Время задержки в миллисекундах

void setup() {
  // Инициализировать последовательную связь
  Serial.begin(9600);

  // Установить режимы вывода
  pinMode(irSensorPin, INPUT);
  pinMode(motorPin, OUTPUT);

  // Инициализировать состояние мотора
  digitalWrite(motorPin, HIGH);  // Запускаем мотор
}

void loop() {
  // Проверяем, обнаружен ли объект
  if (digitalRead(irSensorPin) == HIGH) {
    if (!isObjectDetected) {
      // Объект обнаружен впервые
      isObjectDetected = true;
      Serial.println("Object detected. Stopping motor.");
      digitalWrite(motorPin, LOW);  // Остановить двигатель
      motorStopTime = millis();     // Записываем время остановки
    }
  } else {
    if (isObjectDetected) {
      // Объект больше не обнаруживается
      isObjectDetected = false;
      unsigned long currentTime = millis();
      if (currentTime - motorStopTime >= motorDelayTime) {
        Serial.println("Resuming motor.");
        digitalWrite(motorPin, HIGH); // Запускаем мотор
      }
    }
  }
}

, 👍1

Обсуждение

«_не работает_» — бесполезное описание проблемы. Каково ожидаемое поведение? Каково фактическое поведение?, @Edgar Bonet

@EdgarBonet Извините за плохое разъяснение. Я сделал программу, в которой ИК-датчик обнаруживает объект, а двигатель постоянного тока должен выключаться на 1 секунду или 500 мс. В первой моей программе все работает нормально. двигатель запускается нормально, инфракрасный датчик обнаруживает объект и сообщает двигателю подождать 1 секунду, а затем двигатель снова запускается через 1 секунду, даже если инфракрасный датчик обнаруживает объект впереди. В моей второй программе я использую millis() с задержкой 500 мс, но эта программа не запускает двигатель нормально., @Akash Patil

Я разместил пример кода на аналогичный вопрос по адресу https://arduinoprosto.ru/q/93115/arduino-dc-motor-control-over-ir-sensor-input... он включает ссылку на симуляцию, @jsotola

@jsotola переключить?, @Akash Patil

Какие операторы печати вы видите? Возможно, вход «болтается», поскольку вы вообще его не устраняете, и поэтому motorStopTime продолжает сбрасываться на текущее время., @Chad G

переключиться? ... Я понятия не имею, что это значит, @jsotola


1 ответ


1

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

Версия с использованием delay():

диаграмма состояний

Версия с использованием millis():

диаграмма состояний

На приведенных выше диаграммах серым фоном отмечены состояния, в которых двигатель выключен. Как видно здесь, первая версия никогда не сохраняет двигатель выключен более чем на 0,5 с, где второй может удерживать двигатель отключается на неопределенный срок, если датчик остается ВЫСОКИМ.

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

,