DHT22 Sensor working?


#1

Has anyone gotten the DHT22 sensor working in Arduino mode? I am using the Adafruit libraries found here:

I am just using the basic testing sketch which is mentioned in the tutorial to make sure the DHT is recognized, which is:

   #include "DHT.h"    
   #define DHTPIN 7     // what pin we're connected to
    #define DHTTYPE DHT22   // DHT 22  (AM2302)
    
    DHT dht(DHTPIN, DHTTYPE, 30);
    
    void setup() {
      SerialUSB.begin(115200); 
      SerialUSB.println("DHTxx test!");
     
      dht.begin();
    }
    
    void loop() {
      // Wait a few seconds between measurements.
      delay(2000);
    
      // 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 = dht.readHumidity();
      // Read temperature as Celsius
      float t = dht.readTemperature();
      // Read temperature as Fahrenheit
      float f = dht.readTemperature(true);
      
      // Check if any reads failed and exit early (to try again).
      if (isnan(h) || isnan(t) || isnan(f)) {
        SerialUSB.println("Failed to read from DHT sensor!");
        return;
      }
    
      // Compute heat index
      // Must send in temp in Fahrenheit!
      float hi = dht.computeHeatIndex(f, h);
    
      SerialUSB.print("Humidity: "); 
      SerialUSB.print(h);
      SerialUSB.print(" %\t");
      SerialUSB.print("Temperature: "); 
      SerialUSB.print(t);
      SerialUSB.print(" *C ");
      SerialUSB.print(f);
      SerialUSB.print(" *F\t");
      SerialUSB.print("Heat index: ");
      SerialUSB.print(hi);
      SerialUSB.println(" *F");
    }

It seems to compile and load fine, but then when I go to the Serial monitor to see the output I get nothing. The output on the Arduino IDE is:

WARNING: Category '' in library SPI is not valid. Setting to 'Uncategorized'
Warning: platform.txt from core 'konekt.io Dash and DashPro Boards' contains deprecated recipe.ar.pattern="{compiler.path}{compiler.ar.cmd}" {compiler.ar.flags} {compiler.ar.extra_flags} "{build.path}/{archive_file}" "{object_file}", automatically converted to recipe.ar.pattern="{compiler.path}{compiler.ar.cmd}" {compiler.ar.flags} {compiler.ar.extra_flags} "{archive_file_path}" "{object_file}". Consider upgrading this core.
cc1plus.exe: warning: command line option '-std=c99' is valid for C/ObjC but not for C++ [enabled by default]


Sketch uses 15,644 bytes (1%) of program storage space. Maximum is 1,014,764 bytes.
Error while setting serial port parameters: 9,600 N 8 1

Seems as if this locks up the serial port and just sits there! Anyone have any ideas? Do any other OneWire sensors work like the DS18B20?

Thanks!


#2

@torchris

Thanks for posting your question. While I don’t have that specific sensor to test, I was able to load the library and the sketch you posted. Here is what I found.

  1. Change

    #define DHTPIN 7

to

#define DHTPIN D07

or whichever pin you are using, as listed in GPIO column of the Reference Manual. We’ll be adding support for Arduino-style digital IO pin numbering in a future release. But for now, you need to use the pre-defined macros.

  1. The library calls a core function (delayMicroseconds) that has a bug. The implementation works on our other microcontroller, but it breaks on the one you are using. Thanks for finding it! We’ll be including that fix in the next Arduino update. In the mean time you can try and update your local copy and see if it can get you running until then.

To make the fix, find the Arduino system directory. It varies by OS, but the easiest way to find it is in the Preferences dialog, at the bottom of the dialog, it shows the path to preferences.txt. From that path, you can find the affected file:
/packages/konekt/hardware/sam/0.7.0/cores/arduino/delay.h
On or about line 100, change

sub  %0, #1

to

subs %0, #1

Rebuild your sketch and hopefully that will do the trick.

  1. The library disables all interrupts during parts of the sensor read due to the timing constraints of the 1-wire protocol. The SerialUSB device is interrupt based. If its interrupt isn’t serviced in a timely manner, the connection will be closed by your host computer. So it may be difficult to use SerialUSB and 1-wire protocol at the same time. I’ll look at ways of better supporting the 1-wire protocol. And based on your output, you may not have the correct serial port selected. Try a simple sketch that just does a SerialUSB.print() and delay in the loop function. While that is running, you should be able to select the port from the Arduino menu.

Let us know if you have success or run into any other issues.


#3

Thanks for the quick reply! I must have missed that about the pin numbering. I will give that a try.

With regards to the SerialUSB, could debug information be directed to a hardware UART and accessed via a USB to Serial converter (which can be hooked up to Putty)? It looks like there are multiple UARTs on the board:

Pin L04 = RX1
Pin L03 = TX1
Pin R05 = RX0
Pin R03 = TX0

How would these be addressed in the Arduino IDE? “Serial1.print();”


#4

Interestingly, now that I have changed to using the correct pin definitions, I am at least getting:

Failed to read from DHT sensor!
Failed to read from DHT sensor!
Failed to read from DHT sensor!

I have tried a few different pins (D05, D10 etc) and I have tried playing with the “third parameter” on the DHT object initialization. From the Adafruit library comments:

// NOTE: For working with a faster chip, like an Arduino Due or Teensy, you
// might need to increase the threshold for cycle counts considered a 1 or 0.
// You can do this by passing a 3rd parameter for this threshold.  It's a bit
// of fiddling to find the right value, but in general the faster the CPU the
// higher the value.  The default for a 16mhz AVR is a value of 6.  For an
// Arduino Due that runs at 84mhz a value of 30 works.
// Example to initialize DHT sensor for Arduino Due:
//DHT dht(DHTPIN, DHTTYPE, 30);

On the ESP8266-12, for instance, I find I need to use “DHT dht(DHTPIN, DHTTYPE, 28);” to get consistent readings.

Let me know if you think the UART serial would help this any.

Thanks!!


#5

@torchris

You can definitely use a USB/Serial converter. I use one quite a bit, such as the FT232.

On the Dash, RX0/TX0 are used by Serial0 and RX2/TX2 are used by Serial2. Connect those pins and the ground pin and you should be able to use either PuTTY or the Arduino Serial Monitor.

If you are getting output on the SerialUSB port, it looks like the connection is still alive, which is good. The 1-wire protocol requires exact timing, so that is probably why you are seeing the “Failed to read from DHT sensor!” output. Did you try to make the change to the delayMicroseconds function?

Reading the library code, you can enable debug statements from within the library. Uncomment DHT_DEBUG in DHT.h, and change DEBUG_PRINTER to the serial port you are using (Serial0 or Serial2 with your USB/Serial converter).

In the version of the DHT library I saw, the 3rd parameter, count, was ignored. It instead sets a timeout of 1 millisecond, based on the system clock.

I’ll try and get a DHT22 this week and try it out myself.


#6

Thanks very much for your help! I may stick with the SerialUSB for now since it’s giving me feedback, but good to know on the other UARTs for hooking this thing up to a GPS unit! :smile:

Yes, I did make the delay change you recommended as well.

I will check out that extra debug info and see if it helps.


#7

Got it working!!

Humidity: 59.20 %    Temperature: 19.20 *C 66.56 *F    Heat index: 65.70 *F
Humidity: 58.50 %    Temperature: 19.30 *C 66.74 *F    Heat index: 65.86 *F
Humidity: 57.00 %    Temperature: 19.30 *C 66.74 *F    Heat index: 65.79 *F
Humidity: 55.80 %    Temperature: 19.30 *C 66.74 *F    Heat index: 65.74 *F
Humidity: 55.00 %    Temperature: 19.30 *C 66.74 *F    Heat index: 65.70 *F

I suspect I was using the wrong pin!! Thanks very much for your help. Here is the final sketch that works:

#include <DHT.h>

#define DHTPIN D16     // what pin we're connected to

// Uncomment whatever type you're using!
//#define DHTTYPE DHT11   // DHT 11 
#define DHTTYPE DHT22   // DHT 22  (AM2302)
//#define DHTTYPE DHT21   // DHT 21 (AM2301)

// Connect pin 1 (on the left) of the sensor to +5V
// NOTE: If using a board with 3.3V logic like an Arduino Due connect pin 1
// to 3.3V instead of 5V!
// Connect pin 2 of the sensor to whatever your DHTPIN is
// Connect pin 4 (on the right) of the sensor to GROUND
// Connect a 10K resistor from pin 2 (data) to pin 1 (power) of the sensor

// Initialize DHT sensor for normal 16mhz Arduino
DHT dht(DHTPIN, DHTTYPE,20);
// NOTE: For working with a faster chip, like an Arduino Due or Teensy, you
// might need to increase the threshold for cycle counts considered a 1 or 0.
// You can do this by passing a 3rd parameter for this threshold.  It's a bit
// of fiddling to find the right value, but in general the faster the CPU the
// higher the value.  The default for a 16mhz AVR is a value of 6.  For an
// Arduino Due that runs at 84mhz a value of 30 works.
// Example to initialize DHT sensor for Arduino Due:
//DHT dht(DHTPIN, DHTTYPE, 30);

void setup() {
//  SerialCloud.begin(115200);
  SerialUSB.begin(115200); 
  SerialUSB.println("DHTxx test!");
 
  dht.begin();
}

void loop() {
  // Wait a few seconds between measurements.
  delay(3000);

  // 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 = dht.readHumidity();
  // Read temperature as Celsius
  float t = dht.readTemperature();
  // Read temperature as Fahrenheit
  float f = dht.readTemperature(true);
  
  // Check if any reads failed and exit early (to try again).
  if (isnan(h) || isnan(t) || isnan(f)) {
    SerialUSB.println("Failed to read from DHT sensor!");
    return;
  }

  // Compute heat index
  // Must send in temp in Fahrenheit!
  float hi = dht.computeHeatIndex(f, h);
delay(100);
  SerialUSB.print("Humidity: "); 
  SerialUSB.print(h);
  SerialUSB.print(" %\t");
  SerialUSB.print("Temperature: "); 
  SerialUSB.print(t);
  SerialUSB.print(" *C ");
  SerialUSB.print(f);
  SerialUSB.print(" *F\t");
  SerialUSB.print("Heat index: ");
  SerialUSB.print(hi);
  SerialUSB.println(" *F");
  delay(100);
}

Now to get the info up in the cloud!!