Как использовать 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); // Обновить фактический светодиод
}
}
}
@user2037091, 👍3
Обсуждение2 ответа
Лучший ответ:
Если я правильно понимаю, вы написали пример кода, который переключает Индикатор переключается между двумя состояниями (включено и выключено), и вы застреваете, потому что реальная проблема, которую вы хотите решить, более сложна, чем эта. И действительно, мне кажется, что вы хотите управлять системой с тремя возможными состояниями: она может быть включена или выключена, но когда она выключена, она может быть готова к включению, если влажность высокая, или может находиться в пятиминутном ожидании.
Самый естественный способ думать о такого рода системах - это конечный автомат, или FSM. FSM определяется набором состояний, в которых он может находиться, условиями, которые заставляют его переключать состояния, и действиями , выполняемыми при этом. Если я правильно понял вашу спецификацию, ваша система может быть либо ГОТОВОЙ, ЗАПУЩЕННОЙ, либо ОЖИДАЮЩЕЙ, а переходы следующие:
- когда ВСЕ будет ГОТОВО, если влажность слишком высока, он переключается на РЕЖИМ РАБОТЫ; при этом включается вентилятор
- при ЗАПУСКЕ, если он работает в течение 3 минут, он переключается в режим ОЖИДАНИЯ и выключает вентилятор
- при ОЖИДАНИИ, если он ждал в течение 5 минут, он переключается в режим ГОТОВНОСТИ
Это можно проиллюстрировать следующей диаграммой состояний:
Вы должны поправить меня на этом этапе, если я не до конца понял вашу спецификацию. В противном случае, если диаграмма состояний соответствует вашим требованиям, преобразовать ее в код довольно просто:
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
Для вашей текущей проблемы (включение и выключение светодиодов через 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
- Торговый автомат Arduino для мониторинга ввода монет в слот во время ожидания ввода пользователя
- Та же кнопка одним кликом и двойным кликом
- Как запустить 4 светодиода последовательно на основе кнопочного входа?
- Как справиться с rollover millis()?
- Печать string and integer LCD
- Почему мои часы реального времени показывают неверное время с моего ПК?
- Arduino uno + cnc Shield v3 + драйвер шагового двигателя A4988 + AccelStepper?
- Отправьте несколько значений int из Python в Arduino, используя pySerial
с какой проблемой вы боретесь? ... в чем заключается ваш вопрос?, @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