Прошу помощи с Blink через PID

Almeder
Offline
Зарегистрирован: 26.03.2017

Заранее еще раз напомню, что начинающий "ардуинщик". Поэтому прошу строго не судить. Что-то почитать никогда не против по данной теме.

Итак, ситуация такая. Злободневный PID-регулятор температуры ТЭНов (на данном этапе лампочка)

DHТ11, SSR, Лампа накаливания.

В зависимоти от показания температуры расчитываются показания PID регулятора, в зависимости от показания PID, происходи вкл/выкл SSR по типу Blink.

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

Нарисовал скетч 

int ledPin =  3;     
int ledState = LOW;            
unsigned long previousMillis = 0;   
long OnTime = 50;          
long OffTime = 1000;          
 
void setup() 
{
 
  pinMode(ledPin, OUTPUT);      
}
 
void loop()
{
 
  unsigned long currentMillis = millis();
 
  if((ledState == HIGH) && (currentMillis - previousMillis >= OnTime))
  {
    ledState = LOW;  
    previousMillis = currentMillis; 
    digitalWrite(ledPin, ledState); 
  }
  else if ((ledState == LOW) && (currentMillis - previousMillis >= OffTime))
  {
    ledState = HIGH;  
    previousMillis = currentMillis;   
    digitalWrite(ledPin, ledState);   
  }
}

здесь путем изменения 

long OnTime = 50; 
и         
long OffTime = 1000; 

получается все это регулировать.

Сама суть проблемы -

Когда вставляю этот скетч в скетч самого регулятора, параметры Blink работают по другому. Сам PID работает корректо, по крайней мере для моих задач. Но не регулируется, точнее неккоректно регуляируется длительность мерцания, а промежуток между Блинками не получается опустить менее чем 500 мс.

Первая мысль, которая приходит в голову, это то, что на это происходит в силу времени расчета PID.

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

Сам код PID - регулятора.

#include <PID_v1.h>

#include <Wire.h>
#include <DHT.h>

#define DHTPIN 5
#define DHTTYPE DHT11 

DHT dht(DHTPIN, DHTTYPE);
 
double Setpoint, Input, Output;


 
PID myPID(&Input, &Output, &Setpoint ,8, 0, 1, DIRECT);

int ledPin =  3;
int ledState = LOW;             
unsigned long previousMillis = 0;        
     
 
void setup() 
{
  Serial.begin(9600);
  pinMode(ledPin, OUTPUT);

  Setpoint = 40;
  myPID.SetMode(AUTOMATIC);
  myPID.SetOutputLimits(0, 255);      
}
 
void loop()
{
  
  int t = dht.readTemperature(); // Send the command to get temperatures  
  Input = t;
  
  myPID.Compute();
  int val = Output;
  val = map(val, 0, 255, 0, 100);

  if ( val > 30) {PIDon();}

  if ( val <= 30 && val >= 21) {PIDx();}

  if ( val <= 20 && val >= 10  ) {PIDx1();}

  if ( val <= 9) {PIDx2();}

  if ( val < 3) {PIDoff();}

Serial.print("OUTPUT ");
Serial.print(val);
Serial.print(" %");
Serial.print("Temperature: ");
Serial.print(t);
Serial.println(" *C");
}

void PIDx()
{ 
  long OnTime = 1;          
  long OffTime = 50;
  unsigned long currentMillis = millis();
 
  if((ledState == HIGH) && (currentMillis - previousMillis >= OnTime))
  {
    ledState = LOW;  // Turn it off
    previousMillis = currentMillis;  // Remember the time
    digitalWrite(ledPin, ledState);  // Update the actual LED
  }
  else if ((ledState == LOW) && (currentMillis - previousMillis >= OffTime))
  {
    ledState = HIGH;  // turn it on
    previousMillis = currentMillis;   // Remember the time
    digitalWrite(ledPin, ledState);    // Update the actual LED
  }
}
void PIDx1()
{ 
  long OnTime = 50;          
  long OffTime = 250;
  unsigned long currentMillis = millis();
 
  if((ledState == HIGH) && (currentMillis - previousMillis >= OnTime))
  {
    ledState = LOW;  // Turn it off
    previousMillis = currentMillis;  // Remember the time
    digitalWrite(ledPin, ledState);  // Update the actual LED
  }
  else if ((ledState == LOW) && (currentMillis - previousMillis >= OffTime))
  {
    ledState = HIGH;  // turn it on
    previousMillis = currentMillis;   // Remember the time
    digitalWrite(ledPin, ledState);    // Update the actual LED
  }
}
void PIDx2()
{

  long OnTime = 50;          
  long OffTime = 500;
  unsigned long currentMillis = millis();
 
  if((ledState == HIGH) && (currentMillis - previousMillis >= OnTime))
  {
    ledState = LOW;  // Turn it off
    previousMillis = currentMillis;  // Remember the time
    digitalWrite(ledPin, ledState);  // Update the actual LED
  }
  else if ((ledState == LOW) && (currentMillis - previousMillis >= OffTime))
  {
    ledState = HIGH;  // turn it on
    previousMillis = currentMillis;   // Remember the time
    digitalWrite(ledPin, ledState);    // Update the actual LED
  }
}

