Pages: 1 2 3 [4] 5   Go Down
Author Topic: [LIB] Interrupt driven DHTLib (DHT11 & DHT22 = idDHTLib)  (Read 7167 times)
0 Members and 1 Guest are viewing this topic.
Offline Offline
Newbie
*
Karma: 1
Posts: 47
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

OK, apparently the bug in first place was the first 40ms delay in the acquire method. And for the checksum error is that sometimes the sum var can be more than 256, so we have to make an and to 0xFF before compare to bits[4]
I updated the branch so can you test it again, and hopefully work this time.
« Last Edit: July 30, 2013, 08:27:27 pm by niesteszeck » Logged

Liverpool, UK
Offline Offline
Newbie
*
Karma: 0
Posts: 43
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

In a loop:

Retrieving information from sensor: Read sensor: OK
Humidity (%): 65.70
Temperature (oC): -23.20
Temperature (oF): -9.76
Temperature (K): 249.95
Dew Point (oC): -27.81
Dew Point Slow (oC): -27.84
Printing vars:
bist[0]: 0x2 d2
bist[1]: 0x91 d91
bist[2]: 0x80 d80
bist[3]: 0xE8 dE8
bist[4]: 0xFB dFB
sum: 0xFB d251
idx: 5
cnt: 7

Temperature may need to be flipped to be accurate, not sure what normal temperature is, but I have two sensors so I may be able to compare outputs smiley
Logged

Liverpool, UK
Offline Offline
Newbie
*
Karma: 0
Posts: 43
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Code:
Retrieving information from sensor: Read sensor: OK
Humidity (%): 65.20
Temperature (oC): -23.30
Temperature (oF): -9.94
Temperature (K): 249.85
Dew Point (oC): -27.98
Dew Point Slow (oC): -28.01
Printing vars:
bist[0]: 0x2 d2
bist[1]: 0x8C d8C
bist[2]: 0x80 d80
bist[3]: 0xE9 dE9
bist[4]: 0xF7 dF7
sum: 0xF7 d247
idx: 5
cnt: 7
--------------
==============dht2================
40
2, 8F, 0, E2, 73 =? 173
Humidity: 65.50 % Temperature: 22.60 *C
=================================

But I'm getting checksum errors a lot on the first DHT sensor which I guess indicates the timing might be off still.
Logged

Offline Offline
Newbie
*
Karma: 1
Posts: 47
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

this output is for what sensor?, i get confused
Logged

Liverpool, UK
Offline Offline
Newbie
*
Karma: 0
Posts: 43
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

The second sensor is the other DHT22 sensor I have on my Arduino board, I am using the Adafruit lib for it. It's showing output for the first sensor and then the second. The first one is using your lib. I hacked the second sensor into the example smiley

Here is the full output: http://paste.ee/p/wDbxJ
Logged

Offline Offline
Newbie
*
Karma: 1
Posts: 47
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

i don't understand why the second byte in the first sensor is 0x80 and on the second is 0x00.
if this byte[2]&0x80==0x80 means that is a negative temp, so I got why in the second one the byte is 0x00, but not why in the first is 0x80

can you change the order of the sensors?
Logged

Offline Offline
Newbie
*
Karma: 1
Posts: 47
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

I make another mod, but I don't have any hope that it will repar the - sing in temp. Can you try it?

if not work, i have my brain cooked for today, maybe tomorrow I get  a new aproach

by
Logged

Liverpool, UK
Offline Offline
Newbie
*
Karma: 0
Posts: 43
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

