I'm glad it worked for you.
There were 3 areas I looked at to try to make it work.
1. The sensor will send a "0" as a High pulse between 26us to 28us long, and a "1" as a High for 70us long.
The original code was designed for a 20MHz PIC, so the PulsIn would return the pulsewidth in 2us increments.
Your PIC 18F4580 was running at 40MHz so we needed to adjust the dht value test to accommodate the fact that PulsIn command was now returning the pulsewidth in 1us increments.
The PulsIn command uses the PICs frequency to set the resolution level recorded into the variable.
The way this works is with this formula: Resolution (us) = (1/(Fosc/4)) * 10
For a 40Mhz OSC this would be: Res = (1/(40000000/4)) * 10 = (1/10000000) * 10 = (.0000001) * 10 = .000001 or 1us.
So this means that the value in the PulsIn variable will be a count of 1us increments.
The original code was testing for a zero by checking if the dht value was =>9 and <=21.
With a 20MHz osc, this would would mean the "9" would be "9*2us = 18us" and the "21" would be "21*2us=42us", which would be close. (=>18 and <=42 us)
With your 40MHz osc, it would be testing for 9*1us and 21*1us, which would not be correct (=>9 and <=21 us).
2. With item 1 above and the fact that I "Zeroed" the "hum" variable before loading the bits into it from "dht", I simply tested for a "1" value from the sensor.
"if dht(x)>=35 then hum.0[j] = 1"
I chose "35us" since it is a value greater than a "0" value from the sensor (26-28us) and it is 1/2 of a "1" value from the sensor (70us).
3. The sensor's initialization sequence that is defined in the datasheet you attached plus the DHT C library pushed me to make changes to the initialization sequence in the PBP program.
I would also change the following line of code from "if dht < 9 then goto badresponse" to "if dht < 20 then goto badresponse"., given the 40MHz Osc.
I commented the code below to help describe what is happening.
Code:
hum var word 'Holds final 16bit Humidity value (integral and decimal)
j var byte
x var byte
read_dht:
TRISA.1 = 0 ' Make pin an input
'**Intialization sequence to sensor**
high dht_data '250ms High on data pin to sensor
pause 250
low dht_data '20ms Low on data pin to sensor
pause 20 ' send 20ms low
high dht_data '40us High
pauseus 40
'Read the sensor's acknowledgment of init sequence
PulsIn PORTA.1, 1, dht 'Read a High pulse from the sensor data line
if dht < 20 then goto badresponse 'Not a good signal, maybe noise? Change this to < 20
'**End of Initialization sequence"
'**Load the data from the sensor into the dht byte array
for x = 31 to 0 step-1
PulsIn PORTA.1, 1, dht[x] 'Read 32 High pulses (bits) from the sensor and store them as pulsewidth counts in individual bytes in the dht byte array.
next x
'**End of Load Data**
hum = 0 'Clear hum word variable which holds the final 16bit humidity value
'**Convert the dht byte array to a 16bit word variable
'Stuff values into hum word variable based on the pulsewidth value in dht byte array
'Use "hum.0(j)" to select a specific bit position in the hum word variable.
'0.[j] is treated as an bit-offset into the hum variable. E.g. 0.[0] = hum.0, 0.[1] = hum.0+1, 0.[2] = hum.0+2, etc
j = 15 'Used to select the correct bit in the hum word variable
for x = 31 to 16 step - 1 'Read the 16 bytes for humidity in the dht byte array (humidity pulsewidth values)
if dht(x)>=35 then hum.0[j] = 1 'If the pulsewidth is => 35us then the value is a "1".
'otherwise, the value is a "0", so we do not need to do anything, all bits in "hum" were initialized to "0" with "hum = 0"
j = j - 1
next x
'**End Conversion**
'**Display the result**
'Send the ascii code that is the decimal representation of the humidity, "dec" modifier.
'The 16bit hum variable includes both the integral and 1 digit decimal for the humidity (e.g. hum = 311 = 31.1 %RH).
'So we need to display the value correctly by dividing the value by 10 (integral) and then displaying the decimal portion using the modulo "//" function.
LCDOut $FE,$80+9,"RH ",dec hum/10, "." dec hum //10
Hope this helps.
Bookmarks