Добрый день. Хочу сделать умную вытяжку в ванной-туалете. Все собрал все. Скетч написал. Но не могу разобраться с задержкой. Нужно чтобы при любом нажатии на выключатель(неважно верх или вниз, считываем изменение сигнала на 10 пине) включалась вытяжка на определенное время (timeout). Все вроде работает но не так как я хочу. При включении ардуины сразу через timeot включается вытяжка, неважно было ли изменение на 10 пине или нет. Тоесть миллис меньше таймаута. А потом все работает как нужно, при каждом нажатие на выключатель. Как мне это обойти? Код (C++): #include <stDHT.h> DHT dv(DHT22); #define r1 3 // Указываем что реле на 3 пине #define r2 2 // Указываем что реле на 2 пине #define dht 4 // Указываем что датчик влажности на 4 пине #define k 10 // Сигнал с принудительного включателя на 10 пине #define pirPin 11 // Указываем что датчик движения на 11 пине int val,flag,calibrationTime; unsigned long int currentTime,timeout,T1,lowIn,pause; //lowIn - Время, в которое был принят сигнал отсутствия движения(LOW) boolean lockLow,takeLowTime; void setup() { // put your setup code here, to run once: Serial.begin(9600); // Скорость работы порта pinMode(r1, OUTPUT); pinMode(r2, OUTPUT); pinMode(k, INPUT); pinMode(pirPin, INPUT); digitalWrite(pirPin, LOW); //!ВНИМАНИЕ! При использовании n-p-n реле необходимо в след. строчке поменять HIGH на LOW digitalWrite(r1, HIGH); // Выключаем реле - посылаем высокий сигнал digitalWrite(r2, HIGH); val=digitalRead(k); flag=val; timeout=6000; currentTime = millis()+timeout+1000; calibrationTime = 10; //Время калибровки датчика (10-60 сек. по даташиту) pause = 120000; //pause - Пауза, после которой движение считается оконченным lockLow = true; //lockLow - Флаг. false = значит движение уже обнаружено, true - уже известно, что движения нет } void loop() { T1==millis(); if (millis()<T1) { currentTime = millis()+timeout+1000; } // put your main code here, to run repeatedly: int h = dv.readHumidity(dht); //Измеряем влажность int t = dv.readTemperature(dht); //Измеряем температуру Serial.print("Hum: "); Serial.print(h); Serial.print(" %"); Serial.print("Temp: "); Serial.print(t); Serial.println(" C "); if (digitalRead(pirPin) == HIGH) { Serial.println("yesssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssss"); } delay(500); if (digitalRead(pirPin) == LOW) { Serial.println("OOO"); } delay(50); val = digitalRead(k); // Включаем вытяжку на timeout if (val != flag) { flag=val; currentTime=millis(); } if (millis() - currentTime < timeout) { int xxx = millis() - currentTime; Serial.println(xxx); digitalWrite(r1, LOW); } else { if (h>70) { digitalWrite(r1, LOW); } // Включаем реле - посылаем низкий уровень сигнала else { digitalWrite(r1, HIGH); // Отключаем реле - посылаем высокий уровень сигнала } } //Если обнаружено движение if(digitalRead(pirPin) == HIGH) { //Если до этого момента еще не включили реле if(lockLow) { lockLow = false; //Включаем реле. //!ВНИМАНИЕ! При использовании n-p-n реле необходимо в след. строчке поменять LOW на HIGH digitalWrite(r2, LOW); delay(50); } takeLowTime = true; //takeLowTime - Флаг. Сигнализирует о необходимости запомнить время начала отсутствия движения } //Ели движения нет if(digitalRead(pirPin) == LOW) { //Если время окончания движения еще не записано if(takeLowTime) { lowIn = millis(); //Сохраним время окончания движения takeLowTime = false; //Изменим значения флага, чтобы больше не брать время, пока не будет нового движения } //Если время без движение превышает паузу => движение окончено if(!lockLow && millis() - lowIn > pause) { //Изменяем значение флага, чтобы эта часть кода исполнилась лишь раз, до нового движения lockLow = true; digitalWrite(r2, HIGH); delay(50); } } }
Предположим, два равно по ошибке набрано. В этом случае условие millis() < Т1 выполнится только когда счётчик времени перевалит на второй круг .