I've generalized the DHT include file so it works with both the cheaper DHT11 sensor as well as the more precise DHT22 sensor. The header code is very well commented and also explains the two #DEFINEs used. Both of these devices are commonly available. The point is, thanks to conditional compilation, either one can be easily used with Great Cow Basic now.
I would like to see the include files rival the wide range available for Arduino, and contribute this as step in that direction. As usual, I'll attach the include file in the next post. In the meanwhile, here is a demo program showing the DHT11 in operation.
;Humidity/TemperatureSensordemousingDHT.Hincludefile.;ThomasHenry;Thisrevision:4/22/2014#include<DHT.H> ;DHT sensor include file;-----Settings#chip 16F88, 8 ;PIC16F88 running at 8 MHz#config mclr=off ;reset handled internally#config osc=int ;use internal clock;-----Constants#define DHT_type 11 ;define sensor type#define DHT_pin PortA.0 ;sensor on pin 17#define LCD_IO 4 ;4-bit mode#define LCD_RS PortB.2 ;LCD Register Select on pin 6#define LCD_Enable PortB.3 ;LCD Enable on pin 7#define LCD_DB4 PortB.4 ;DB4 on pin 8#define LCD_DB5 PortB.5 ;DB5 on pin 9#define LCD_DB6 PortB.6 ;DB6 on pin 10#define LCD_DB7 PortB.7 ;DB7 on pin 11#define LCD_NO_RW 1 ;ground the RW line on LCD#define degree 223 ;ASCII code for degree mark#define period 2 S ;update period;-----Variablesdimmsg,whole,tenthsasbytedimrh,cels,fahrasinteger;-----MainProgramdirportB0b00000000;PortBisalloutputclsprint"Initializing..."waitperiod;letunitstabilizedoreadDHT(rh,cels,fahr,msg);getcurrentvaluesclsselectcasemsgcase0:;allokay,soproceedprint"Humidity: ";printrelativehumidityprintrhprint"%"locate1,0;printtemperatureinCelsiusprint"C:"printcelsLCDWriteChardegree;printdegreemarkprint" "print"F:";printtemperatureinFahrenheitprintfahrLCDWriteChardegree;printdegreemarkcase1:;unitnotrespondingprint"No response..."case2:;checksumerrorprint"Bad checksum..."endselectwaitperiod;2secondsminbetweenreadingsloop;repeatinperpetuity
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
I integrated into my GLCD project in 30 seconds. Thank you.
See http://youtu.be/9hvy0fCvFDM for a demonstration. (This video will be uploaded at 2130 21 April 2014... Slow upload today.)
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
Anonymous
-
2014-04-24
That's a nice demo, Anobium. Displaying the data by means of a bar graph is a great idea--it gives a good idea of the trends. By the way, I was amazed at how rapidly the device responded to the humidity of your breath. That's not a bad sensor.
I keep forgetting to mention, if the sensor has been stored for a long period of time, it may need to be exposed to extremes to restore the full range. Put it in the shower room for a while, and then put it outside on a crisp fall day to get the full range of humidity from it. At least, that's what I've read. But my unit performs better than a commercial unit I have (and faster).
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
I did have some initial problems with it that took me considerable time to figure out. I'm using a 18F452 at 20 MHz. At first it kept producing very low values for both humidity and temperature. When I finally changed the variable DHT_byte from a BYTE to WORD everything worked perfectly.
Thanks for some really great software!
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
Anonymous
-
2014-06-22
Well, thank you very much. I'm glad you found it useful.
I'm really puzzled by your needing to promote DHT_byte to a word. That variable's only purpose in life is to roll in the 8 bits one by one. Is there something very different about the 18F452 that needs accounting for (compared to the 16F88 I used)?
Can anyone explain what MBB saw? The code is so short involving this variable it's hard to imagine why a word was needed.
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
@MBB. What version of the compiler are you using? Releases before May this year did have an issue where you may get variable corruption. This may be the answer.
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
I was using an older version but I have now tried it with the HOT RELEASE. The problem was the same. It did not work until I changed the variable DHT_byte from a BYTE to WORD.
This is my first time using the Hot Release and I had one problem with it. The first several dozen times I tried to program the PIC only part of the program worked. Then suddenly it started working.
I can now change between BYTE and WORD for the DHT_byte variable but it is accurate only when i make it a WORD variable. I've done this at least ten times
One more thing you should know is that I imported Thomas' DHT include file into my main program but I don't think that should make a difference.
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
I modified my code so it would use the DHT.h include file instead of including the DHT.h in the main body of the program.
I used the Hot Release version.
I still have the same problem. If DHT_byte is a byte I get checksum errors.
If I change it to word (inside the DHT.h file) I get very accurate readings.
Thanks. Can you post your code so I can compile. I will examine the ASM to figure out what is going on.
But, can you please change your loop.... do not use LOOP and GOTO LOOP. Use "Do forever" and "loop". Your use of loop may create an issue with the reserved word LOOP.
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
Sorry, I am not making my self clear. Package up all the code as a ZIP. Delete any code you need to hide but can you make sure it compiles and generates a hex file.
I can see already that you have changed a few variable but I think this is something about the definition of variable and the scope for those variables. You have defined variables "Dim DHT_rh, DHT_cels, DHT_fahr As integer" and these are defined when you call the sub routine (which I guess is the standard sub as I don't have it).
But, I am guessing without all the code.
Anobium
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
I have used the DHT.h include with several different processors and did not have to make any changes. I have operated it from 4 to 16MHz with no problems. However. the LCD will not operate with PIC16F1829 @ 32 MHz. due to timing problems in LCD.h, but that is another issue.
It is odd that changing the variable from byte to word makes the checksum error go away while keeping accuracy. It the reported humidity value actually correct? Has it been compared to a know good value?. If it is off by 10% how would you know ?
I suspect that this may be a timing related issue where an extra bit is being added and the data is shifted by one bit. I would look at the timing delays for the bit time counter in DHT.h
As I read the DHT-11 that I have here with a logic analyzer, The initial response bit is 88us, the spaces are 55us, a "low" is 24.3us and a "high" is 72.7us.
With the bit timer delay of 10 us, there is not much resolution and therefore not much room for error.
My suggestion is to change line 144 in DHT.h
..... From: if DHT_counter > 4 then ;long pulse is a 1
..... To: if DHT_counter > 5 then ;long pulse is a 1
If 5 doesn't work then try 3
William
Last edit: William Roth 2014-06-28
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
There believe there are some errors in the coding style, see https://sourceforge.net/p/gcbasic/discussion/579125/thread/0db03f8b/ which is an interesting discussion on the matter of variable scope. Defining the variables Dim DHT_rh, DHT_cels, DHT_fahr As integer when these are defined in the sub routine. You should try as shown in below, which I have taken from the first posting in this discussion.
';----- Variables
dim msg, whole, tenths as byte
dim rh, cels, fahr as integer'
Would you please try and let us know the result? And, would you please post the DHT.h file? I still cannot compile your code as you may have changed the .h file.
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
I tried your suggestions. I still have the same problem.
William Roth asked: It the reported humidity value actually correct? Has it been compared to a know good value?. If it is off by 10% how would you know ?
Good point. I have a store bought thermometer/RH device. My DHT11 matches it
within 1% for RH and 1 degree for temperature.
William suggested to change line 144 in DHT.h
..... From: if DHT_counter > 4 then ;long pulse is a 1
..... To: if DHT_counter > 5 then ;long pulse is a 1
If 5 doesn't work then try 3
I tried this with DHT_counter > 1, 2, 3, 4, 5, 6, 7, 8, 9, and 10. I got either
CHECKSUM or DID NOT RESPOND messages.
Anobium suggested trying:
';----- Variables
dim msg, whole, tenths as byte
dim rh, cels, fahr as integer'
I tried this but got the same results as I did with my original version.
Also, I couldn't find where the variables "whole" and "tenths" are used in DHT.h or
the first posting.
Anobium also asked me to post my DHT.h file.
This got me thinking that maybe my file was corrupted so I re-downloaded it
from the GCB site. But still have the same problem.
I posted the file below. You'll notice I changed:
dim DHT_counter, DHT_i, DHT_byte as byte
to this:
dim DHT_counter, DHT_i as byte
dim DHT_byte as word; * Changed from BYTE to WORD***
Good idea Thomas. I tried a 16F876 with it set as byte and IT WORKED! It also worked with it set as Word.
There must be something different with the 18F452.
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
Anonymous
-
2014-07-01
That is good news. Now, the variable in question only appears twice in the code:
DHT_byte = 2 * DHT_byte ;shift left one place
and
DHT_values(DHT_i) = DHT_byte ;store complete byte
So we now have to ask the experts what is different when either of these two lines is compiled for an 18F versus a 16F chip. Once we get an answer, then perhaps the include file could be updated to handle either type.
And something else just occurred to me. Has anybody tried this on an AVR chip yet?
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
I've generalized the DHT include file so it works with both the cheaper DHT11 sensor as well as the more precise DHT22 sensor. The header code is very well commented and also explains the two #DEFINEs used. Both of these devices are commonly available. The point is, thanks to conditional compilation, either one can be easily used with Great Cow Basic now.
I would like to see the include files rival the wide range available for Arduino, and contribute this as step in that direction. As usual, I'll attach the include file in the next post. In the meanwhile, here is a demo program showing the DHT11 in operation.
And here is the include file.
I have moved DHT.H to the current Code base. See https://sourceforge.net/p/gcbasic/code/HEAD/tree/GCBASIC/trunk/include
I have also updated the hardware page on the web site to point to these forum postings.
Thank you.
I will test asap. I have a new sensor and I will test soon. I will respond with the results.
With you permission I will lift into the Help File - if this is OK?
Works like a dream. Well done.
I integrated into my GLCD project in 30 seconds. Thank you.
See http://youtu.be/9hvy0fCvFDM for a demonstration. (This video will be uploaded at 2130 21 April 2014... Slow upload today.)
That's a nice demo, Anobium. Displaying the data by means of a bar graph is a great idea--it gives a good idea of the trends. By the way, I was amazed at how rapidly the device responded to the humidity of your breath. That's not a bad sensor.
I keep forgetting to mention, if the sensor has been stored for a long period of time, it may need to be exposed to extremes to restore the full range. Put it in the shower room for a while, and then put it outside on a crisp fall day to get the full range of humidity from it. At least, that's what I've read. But my unit performs better than a commercial unit I have (and faster).
Hi Thomas,
I just tried this and it works great.
I did have some initial problems with it that took me considerable time to figure out. I'm using a 18F452 at 20 MHz. At first it kept producing very low values for both humidity and temperature. When I finally changed the variable DHT_byte from a BYTE to WORD everything worked perfectly.
Thanks for some really great software!
Well, thank you very much. I'm glad you found it useful.
I'm really puzzled by your needing to promote DHT_byte to a word. That variable's only purpose in life is to roll in the 8 bits one by one. Is there something very different about the 18F452 that needs accounting for (compared to the 16F88 I used)?
Can anyone explain what MBB saw? The code is so short involving this variable it's hard to imagine why a word was needed.
An idea.
@MBB. What version of the compiler are you using? Releases before May this year did have an issue where you may get variable corruption. This may be the answer.
I was using an older version but I have now tried it with the HOT RELEASE. The problem was the same. It did not work until I changed the variable DHT_byte from a BYTE to WORD.
This is my first time using the Hot Release and I had one problem with it. The first several dozen times I tried to program the PIC only part of the program worked. Then suddenly it started working.
I can now change between BYTE and WORD for the DHT_byte variable but it is accurate only when i make it a WORD variable. I've done this at least ten times
One more thing you should know is that I imported Thomas' DHT include file into my main program but I don't think that should make a difference.
I recommend you post your code as a ZIP. This may help us understand as this is most strange as this code works great for me with no changes.
I modified my code so it would use the DHT.h include file instead of including the DHT.h in the main body of the program.
I used the Hot Release version.
I still have the same problem. If DHT_byte is a byte I get checksum errors.
If I change it to word (inside the DHT.h file) I get very accurate readings.
Here is my code:
;Chip Settings
#chip 18F452,20
#config OSC=HS
;Include files (Libraries)
#include <DHT.h>
;Defines (Constants)
#define LCD_IO 2
#define LCD_CB PORTC.1
#define LCD_DB PORTC.2
#define DHT_PIN PORTE.0; Temperture-Humidity Sensor
#define DHT_TYPE 11
;Variables
Dim DHT_rh, DHT_cels, DHT_fahr As integer
'
wait 1 s
Loop:
'
readDHT(DHT_rh, DHT_cels, DHT_fahr, DHT_error)
'
Locate 0, 0
Print DHT_rh
print "% Rel. Hum."
'
Locate 1, 0
print DHT_cels
LCDWriteChar 223
print "C"
'
locate 2, 0
print DHT_fahr
LCDWriteChar 223
print "F"
'
locate 3, 0
If DHT_error = 1 then
print " NO Response"
end if
'
If DHT_error = 2 then
print " CheckSum Error"
end if
'
wait 3 s
CLS
Goto Loop
'
Thanks. Can you post your code so I can compile. I will examine the ASM to figure out what is going on.
But, can you please change your loop.... do not use LOOP and GOTO LOOP. Use "Do forever" and "loop". Your use of loop may create an issue with the reserved word LOOP.
Here is the .ASM file.
Sorry, I am not making my self clear. Package up all the code as a ZIP. Delete any code you need to hide but can you make sure it compiles and generates a hex file.
I can see already that you have changed a few variable but I think this is something about the definition of variable and the scope for those variables. You have defined variables "Dim DHT_rh, DHT_cels, DHT_fahr As integer" and these are defined when you call the sub routine (which I guess is the standard sub as I don't have it).
But, I am guessing without all the code.
Anobium
Here it is.
I have used the DHT.h include with several different processors and did not have to make any changes. I have operated it from 4 to 16MHz with no problems. However. the LCD will not operate with PIC16F1829 @ 32 MHz. due to timing problems in LCD.h, but that is another issue.
It is odd that changing the variable from byte to word makes the checksum error go away while keeping accuracy. It the reported humidity value actually correct? Has it been compared to a know good value?. If it is off by 10% how would you know ?
I suspect that this may be a timing related issue where an extra bit is being added and the data is shifted by one bit. I would look at the timing delays for the bit time counter in DHT.h
As I read the DHT-11 that I have here with a logic analyzer, The initial response bit is 88us, the spaces are 55us, a "low" is 24.3us and a "high" is 72.7us.
With the bit timer delay of 10 us, there is not much resolution and therefore not much room for error.
My suggestion is to change line 144 in DHT.h
..... From: if DHT_counter > 4 then ;long pulse is a 1
..... To: if DHT_counter > 5 then ;long pulse is a 1
If 5 doesn't work then try 3
William
Last edit: William Roth 2014-06-28
There believe there are some errors in the coding style, see https://sourceforge.net/p/gcbasic/discussion/579125/thread/0db03f8b/ which is an interesting discussion on the matter of variable scope. Defining the variables Dim DHT_rh, DHT_cels, DHT_fahr As integer when these are defined in the sub routine. You should try as shown in below, which I have taken from the first posting in this discussion.
Would you please try and let us know the result? And, would you please post the DHT.h file? I still cannot compile your code as you may have changed the .h file.
I tried your suggestions. I still have the same problem.
William Roth asked: It the reported humidity value actually correct? Has it been compared to a know good value?. If it is off by 10% how would you know ?
William suggested to change line 144 in DHT.h
..... From: if DHT_counter > 4 then ;long pulse is a 1
..... To: if DHT_counter > 5 then ;long pulse is a 1
If 5 doesn't work then try 3
Anobium suggested trying:
dim msg, whole, tenths as byte
dim rh, cels, fahr as integer'
I tried this but got the same results as I did with my original version.
Also, I couldn't find where the variables "whole" and "tenths" are used in DHT.h or
the first posting.
Anobium also asked me to post my DHT.h file.
from the GCB site. But still have the same problem.
I posted the file below. You'll notice I changed:
dim DHT_counter, DHT_i, DHT_byte as byte
to this:
dim DHT_counter, DHT_i as byte
dim DHT_byte as word; * Changed from BYTE to WORD***
Here's the .gcb file I'm using.
MBB, do you have a 16F PIC you could try instead? This might be the fastest way to eliminate one possibility.
Good idea Thomas. I tried a 16F876 with it set as byte and IT WORKED! It also worked with it set as Word.
There must be something different with the 18F452.
That is good news. Now, the variable in question only appears twice in the code:
So we now have to ask the experts what is different when either of these two lines is compiled for an 18F versus a 16F chip. Once we get an answer, then perhaps the include file could be updated to handle either type.
And something else just occurred to me. Has anybody tried this on an AVR chip yet?
I had the same problem with PIC18F25K80. The problem was solved by changing the line that shifts the data bits.
Original Line: DHT_byte = 2 * DHT_byte
Change to :
DHT_byte = DHT_Byte * 2
For some reason (that I did not investigate further) it seems that the order of the math to shift the bit makes a difference on some chips.
In any case, to shift a bit using multiplication it is more common to use byte x 2 than 2 x byte. Suggest you change the DHT.h file accordingly.
This may be something that needs to be investigated further.
Both chips that had the problem were PIC18. All PIC18 chips have an
8 x 8 hardware multiplier. This may or may not be relevant.
Last edit: William Roth 2014-07-30
Good find William!
I tried your suggestion and it worked. Now the DHT_byte works as a byte variable.
There must be something different about the 18F series.