Как использовать Multipile millis()

У меня есть вытяжной вентилятор, который работает при высокой влажности. Когда вытяжной вентилятор включен, он должен работать в течение 3 минут и должен подождать еще 5 минут, чтобы включиться. Я новичок в этой борьбе уже почти 2 дня. с помощью этого кода светодиод просто мигает и гаснет

int ledPin =  2;      // номер вывода светодиода
int ledState = LOW;             // ledState используется для установки светодиода
unsigned long previousMillis2 = 0;
unsigned long previousMillis = 0;
long interval = 10000;           // при
long OnTime = 1000;           // миллисекунды времени включения длительное время
long OffTime = 2000;          // миллисекунды времени простоя

void setup()
{

  Serial.begin(9600);
  // установите цифровой вывод в качестве выходного:
  pinMode(ledPin, OUTPUT);
}

void loop()
{

  unsigned long currentMillis2 = millis();

  if (currentMillis2 - previousMillis2 > interval) {
    // сохраните время последнего мигания светодиода



    // проверьте, не пришло ли время изменить состояние светодиода
    Serial.print("hellohh ");
    unsigned long currentMillis = millis();

    if ((ledState == HIGH) && (currentMillis - previousMillis >= OnTime))
    {
      Serial.print("hellohh2 ");
      ledState = LOW;  // Выключите его
      previousMillis = currentMillis;  // Запомните время
      digitalWrite(ledPin, ledState);  // Обновить фактический светодиод
    }
    else if ((ledState == LOW) && (currentMillis - previousMillis >= OffTime))
    {
      Serial.print("hellohh 3");
      ledState = HIGH;  // включите его
      previousMillis = currentMillis;
      previousMillis2 = 0; // Запомнить время
      digitalWrite(ledPin, ledState);    // Обновить фактический светодиод

    }
  }
}

, 👍3

Обсуждение

с какой проблемой вы боретесь? ... в чем заключается ваш вопрос?, @jsotola

@jsotola 1-я проверка и 3-я проверка работают только, @user2037091

Что печатается на вашем последовательном мониторе? привет / привет2 / привет3? Можете ли вы отредактировать свой вопрос и скопировать / вставить часть выходных данных, чтобы мы могли видеть, какие логические ветви соблюдаются., @Nick Gammon

В своем вопросе вы сказали 3 минуты и 5 минут, но я не вижу никаких ссылок на это в коде (3 минуты были бы 3 * 60 * 1000 миллисекунды = 180000)., @Nick Gammon

@NickGammon сейчас просто пытаюсь использовать несколько светодиодов,, @user2037091

@NickGammon один вытяжной вентилятор при высокой влажности воздуха в течение 3 минут, если влажность все еще высокая, вентилятор снова включится, мне нужен 5-минутный промежуток между включением следующего вентилятора, вот что я имел в виду, @user2037091

Ваш первый тест if (currentMillis2 - previousMillis2> interval) { предназначен для более длительного интервала, чем 1000/2000, поэтому я ожидаю странного поведения. Вы не сказали, что происходит на самом деле. Сказать, что "проверка работает", немного неконкретно. Что печатается? Горит ли светодиод?, @Nick Gammon

теперь светодиод мигает и выключается @NickGammon, @user2037091

Это не форум. Пожалуйста, ** отредактируйте свой вопрос ** и предоставьте дополнительную информацию, например, что такое последовательный вывод и что происходит на самом деле. Комментарии предназначены ** не для отладки проблемы **., @Nick Gammon

хорошо @NickGammon новичок в вещах, понятия не имею, как что-то делать, извините, @user2037091

Я понимаю, что вы новичок, и я предложил вам сделать определенные вещи, которые вы не сделали, пока я пишу это. Я рекомендую вам следовать моим предыдущим советам о том, как лучше документировать вашу проблему, и тогда мы сможем помочь вам лучше., @Nick Gammon

Кроме того, вопрос и комментарии (несколько вентиляторов в течение 3-5 минут) и ваш код (индикатор включения на 1 секунду / выключения на 2 секунды), похоже, вообще не совпадают., @towe

@towe просто тестирую, но это застряло, @user2037091


2 ответа


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

5

Если я правильно понимаю, вы написали пример кода, который переключает Индикатор переключается между двумя состояниями (включено и выключено), и вы застреваете, потому что реальная проблема, которую вы хотите решить, более сложна, чем эта. И действительно, мне кажется, что вы хотите управлять системой с тремя возможными состояниями: она может быть включена или выключена, но когда она выключена, она может быть готова к включению, если влажность высокая, или может находиться в пятиминутном ожидании.

Самый естественный способ думать о такого рода системах - это конечный автомат, или FSM. FSM определяется набором состояний, в которых он может находиться, условиями, которые заставляют его переключать состояния, и действиями , выполняемыми при этом. Если я правильно понял вашу спецификацию, ваша система может быть либо ГОТОВОЙ, ЗАПУЩЕННОЙ, либо ОЖИДАЮЩЕЙ, а переходы следующие:

  • когда ВСЕ будет ГОТОВО, если влажность слишком высока, он переключается на РЕЖИМ РАБОТЫ; при этом включается вентилятор
  • при ЗАПУСКЕ, если он работает в течение 3 минут, он переключается в режим ОЖИДАНИЯ и выключает вентилятор
  • при ОЖИДАНИИ, если он ждал в течение 5 минут, он переключается в режим ГОТОВНОСТИ

Это можно проиллюстрировать следующей диаграммой состояний:

state diagram

Вы должны поправить меня на этом этапе, если я не до конца понял вашу спецификацию. В противном случае, если диаграмма состояний соответствует вашим требованиям, преобразовать ее в код довольно просто:

const uint32_t MINUTE = 60000;

void loop() {
    static enum {READY, RUNNING, WAITING} state;
    static uint32_t last_change;
    uint32_t now = millis();
    switch (state) {
        case READY:
            if (humidity_is_high()) {
                turn_fan_on();
                state = RUNNING;
                last_change = now;
            }
            break;
        case RUNNING:
            if (now - last_change >= 3 * MINUTE) {
                turn_fan_off();
                state = WAITING;
                last_change = now;
            }
            break;
        case WAITING:
            if (now - last_change >= 5 * MINUTE) {
                state = READY;
            }
            break;
    }
}
,

Я не знаю , как вас благодарить , это работает как шарм ., @user2037091

Спасибо за понимание моей цели :), @user2037091


2

Для вашей текущей проблемы (включение и выключение светодиодов через 1-2 секунды) большая часть вашего кода может быть упрощена:

int ledPin =  2;     // Номер вывода светодиода
int ledState = LOW;  // ledState используется для установки светодиода
unsigned long TimeLedOFF = 0;     // Время, в которое светодиод в последний раз выключался
unsigned long TimeLedON = 0;      // Время, в которое светодиод в последний раз включался
unsigned long TimeLastCheck = 0;  // Время, в которое было определено следующее состояние светодиода последний
long interval = 100;  // Как часто проверять наличие изменений в окружающей среде - должно быть короче, чем длительность вашего переключения
long OnTime = 1000;   // Миллисекунды времени
long OffTime = 2000;  // Миллисекунды в нерабочее время

void setup() {
  Serial.begin(9600);
  pinMode(ledPin, OUTPUT); // установите вывод светодиода в качестве вывода:
}

void loop() {
  if (millis() - TimeLastCheck > interval) { // Если состояние светодиода должно быть оценено снова - "интервал" прошел
    TimeLastCheck = millis();

    Serial.println("Determining next LED state");

    if (ledState == HIGH && (millis() - TimeLedON >= OnTime)) { //Если светодиод был включен достаточно долго
      Serial.println("OnTime elapsed. Turning off.");
      TimeLedOFF = millis(); // Запомнить время
      ledState = LOW;        // Выключить индикатор
      digitalWrite(ledPin, ledState); // Обновить фактический светодиод
    }
    else if (ledState == LOW && (millis() - TimeLedOFF >= OffTime)) { //Если светодиод был выключен достаточно долго
      Serial.println("OffTime elapsed. Turning on.");
      TimeLedON = millis(); // Запомнить время
      ledState = HIGH;  // включите
      digitalWrite(ledPin, ledState);    // Обновите фактический светодиод
    }
  }
}

Это приводит к тому, что светодиод включается на одну секунду, а затем выключается на две секунды.

,

Спасибо, когда я меняю интервал времени на 20000 Время включения длительное время выключения автоматически изменяется на 20000 @ towe, @user2037091

Да, поскольку вы проверяете, должно ли что-то происходить только один раз за "интервал времени". К тому времени два других срока уже давно прошли. Для чего именно вам нужен / нужен интервал времени?, @towe

Да, мне нужен точный интервал времени, я не знаю, как проверить: (, @user2037091

мой датчик влажности постоянно проверяет температуру и шум, я не хочу, чтобы мой вентилятор работал все время, поэтому мне нужен интервал времени 5 м, если это необходимо, @user2037091

Это не то, что делает "интервал времени" в вашем (или моем) скетче - вентилятор выключается по истечении времени включения., @towe

Да, я проверил. Как я могу этого добиться ? можете ли вы показать мне пример?, @user2037091

Просто чтобы уточнить, я вас правильно понял: Вы считываете уровень влажности. Если она слишком высока, вы хотите, чтобы вентилятор работал не более трех минут. Затем он должен подождать пять минут, пока снова не проверит влажность и не решит, включать вентилятор снова или нет (на три минуты)?, @towe

Да, верно. если(влажность < 50){ туманоуловитель ();} еще, если (влажность> 70){ digitalWrite(мощность DHT, НИЗКАЯ); // exhuast вентилятор включен здесь }еще, если ((temp> 32) && (гул < 55)) { туманоуловитель (); }, @user2037091

датчик будет продолжать проверять влажность после включения вентилятора в течение 3 минут, должно пройти 5 минут, чтобы снова включить его в течение 3 минут, @user2037091

Значит, он будет постоянно проверять влажность и включать вентилятор, если ваш уровень превысит 70? Что делает функция fogger()?, @towe

туманоуловитель на самом деле включает его, когда влажность ниже 50, @user2037091

спасибо вам за ваше время и усилия, я получил код. Спасибо за вашу помощь, @user2037091