Serial Comms and Crystals


Closed Thread
Results 1 to 40 of 43

Hybrid View

  1. #1
    Join Date
    Jan 2013
    Location
    Texas USA
    Posts
    229


    Did you find this post helpful? Yes | No

    Default Re: Serial Comms and Crystals

    As Richard has stated, the DHT11 doesn't seem to be too accurate in his experience.

    As far as your readings go 39 00 16 23

    This is 35% RH and 22c Temp.

    Just use dht[4] for RH and dht[2] for Temp.
    Regards,
    TABSoft

  2. #2
    Join Date
    Oct 2009
    Posts
    583


    Did you find this post helpful? Yes | No

    Default Re: Serial Comms and Crystals

    Thanks guys - I'll look at getting a DH22 as I need something more precise given that this will be monitoring the humidity in my snakes enclosure.

  3. #3
    Join Date
    Jan 2013
    Location
    Texas USA
    Posts
    229


    Did you find this post helpful? Yes | No

    Default Re: Serial Comms and Crystals

    Hi Richard,

    I was wondering if you could help me understand your use of Timer2 in this project during the read loop for the 40 bits from the DHT11.

    In this section of code.....
    " t2con=6
    while ( dht_data)
    wend
    t2con=0
    if ((tmr2>12)&&(tmr2<50)) then ' noise ?
    if (tmr2 >31 ) then
    dht.0[bits] = 1
    endif
    else
    goto badread ' noise ?
    endif"

    I see that Timer2 is turned on with the Prescaler set to 16.
    Then after the data line drops to 0, Timer2 is stopped.

    Then the TMR2 register is tested for its count value.
    If the count is less than 12 or greater than 50, then it's a bad read.
    Otherwise if the count is greater than 31 and less than 50 the bit is a 1.
    Is this correct?

    If the Fosc is 40Mhz and Timer2 counts at Fosc/4 and the Timer2 Prescaler is 16.
    Then
    Would the test "((tmr2>12)&&(tmr2<50))" equate to
    If count is greater than 19.2us and less than 80us?

    And then would the test "(tmr2 >31 )" equate to
    If count is greater than 49.6us?

    Which I think the test logic would translate to...
    If the count is less than 19.2us or greater than 80us then it's a bad read.
    Otherwise if the count is greater than 49.6us and less than 80us the bit is a 1.

    I think this is right, but please let me know if not.
    Just trying to understand how it is implemented.

    Thanks
    Regards,
    TABSoft

  4. #4
    Join Date
    May 2013
    Location
    australia
    Posts
    2,666


    Did you find this post helpful? Yes | No

    Default Re: Serial Comms and Crystals

    Which I think the test logic would translate to...
    If the count is less than 19.2us or greater than 80us then it's a bad read.
    Otherwise if the count is greater than 49.6us and less than 80us the bit is a 1.
    that's it although a '0' is 26-28uS and a 1 is 70us according to the data sheet I have added some tolerance (this helps if interrupts are involved) if the count is outside this range then its not right and the process is abandoned , this test is not strictly necessary and could be omitted

    the 1/0 test is basically centered in between the 1 and the 0 times ie 50 is halfway between 30 and 70 once again to add some tolerance . if less than halfway its a 0 otherwise a 1


    there is some risk in this method in that hangs are possible if the dht responds in an unforseen manner . in my production version the tmrx int is enabled and if it is triggered then the process is also aborted to recover from such a sensor hang .

  5. #5
    Join Date
    Oct 2009
    Posts
    583


    Did you find this post helpful? Yes | No

    Default Re: Serial Comms and Crystals

    Tabsoft / Richard,

    I've incorporated the code below into my main program and whilst it runs fine, it does flash up a fair few "bad read" errors. Is there anything I could tweak to reduce these occurancies

    Code:
    read_dht:
     for bits=4 to 0 step-1 
     dht[bits]=0 
     next
     
     tmr2=0
     dht_dir=0
     dht_data=0
     pause 18 'start it up
     dht_data=1
     pauseus 30
     dht_dir=1
     pauseus 40 'wait till middle of response pulse window
     if ( dht_data)then goto badresponse 'no response then give up
     while (!dht_data)
     wend 
     t2con=6
     while ( dht_data) 
     wend 
     t2con=0
     if ((tmr2 <45)||(tmr2>55))then goto badpresence ' confirm presence ?
     for bits =39 to 0 step -1
     tmr2=0
     while (!dht_data) 
     wend 
     t2con=6
     while ( dht_data) 
     wend 
     t2con=0
     if ((tmr2>12)&&(tmr2<50)) then ' noise ?
     if (tmr2 >31 ) then
     dht.0[bits] = 1 
    
     endif 
    
     else
     goto badread ' noise ?
     endif
     next 
     crc=0 
     for bits=1 to 4 
     crc=crc+ dht[bits]
     next
     if crc != dht[0] then goto badcrc 'crc
    
     return
    
     badread:
     LCDOut $FE,$94 +8,"Bad read"
     pause 1000
     LCDOut $FE,$94 +8,"        "
     ' next
     return
     badcrc:
     for bits=4 to 0 step-1 
     LCDOut $FE,$94 +16,hex dht[bits],"," 
    pause 1000
     next 
     return
    badresponse:
     LCDOut $FE,$94+8,"No Response"
     return
    
    badpresence:
     LCDOut $FE,$d4,"pr",#tmr2
     return

  6. #6
    Join Date
    May 2013
    Location
    australia
    Posts
    2,666


    Did you find this post helpful? Yes | No

    Default Re: Serial Comms and Crystals

    does your program use interrupts ? if so how long does the isr take to execute ?
    the tolerance here is 10uS + or - so an interrupt can easily cause the timing tolerance to be exceeded
    possible solutions
    1. disable interrupts during dht read
    2. increase tolerance
    3. ignore bad reading and retry
    4. remove the noise test
    Code:
    t2con=0
     
    if ((tmr2>12)&&(tmr2<50)) then ' noise ?
     if (tmr2 >31 ) then
     dht.0[bits] = 1 
    
     endif 
    
     else
     goto badread ' noise ?
    
     endif
    5. use a faster chip

  7. #7
    Join Date
    Jan 2013
    Location
    Texas USA
    Posts
    229


    Did you find this post helpful? Yes | No

    Default Re: Serial Comms and Crystals

    To get a better understanding what is going on, why don't you make a small change for debugging.

    Instead of this...
    Code:
    for bits =39 to 0 step -1
        tmr2=0
        while (!dht_data) 
        wend 
        t2con=6
        while ( dht_data) 
        wend 
        t2con=0
        if ((tmr2>12)&&(tmr2<50)) then ' noise ?
            if (tmr2 >31 ) then
                dht.0[bits] = 1 
            
            endif 
        
        else
            goto badread ' noise ?
        endif
    next
    Do this instead...
    Code:
     
     for bits =39 to 0 step -1
         tmr2=0
         while (!dht_data) 
         wend 
         t2con=6
         while ( dht_data) 
         wend 
         t2con=0
         if tmr2 <= 12 then goto tooshort
         if tmr2 => 50 then goto toolong
         if (tmr2 >31 ) then
            dht.0[bits] = 1 
         endif 
    
     next
    Then create the 2 subs, tooshort and toolong and have each print a different error message.
    Regards,
    TABSoft

Similar Threads

  1. PC Serial comms
    By Bill Legge in forum Serial
    Replies: 7
    Last Post: - 13th December 2009, 23:37
  2. Simple Serial Comms.
    By koossa in forum mel PIC BASIC Pro
    Replies: 1
    Last Post: - 23rd November 2007, 08:12
  3. Some comments on serial comms please.
    By muddy0409 in forum Schematics
    Replies: 1
    Last Post: - 15th June 2007, 09:53
  4. Serial Comms Buffer?
    By koossa in forum mel PIC BASIC Pro
    Replies: 5
    Last Post: - 2nd December 2005, 01:29
  5. Serial comms / Bootloader
    By koossa in forum mel PIC BASIC Pro
    Replies: 14
    Last Post: - 30th October 2005, 18:48

Members who have read this thread : 0

You do not have permission to view the list of names.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts