Помогите избавиться от delay()

Soichi
Soichi аватар
Offline
Зарегистрирован: 02.11.2015

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

if (n == 5)
	{
		digitalWrite(oneLamp, HIGH);
		delay(1000);
		digitalWrite(twoLamps, HIGH);
		oneLampStat = 1;
		twoLampsStat = 1;
		threeLampsStat = 1;
		delay(1000);
	}

Не получается это всё заменить на пример с previousMillis. Если сделать так, реле включаются одновременно

if (n == 5)
	{	
		digitalWrite(oneLamp, HIGH);
		if (millis() - previousMillis > 1000) {
			previousMillis = millis();			
			digitalWrite(twoLamps, HIGH);
			oneLampStat = 1;
			twoLampsStat = 1;
			threeLampsStat = 1;
		}		
	}

Как сделать эту задержку? :(

Nosferatu
Offline
Зарегистрирован: 04.11.2012

Тут надо понимать, нужно ли включать второе реле, если за время задержки переменная "n" станет неровна пяти.

Soichi
Soichi аватар
Offline
Зарегистрирован: 02.11.2015

Да нет, мне надо чтобы реле включались с задержкой в одну секунду, а не обе сразу.

С delay всё работает, а переделать под millis не выходит..

void smartLight(int n)
{
if (n == 5)
	{
		digitalWrite(oneLamp, HIGH);
		delay(1000);
		digitalWrite(twoLamps, HIGH);
		oneLampStat = 1;
		twoLampsStat = 1;
		threeLampsStat = 1;
		delay(1000);
	}
}

 

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

Конечный автомат тебе в помощь

if (n == 5)
{	
 digitalWrite(oneLamp, HIGH);
 if (millis() - previousMillis > 1000) 
 {
  previousMillis = millis();
  switch (st)
  {
  case 0: digitalWrite(oneLamps, HIGH); oneLampStat = 1; st++; break;
  case 1: digitalWrite(twoLamps, HIGH); twoLampsStat = 1; st++; break;
  case 2: digitalWrite(threeLamps, HIGH); threeLampsStat = 1; st=0; break;
  }		
 }
}

 

Nosferatu
Offline
Зарегистрирован: 04.11.2012

А я вижу это так.

void smartLight(int n) {
  if (n == 5)
  {
    digitalWrite(oneLamp, HIGH);
    if (flag == false) {
      previousMillis = millis();
      flag = true;
    } else {
      //flag = false; // Если n!=5, то второе реле не включать.
    }
  }
  if (millis() - previousMillis > 1000 && flag == true) {
    digitalWrite(twoLamps, HIGH);
    oneLampStat = 1;
    twoLampsStat = 1;
    threeLampsStat = 1;
    flag = false;
  }
}

Сначала объявить глобальную переменную.

boolean  flag = false;

Работоспособность не проверялась.

Logik
Offline
Зарегистрирован: 05.08.2014

Я бы шотот типа такого делал.

boolean smartLight(int n) 
{
static byte State;
static unsigned long previousMillis;
unsigned long t;

t=millis();
if(State)
    if (t - previousMillis < 1000)    
       return false;
switch (State)
{
  case 0:
        if (n == 5)
	{
		digitalWrite(oneLamp, HIGH);
                State++;
                previousMillis=t;
                return true;
	}
      break;
  case 1:        digitalWrite(twoLamps, HIGH);
                 oneLampState = 1;
                 twoLampsState = 1;
                 threeLampsState = 1;
                 State++;
                previousMillis=t;
     break;
  case 2:
      State=0;
      return true;
  }
  
  return false;
}

 

Soichi
Soichi аватар
Offline
Зарегистрирован: 02.11.2015

Спасибо за ответы. Попытаюсь прикрутить какой нибудь из вариантов :)

Наверное это надо было сделать сразу.. Вот весь код, с delay.

#include <IRremote.h>
#include <SPI.h>
#include <Ethernet.h>
 
int RECV_PIN = 9;

int oneLamp	=	2;
int	twoLamps	=	3;
int tableLamp	=	5;
int tableLampTwo	=	6;

int oneLampStat	=	0;
int twoLampsStat	=	0;
int threeLampsStat	=	0;
int tableLampStat	=	0;
int tableLampTwoStat	=	0;
int tableLampThreeStat	=	0;
 
IRrecv irrecv(RECV_PIN);
decode_results results;

