Hi All

This might just be the solution everyone has been looking for - to be able to read the DHT11 / 22 humidity and temperature without any extra hardware like 555 timers. Just software - and all the way down to 16MHz. (Correction - not to 16MHz - external resonator fixes freq to 4 x resonator - see Technical post below)

To be fair to everyone else who has put loads of time into this, the solution has already been published several times but always with a timing / reliability / need for repeat readings / need for hardware support caveat.

All the pulsin C.2, 1, @bptrinc based solutions are correct. However, the key items that I haven't seen brought together anywhere before are :-

1 The DHT11 / 22 appear to have a quirk that demands a hard pull up at the end of the 18mS intialisation pulse (Credits to Craig Ringer's "Beware of Soapy Frogs" blog for this tip)

2 It only works on a PICAXE with external resonator - limiting it to a 28X2 or a 40X2. It will not work on any PICAXE that I've tried by using the internal resonator - so that lets out all the M2 / M2+ series - and lets out the 28X2 / 40X2 on setfreq mxx for the internal resonator. Must be external resonator to work.

3 Reliable detection of the end of the DHT acknowledgement - the 80uS low followed by 80uS high before sending data - so that the PICAXE can be synchronised to the start of the series of data pulses.

Note - The DHT11 datasheet is incorrect. It states that RH and T are in the 2nd and 4th bytes respectively. The DHT11 I have returns an integer value for each in the 1st and 3rd bytes. Bytes 2 and 4 are all zeros.

The solution is as follows :-

1 Choose a 28X2 or 40X2 based PICAXE board. I used the AXE401 Shield Base.

2 Fit a 16MHz external resonator

3 Use ports C.1 and C.2. C1 provides the 18mS DHT initialisation pulse and is then set to be an input. C.2 is an input only with the pulsin command behind it. It appears that the PICAXE takes some time to turn an output into an input hence the need for 2 ports. Using just one port failed to read any data.

4 Use the code below - which is the test software I used with the simple read out into Debug. I don't use any of the bx registers so it makes for an easy read in Debug.

ReadDHT2:

high C.1 'set port 1 high

let bptr = 0

' *************************************

' ***** Sensor Driver - read data *****

' *************************************

ReadSensor2:

input C.2 'Data in - make c.2 an input - 5k resistor pull up

setfreq em64 'Have to use em64 due to ext resonator = 16MHz. Can not use m16 etc internal resonator settings 'See Technical post below

'PICAXE Request To Send data

pulsout C.1,18000 'c.1 = low for 18mS (0.625uS / unit at 64MHz = 11.25mS)

input C.1

'RTSLow: if pinC.2 = 1 then goto RTSLow '(80uS) - Too slow so don't use this approach

'Ignore DHT 80uS low response, wait for high pulse, count it, store in b0 just for fun, start data store from b1

pulsin C.2, 1,@bptrinc 'wait for DHT rising edge - (80uS) DHT DSR then move on

'Having asked sensor for data then poll pin as fast as poss and store result

'RH1 'Inter data pulse 50uS = 80 (which doesn't show up on Debug)

pulsin C.2, 1,@bptrinc 'rising edge = start of 1st data pulse = bit 7 of RH Integer

pulsin C.2, 1,@bptrinc 'should be about 43 (27uS) for a 0 and 112 (70uS) for a 1 @ 64MHz - or any clock speed down to 16MHz

pulsin C.2, 1,@bptrinc

pulsin C.2, 1,@bptrinc 'Note instead of @bptrinc I also used direct write to a b register e.g. b4 for this line. Works just as well.

pulsin C.2, 1,@bptrinc

pulsin C.2, 1,@bptrinc

pulsin C.2, 1,@bptrinc

pulsin C.2, 1,@bptrinc

'RH2

pulsin C.2, 1,@bptrinc

pulsin C.2, 1,@bptrinc

pulsin C.2, 1,@bptrinc

pulsin C.2, 1,@bptrinc

pulsin C.2, 1,@bptrinc

pulsin C.2, 1,@bptrinc

pulsin C.2, 1,@bptrinc

pulsin C.2, 1,@bptrinc

'T1

pulsin C.2, 1,@bptrinc

pulsin C.2, 1,@bptrinc

pulsin C.2, 1,@bptrinc

pulsin C.2, 1,@bptrinc

pulsin C.2, 1,@bptrinc

pulsin C.2, 1,@bptrinc

pulsin C.2, 1,@bptrinc

pulsin C.2, 1,@bptrinc

'T2

pulsin C.2, 1,@bptrinc

pulsin C.2, 1,@bptrinc

pulsin C.2, 1,@bptrinc

pulsin C.2, 1,@bptrinc

pulsin C.2, 1,@bptrinc

pulsin C.2, 1,@bptrinc

pulsin C.2, 1,@bptrinc

pulsin C.2, 1,@bptrinc

'Checksum

pulsin C.2, 1,@bptrinc

pulsin C.2, 1,@bptrinc

pulsin C.2, 1,@bptrinc

pulsin C.2, 1,@bptrinc

pulsin C.2, 1,@bptrinc

pulsin C.2, 1,@bptrinc

pulsin C.2, 1,@bptrinc

pulsin C.2, 1,@bptrinc

setfreq m4

return

Have passed a copy of this lot to Rev-Ed for their review, so they are aware of the internal / external resonator quirk.

If anyone has any insight into the differences between the internal / external resonator operation that would be very interesting.

Otherwise - please enjoy

Bob

Edit 1 - 17/10/12 - updates following Technical response below

This might just be the solution everyone has been looking for - to be able to read the DHT11 / 22 humidity and temperature without any extra hardware like 555 timers. Just software - and all the way down to 16MHz. (Correction - not to 16MHz - external resonator fixes freq to 4 x resonator - see Technical post below)

To be fair to everyone else who has put loads of time into this, the solution has already been published several times but always with a timing / reliability / need for repeat readings / need for hardware support caveat.

All the pulsin C.2, 1, @bptrinc based solutions are correct. However, the key items that I haven't seen brought together anywhere before are :-

1 The DHT11 / 22 appear to have a quirk that demands a hard pull up at the end of the 18mS intialisation pulse (Credits to Craig Ringer's "Beware of Soapy Frogs" blog for this tip)

2 It only works on a PICAXE with external resonator - limiting it to a 28X2 or a 40X2. It will not work on any PICAXE that I've tried by using the internal resonator - so that lets out all the M2 / M2+ series - and lets out the 28X2 / 40X2 on setfreq mxx for the internal resonator. Must be external resonator to work.

3 Reliable detection of the end of the DHT acknowledgement - the 80uS low followed by 80uS high before sending data - so that the PICAXE can be synchronised to the start of the series of data pulses.

Note - The DHT11 datasheet is incorrect. It states that RH and T are in the 2nd and 4th bytes respectively. The DHT11 I have returns an integer value for each in the 1st and 3rd bytes. Bytes 2 and 4 are all zeros.

The solution is as follows :-

1 Choose a 28X2 or 40X2 based PICAXE board. I used the AXE401 Shield Base.

2 Fit a 16MHz external resonator

3 Use ports C.1 and C.2. C1 provides the 18mS DHT initialisation pulse and is then set to be an input. C.2 is an input only with the pulsin command behind it. It appears that the PICAXE takes some time to turn an output into an input hence the need for 2 ports. Using just one port failed to read any data.

4 Use the code below - which is the test software I used with the simple read out into Debug. I don't use any of the bx registers so it makes for an easy read in Debug.

ReadDHT2:

high C.1 'set port 1 high

let bptr = 0

' *************************************

' ***** Sensor Driver - read data *****

' *************************************

ReadSensor2:

input C.2 'Data in - make c.2 an input - 5k resistor pull up

setfreq em64 'Have to use em64 due to ext resonator = 16MHz. Can not use m16 etc internal resonator settings 'See Technical post below

'PICAXE Request To Send data

pulsout C.1,18000 'c.1 = low for 18mS (0.625uS / unit at 64MHz = 11.25mS)

input C.1

'RTSLow: if pinC.2 = 1 then goto RTSLow '(80uS) - Too slow so don't use this approach

'Ignore DHT 80uS low response, wait for high pulse, count it, store in b0 just for fun, start data store from b1

pulsin C.2, 1,@bptrinc 'wait for DHT rising edge - (80uS) DHT DSR then move on

'Having asked sensor for data then poll pin as fast as poss and store result

'RH1 'Inter data pulse 50uS = 80 (which doesn't show up on Debug)

pulsin C.2, 1,@bptrinc 'rising edge = start of 1st data pulse = bit 7 of RH Integer

pulsin C.2, 1,@bptrinc 'should be about 43 (27uS) for a 0 and 112 (70uS) for a 1 @ 64MHz - or any clock speed down to 16MHz

pulsin C.2, 1,@bptrinc

pulsin C.2, 1,@bptrinc 'Note instead of @bptrinc I also used direct write to a b register e.g. b4 for this line. Works just as well.

pulsin C.2, 1,@bptrinc

pulsin C.2, 1,@bptrinc

pulsin C.2, 1,@bptrinc

pulsin C.2, 1,@bptrinc

'RH2

pulsin C.2, 1,@bptrinc

pulsin C.2, 1,@bptrinc

pulsin C.2, 1,@bptrinc

pulsin C.2, 1,@bptrinc

pulsin C.2, 1,@bptrinc

pulsin C.2, 1,@bptrinc

pulsin C.2, 1,@bptrinc

pulsin C.2, 1,@bptrinc

'T1

pulsin C.2, 1,@bptrinc

pulsin C.2, 1,@bptrinc

pulsin C.2, 1,@bptrinc

pulsin C.2, 1,@bptrinc

pulsin C.2, 1,@bptrinc

pulsin C.2, 1,@bptrinc

pulsin C.2, 1,@bptrinc

pulsin C.2, 1,@bptrinc

'T2

pulsin C.2, 1,@bptrinc

pulsin C.2, 1,@bptrinc

pulsin C.2, 1,@bptrinc

pulsin C.2, 1,@bptrinc

pulsin C.2, 1,@bptrinc

pulsin C.2, 1,@bptrinc

pulsin C.2, 1,@bptrinc

pulsin C.2, 1,@bptrinc

'Checksum

pulsin C.2, 1,@bptrinc

pulsin C.2, 1,@bptrinc

pulsin C.2, 1,@bptrinc

pulsin C.2, 1,@bptrinc

pulsin C.2, 1,@bptrinc

pulsin C.2, 1,@bptrinc

pulsin C.2, 1,@bptrinc

pulsin C.2, 1,@bptrinc

setfreq m4

return

Have passed a copy of this lot to Rev-Ed for their review, so they are aware of the internal / external resonator quirk.

If anyone has any insight into the differences between the internal / external resonator operation that would be very interesting.

Otherwise - please enjoy

Bob

Edit 1 - 17/10/12 - updates following Technical response below

Last edited by a moderator: