Как вызвать несколько отложенных функций с помощью одного миллиметра()

Я работаю в проекте, где мне нужно вызвать более 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" выполняется в правильной последовательности и времени, но остальные остальные делают беспорядочный вывод.

Как я могу это исправить, пожалуйста?

- Спасибо.

, 👍1

Обсуждение

Как вы хотите, чтобы функции вызывались по порядку? Как "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


2 ответа


0

ваш 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


2

Текущая структура с несколькими операторами 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