два таймера из одного millis

itar
itar аватар
Offline
Зарегистрирован: 20.03.2018

вот целиком

const int ledPin = 13;
int State = LOW;
unsigned long previousMillis;
const long interval_1 = 1000;
const long interval_2 = 10000;
void setup() {
  pinMode(ledPin, OUTPUT);
}
void loop() {
    unsigned long currentMillis = millis ( );
  if ( State == LOW ) {
  if ( currentMillis - previousMillis >= interval_1 ) { 
     previousMillis = currentMillis;                   
     State = HIGH;
     digitalWrite (ledPin, State );
   }}
  if ( State == HIGH ) {
  if ( currentMillis - previousMillis >= interval_2 ) { 
     previousMillis = currentMillis;                 
     State = LOW;
     digitalWrite ( ledPin, State );
    }
  }
}

 

ven-til
Offline
Зарегистрирован: 13.02.2018

itar пишет:

вот целиком

Работает.

ven-til
Offline
Зарегистрирован: 13.02.2018

Вот такой код тоже работает.

if ( currentMillis - previousMillis >= interval ) {  
     previousMillis = currentMillis;                    
     boolState = !boolState;
     digitalWrite ( sveha, boolState );
     interval = 11000-interval;
   }

 

b707
Offline
Зарегистрирован: 26.05.2017

itar. вы настолько криворукий. что даже готовый код не в состоянии использовать?

Для наглядности добавил вывод в Сериал:

const int ledPin = 13;
int State = LOW;
unsigned long previousMillis;
const long interval_1 = 1000;
const long interval_2 = 2000;
void setup() {
  pinMode(ledPin, OUTPUT);
  Serial.begin(9600);
}
void loop() {
    unsigned long currentMillis = millis ( );
  if ( State == LOW ) {
  if ( currentMillis - previousMillis >= interval_1 ) { 
     previousMillis = currentMillis;                   
     State = HIGH;
     Serial.print(" Go to High ");
     Serial.println(currentMillis);
     digitalWrite (ledPin, State );
   }}
  if ( State == HIGH ) {
  if ( currentMillis - previousMillis >= interval_2 ) { 
     previousMillis = currentMillis;                 
     State = LOW;
     Serial.print(" Go to Low ");
     Serial.println(currentMillis);
     digitalWrite ( ledPin, State );
    }
  }
}

А вот результат работы

Go to High 1000
 Go to Low 3000
 Go to High 4000
 Go to Low 6000
 Go to High 7000
 Go to Low 9000
 Go to High 10000

 

b707
Offline
Зарегистрирован: 26.05.2017

ven-til пишет:

Вот такой код тоже работает.

не забудьте только правильно указать типы данных - а то ТС сам не справится. У него, заметьте - интервал типа long

itar
itar аватар
Offline
Зарегистрирован: 20.03.2018

Если наоборот.

вот в таком виде действительно получилось,то что и требовалось.