byte mac[] = {0x90, 0xA2, 0xDA, 0x0D, 0x48, 0xD3 };
IPAddress ip(192,168,0,222);
IPAddress gateway(192,168,0,1);
IPAddress subnet(255, 255, 255, 0);
EthernetServer server(80);
String readString;

void smartLight(int n)
{
	if (n == 1)
	{
		digitalWrite(oneLamp, HIGH);
		oneLampStat = 1;
		delay(1000);
	}
	if (n == 2)
	{
		digitalWrite(oneLamp, LOW);
		oneLampStat = 0;
		delay(1000);
	}
	if (n == 3)
	{
		digitalWrite(twoLamps, HIGH);
		twoLampsStat = 1;
		delay(1000);
	}
	if (n == 4)
	{
		digitalWrite(twoLamps, LOW);
		twoLampsStat = 0;
		delay(1000);
	}
	if (n == 5)
	{
		digitalWrite(oneLamp, HIGH);
		delay(1000);
		digitalWrite(twoLamps, HIGH);
		oneLampStat = 1;
		twoLampsStat = 1;
		threeLampsStat = 1;
		delay(1000);
	}
	if (n == 6)
	{
		digitalWrite(oneLamp, LOW);
		delay(1000);
		digitalWrite(twoLamps, LOW);
		oneLampStat = 0;
		twoLampsStat = 0;
		threeLampsStat = 0;
		delay(1000);
	}
	if (n == 7)
	{
		digitalWrite(tableLamp, HIGH);
		tableLampStat = 1;
		delay(1000);
	}
	if (n == 8)
	{
		digitalWrite(tableLamp, LOW);
		tableLampStat = 0;
		delay(1000);
	}
}
 
void setup()
{
	irrecv.enableIRIn();
	pinMode(oneLamp, OUTPUT);
	pinMode(twoLamps, OUTPUT);
	pinMode(tableLamp, OUTPUT);
	pinMode(tableLampTwo, OUTPUT);
	
	Ethernet.begin(mac, ip, gateway, subnet);
	server.begin();
}
 
void loop() {

if((oneLampStat == 1) && (twoLampsStat == 1)){
		threeLampsStat = 1;
	}
	else{
		threeLampsStat = 0;
	}	

  EthernetClient client = server.available();
  if (client)

  {
    while (client.connected())
    {
      if (client.available())

      {
        char c = client.read();
        
        if (readString.length() < 100)

        {
          
          readString += c;
          
          if (c == '\n') {
          

client.println("HTTP/1.1 200 OK");
            client.println("Content-Type: text/html");
            client.println();
            client.println("<HTML>");
            client.println("<HEAD>");                    
            client.println("<meta http-equiv='Content-Type' content='text/html; charset=utf-8' />");
            client.println("<meta http-equiv='refresh' content='5' />");
            client.println("<TITLE>Smart Light v0.3</TITLE>");
            client.println("<center>");
            client.println("</HEAD>");
            client.println("<BODY>");
            client.println("<a href='http://192.168.0.222/'><H1>Smart Light v0.3</H1></a>");            
            client.println("<hr />");
            client.println("<center>");

			if (oneLampStat == 0) {
				client.println("<font color=\"green\" size=\"6\"><a href=\"/?onelampon\"\">Люстра 1-ON</a>");
				client.println("<br />");
				client.println("<br />");
				}
			else {
				client.println("<font color=\"green\" size=\"6\"><a href=\"/?onelampoff\"\">Люстра 1-OFF</a>");
				client.println("<br />");
				client.println("<br />");
				}
			if (twoLampsStat == 0) {
				client.println("<a href=\"/?twolampon\"\">Люстра 2-ON</a>");     
				client.println("<br />");
				client.println("<br />");
				}
			else {
				client.println("<a href=\"/?twolampoff\"\">Люстра 2-OFF</a>");     
				client.println("<br />");
				client.println("<br />");
				}
			if (threeLampsStat == 0) {
				client.println("<a href=\"/?threelampon\"\">Люстра ON</a>");     
				client.println("<br />");
				client.println("<br />");
				}
			else {
				client.println("<a href=\"/?threelampoff\"\">Люстра OFF</a>");     
				client.println("<br />");
				client.println("<br />");
				}
			if (tableLampStat == 0) {
				client.println("<a href=\"/?tablelampon\"\">Cвет над столом ON</a>");     
				}
			else {
				client.println("<a href=\"/?tablelampoff\"\">Cвет над столом OFF</a><br />");
				}

            client.println("</BODY>");
            client.println("</HTML>");

            delay(1);
            
            client.stop();

            
            if(readString.indexOf("?onelampon") >0)
            {
				smartLight(1);              
            }
			if(readString.indexOf("?onelampoff") >0)
            {
				smartLight(2);              
            }
			if(readString.indexOf("?twolampon") >0)
            {
				smartLight(3);              
            }
			if(readString.indexOf("?twolampoff") >0)
            {
				smartLight(4);              
            }
			if(readString.indexOf("?threelampon") >0)
            {
				smartLight(5);              
            }
			if(readString.indexOf("?threelampoff") >0)
            {
				smartLight(6);              
            }
			if(readString.indexOf("?tablelampon") >0)
            {
				smartLight(7);              
            }
			if(readString.indexOf("?tablelampoff") >0)
            {
				smartLight(8);              
            }            
            
            
            readString="";

            
            delay(1);
            
            client.stop();
          }
        }
      }
    }
  }

if (irrecv.decode(&results)) {

	
	if (results.value == 0x40BF00FF && tableLampStat == 0)
	{
		smartLight(7);
	}
	else
	if (results.value == 0x40BF20DF && tableLampStat == 1)
	{
		smartLight(8);
	}
	
	if (results.value == 0x40BF807F && oneLampStat == 0)
	{
		smartLight(1);
	}
	else
	if (results.value == 0x40BFA05F && oneLampStat == 1)
	{
		smartLight(2);
	}
	
	if (results.value == 0x40BF40BF && twoLampsStat == 0)
	{
		smartLight(3);
	}
	else
	if (results.value == 0x40BF609F && twoLampsStat == 1)
	{
		smartLight(4);
	}	
	
	if (results.value == 0x40BF906F && threeLampsStat == 0)
	{
		smartLight(5);
	}
	else
	if (results.value == 0x40BF50AF && threeLampsStat == 1)
	{
		smartLight(6);
	}
	 
	irrecv.resume();
}
}

 

NeiroN
NeiroN аватар
Offline
Зарегистрирован: 15.06.2013

А может их просто удалить? Я так и не понял их сокральное значение. Включить лампу, подожать 1 сек и продолжить обработку данных - зачем ждать неясно.

 

Вот с тем что между двумя включениями - надо мудрить.  Обработчик ламп нужно сделать в общий цикл.

Soichi
Soichi аватар
Offline
Зарегистрирован: 02.11.2015

Если 2 реле включаются/выключаются одновременно, ардуинка начинает глючить. Такое ощущение что нехватает тока чтобы ими дергать. С задержкой же всё работает как часы.

 

З.Ы. Реле находится где то на расстоянии 8 метров от ардуины :)

NeiroN
NeiroN аватар
Offline
Зарегистрирован: 15.06.2013

Команда включения у вас управляет максимум 2 пинами. Нужно завести 3 глобальных переменных - две для номера пинов и 3 для их состояния.

В общий цикл сунуть это:

if(p1 != -1){
digitalWrite(p1,state);
p1 = -1;
}
if(p2 != -1 && millis() - previusMillis > 1000 && previusMillis != 0){
digitalWrite(p2, state);
p2 = -1;
}

if (n == 5)
	{
		p1 = oneLamp;
		p2 = twoLamps;
                state = HIGH;
                previusMillis = millis();
		oneLampStat = 1;
		twoLampsStat = 1;
		threeLampsStat = 1;
		delay(1000);
	}

код включения сделать таким

Nosferatu
Offline
Зарегистрирован: 04.11.2012

С минимумом изменений, как-то так.


