Проблема с millis

RyuuKiiroi
Offline
Зарегистрирован: 23.03.2016

Подскажет кто как правильно заставить работать millis ?
Не получается сделать отсчет для каждого действия, время идет общее.
Или просто отсчет идет, а ничего не срабатывает.

В программировании я так себе и только начал изучать ардуину.

delay не подойдет, потому что еще будет эмуляция клавиатуры.

int ACC = A4; //сигнал АСС
int Nex = 2; //несус
int Hub = 3; //хаб
int Per = 5; //периферия
float Vout = 0.00;
float Vbat = 0.00;
float R1 = 24000.0; // сопротивление R8 (24кОм)
float R2 = 680.0; // сопротивление R7 (680Ом)
int ACCState = 0;
int State = 0;
unsigned long time=0;
unsigned long looptime;

void setup() {               
  
  pinMode(ACC,INPUT);
  pinMode(Per,OUTPUT);  
  pinMode(Nex,OUTPUT); 
  pinMode(Hub,OUTPUT);
  
}
 
void loop() {
  
  
  
  //Serial.print("analogRead(ACC): ");
  //Serial.println(analogRead(ACC));
  Serial.print("Time: ");
  Serial.println(time);
  Serial.print("Vbat: ");
  Serial.println(Vbat);
  
  // считывание аналогового значения
   ACCState = analogRead(ACC);
   Vout = (ACCState * 5.0) / 1024.0;
   Vbat = Vout / (R2/(R1+R2));
   if (Vbat<0.09)
     {
       Vbat=0.00;// обнуляем нежелательное значение
     }
  
  if (Vbat >= 12.00)
  {
  time = millis();
  }
  
if (millis() - time >= 200 && Vbat >= 12.00)//если напряжение больше "Х"
   {
   digitalWrite(Per,HIGH);//подаем питание на управляющий пин
   time = 0;
   State = 1;
   }
  
  if (State == 1)
  {
  time = millis();
    State = 2;
  }
  
if (millis() - time >= 200 && State == 2)
   {
   digitalWrite(Nex, HIGH);
   time = 0;
   State = 3;
   } 
  
  if (State == 3)
  {
  time = millis();
    State = 4;
  }
  
  if (Vbat <= 12.00)//если напряжение меньше "Х"
  {
  		if (millis() - time >= 200)
          digitalWrite(Per,LOW);//обестачиваем схему
          digitalWrite(Nex,LOW);
  }
}

 

Andy
Andy аватар
Offline
Зарегистрирован: 01.01.2016
текущее_время = millis();

if (текущее_время - время_события1  > интервал1)
{
  делаешь_что_нужно;
  время_события1 = текущее_время;
}
if (текущее_время - время_события2 > интервал2)
{
  делаешь_что_нужно;
  время_события2 = текущее_время;
}

 

RyuuKiiroi
Offline
Зарегистрирован: 23.03.2016

Так? Не очень понял.

При таком варианте отсчет идет от общего времени. То есть включается все сразу, если прошло уже 200 микросекунд с начала запуска.

А мне нужно примерно.

Если прошло столько то с момента предыдущего действия, то делаем.

Или, в конце там, если напрядение меньше 12В, то ждем сколько то, потом делаем.

 

int ACC = A4; //сигнал АСС
int Nex = 2; //несус
int Hub = 3; //хаб
int Per = 5; //периферия
float Vout = 0.00;
float Vbat = 0.00;
float R1 = 24000.0; // сопротивление R8 (24кОм)
float R2 = 680.0; // сопротивление R7 (680Ом)
int ACCState = 0;
int State = 0;
unsigned long time=0;
unsigned long looptime;
unsigned long time1=0;
unsigned long time2=0;
unsigned long time3=0;

void setup() {               
  
  pinMode(ACC,INPUT);
  pinMode(Per,OUTPUT);  
  pinMode(Nex,OUTPUT); 
  pinMode(Hub,OUTPUT);
  
}
 