void PIDon()
{
  digitalWrite(ledPin, HIGH);
}

void PIDoff()
{
  digitalWrite(ledPin, LOW);
}

За ранее благодарен и прошу прощения за почерк.

Клапауций 112
Клапауций 112 аватар
Offline
Зарегистрирован: 01.03.2017
Almeder
Offline
Зарегистрирован: 26.03.2017

Извините, я не нашел где в этом классе можно задать время горения LED? Мне необходимо, чтобы светодиод "сверкал", т.е. говоря аппаратным языком - горел 50 млс, а негорел 1000 млс.

Almeder
Offline
Зарегистрирован: 26.03.2017

И кстати, попробовал поставить этот класс в свой скетч, таже история, ставлю 100, а все равно быстрее 500 не моргает.

Клапауций 112
Клапауций 112 аватар
Offline
Зарегистрирован: 01.03.2017

Almeder пишет:

И кстати, попробовал поставить этот класс в свой скетч, таже история, ставлю 100, а все равно быстрее 500 не моргает.

поробуй этот "класс" воткнуть в свой скетч

digitalWrite(13, !digitalRead(13));

тоже быстрее 500 не моргает? :D

Клапауций 112
Клапауций 112 аватар
Offline
Зарегистрирован: 01.03.2017

Almeder пишет:

Извините, я не нашел где в этом классе можно задать время горения LED? Мне необходимо, чтобы светодиод "сверкал", т.е. говоря аппаратным языком - горел 50 млс, а негорел 1000 млс.

казалось бы, вкуда здесь nD_01.read(100); #28 воткнуть 100, что бы тикало каждые 100 миллисекунд?

что нужно сделать, что бы тикало то 50, то 1000 - угадай с первого раза?


#include "class_noDELAY.h"

noDELAY led;

void setup () {
pinMode(13, OUTPUT); // LED_01
digitalWrite(13, 1);
led.start();
}

void loop() {
unsigned int t;
if (digitalRead(13) == 1) {t = 1000;}
else                      {t =   50;}
led.read(t);
if (led.tick == 1) {digitalWrite(13, !digitalRead(13));}
}

 

DetSimen
DetSimen аватар
Offline
Зарегистрирован: 25.01.2017
#include "Arduino.h"
#include "uTimerList.h"

extern TTimerList TimerList;

void BlinkOff(void)
{
	digitalWrite(13, LOW);
}

void BlinkOn(void)
{
	digitalWrite(13, HIGH);
}

void setup()
{
	pinMode(13, OUTPUT);

	TimerList.Add(BlinkOff, 50);
	TimerList.Add(BlinkOn, 1000);

}

void loop()
{

  /* add main program code here */

}

всё.

Almeder
Offline
Зарегистрирован: 26.03.2017

Клапауций 112 пишет:

Almeder пишет:

Извините, я не нашел где в этом классе можно задать время горения LED? Мне необходимо, чтобы светодиод "сверкал", т.е. говоря аппаратным языком - горел 50 млс, а негорел 1000 млс.

казалось бы, вкуда здесь nD_01.read(100); #28 воткнуть 100, что бы тикало каждые 100 миллисекунд?

что нужно сделать, что бы тикало то 50, то 1000 - угадай с первого раза?

#include "class_noDELAY.h"

noDELAY led;

