Generalized DHT Humidity/Temperature Include File

2014-04-23
2014-08-25
1 2 > >> (Page 1 of 2)
  • Thomas Henry
    Thomas Henry
    2014-04-23

    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/Temperature Sensor demo using DHT.H include file.
    ;Thomas Henry
    ;This revision: 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
    
    ;----- Variables
    
    dim msg, whole, tenths as byte
    dim rh, cels, fahr as integer
    
    ;----- Main Program
    
    dir portB 0b00000000                ;Port B is all output
    
    cls
    print "Initializing..."
    wait period                         ;let unit stabilize
    
    do
      readDHT(rh, cels, fahr, msg)      ;get current values
      cls  
      select case msg
        case 0:                         ;all okay, so proceed
          print "Humidity: "            ;print relative humidity
          print rh
          print "%"
    
          locate 1,0                    ;print temperature in Celsius
          print "C:"
          print cels
          LCDWriteChar degree           ;print degree mark
          print " "
    
          print "F:"                    ;print temperature in Fahrenheit
          print fahr
          LCDWriteChar degree           ;print degree mark
        case 1:                         ;unit not responding
          print "No response..."
        case 2:                         ;checksum error
          print "Bad checksum..."
      end select
      wait period                       ;2 seconds min between readings
    loop                                ;repeat in perpetuity
    
     
  • Thomas Henry
    Thomas Henry
    2014-04-23

    And here is the include file.

     
    Attachments
  • Anobium
    Anobium
    2014-04-23

    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?

     
  • Anobium
    Anobium
    2014-04-23

    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.)

     
  • Thomas Henry
    Thomas Henry
    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).

     
  • MBB
    MBB
    2014-06-22

    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!

     
  • Thomas Henry
    Thomas Henry
    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.

     
  • Anobium
    Anobium
    2014-06-23

    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.

     
  • MBB
    MBB
    2014-06-27

    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.

     
  • Anobium
    Anobium
    2014-06-27

    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.

     
  • MBB
    MBB
    2014-06-28

    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

    '

     
  • Anobium
    Anobium
    2014-06-28

    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.

     
  • MBB
    MBB
    2014-06-28

    Here is the .ASM file.

     
  • Anobium
    Anobium
    2014-06-28

    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

     
  • MBB
    MBB
    2014-06-28

    Here it is.

     
    Attachments
  • William Roth
    William Roth
    2014-06-28

    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
  • Anobium
    Anobium
    2014-06-29

    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.

     
  • MBB
    MBB
    2014-06-30

    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***

     
    Attachments
  • MBB
    MBB
    2014-06-30

    Here's the .gcb file I'm using.

     
  • Thomas Henry
    Thomas Henry
    2014-07-01

    MBB, do you have a 16F PIC you could try instead? This might be the fastest way to eliminate one possibility.

     
  • MBB
    MBB
    2014-07-01

    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.

     
  • Thomas Henry
    Thomas Henry
    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?

     
  • William Roth
    William Roth
    2014-07-30

    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
  • MBB
    MBB
    2014-08-05

    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.

     
1 2 > >> (Page 1 of 2)