void loop() {
  
  
  
  //Serial.print("analogRead(ACC): ");
  //Serial.println(analogRead(ACC));
  Serial.print("Time: ");
  Serial.println(time);
  Serial.print("Vbat: ");
  Serial.println(Vbat);
  
  // считывание аналогового значения
   ACCState = analogRead(ACC);
   Vout = (ACCState * 5.0) / 1024.0;
   Vbat = Vout / (R2/(R1+R2));
   if (Vbat<0.09)
     {
       Vbat=0.00;// обнуляем нежелательное значение
     }
  
  time = millis();
  
if (time - time1 >= 200 && Vbat >= 12.00)//если напряжение больше "Х"
   {
   digitalWrite(Per,HIGH);//подаем питание на управляющий пин
   time1 = time;
   State = 1;
   }
  
  
if (time - time2 >= 200 && State == 1)
   {
   digitalWrite(Nex, HIGH);
   time2 = time;
   State = 3;
   } 
  
  
  if (Vbat <= 12.00)//если напряжение меньше "Х"
  {
  		if (time - time3 >= 200)
          digitalWrite(Per,LOW);//обестачиваем схему
          digitalWrite(Nex,LOW);
    time3 = time;
  }
}

 

Andy
Andy аватар
Offline
Зарегистрирован: 01.01.2016

RyuuKiiroi пишет:
А мне нужно примерно.

Если прошло столько то с момента предыдущего действия, то делаем.

Или, в конце там, если напрядение меньше 12В, то ждем сколько то, потом делаем.

текущее_время = millis();

if (событие1_разрешено && текущее_время - время_события1 > интервал1)
{
  делаешь_что_нужно1;
  событие1_разрешено = false;
  событие2_разрешено = true;
  время_события2 = текущее_время;
}
if (событие2_разрешено && текущее_время - время_события2 > интервал2)
{
  делаешь_что_нужно2;
  событие2_разрешено = false;
  if (напряжение < 12) 
  {
    событие3_разрешено = true;
    время_события3 = текущее_время;
  }
}
if (событие3_разрешено && текущее_время - время_события3 > ждем_сколько_то)
{
  делаешь_что_нужно3;
  событие3_разрешено = false;
}

 

RyuuKiiroi
Offline
Зарегистрирован: 23.03.2016

Пока что мне больше всего нравитсявот так.

Проблема здесь в том, что нужно выставлять значение задержки от большего к меньшему.

Если выставлять наоборот, на задержку 5 пина 1сек, а на 2 пин- 2сек, то он включается если только передернуть А0.

Блок выключения работает вроде нормально.

 

int ACC = A0; //сигнал АСС
int Nex = 2; //несус
int Hub = 3; //хаб
int Per = 5; //периферия
float Vout = 0.00;
float Vbat = 0.00;
float R1 = 24000.0; // сопротивление R8 (24кОм)
float R2 = 680.0; // сопротивление R7 (680Ом)
int ACCState = 0;
int State = 0;
unsigned long currenttime;
unsigned long looptime;
//unsigned long previousMillis;
//unsigned long time2;
//unsigned long time3;

void setup() {               
  
  pinMode(ACC,INPUT);
  pinMode(Per,OUTPUT);  
  pinMode(Nex,OUTPUT); 
  pinMode(Hub,OUTPUT);
  
}
 
void loop() {
  
  
  
  //Serial.print("analogRead(ACC): ");
  //Serial.println(analogRead(ACC));
  //Serial.print("Time: ");
  //Serial.println(currenttime);
  //Serial.print("Vbat: ");
  //Serial.println(Vbat);
  
  // считывание аналогового значения
   ACCState = analogRead(ACC);
   Vout = (ACCState * 5.0) / 1024.0;
   Vbat = Vout / (R2/(R1+R2));
   if (Vbat<0.09)
     {
       Vbat=0.00;// обнуляем нежелательное значение
     }
  
  currenttime = millis();

if ((Vbat >= 12.00) && (millis() - looptime >= 2000))//если напряжение больше "Х"
   {
   looptime = currenttime;
   digitalWrite(Per,HIGH);//подаем питание на управляющий пин
   State = 1;
   }
  
if ((State == 1) && (millis() - looptime >= 1000))
   {
   looptime = currenttime;
   digitalWrite(Nex, HIGH);
   State = 2;
   }
  
if ((State == 2) && Vbat <= 12.00)//если напряжение меньше "Х"
  {
      if (millis() - looptime >= 10000)
      {
          looptime = currenttime; 
          digitalWrite(Per,LOW);//обестачиваем схему
          digitalWrite(Nex,LOW);
      }  
  }
}

