Go Down

Topic: DHT11 and PulseSensor incompatibility (Read 742 times) previous topic - next topic

pooya_ww

Mar 07, 2016, 12:18 am Last Edit: Mar 07, 2016, 12:26 am by pooya_ww
I am working on an IoT project to send data acquired from DHT11 and PulseSensor to a website. I can send the data properly when I use each of sensors alone but when I write a wrapper to use both sensors simultaneously, DHT11 returns check-sum error. PulseSensor uses interrupt based on TIMER2 , whenever I remove interruptSetup(); from setup block the problem is solved but obviously the PulseSensor does not work in this case. I searched inside the DHT11 library, as far as I could understand it does not use any Timer or interrupt to make a conflict with PulseSensor requirements. This project use two serial port to communicate with PC for debugging and another one to communicate with ESP8266. Please help me in finding a solution for this problem.

Code is attached.

Koepel

Why are interrupts disabled during the ISR ?
If there is no very special reason, please remove the cli() and the sei() from the ISR.
Perhaps the code from the ISR is copied from another processor ?

The ISR is rather long.

The DHT uses a protocol with specific timing. Some libraries turn off the interrupts while doing that. Which DHT library do you use ?

pooya_ww

#2
Mar 08, 2016, 07:05 pm Last Edit: Mar 08, 2016, 07:13 pm by pooya_ww Reason: wrong attachment
I think when ISR for Timer 2 is executed the interrupts are disabled whether to introduce  cli() and sei() or not.
Yes, the ISR code is kind of driver for PulseSensor which is not dedicated only to Arduino.

I could fix the problem and it was due to the long ISR.

The DHT requires some precise timing on its one-wire interface e.g. a >40us HIGH pulse == 1, while a <40us HIGH pulse == 0. DHT library doesn't use interrupts directly but it does use micros() which is based on regular interrupts, which are disabled automatically when we are within the TIMER2 ISR, If we waste too much time in the ISR, We will miss bits/pulses on the DHT line and obtain incorrect data, hence checksum error.

The simplest solution is to disable the TIMER2 interrupt before the read11() call and enable it again after. I and it really works.

Code: [Select]

#define TIM2_EN() (TIMSK2 = 0x02)
#define TIM2_DIS() (TIMSK2 = 0x00)

// The code as usual

void loop(){
  // ...as before...

  TIM2_DIS(); //Enable TIMER2 Interrupt

  //Read DH11 Data
  int chk = DHT.read11(DHT11_PIN);

  TIM2_EN(); //Disable TIMER2 Interrupt

 //...as before...
}

// The code as before


By the way, Do you have any general methodology in your mind to avoid this kind of conflicts when installing several sensors? I mean is there any pattern to follow in writing flaw-less codes?

The corrected code is attached and might be useful for others. If anyone needs more details(such as schematic which is not ready yet   ;)  ) let me know... :)

Koepel

#3
Mar 08, 2016, 07:12 pm Last Edit: Mar 08, 2016, 07:18 pm by Koepel
As far as I know, there is no general methodology. Some sensors (DHT11, DS18B20, Neopixels) require specific timing. Even some I2C sensors require a delay before data can be read. That can easily get in the way of something else.

There are many solutions.
For example an extra Arduino, only for collecting all the sensor data.
Or checking the sensors over and over again, until the checksum is okay.
Or a whole bunch of extra Arduino boards which send data wireless to a central unit.

Go Up