void smartLight(int n)
{
  static unsigned long previousMillis;
  if (n == 1 && millis() - previousMillis > 1000)
  {
    digitalWrite(oneLamp, HIGH);
    oneLampStat = 1;
    previousMillis = millis();
  }
...............
...............
...............

 

Nosferatu
Offline
Зарегистрирован: 04.11.2012
void smartLight(int n)
{
  static unsigned long previousMillis;
  static boolean  flag;
  if (n == 1 && millis() - previousMillis > 1000)
  {
    digitalWrite(oneLamp, HIGH);
    oneLampStat = 1;
    previousMillis = millis();
  }

  ...............
  ...............
  ...............

 	if (n == 5 && flag != true;)
	{
		digitalWrite(oneLamp, HIGH);
    previousMillis = millis();
    flag = true;
  }

  if (millis() - previousMillis > 1000 && flag == true)
  {
		digitalWrite(twoLamps, HIGH);
		oneLampStat = 1;
		twoLampsStat = 1;
		threeLampsStat = 1;
    flag = false;
	}

  ...............
  ...............
  ...............

}

 

Alexey Orlov
Offline
Зарегистрирован: 07.10.2017

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

float Y=50.00;

 
#include "DHT.h"
 
#define DHTPIN A2  
#define DHTTYPE DHT22
DHT dht(DHTPIN, DHTTYPE);
 
void setup(){
  
pinMode(5,INPUT);
pinMode(10,OUTPUT);
  Serial.begin(9600);
  Serial.println("DHTxx test!");
 
  dht.begin();
 
  delay(3000);
}
void loop(){
   delay(100);
  boolean kn1 = digitalRead(5);// присвоим переменной значение с датчика
  if (kn1 == 1)Y=Y+5.00;
  delay(50);
  if (Y > 100.00) Y=20.00;
  float h = dht.readHumidity();
  float D = Y-h;
  int X=D;
 
 
  if (X>0 && X<=5){ digitalWrite(10, HIGH);
  delay(500);
  digitalWrite(10, LOW);}
  else  if (X>5 && X<=10){ digitalWrite(10, HIGH);
  delay(1000);
  digitalWrite(10, LOW);}
  else  if (X>10 && X<=15){ digitalWrite(10, HIGH);
  delay(1000);
  digitalWrite(10, LOW);}
   else  if (X>15 && X<=20){ digitalWrite(10, HIGH);
  delay(1500);
  digitalWrite(10, LOW);}
   else  if (X>20 && X<=25){ digitalWrite(10, HIGH);
  delay(2000);
  digitalWrite(10, LOW);}
   else  if (X>25 && X<=30){ digitalWrite(10, HIGH);
  delay(2500);
  digitalWrite(10, LOW);}
   else  if (X>30 && X<=35){ digitalWrite(10, HIGH);
  delay(3000);
  digitalWrite(10, LOW);}
   else  if (X>35 ){ digitalWrite(10, HIGH);
  delay(3500);
  digitalWrite(10, LOW);}
 
  
  
  Serial.print("fakt :");
  Serial.println(h);
  Serial.print("ustanov :");
  Serial.println(Y);
  
  delay(15000);
  
 
}
 
MaksVV
Offline
Зарегистрирован: 06.08.2015
float Y=50.00;

 
#include "DHT.h"
 
#define DHTPIN A2  
#define DHTTYPE DHT22
DHT dht(DHTPIN, DHTTYPE);

int interval = 0;
unsigned long prev = 0;

 unsigned long TimeStart, timerStart=0;
bool timerenabled=false;
#define TIMEREXPIRED (TimeStart-timerStart)>interval



void setup(){
  
pinMode(5,INPUT);
pinMode(10,OUTPUT);
  Serial.begin(9600);
  Serial.println("DHTxx test!");
 
  dht.begin();
 
  delay(3000);
}
void loop(){

TimeStart = millis();

if (timerenabled) {if (TIMEREXPIRED) {digitalWrite (10, LOW); timerenabled=false;}}
  
  if (millis()-prev>15000){
  boolean kn1 = digitalRead(5);// присвоим переменной значение с датчика
  if (kn1 == 1)Y=Y+5.00;
  delay(50);
  if (Y > 100.00) Y=20.00;
  float h = dht.readHumidity();
  float D = Y-h;
  int X=D;
 
 
  if (X>0 && X<=5) interval=500; 
  else if (X>5 && X<=10)   interval=1000; 
  else  if (X>10 && X<=15) interval=1000; 
  else  if (X>15 && X<=20) interval=1500; 
  else  if (X>20 && X<=25) interval=2000; 
  else  if (X>25 && X<=30) interval=2500; 
  else  if (X>30 && X<=35) interval=3000; 
  else  if (X>35 )         interval=3500; 
  
  Pin_10_Zapusk ();
 
  
  
  Serial.print("fakt :");
  Serial.println(h);
  Serial.print("ustanov :");
  Serial.println(Y);
  prev = millis();
  }
  
 
}


void Pin_10_Zapusk () {
  digitalWrite (10, HIGH); 
  timerStart=TimeStart; 
  timerenabled=true;
    }