И еще таким макаром можно

if ((Vbat >= 12.00) && (millis() - looptime >= 2000))//если напряжение больше "Х"
   {
   //looptime = currenttime;
   digitalWrite(Per,HIGH);//подаем питание на управляющий пин
   State = 1;
   }
  
if ((Vbat >= 12.00) && (millis() - looptime >= 5000))
   {
   looptime = currenttime;
   digitalWrite(Nex, HIGH);
   State = 2;
   }

 

RyuuKiiroi
Offline
Зарегистрирован: 23.03.2016

Доделал я его, понял примерно логигу. Может кому будет полезно.

Задержки все конечно тестовые.

int ACC = A0; //сигнал АСС
int Per1 = 2; //периферия1
int Per2 = 10; //периферия2
int Hub = 3; //хаб
int Nex = 5; //несус
float Vout = 0.00;
float Vbat = 0.00;
float R1 = 24000.0; // сопротивление R8 (24кОм)
float R2 = 680.0; // сопротивление R7 (680Ом)
int ACCState = 0;
int State = 0;
unsigned long previousMillis1=0;
unsigned long previousMillis2=0;
unsigned long previousMillis3=0;
unsigned long previousMillis4=0;
unsigned long previousMillis5=0;


void setup() {               
  
  pinMode(ACC,INPUT);
  pinMode(Per1,OUTPUT);
  pinMode(Per2,OUTPUT);  
  pinMode(Nex,OUTPUT); 
  pinMode(Hub,OUTPUT);
  
}
 
void loop() {
  

  unsigned long currentMillis = millis();
  unsigned long currentMillis2 = millis();
  
  //Serial.print("analogRead(ACC): ");
  //Serial.println(analogRead(ACC));
  Serial.print("Time: ");
  Serial.println(currentMillis);
  Serial.print("Vbat: ");
  Serial.println(Vbat);
  
  // считывание аналогового значения
   ACCState = analogRead(ACC);
   Vout = (ACCState * 5.0) / 1024.0;
   Vbat = Vout / (R2/(R1+R2));
   if (Vbat<0.09)
     {
       Vbat=0.00;// обнуляем нежелательное значение
     }


  //включение реле, вклюление планшета
if ((Vbat >= 12.00) && ((unsigned long)(currentMillis - previousMillis1) >= 3000))//если напряжение больше "Х"
   {
   previousMillis1 = currentMillis;
   digitalWrite(Nex,HIGH);//подаем питание на управляющий пин
   State = 1;
   }

   //периферия1
if ((State == 1) && ((unsigned long)(currentMillis - previousMillis2) >= 5000))
   {
   previousMillis2 = currentMillis;
   digitalWrite(Per1, HIGH);
   State = 2;
   }

   //вклюление хаба
if ((State == 2) && ((unsigned long)(currentMillis - previousMillis3) >= 10000))
   {
   previousMillis3 = currentMillis;
   digitalWrite(Hub, HIGH);
   State = 3;
   }

   //периферия2
if ((State == 3) && ((unsigned long)(currentMillis - previousMillis4) >= 5000))
   {
   previousMillis4 = currentMillis;
   digitalWrite(Per2, HIGH);
   State = 4;
   }

//отсчет при потере напряжения
if ((State == 4) && Vbat <= 12.00)//если напряжение меньше "Х"
   {
    previousMillis5 = currentMillis2;
    State = 5;
   }

  //отключаем периферию 2
if ((State == 5) && (unsigned long)(currentMillis2 - previousMillis5) >= 2000)
   {
    digitalWrite(Per2,LOW);
   }

   //отключаем периферию
if ((State == 5) && (unsigned long)(currentMillis2 - previousMillis5) >= 4000)
   {
    digitalWrite(Per1,LOW);
   }

  //отключаем хаб
if ((State == 5) && (unsigned long)(currentMillis2 - previousMillis5) >= 6000)
   {
    digitalWrite(Hub,LOW);
   }

  //обестачиваем схему
if ((State == 5) && (unsigned long)(currentMillis2 - previousMillis5) >= 8000)
   {
    digitalWrite(Nex,LOW);
   }
}