The sensors are getting data one after the other in the main loop -- I can change the order in the code, but not sure it will make a difference? I already applied all modifications -- the latest output is coming from the latest commit to dht22_bug_detect (#8374114) with some modifications to the example to support the second sensor.
Logged

Liverpool, UK
Offline Offline
Newbie
*
Karma: 0
Posts: 43
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

I swapped the two sensors on the breadboard. Here is the output now:

Code:
Retrieving information from sensor: Read sensor: OK
Humidity (%): 65.00
Temperature (oC): -38.90
Temperature (oF): -38.02
Temperature (K): 234.25
Dew Point (oC): -42.96
Dew Point Slow (oC): -42.97
Printing vars:
bist[0]: 0x2 d2
bist[1]: 0x8A d8A
bist[2]: 0x81 d81
bist[3]: 0x85 d85
bist[4]: 0x92 d92
sum: 0x92 d146
idx: 5
cnt: 7
--------------
==============dht2================
40
2, 36, 0, FD, 35 =? 135
Humidity: 56.60 % Temperature: 25.30 *C
=================================

Here is full output after I let it run a little while: http://paste.ee/p/fEpVh
« Last Edit: July 30, 2013, 10:19:16 pm by Dessimat0r » Logged

Liverpool, UK
Offline Offline
Newbie
*
Karma: 0
Posts: 43
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Here's something to wrap your chops around: both sensors and both libs used in the same program smiley With proper delays.

http://paste.ee/p/ffRia

Source code:
Code:
/*
  Board           int.0   int.1   int.2   int.3   int.4   int.5
 Uno, Ethernet   2   3
 Mega2560   2   3   21   20   19   18
 Leonardo   3   2   0   1
 Due           (any pin, more info http://arduino.cc/en/Reference/AttachInterrupt)
 
 This example, as difference to the other, make use of the new method acquireAndWait()
 */

#include <idDHTLib.h>
#include <DHT.h>

#define DHTTYPE DHT22   // DHT 22  (AM2302)

//declaration
void dhtLib1_wrapper(); // must be declared before the lib initialization
void dhtLib2_wrapper(); // must be declared before the lib initialization

// Lib instantiate
idDHTLib DHTLib1(2,0,dhtLib1_wrapper);
idDHTLib DHTLib2(3,1,dhtLib2_wrapper);
DHT dht1(2, DHTTYPE);
DHT dht2(3, DHTTYPE);

void setup()
{
  Serial.begin(9600);
  Serial.println("idDHTLib Example program");
  Serial.print("LIB version: ");
  Serial.println(IDDHTLIB_VERSION);
  Serial.println("---------------");
  dht1.begin();
  dht2.begin();
  delay(3000); // The sensor need like 2 sec to initialize, if you have some code before this that make a delay, you can eliminate this delay
}
// This wrapper is in charge of calling
// mus be defined like this for the lib work
void dhtLib1_wrapper() {
  DHTLib1.dht22Callback(); // Change dht11Callback() for a dht22Callback() if you have a DHT22 sensor
}
void dhtLib2_wrapper() {
  DHTLib2.dht22Callback(); // Change dht11Callback() for a dht22Callback() if you have a DHT22 sensor
}
void loop()
{
  {
  Serial.println("============= DHTLib DHT 1 =============");
  Serial.print("\nRetrieving information from sensor: ");
  Serial.print("Read sensor: ");
  //delay(100);
 
  int result = DHTLib1.acquireAndWait();
  switch (result)
  {
  case IDDHTLIB_OK:
    Serial.println("OK");
    break;
  case IDDHTLIB_ERROR_CHECKSUM:
    Serial.println("Error\n\r\tChecksum error");
    break;
  case IDDHTLIB_ERROR_TIMEOUT:
    Serial.println("Error\n\r\tTime out error");
    break;
  case IDDHTLIB_ERROR_TIMEOUT_2:
    Serial.println("Error\n\r\tTime out error 2");
    break;
  case IDDHTLIB_ERROR_TIMEOUT_3:
    Serial.println("Error\n\r\tTime out error 3");
    break;
  case IDDHTLIB_ERROR_ACQUIRING:
    Serial.println("Error\n\r\tAcquiring");
    break;
  case IDDHTLIB_ERROR_DELTA:
    Serial.println("Error\n\r\tDelta time to small");
    break;
  case IDDHTLIB_ERROR_NOTSTARTED:
    Serial.println("Error\n\r\tNot started");
    break;
  default:
    Serial.println("Unknown error");
    break;
  }
  Serial.print("Humidity (%): ");
  Serial.println(DHTLib1.getHumidity(), 2);

  Serial.print("Temperature (oC): ");
  Serial.println(DHTLib1.getCelsius(), 2);

  Serial.print("Temperature (oF): ");
  Serial.println(DHTLib1.getFahrenheit(), 2);

  Serial.print("Temperature (K): ");
  Serial.println(DHTLib1.getKelvin(), 2);

  Serial.print("Dew Point (oC): ");
  Serial.println(DHTLib1.getDewPoint());

  Serial.print("Dew Point Slow (oC): ");
  Serial.println(DHTLib1.getDewPointSlow());

  DHTLib1.printVars();
 
  Serial.println("==========================================");
  }
  Serial.println();
  {
  Serial.println("============= DHTLib DHT 2 =============");
  Serial.print("\nRetrieving information from sensor: ");
  Serial.print("Read sensor: ");
  //delay(100);
 
  int result = DHTLib2.acquireAndWait();
  switch (result)
  {
  case IDDHTLIB_OK:
    Serial.println("OK");
    break;
  case IDDHTLIB_ERROR_CHECKSUM:
    Serial.println("Error\n\r\tChecksum error");
    break;
  case IDDHTLIB_ERROR_TIMEOUT:
    Serial.println("Error\n\r\tTime out error");
    break;
  case IDDHTLIB_ERROR_TIMEOUT_2:
    Serial.println("Error\n\r\tTime out error 2");
    break;
  case IDDHTLIB_ERROR_TIMEOUT_3:
    Serial.println("Error\n\r\tTime out error 3");
    break;
  case IDDHTLIB_ERROR_ACQUIRING:
    Serial.println("Error\n\r\tAcquiring");
    break;
  case IDDHTLIB_ERROR_DELTA:
    Serial.println("Error\n\r\tDelta time to small");
    break;
  case IDDHTLIB_ERROR_NOTSTARTED:
    Serial.println("Error\n\r\tNot started");
    break;
  default:
    Serial.println("Unknown error");
    break;
  }
  Serial.print("Humidity (%): ");
  Serial.println(DHTLib2.getHumidity(), 2);

  Serial.print("Temperature (oC): ");
  Serial.println(DHTLib2.getCelsius(), 2);

  Serial.print("Temperature (oF): ");
  Serial.println(DHTLib2.getFahrenheit(), 2);

  Serial.print("Temperature (K): ");
  Serial.println(DHTLib2.getKelvin(), 2);

  Serial.print("Dew Point (oC): ");
  Serial.println(DHTLib2.getDewPoint());

  Serial.print("Dew Point Slow (oC): ");
  Serial.println(DHTLib2.getDewPointSlow());

  DHTLib2.printVars();
 
  Serial.println("==========================================");
  dht1.begin();
  dht2.begin();
  delay(2500);
  }
  Serial.println();
  {
  Serial.println("============= adafruit dht #1 ============");
 
  // Reading temperature or humidity takes about 250 milliseconds!
  // Sensor readings may also be up to 2 seconds 'old' (its a very slow sensor)
  float h = dht1.readHumidity();
  float t = dht1.readTemperature();

  // check if returns are valid, if they are NaN (not a number) then something went wrong!
  if (isnan(t) || isnan(h)) {
    Serial.println("Failed to read from DHT");
  } else {
    Serial.print("Humidity: ");
    Serial.print(h);
    Serial.print(" %\t");
    Serial.print("Temperature: ");
    Serial.print(t);
    Serial.println(" *C");
    Serial.println("==========================================");
  }
 
  }
  Serial.println();
  {
  Serial.println("============= adafruit dht #2 ============");
 
  // Reading temperature or humidity takes about 250 milliseconds!
  // Sensor readings may also be up to 2 seconds 'old' (its a very slow sensor)
  float h = dht2.readHumidity();
  float t = dht2.readTemperature();

  // check if returns are valid, if they are NaN (not a number) then something went wrong!
  if (isnan(t) || isnan(h)) {
    Serial.println("Failed to read from DHT");
  } else {
    Serial.print("Humidity: ");
    Serial.print(h);
    Serial.print(" %\t");
    Serial.print("Temperature: ");
    Serial.print(t);
    Serial.println(" *C");
    Serial.println("==========================================");
  }
 
  Serial.println();
  }
 
  delay(2500);
}
« Last Edit: July 30, 2013, 11:04:52 pm by Dessimat0r » Logged

Offline Offline
Newbie
*
Karma: 1
Posts: 47
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Looks like the temp is calculated right and only the negative is wrong.
Is strange 'cause if we received a 0x00 on byte 2, then the checksum is going to fail, so we can assume that the bits are interpreted in the right way, but maybe we are in some rarely and not probably case that the interpretation of bits get a good checksum not matter the error, maybe the error is repeated in some bits so the checksum compare get right.


I made some mods, but still not hope to get a solution, sorry. Can you try it, there are 3 new commits
Logged

Liverpool, UK
Offline Offline
Newbie
*
Karma: 0
Posts: 43
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Yeah, the checksum seems nearly useless, considering it is letting invalid values through somehow smiley I'll test the new commits when I get home.
Logged

Liverpool, UK
Offline Offline
Newbie
*
Karma: 0
Posts: 43
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Fresh output for ya: http://paste.ee/p/EBsnD
Logged

Offline Offline
Newbie
*
Karma: 1
Posts: 47
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

on line 181 and 484 there is a good reading, and now there is a lot more checksum errors, so I suspect that is a small timing issue. It'll be a good think to do as next step to see the signal with a logic analyzer or an oscilloscope( if you have one, send me an screenshot and the serial output to analyse it, the output generated when you take the screenshot), to see the exact timing and which bit is interpreted in a wrong way.

If you don't have this kind of tools the only thing that we can do is to play with the timing numbers, If I make a change it take some time to you to get it, so I recommend you to try different timing numbers to always get all bits right. The important numbers are the ones on lines:

line 98
Code:
} if(125<delta && delta<190) {

The start signal from the sensor takes 80us down and 80us up, so this range should be good, and I don't think this part is failing, 'cause we are not getting an timeout error.

line 113
Code:
if(delta>95) //is a one
for a 0 the sensor put down the signal for 50us and then up for 22-28us and for a 1 it puts the signal low for the same 50us and then up for 70 more us. So I think 95us of delta should be enough to discriminate between a 1 an a 0, but apparently isn't (that's why I recommend to see the signal in an oscilloscope) (or try with an 100)

line 111
Code:
} else if(60<delta && delta<145) { //valid in timing
In this line we check that the timing is between an acceptable range, that can be a 0 or a 1.


So you can play with this numbers and make a try and error test to get good values for the sensor. Just remember that the lib use the falling edge to call the interrupt and that's why it checks the timing adding the low signal time plus the high signal time.

An optimization that you can try to, is to pass the if on line 107
Code:
if(delta<10) {
after the if in line 111
Code:
} else if(60<delta && delta<145) { //valid in timing
so the error if (line 107) will be checked only if there is an error in timing, saving us a little bit of time. I'll do this on the main branch so you can look at it if you don't understand this proposal.

more info
http://www.adafruit.com/datasheets/DHT22.pdf
http://robocraft.ru/files/datasheet/DHT11.pdf
Logged

Liverpool, UK
Offline Offline
Newbie
*
Karma: 0
Posts: 43
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

I don't have an oscilloscope sorry smiley-sad But wouldn't it be possible to query the Arduino using interrupts to work out where the signal is high and output all that, including delays between those signals?
Logged

Pages: 1 2 3 [4] 5   Go Up
Jump to: