Main Site Documentation

DHT22 temperature and humidity sensor


#1

Hey guys, I just got a FEZ Panda and I’m starting to learn what this thing can do. At this time I have Arduino hardware too but the Panda just seems like a much better playform however I have a little snag.

I’m trying to use a DHT22 sensor sold by sparkfun, http://www.sparkfun.com/products/10167, this sensor works really well with my arduino, but I have no idea how to reproduce the code in my fez, you have to send it custom pulses and wait for specific lengths of time but from what I gathered in discussions elsewhere it’s not possible to do this in the fez.

I’m not sure if anyone here has seen an implementation of this chip or can suggest how I could reproduce the library. In the arduino it pulses the signal for a few uS and then reads the pulses over the next several uS to see if an appropriate signal has come back, but I’m not sure the Panda can even time such small intervals since it’s threaded plus running .net.

Please advise.


#2

Yes, this needs RLP code to run with the Panda. Peddy on the forum has some code and perhaps he will post it on code.tinyclr.com.


#3

I can’t analizy the sensor at the moment but I can point you in some direction. Look in GHI SDK documentation:

http://www.ghielectronics.com/downloads/NETMF/Library%20Documentation/Index.html

search for two classes:

  • OutputCompare
  • PinCapture

You can use the first one to generate custom pulse as you would do in native code. Second class can be used to capture the response wave. You don’t event have to touch RLP!


#4

ooh, thanks, I’ll definitely read up on these classes and see how they can work for me.


#5

Hello !

No need for RLP since we have the PinCapture class available !

Please find below some (very quick) code I made this morning to read temp/humid from a DHT11 sensor. It is similar to the DHT22 (proprietary one-wire protocol), but you need testing. The DHT11 is great because cheap and accurate enough ! However its temperature range is only 0-50°C therefore I don’t know if the code below will work for negative temperature. Send me a DHT22 sensor and I’ll make you the driver :smiley:

However, I was never able to make it work just using a single pin of my fez domino : PinCapture is made with an InputPin, and I was never quick enough on the same pin sending an Output “start signal” with “OutputPin” then switching to PinCapture to read the results. Then I used 2 pins I connected together to the sensor data pin. One pin “DHT11out” is a tristate port, because it can send a low 0 and high impedance 1s. One pin “DHT11in” is the Pincapture port.

for my test, the DHT11 is powered with 3.3v, I use data pin 6 as output and data pin 7 as input/pincapture (hardwired together). You may pick up any other port as far as they can work as interrup inputs.

Someday I will post an official driver, but at least this code is giving you a working example.


using System;
using System.Threading;
using Microsoft.SPOT;
using Microsoft.SPOT.Hardware;
using GHIElectronics.NETMF.FEZ;
using GHIElectronics.NETMF.Hardware;

namespace DHT11
{
    public class Program
    {
        
        public static void Main()
        {
            uint[] buffer = new uint[100];
            int nb,i;

            TristatePort DHT11out = new  TristatePort((Cpu.Pin)FEZ_Pin.Digital.Di6, false,false,Port.ResistorMode.PullUp);
            if (DHT11out.Active == false) DHT11out.Active = true; // Make tristateport "output" 
            DHT11out.Write(true);   //"high up"
            PinCapture DHT11in = new PinCapture((Cpu.Pin)FEZ_Pin.Digital.Di7, Port.ResistorMode.PullUp, Port.InterruptMode.InterruptEdgeBoth);
            bool rt=DHT11in.InternalPort.Read();
            DHT11out.Write(false);  // "low down" : initiate transmission
            bool rf=DHT11in.InternalPort.Read();
            Thread.Sleep(20);       // For "at least 18ms"
            if (!rt || rf) Debug.Print("Error : the 2 pins are not hardwired together !");
            DHT11out.Write(true);   //"high up" then listen
            nb = DHT11in.Read(false, buffer, 0, 100, 1000);

            if (nb < 81) Debug.Print("Error : did not get enough state change");
            else // We read it from the last bit, since we don't know when we started recording
            {
                nb -= 2; // skip last 50us down          
                byte checksum=0,decimalT=0,integralT=0,decimalRH=0,integralRH=0;
                for (i = 0; i < 8; i++, nb -= 2) checksum |= (byte)(buffer[nb] > 50 ? 1 << i : 0);
                for (i = 0; i < 8; i++, nb -= 2) decimalT |= (byte)(buffer[nb] > 50 ? 1 << i : 0);
                for (i = 0; i < 8; i++, nb -= 2) integralT |= (byte)(buffer[nb] > 50 ? 1 << i : 0);
                for (i = 0; i < 8; i++, nb -= 2) decimalRH |= (byte)(buffer[nb] > 50 ? 1 << i : 0);
                for (i = 0; i < 8; i++, nb -= 2) integralRH |= (byte)(buffer[nb] > 50 ? 1 << i : 0);
                //check if checksum is correct
                if (((integralRH + decimalRH + integralT + decimalT) & 0xFF) != checksum) Debug.Print("Checksum Error");
                else
                {
                    Debug.Print("Temperature = " + integralT + "." + decimalT);
                    Debug.Print("Humidity = " + integralRH + "." + decimalRH);
                }
  
            }
            
        }

    }
}