const int ledPin = 13;
int State = LOW;
unsigned long previousMillis;
const long interval_1 = 10000;
const long interval_2 = 1000;
void setup() {
  pinMode(ledPin, OUTPUT);
  Serial.begin(9600);
}
void loop() {
    unsigned long currentMillis = millis ( );
  if ( State == LOW ) {
  if ( currentMillis - previousMillis >= interval_1 ) {
     previousMillis = currentMillis;                  
     State = HIGH;                           //потушили
     Serial.print(" Go to High ");
    Serial.println(currentMillis);
     digitalWrite (ledPin, State );
   }}
  if ( State == HIGH ) {
  if ( currentMillis - previousMillis >= interval_2 ) {
     previousMillis = currentMillis;                
     State = LOW;                                 //включили
     Serial.print(" Go to Low ");
     Serial.println(currentMillis);
     digitalWrite ( ledPin, State );

Спасибо.

 

b707
Offline
Зарегистрирован: 26.05.2017

itar пишет:

Если наоборот.

вот в таком виде действительно получилось,то что и требовалось.

Ну слава богу - заказчик принял работу :)

itar, так в чем выражалось "не работает" ? - то что я в примере поставил интервал 2 сек вместо нужных Вашему Сиятельству 10-ти? :)

Офигеть - уже и значения констант в готовом скетче сами поменять не могут.

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

b707 пишет:

Офигеть - уже и значения констант в готовом скетче сами поменять не могут.

Не царское это дело! Взялся, так будь любезен не халтурить, а выставлять все константы как надо! Совсем помогатели распустились, блин!

itar
itar аватар
Offline
Зарегистрирован: 20.03.2018

я не  знаю почему вариант ven-tilа  не работал . светодиод просто горел.

b707
Offline
Зарегистрирован: 26.05.2017

itar пишет:

я не  знаю почему вариант ven-tilа  не работал

причем тут вариант ven-tilа - я спрашиваю про свой код - который ваш скетч из #51

itar
itar аватар
Offline
Зарегистрирован: 20.03.2018

Столько агрессии.я же не утверждал, что я специалист.

приобрел плату месяц назад, это весь мой опыт.

itar
itar аватар
Offline
Зарегистрирован: 20.03.2018

ваш код работал .только я местами поменял интервалы и все.

bwn
Offline
Зарегистрирован: 25.08.2014

itar пишет:

Столько агрессии.я же не утверждал, что я специалист.

приобрел плату месяц назад, это весь мой опыт.

Они тут такие.

itar
itar аватар
Offline
Зарегистрирован: 20.03.2018

всего пару дней поплевали. Зато результат.

И на том спасибо.

ven-til
Offline
Зарегистрирован: 13.02.2018

itar пишет:

всего пару дней поплевали. Зато результат.

И на том спасибо.

Просто кто-то наплевательски отнесся к вразумительной подаче ответов.

Pyotr
Offline
Зарегистрирован: 12.03.2014

Часто так строю loop()

void loop(){
  carrMillis = millis();
  if(carrMillis - prevMillis >= 10){//10ms
    prevMillis += intervalMs;
   // делаем три действия каждые 100 мс, но со сдвигом "по фазе" в 20 мс
    if(((countCycle + 13) % 10) == 0){//кажд.100 мс 
     //действие 1
    }
    if(((countCycle + 15) % 10) == 0){//кажд.100 мс      
      //действие 2
    }
    if(((countCycle + 17) % 10) == 0){//кажд.100 мс
      //действие 3
    }
    switch (countCycle){
      case 0 ... (TOTAL_STR -1):  //TOTAL_STR - всего строк     
        if(menu == 0)  printLCD(countCycle); //выводим по одной строке за луп
        break;//раз в сек
     
      case 5:
       if((second % 3) == 0) tempAer = getDS();//кажд.3 сек. В сот *С
     
      break;
      case 6: 
        if((second % 3) == 2)  startDS();  break;//за 1 сек до чтения
      case 7:  
        tempKot = readTempKTY81(PIN_KTY_KOTEL);//в сотых *С  каждую сек
        break;
      case 8:  
        //действие 4
        break;  
      case 40: 
        if(!menu && !startStroka) { lcd.setCursor(2, startStroka);  lcd.print(' '); }//мигает ":" на часах
        break;
      case 80: 
        tempOil = readTempKTY81(PIN_KTY_OIL);//в сотых *С
      
        break;        
    }    
    if(++countCycle >= 100){//прошла  1 сек
      countCycle = 0;
    }
  }
}//END loop()

 

Bruzzer
Offline
Зарегистрирован: 17.03.2020

Pyotr пишет:

Часто так строю loop()

void loop(){
  carrMillis = millis();
  if(carrMillis - prevMillis >= 10){//10ms
    prevMillis += intervalMs;
   // делаем три действия каждые 100 мс, но со сдвигом "по фазе" в 20 мс
    if(((countCycle + 13) % 10) == 0){//кажд.100 мс 
     //действие 1
    }
    if(((countCycle + 15) % 10) == 0){//кажд.100 мс      
      //действие 2
    }
    if(((countCycle + 17) % 10) == 0){//кажд.100 мс
      //действие 3
    }
    switch (countCycle){
      case 0 ... (TOTAL_STR -1):  //TOTAL_STR - всего строк     
        if(menu == 0)  printLCD(countCycle); //выводим по одной строке за луп
        break;//раз в сек
     
      case 5:
       if((second % 3) == 0) tempAer = getDS();//кажд.3 сек. В сот *С
     
      break;
      case 6: 
        if((second % 3) == 2)  startDS();  break;//за 1 сек до чтения
      case 7:  
        tempKot = readTempKTY81(PIN_KTY_KOTEL);//в сотых *С  каждую сек
        break;
      case 8:  
        //действие 4
        break;  
      case 40: 
        if(!menu && !startStroka) { lcd.setCursor(2, startStroka);  lcd.print(' '); }//мигает ":" на часах
        break;
      case 80: 
        tempOil = readTempKTY81(PIN_KTY_OIL);//в сотых *С
      
        break;        
    }    
    if(++countCycle >= 100){//прошла  1 сек
      countCycle = 0;
    }
  }
}//END loop()

Спасибо за пример. Маленькое замечание. У вас нумерация действий  идет в обратном порядке. Сначала выполнится 3 потом 2 потом 1.

    if(((countCycle + 13) % 10) == 0){//кажд.100 мс 
     //действие 1
    }
    if(((countCycle + 15) % 10) == 0){//кажд.100 мс      
      //действие 2
    }
    if(((countCycle + 17) % 10) == 0){//кажд.100 мс
      //действие 3
    }
rkit
Offline
Зарегистрирован: 23.11.2016

Pyotr пишет:

   if(((countCycle + 15) % 10) == 0){//кажд.100 мс      

И получаешь не пропуски так повторы. Кошмар.

Pyotr
Offline
Зарегистрирован: 12.03.2014

rkit пишет:

Pyotr пишет:

   if(((countCycle + 15) % 10) == 0){//кажд.100 мс      

И получаешь не пропуски так повторы. Кошмар.

rkit,  почему кошмар? Обычный быдлокод ардуинщика.

Сейчас проверить не могу, покажи, если не трудно, код где видны пропуски и повторы.

bwn
Offline
Зарегистрирован: 25.08.2014

Вышел я из возраста, на слабО и писькометрии. Любой, желающий поплеваться желчью, может это сделать, если хотя-бы равен оппоненту по уровню. А Архатовщина, еще два года назад достала. В результате оставил код от Петра.
Влад, твой последний пост тоже зачистил, захочет разобраться, сам найдет. ИМХО.

ua6em
ua6em аватар
Offline
Зарегистрирован: 17.08.2016

можно и через миллис, но нужно ли?

{
digitalWrite(LED,HIGH);
delay(1000);
digitalWrite(LED,LOW);
delay(10000);

}

Pyotr
Offline
Зарегистрирован: 12.03.2014

rkit пишет:

Pyotr пишет:

   if(((countCycle + 15) % 10) == 0){//кажд.100 мс      

И получаешь не пропуски так повторы. Кошмар.

Написал проверочный код. Самые первые действия идут через 40, 60, 80 мс, а дальше каждое действие строго через 100 мс. 
При переполнении currMillis интервалы сохраняют свое значение в 100 мс.
Где кошмар??

void setup() {
  Serial.begin(115200);
}

void loop(){
  static word prevMillis=0, intervalMs=10, interval_100ms = 100;
  static byte countCycle = 0; 
  word currMillis = (word)millis();
  static word prevMs_1 = currMillis, prevMs_2 = currMillis, prevMs_3 = currMillis;
  
  if(currMillis - prevMillis >= intervalMs){//10ms
    prevMillis += intervalMs;
   // делаем три действия каждые 100 мс, но со сдвигом "по фазе" в 20 мс
    if(((countCycle + 13) % 10) == 0){//кажд.100 мс. ЭТО ДЕЙСТВИЕ ПОСЛЕДНЕЕ!!
      if(prevMs_1 != currMillis){ 
        Serial.print("ERROR  ");
      }else{
        Serial.print("do1="); //Serial.println(currMillis); 
      }        
      prevMs_1 = currMillis + interval_100ms;
      Serial.println(currMillis);    
      Serial.println(); //разделитель между тремя действиями
    }
    if(((countCycle + 15) % 10) == 0){//кажд.100 мс      
      if(prevMs_2 != currMillis){ 
        Serial.print("ERROR  ");
      }else{
        Serial.print("do2="); //Serial.println(currMillis); 
      }        
      prevMs_2 = currMillis + interval_100ms;
      Serial.println(currMillis);    
    }
    if(((countCycle + 17) % 10) == 0){//кажд.100 мс
      if(prevMs_3 != currMillis){ 
        Serial.print("ERROR  ");
      }else{
        Serial.print("do3="); //Serial.println(currMillis); 
      }        
      prevMs_3 = currMillis + interval_100ms;
      Serial.println(currMillis);    
    }
       
    if(++countCycle >= 100){//прошла  1 сек
      countCycle = 0;
    }
  }
}//END loop()

 

Pyotr
Offline
Зарегистрирован: 12.03.2014

Bruzzer пишет:

 Маленькое замечание. У вас нумерация действий  идет в обратном порядке. Сначала выполнится 3 потом 2 потом 1.

    if(((countCycle + 13) % 10) == 0){//кажд.100 мс 
     //действие 1
    }
    if(((countCycle + 15) % 10) == 0){//кажд.100 мс      
      //действие 2
    }
    if(((countCycle + 17) % 10) == 0){//кажд.100 мс
      //действие 3
    }

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

JhonKnow
Offline
Зарегистрирован: 23.01.2020

Я бы таким как ты пасть зашивал, чтобы лаял меньше