void setup () {
pinMode(13, OUTPUT); // LED_01
digitalWrite(13, 1);
led.start();
}

void loop() {
unsigned int t;
if (digitalRead(13) == 1) {t = 1000;}
else                      {t =   50;}
led.read(t);
if (led.tick == 1) {digitalWrite(13, !digitalRead(13));}
}

 

Ругается

 
 
sketch_apr20d:16: error: 'class noDELAY' has no member named 'tick'
 
 if (led.tick == 1) {digitalWrite(13, !digitalRead(13));}
 
         ^
 
exit status 1
'class noDELAY' has no member named 'tick'
 
 
Almeder
Offline
Зарегистрирован: 26.03.2017

DetSimen пишет:

#include "Arduino.h"
#include "uTimerList.h"

extern TTimerList TimerList;

void BlinkOff(void)
{
	digitalWrite(13, LOW);
}

void BlinkOn(void)
{
	digitalWrite(13, HIGH);
}

void setup()
{
	pinMode(13, OUTPUT);

	TimerList.Add(BlinkOff, 50);
	TimerList.Add(BlinkOn, 1000);

}

void loop()
{

  /* add main program code here */

}

всё.

Спасибо большое.

Я так понимаю это таймер, еще не изучал работу по таймеру.

Но всё заработало как положено, только возникает большая проблемма -  виснет монитор порта через несколько секунд((((

Клапауций 112
Клапауций 112 аватар
Offline
Зарегистрирован: 01.03.2017

Almeder пишет:

Ругается

#7 #5

Используем библиотеку class_noDELAY в папке: D:\MyDOC\Arduino\libraries\class_noDELAY (legacy)
Скетч использует 904 байт (14%) памяти устройства. Всего доступно 6144 байт.
Глобальные переменные используют 19 байт (1%) динамической памяти, оставляя 1005 байт для локальных переменных. Максимум: 1024 байт.

 

DetSimen
DetSimen аватар
Offline
Зарегистрирован: 25.01.2017

странно. переделал вот так 

void BlinkOn(void)
{
	static int16_t count = 0;
		digitalWrite(13, HIGH);
		Serial.print("Tick  "); Serial.println(count++);
}

void setup()
{
	Serial.begin(115200);
		pinMode(13, OUTPUT);

		TimerList.Add(BlinkOff, 50);
		TimerList.Add(BlinkOn, 1000);
}

не зависает сериал.  не хочет, наерн. :)

Almeder
Offline
Зарегистрирован: 26.03.2017

DetSimen пишет:

странно. переделал вот так 

void BlinkOn(void)
{
	static int16_t count = 0;
		digitalWrite(13, HIGH);
		Serial.print("Tick  "); Serial.println(count++);
}

void setup()
{
	Serial.begin(115200);
		pinMode(13, OUTPUT);

		TimerList.Add(BlinkOff, 50);
		TimerList.Add(BlinkOn, 1000);
}

не зависает сериал.  не хочет, наерн. :)

 

Отдельным скетчем не зависает, когда в скетч пида вставляю зависает.

Almeder
Offline
Зарегистрирован: 26.03.2017

Клапауций 112 пишет:

 

#7 #5

Используем библиотеку class_noDELAY в папке: D:\MyDOC\Arduino\libraries\class_noDELAY (legacy)
Скетч использует 904 байт (14%) памяти устройства. Всего доступно 6144 байт.
Глобальные переменные используют 19 байт (1%) динамической памяти, оставляя 1005 байт для локальных переменных. Максимум: 1024 байт.

 

Таже самая история, отдельным скетчем работает все как положено, в скетче пида минимум 500, даже когда задано 100.(((

Клапауций 112
Клапауций 112 аватар
Offline
Зарегистрирован: 01.03.2017

Almeder пишет:

Таже самая история, отдельным скетчем работает все как положено, в скетче пида минимум 500, даже когда задано 100.(((

я же тебя просил проверить digitalWrite(13, !digitalRead(13));

DetSimen
DetSimen аватар
Offline
Зарегистрирован: 25.01.2017

мошт, надо нам пидаскетч показать?

Almeder
Offline
Зарегистрирован: 26.03.2017

DetSimen пишет:

мошт, надо нам пидаскетч показать?

в самом начале нарисован

Almeder
Offline
Зарегистрирован: 26.03.2017

DetSimen пишет:

мошт, надо нам пидаскетч показать?

Если уже с таймером, то 

Вариант 1 


#include <PID_v1.h>

#include "Arduino.h"
#include "uTimerList.h"

#include <Wire.h>
#include <DHT.h>

#define DHTPIN 5
#define DHTTYPE DHT11 

DHT dht(DHTPIN, DHTTYPE);
 
double Setpoint, Input, Output;

extern TTimerList TimerList;
 
PID myPID(&Input, &Output, &Setpoint ,8, 0, 1, DIRECT);

int ledPin =  3;
int ledState = LOW;             

void BlinkOff(void)
{
  digitalWrite(ledPin, LOW);
}

void BlinkOn(void)
{
  digitalWrite(ledPin, HIGH);
}
        


void setup() 
{
  Serial.begin(9600);
  pinMode(ledPin, OUTPUT);

  Setpoint = 36;
  myPID.SetMode(AUTOMATIC);
  myPID.SetOutputLimits(0, 255);      
}
 
void loop()
{
  
  int t = dht.readTemperature(); // Send the command to get temperatures  
  Input = t;
  
  myPID.Compute();
  int val = Output;
  val = map(val, 0, 255, 0, 100);

  if ( val > 30) {PIDon();}

  if ( val <= 30 && val >= 21) {PIDx();}

  if ( val <= 20 && val >= 10  ) {PIDx1();}

  if ( val <= 9) {PIDx2();}
  

  if ( val < 3) {PIDoff();}

Serial.print("OUTPUT ");
Serial.print(val);
Serial.print(" %");
Serial.print("Temperature: ");
Serial.print(t);
Serial.println(" *C");
}

void PIDx()
{ 
 
  TimerList.Add(BlinkOff, 50);
  TimerList.Add(BlinkOn, 100);

}
void PIDx1()
{
 

  TimerList.Add(BlinkOff, 50);
  TimerList.Add(BlinkOn, 500);

}
void PIDx2()
{
 

  TimerList.Add(BlinkOff, 50);
  TimerList.Add(BlinkOn, 1000);

}

void PIDon()
{
  digitalWrite(ledPin, HIGH);
}

void PIDoff()
{
  digitalWrite(ledPin, LOW);
}

Вариан 2


#include <PID_v1.h>


#include "uTimerList.h"

#include <Wire.h>
#include <DHT.h>

#define DHTPIN 5
#define DHTTYPE DHT11 

DHT dht(DHTPIN, DHTTYPE);
 


extern TTimerList TimerList;

double Setpoint, Input, Output;
 
PID myPID(&Input, &Output, &Setpoint ,8, 0, 1, DIRECT);

int ledPin =  3;
            
void BlinkOff(void)
{
  digitalWrite(ledPin, LOW);
}

void BlinkOn(void)
{
  digitalWrite(ledPin, HIGH);
}
       

void setup() 
{
  Serial.begin(9600);
  pinMode(ledPin, OUTPUT);

  Setpoint = 36;
  myPID.SetMode(AUTOMATIC);
  myPID.SetOutputLimits(0, 255);      
}
 
void loop()
{
  
  int t = dht.readTemperature(); // Send the command to get temperatures  
  Input = t;
  
  myPID.Compute();
  int val = Output;
  val = map(val, 0, 255, 0, 100);

  if ( val > 30) {
    digitalWrite(ledPin, HIGH);}

  if ( val <= 30 && val >= 21) 
  {  
  TimerList.Add(BlinkOff, 50);
  TimerList.Add(BlinkOn, 100);
  }

  if ( val <= 20 && val >= 10  ) 
  {
  TimerList.Add(BlinkOff, 100);
  TimerList.Add(BlinkOn, 300);
  }

  if ( val <= 6) 
  {  
    
  TimerList.Add(BlinkOff, 50);
  TimerList.Add(BlinkOn, 500);
  }
  

  if ( val < 3) {digitalWrite (ledPin, LOW);}

Serial.print("OUTPUT ");
Serial.print(val);
Serial.print(" %");
Serial.print("Temperature: ");
Serial.print(t);
Serial.println(" *C");
}


Во втором варианте строчка 

 if ( val < 3) {digitalWrite (ledPin, LOW);}

вообще не срабатывает.

 

DetSimen
DetSimen аватар
Offline
Зарегистрирован: 25.01.2017

А всё, въехал. Прочитал 1 пост внимательно.  Мой TTimerList Вам не подойдет.

Хотя, могу его чуть переделать.

DetSimen
DetSimen аватар
Offline
Зарегистрирован: 25.01.2017



#include <PID_v1.h>

#include "Arduino.h"
#include "uTimerList.h"

#include <Wire.h>
#include <DHT.h>

#define DHTPIN 5
#define DHTTYPE DHT11 

DHT dht(DHTPIN, DHTTYPE);

double Setpoint, Input, Output;

extern TTimerList TimerList;

PID myPID(&Input, &Output, &Setpoint, 8, 0, 1, DIRECT);

int ledPin = 3;
int ledState = LOW;

void BlinkOff(void)
{
	digitalWrite(ledPin, LOW);
}

void BlinkOn(void)
{
	digitalWrite(ledPin, HIGH);
}

THandle Offhnd;
THandle Onhnd;


void setup()
{
	Serial.begin(9600);
	pinMode(ledPin, OUTPUT);

	Setpoint = 36;
	myPID.SetMode(AUTOMATIC);
	myPID.SetOutputLimits(0, 255);

	Offhnd = TimerList.Add(BlinkOff, 50);         //добавили 2 таймера
	Onhnd =  TimerList.Add(BlinkOn, 1000);
	TimerList.TimerStop(Offhnd);                  // и остановили пока
	TimerList.TimerStop(Onhnd);

}

void loop()
{

	int t = dht.readTemperature(); // Send the command to get temperatures  
	Input = t;

	myPID.Compute();
	int val = Output;
	val = map(val, 0, 255, 0, 100);

	if (val > 30) { PIDon(); }

	if (val <= 30 && val >= 21) { PIDx(); }

	if (val <= 20 && val >= 10) { PIDx1(); }

	if (val <= 9) { PIDx2(); }


	if (val < 3) { PIDoff(); }

	Serial.print("OUTPUT ");
	Serial.print(val);
	Serial.print(" %");
	Serial.print("Temperature: ");
	Serial.print(t);
	Serial.println(" *C");
}

void PIDx()
{
	TimerList.TimerNewInterval(Offhnd, 50);
	TimerList.TimerNewInterval(Onhnd, 100);

}
void PIDx1()
{

	TimerList.TimerNewInterval(Offhnd, 50);
	TimerList.TimerNewInterval(Onhnd, 500);

}
void PIDx2()
{

	TimerList.TimerNewInterval(Offhnd, 50);
	TimerList.TimerNewInterval(Onhnd, 1000);

}

void PIDon()
{
	TimerList.TimerStop(Offhnd);
	TimerList.TimerStop(Onhnd);         // оба таймера остановлены, светодиод просто горит
	digitalWrite(ledPin, HIGH);
}

void PIDoff()
{
	TimerList.TimerStop(Offhnd);
	TimerList.TimerStop(Onhnd);         // оба таймера остановлены, светодиод просто потушен

	digitalWrite(ledPin, LOW);
}

скачайте новый uTimerList и пропробовайте так.

Almeder
Offline
Зарегистрирован: 26.03.2017

DetSimen пишет:

скачайте новый uTimerList и пропробовайте так.

Там же на GitHube? Скачал. В общем ситуация такая, все работает, не виснет но когда val опускается ниже 21, ledPin выключается совсем, т.е. уже на PIDx1() срабатывает LOW, в скетче причины не нашел. Ну а так начало отличное.

DetSimen
DetSimen аватар
Offline
Зарегистрирован: 25.01.2017

ОК, приеду с дачи, буду разбираца

Almeder
Offline
Зарегистрирован: 26.03.2017

DetSimen пишет:

ОК, приеду с дачи, буду разбираца

Хорошо, будем подождать))

DetSimen
DetSimen аватар
Offline
Зарегистрирован: 25.01.2017

А меня пока работой завалили. :(

Almeder
Offline
Зарегистрирован: 26.03.2017

DetSimen пишет:

А меня пока работой завалили. :(

Ясненько :( , ну ладно, как будет времячко по свободнее, тогда поглядите что там, да как...Если все заработает я закину вам немножко спасибо ))

DetSimen
DetSimen аватар
Offline
Зарегистрирован: 25.01.2017

попробуй в loop вотак написать, чо будет?

	if (val > 30) PIDon(); else

	if (val>=20)  PIDx(); else

	if (val>=10)  PIDx1(); else

	if (val>=3) PIDx2(); else PIDoff(); 

 

Almeder
Offline
Зарегистрирован: 26.03.2017

DetSimen пишет:

попробуй в loop вотак написать, чо будет?

	if (val > 30) PIDon(); else

	if (val>=20)  PIDx(); else

	if (val>=10)  PIDx1(); else

	if (val>=3) PIDx2(); else PIDoff(); 

 

Тоже самое, там кстати надо < а не >, val обратно температуре. 

Дошло до уставки с такими условиями

  if (val > 30) { PIDon(); }

  if (val <= 30 ) { PIDx(); }

  else if (val <= 20 ) { PIDx1(); }

  else if (val <= 9) { PIDx2(); }


  if (val < 3) { PIDoff(); }

Но частота блинка не менялась.

А если поменять значения в PIDx1 например на  500 , то вообще не моргает (LOW)

DetSimen
DetSimen аватар
Offline
Зарегистрирован: 25.01.2017

А кинь мне весь скетч на почту, я ночером поразбира

Almeder
Offline
Зарегистрирован: 26.03.2017

DetSimen пишет:

А кинь мне весь скетч на почту, я ночером поразбира

кинуто)

DetSimen
DetSimen аватар
Offline
Зарегистрирован: 25.01.2017

а я понял в чем дело. loop выполняется быстро и таймеры каждый раз при выполнении условия перезапускаюца. Во первых исправь if-ы вот так 

	if (val < 3)  PIDoff(); else

		if (val <= 9)  PIDx2(); else

			if (val <= 20)  PIDx1(); else

				if (val <= 30)  PIDx(); else PIDon();

скопируй как есть, не исправляй ничего.  

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

примерно так

staticint oldval=0;  
int t = dht.readTemperature(); // Send the command to get temperatures  
  Input = t;

  myPID.Compute();
  int val = Output;
  val = map(val, 0, 255, 0, 100);
if (val==oldval) return; else oldval=val

  у меня моргает как заводная. :) 

Смекаешь?

DetSimen
DetSimen аватар
Offline
Зарегистрирован: 25.01.2017

правильней бы было вообще опрос датчика из loop убрать а в нем проверять только изменения.

Домашка: сделай опрос датчика тоже по таймеру, раз допустим в 3 - 5 секунд.

только переменную, где хранишь val обьяви как volatile int

Almeder
Offline
Зарегистрирован: 26.03.2017

DetSimen пишет:

правильней бы было вообще опрос датчика из loop убрать а в нем проверять только изменения.

Домашка: сделай опрос датчика тоже по таймеру, раз допустим в 3 - 5 секунд.

только переменную, где хранишь val обьяви как volatile int

Хорошо, будем попробывать). Мне кстати в ближайшие пару дней далласы придут, я поменяю DHT на даллас)

Almeder
Offline
Зарегистрирован: 26.03.2017

DetSimen пишет:

правильней бы было вообще опрос датчика из loop убрать а в нем проверять только изменения.

Домашка: сделай опрос датчика тоже по таймеру, раз допустим в 3 - 5 секунд.

только переменную, где хранишь val обьяви как volatile int

Что-то не получается, даже DHT не заводится, пицот вариантов испробывал и две библиотеки, не то что время опроса датчика не изменяется, сам датчик с таймером запустить не могу.

На сегодня силы исчерпаны. Может завтра еще попробую.

А PID заработал, спасибо огромное, как обещал с з.п. закину немного спасибо)

DetSimen
DetSimen аватар
Offline
Зарегистрирован: 25.01.2017

не пытайся в функции таймера читать DHT, она работает в контексте прерывания, DHT врет безбожно, потому что micros() не работает.

Как я сделал:  В функции таймера которая вызывается раз в 5 секунд взвожу флаг, что надо прочитать DHT, a в loop, если этот флаг взведен, вызываю уже функцию чтения DHT, которая флаг этот сбрасывает, то есть следующее чтение будет опять через 5 сек.