Sorry for the ansi C looking like code :stuck_out_tongue:


#6

Nicolas no goto? :wink:


#7

Not today ::slight_smile:
I must say that as an embedded system assembler language programmer (20 years ago…) I have used more than one unconditional jump !!! And that was good :stuck_out_tongue:


#8

He did it in hw:

;D ;D ;D


#9

Is that bad ?
As far as the pins are not used for anything else, there should be no risk, since this is High Impedance… and when the ports are not initialized, they are “high impedance” too.


#10

I was just kidding, man! ;D


#11

It’s greate we have hw guys like you. I hope we can lear a lot from you and give something in return


#12

Those assembler guys take everything so seriously :wink:


#13

:stuck_out_tongue:
Since I’m new here I was just worrying I did something that was discussed as evil in an earlier post :wink: !!


#14

thanks nicolas. I’ll go through the code later today, but from what I’m seeing it is the same as the dht22.


#15

I posted an updated driver on code.tinyclr.com :
http://code.tinyclr.com/project/289/dht11---temperature-and-humidity-sensor/


#16

I posted a specific driver for the DHT22 here : http://code.tinyclr.com/project/318/dht22-rht3---temperature-and-humidity-sensor/

I found out that the protocol between DHT11 and DHT22 is similar, however the data structure is different between the 2 sensors.


#17

Hi there,

as another bloody beginner, i get insane with reading the dht22.
Nicloas handy code reports not enought data from sensor - in fact i get not one byte.
I played with different resistors between pin1 and pin2 [0…10k], used caps from 0 to 100nF on pin1 and pin4, took 3.3 and 5V…

Could someone help me with that simple task?

thanks,
mark


#18

Hi Mark, welcome to the forums!

I suspect wiring - can you confirm what pins you’ve got the DHT22 connected to? Can you also show us the constructor?


#19

Thanks Brett!

sensor viewed from top, pin1 left - as the datasheet says.

wiring as described in http://www.tinyclr.com/forum/2/3978/#/1/msg37490

pin1 -> Vcc from panda2
pin2 -> to Di6 + Di7
pin3 -> n.c.
pin4 -> gnd

  • resistor & cap as i wrote above.

With nothing else connected to panda2 i run Nicolas code: http://www.tinyclr.com/forum/1/2835/#/1/msg27784
addapted to dht22: http://code.tinyclr.com/project/318/dht22-rht3---temperature-and-humidity-sensor/

Shame on me, that’s pretty simple, but i failed…


#20

Hi !

This is what I use here on 2 of my projects on a panda2:
pin 1 : to VCC 3.3V
pin 2 : to di30 and di32
pin3 : nc
pin4 : gnd

100nF condensator between pin 1 and 4 as close as possible to the sensor (important !)
1K resistor between pin2 and VCC, as close as possible to the sensor

di6 and di7 should be good as far as they are interrupt ports.
BE careful : ot to have another shield using di6 or di7 at the same time (as the ethernet shield for an example…).