Dear all,
First, thanks to everyone that will help/give advice/...
I've already looked intensively on this forum and on Internet but I coulnd't find the solution to my current issue.
I'm finshing a ventilation project for my house.
Hardware
I used an Arduino Mega (ATmega2560). This arduino collects information from
- 7 DHT 22 sensors with 4.7k pullup and 100nF capacitor between GND and 5V
- 3 presence sensors
- 2 DS18B20 sensors (1-Wire)
- 1 dust sensor
- 1 Air Quality sensor (Analogic)
- 1 3.5" TFT touch screen Kuman
The arduino pilots 19 relays :
- 1 for turning on/off the TFT (5V)
- 4 for turning on/off blowers (220V) - 2 blowers - 2speed each
-14 for opening/closing 7 valves (220V)
The arduino is fed by a dedicated 5V-5A power supply
The relay are fed by a separated 5V-2A power supply
First Issue with DHT22
At the beginning, I had a first issue with the DHT22. At the start-up of the arduino, they were giving correct values. But, as soon as one 220V relay was switching-off, I lost the communication with DHT22 sensors. I solve the problem by connecting capacitors between the 2 pins of the relay (0.1 microF-630V for the blowers and 0.047 microF-630V for the valve).
This solved the issue. (I suppose taht, even with different power supply, the voltage surge (220--> 300V) when the relay was switching could influence arduino voltage).
Description of current issue
Now, everything is working fine but, it remains one issue : DHT22 stop responding after 24-72 hours, sometimes more. And, not all stopped responding at the same time.
Another point is that I don't need to reboot the arduino to have them worked again. If I unplug the sensor for a second and that I plug it again, it starts working again.
I have thought of putting the supply of the DHT22 sensors through a transistor and to restart the supply when the error is occuring but I would prefer to find more elegant solution.
Code used for DHT
I tried with many different library.
Now, I switched to DHTNEW RobTillart Library.
I see that when the sensor stopped responding, it is due to the fact tha it never goes HIGH in this part of the library code :
// SENSOR STAYS LOW for ~80 us => or TIMEOUT
if (_waitFor(HIGH, 90)) return DHTLIB_ERROR_TIMEOUT_A;
// SENSOR STAYS HIGH for ~80 us => or TIMEOUT
if (_waitFor(LOW, 90)) return DHTLIB_ERROR_TIMEOUT_B;
I have 7 sensors and I request temperature every 3 second to 1 of them. So, each sensor has to respond every 21 second.
I do not use the "delay" function for this because the loop should still be working for the interface but I use the millis() function to determine when to read the sensor.
Here is the code used for reading one sensor.
// Lecture d'un capteur DHT22 Température et Humidité avec la librairie dhtnew de Rob Tillaart
void readDHT22(DHTNEW mySensor, float* temperature, float* humidity)
{
float tempe;
float hum;
static uint16_t dht_delay = 1000;
uint8_t type = 22;
mySensor.setType(type);
// READ DATA
//uint32_t start = micros();
int chk = mySensor.read();
//uint32_t stop = micros();
switch (chk)
{
case DHTLIB_OK:
Serial.print("OK,\t");
dht_delay -= 10;
break;
case DHTLIB_ERROR_CHECKSUM:
Serial.print("Checksum error,\t");
dht_delay += 10;
break;
case DHTLIB_ERROR_TIMEOUT_A:
Serial.print("Time out error A,\t");
dht_delay += 10;
break;
case DHTLIB_ERROR_TIMEOUT_B:
Serial.print("Time out error B,\t");
dht_delay += 10;
break;
case DHTLIB_ERROR_TIMEOUT_C:
Serial.print("Time out error C,\t");
dht_delay += 10;
break;
case DHTLIB_ERROR_TIMEOUT_D:
Serial.print("Time out error D,\t");
dht_delay += 10;
break;
case DHTLIB_ERROR_SENSOR_NOT_READY:
Serial.print("Sensor not Ready Error,\t");
dht_delay += 10;
break;
default:
Serial.print("Unknown error,\t");
dht_delay += 10;
break;
}
dht_delay = constrain(dht_delay, 100, 5000);
// Record DATA
hum = 0.1*(10mySensor.getHumidity());
tempe = 0.1(10*mySensor.getTemperature());
*humidity = hum;
*temperature = tempe;
//uint32_t duration = stop - start;
delay(dht_delay);
}
And, this code is launched in this function that manage all sensors :
// Fonction de lecture de tous les DHT22
void readAllDHT22(){ // Modification de la fonction pour des mesures en cascade
static unsigned long long previousMillis = 0;
static unsigned long long storeMillis = 0;
static int count = 0;
int nbMeas = 7;
int interval = nbMeas + 1;
if (previousMillis + DelayMeas/interval < supMillis and count == 0){
readDHT22(T_HUM_SDBp, &temp_SDBp, &hum_SDBp);
count ++;
previousMillis = supMillis;
}
else if (previousMillis + DelayMeas/interval < supMillis and count == 1)
{readDHT22(T_HUM_SDBe, &temp_SDBe, &hum_SDBe); count ++; previousMillis = supMillis;}
else if (previousMillis + DelayMeas/interval < supMillis and count == 2)
{readDHT22(T_HUM_WC, &temp_WC, &hum_WC); count ++; previousMillis = supMillis;}
else if (previousMillis + DelayMeas/interval < supMillis and count == 3)
{readDHT22(T_HUM_Chamb, &temp_Chamb, &hum_Chamb); count ++; previousMillis = supMillis;}
else if (previousMillis + DelayMeas/interval < supMillis and count == 4)
{readDHT22(T_HUM_Sdj, &temp_Sdj, &hum_Sdj); count ++; previousMillis = supMillis;}
else if (previousMillis + DelayMeas/interval < supMillis and count == 5)
{readDHT22(T_HUM_Outside, &temp_Outside, &hum_Outside); count ++; previousMillis = supMillis;}
else if (previousMillis + DelayMeas/interval < supMillis and count == 6)
{readDHT22(T_HUM_Hall, &temp_Hall, &hum_Hall); count = 0; previousMillis = supMillis;}
}
Thanks a lot for your help,
Laurent
