Как вызвать несколько отложенных функций с помощью одного миллиметра()
Я работаю в проекте, где мне нужно вызвать более 1 функции, на самом деле 4 функции, используя один millis()
Вот код ниже.
unsigned long then = 0;
void loop(){
unsigned long now = millis();
if(now-then >=0){
Serial.println("Function 1 called");
}else if(now-then>=2000){
Serial.println("Function 2 called");
}else if(now-then>=4000){
Serial.println("Function 3 called");
}else if(now-then>=6000){
Serial.println("Function 4 called");
Serial.println("The end");
then = now;
}
}
Все вышеперечисленные функции выполняются успешно, но не в правильной последовательности.
Последовательность выполнения функций кажется очень неправильной и случайной.
"Функция 1" выполняется в правильной последовательности и времени, но остальные остальные делают беспорядочный вывод.
Как я могу это исправить, пожалуйста?
- Спасибо.
2 ответа
ваш else
в этом наборе if
's вызывает только одно if, которое может быть истинным в любой момент времени, и как только линия now-then
построится, только первый в этой линии когда-либо будет выполняться. удалите else
из вашего блока if. относитесь к каждому "если" как к своей собственной вещи.
if(now-then >=0) { /* do thing 1*/ }
if(now-then >=1000) { /* do thing 2*/ }
if(now-then >=2000) { /* do thing 3*/ }
if(now-then >=3000) { /* do thing 4*/ }
таким образом, даже если условия совпадают, все блоки будут проверены, и все if
, которые разрешают true, будут выполняться.
ваш код приведет к последовательности 1, 1, 2, 1, 2, 3, 1, 2, 3, 4, @jsotola
Вам нужна печать для каждой "вещи x", потому что вам придется сбросить каждую из них до текущего миллиметра, когда "вещь" будет выполнена., @Sim Son
Текущая структура с несколькими операторами if и переменной on timestamp работает только в том случае, если вы также проверяете наличие функции millis()-тогда
она меньше следующего интервала. В противном случае всегда будет выполняться первый оператор if.
Я думаю, что это становится проще, когда вы используете только один оператор if, но помещаете интервалы в массив. В этом операторе if вы можете либо использовать оператор switch для выполнения кода для соответствующего интервала, либо использовать указатель функции. Примерно так (непроверено):
unsigned long then = 0;
unsigned long intervals[4] = {0, 2000, 4000, 6000};
int current_interval_index = 0;
...
void loop(){
unsigned long now = millis();
if(now-then >= intervals[current_interval_index]){
switch(current_interval_index){
case 0:
Serial.println("Function 1");
break;
case 1:
Serial.println("Function 2");
break;
case 2:
Serial.println("Function 3");
break;
case 3:
Serial.println("Function 4");
break;
}
then = now;
current_interval_index = (current_interval_index + 1) % 4; // increment index and wrap it back to zero, if it goes to 4
}
}
Таким образом, вы можете легко экстентировать больше функций, а интервалы удобно управлять в массиве. Обратите внимание, что интервалы здесь складываются. Таким образом, функция 4 выполняется через 2 с+3 с+6 с = 11 с.
Нет, я виноват, пропустил масштаб обновления индекса., @SoreDakeNoKoto
- Использовать timer0, не влияя на millis() и micros().
- Торговый автомат Arduino для мониторинга ввода монет в слот во время ожидания ввода пользователя
- Arduino Мигает двумя светодиодами без задержки (количество повторений)
- Сброс Arduino с помощью ПО (каждый день)
- Та же кнопка одним кликом и двойным кликом
- Как сбросить millis()?
- Реструктурировать код для многозадачности Neopixel + ИК-пульт + ардуино
- Кнопка переключения переключает между операторами обращения с разблокированием кнопки
Как вы хотите, чтобы функции вызывались по порядку? Как "1,2,3,4 ... 1,2,3,4" или как "1...1,2...1,2,3...1,2,3,4...1...1,2..."?, @chrisl
Например, заказ "1234", @Subha Jeet Sikdar
почему с " еще
? почему только одно " тогда
?, @Juraj