Menu

DS18B20 "readtemp12" is only 9 bit?

2020-04-13
2020-04-17
  • James Whyte

    James Whyte - 2020-04-13

    RESOLVED - THE DS18B20 LIBRARY HAS BEEN UPDATED TO SUPPORT THE SETTING OF THE OPERATING RESOLUTION. See https://github.com/Anobium/Great-Cow-BASIC-Help/blob/master/source/ds18b20setresolution.adoc

    Original post follows.


    I am using the DS18B20 for some temperature readings.
    I am using (I think) the standard example code (see below).
    However I only seem to be getting 0.5 Deg resolution from readtemp12
    Looking at the Raw read for DSdata shows it in steps of 8, i.e
    192 = 12.0
    200 = 12.5
    208 = 13.0

    Am I missing something? or is my DS18B20 a cheap knock off without true 12bit?
    I don't understand the code in DS18B20.h well enough to see where the resolution is set.
    If someone can confirm they have been getting 12bit reads that would help, or I will need to dig deeper.

    • Thanks
    Sub GET_DS18B20
    
    ' The function readtemp12 returns the raw value of the sensor.
           ' The sensor is read as a 12 bit value therefore each unit equates to 0.0625 of a degree
           DSdata = readtemp12
           HSerPrint DSdata
           HSerPrint ","
           DS18B20_SIGNBIT = DSdata / 256 / 128
           If DS18B20_SIGNBIT = 0 Then
            goto Positive
           end if
           ' its negative!
           DSdata = ( DSdata # 0xffff ) + 1 ' take twos comp
        Positive:
           ' Convert value * 0.0625. Mulitple value by 6 then add result to multiplication of the value with 25 then divide result by 100.
           DS18B20_TempC_100 =  DSdata * 6
           DSdata = ( DSdata * 25 ) / 100
           DS18B20_TempC_100 = DS18B20_TempC_100 + DSdata
    
           DS18B20_WHOLE = DS18B20_TempC_100 / 100  ;Get Whole number part
           DS18B20_FRACT = DS18B20_TempC_100 % 100  ;Get remainder or decimal
    
           If DS18B20_SIGNBIT = 0 Then
            goto DisplayTemp
           end if
    
           hserprint "-"
        DisplayTemp:
           hserprint str(DS18B20_WHOLE)
           hserprint "."
          ' To ensure the decimal part is two DS18B20_DIGits
           DS18B20_DIG = DS18B20_FRACT / 10
           hserprint DS18B20_DIG
           DS18B20_DIG = DS18B20_FRACT % 10
           hserprint DS18B20_DIG
           hserprint "C"
           HSerSend 13
    
    end sub
    
     

    Last edit: Anobium 2020-04-16
  • Anobium

    Anobium - 2020-04-14

    Hi.

    The library sets a global integer variable called DSDATA. Calling DS18B20DeviceRead() will aslo set the DSDATA varialbe. That is a raw read of the IC.

    The example code simply converts the raw data in to strings for display. In the format of Wholenumber.Decimalnumber.

    Therefore, it is a simple change to this code to display greater accurancy. To ensure the decimal part is two DS18B20_DIGits

         hserprint str(DS18B20_WHOLE)
           hserprint "."
          ' To ensure the decimal part is two DS18B20_DIGits
           DS18B20_DIG = DS18B20_FRACT / 10
           hserprint DS18B20_DIG
           DS18B20_DIG = DS18B20_FRACT % 10
           hserprint DS18B20_DIG
           hserprint "C"
           HSerSend 13
    

    So, start after these lines of code shown below. As as this point DS18B20_TempC_100 is set per Table 1 in the DS18B20 datasheet.

      Convert value * 0.0625. Mulitple value by 6 then add result to multiplication of the value with 25 then divide result by 100.
       DS18B20_TempC_100 =  DSdata * 6
    

    Summary... the example code displays a two digit decimale temperature. You need to adapt to show a higher resolution using DS18B20_TempC_100 as your starting point.

    Anobium

     
    • Anobium

      Anobium - 2020-04-14

      I did not write the DS18B20 library, but, there is chance that the DS18B20 is not operating in the default 12bit mode. But, if the temperature is correct (apart from the displayed resolution) then it will be operating in the default 12bit mode.

      I have just hooked up the Training Video 16 (recent YouTube video) and at about 25C I got a value of 402 for DSData, and ( 404 * 0.0625 ) =25.25C... so, if that value was return as 405 that would be calcaulated as 25.3125C

      So, I think the read is correct. This is just a display formatting thing to be fixed.

       
  • James Whyte

    James Whyte - 2020-04-14

    Yes, it does display a 2 digit decimal, but it is only 9Bit resolution or 0.5 Deg increments
    I am only seeing the DSdata Raw in steps of 8;
    192 = 12.00
    200 = 12.50
    208 = 13.00

    How is R1 and R2 set for 12bit results as per datasheet Table 2?
    I may have missed it, but I can't see any setup for 12bit in DS18B20.h

     
  • Anobium

    Anobium - 2020-04-14

    The core is the display and factorisation.

    So, focus on the following.

    ' Convert value * 0.0625. Mulitple value by 6 then add result to multiplication of the value with 25 then divide result by 100.
           DS18B20_TempC_100 =  DSdata * 6
    

    The mutliple by 6 is the constraint. Make that 625 to fully factorise. Where TempC_100 will need to be change to a LONG.

       TempC_100 =  DSdata * 625
       DSdata = DSdata / 100
       TempC_100 = TempC_100 + DSdata
    

    Now TempC_100 is now factorised to cater. Remember we using integer maths.

    So, old calc v new calc

    OLD = a value 191 = yielded 1193. Factor was 100 therefore 11.93
    NEW = a value of 191 = now yields 119376. Factor 10000 therefore 11.9376

    So, now you have to show (I think - untested)

           DS18B20_WHOLE = DS18B20_TempC_100 / 10000  ;Get Whole number part
           DS18B20_FRACT = DS18B20_TempC_100 % 10000  ;Get remainder or decimal
    
     
  • James Whyte

    James Whyte - 2020-04-14

    Yes, quite right... There is nothing wrong with the Math or method.
    The problem is can not get a raw value of 191. it is in steps of 8.
    A rising temperature will only give steps of Raw value;
    186 = 11.50
    192 = 12.00
    200 = 12.50

    A Raw value of 191 for example never occurs.

    I will dig through DS18B20.h some more, get my head around that and see if I can set the resolution according to the datasheet.
    I think for now I will take it as the problem is my device's default settings, rather than a problem with the example code
    -Thanks

     
    • Anobium

      Anobium - 2020-04-14

      It could be that your device is in 9-bit mode... but, I would try the code I posted that displays to 4 decimal places.

       
  • Anobium

    Anobium - 2020-04-14

    It is not a library issue.

    Let me knock up the code.

     
  • Anobium

    Anobium - 2020-04-14

    Here you go. Larger factorisation meant I had to change some of the variables from bytes to words, and the formatting of the decimal needed to left padded.

    Evan

    #chip 16f18313
    #config MCLR=ON
    #option Explicit
    #include <ds18b20.h>
    
        'Generated by PIC PPS Tool for Great Cow Basic
        'PPS Tool version: 0.0.6.1
        'PinManager data: v1.79.0
        'Generated for 16f18313
        '
        'Template comment at the start of the config file
        '
        #startup InitPPS, 85
        #define PPSToolPart 16f18313
    
        Sub InitPPS
    
                'Module: EUSART
                RA5PPS = 0x0014    'TX > RA5
    
        End Sub
        'Template comment at the end of the config file
    
        'USART settings for USART1
        #define USART_BAUD_RATE 115200
        #define USART_TX_BLOCKING
        #define USART_DELAY OFF
    
        #define LCD_IO 107   'K107
    
    
        ; ----- Constants
        ' DS18B20 port settings
        #define DQ RA4
    
    
    ; ----- Quick Command Reference:
    
     '''Set LCD_10 to 10 for the YwRobot LCD1602 IIC V1 or the Sainsmart LCD_PIC I2C adapter
     '''Set LCD_10 to 12 for the Ywmjkdz I2C adapter with pot bent over top of chip
    
    ; ----- Variables
      dim TempC_100 as LONG   ' a variabler to handle the temperature calculations
      Dim DSdata,WHOLE, FRACT, DIG as word
      Dim CCOUNT, SIGNBIT as Byte
    
    
    ; ----- Main body of program commences here.
    
        ccount = 0
        CLS
        print "GCBasic 2020"
        locate 1,0
        print "DS18B20 Demo"
        wait 2 s
        CLS
    
        do forever
           ' The function readtemp returns the integer value of the sensor
           DSdata = readtemp
    
           ' Display the integer value of the sensor on the LCD
           locate 0,0
           print hex(ccount)
           print " Ceil"
           locate 0,8
           print DSdata
           print chr(223)+"C"
    
    
    
           ' Display the integer and decimal value of the sensor on the LCD
    
           ' The function readtemp12 returns the raw value of the sensor.
           ' The sensor is read as a 12 bit value therefore each unit equates to 0.0625 of a degree
           DSdata = readtemp12
    
    
           SignBit = DSdata / 256 / 128
           If SignBit = 0 Then goto Positive
           ' its negative!
           DSdata = ( DSdata # 0xffff ) + 1 ' take twos comp
    
    
        Positive:
           ' Convert value * 0.0625 by factorisation
           TempC_100 =  DSdata *  625
           Whole = TempC_100 / 10000
           Fract = TempC_100 % 10000
    
    
           If SignBit = 0 Then goto DisplayTemp
           Print "-"
    
        DisplayTemp:
           Locate 3,0
           Print Whole
           Print "."
           Print leftpad( str(Fract),4,"0")
    
           wait 2 s
           ccount++
    
        loop
    
     
  • George Towler

    George Towler - 2020-04-14

    Of course Dallas only claim "is accurate to ±0.5°C over the range of -10°C to +85°C."

     
  • James Whyte

    James Whyte - 2020-04-14

    Thanks.
    The output from your code. Note I changed the output of DSdata to raw so you can see whats going on.

    CCOUNT Dsdata (Raw) Temp C
    0 184 11.5000 C
    1 176 11.0000 C
    2 176 11.0000 C
    3 176 11.0000 C
    4 176 11.0000 C
    5 176 11.0000 C
    6 176 11.0000 C
    7 192 12.0000 C
    8 248 15.5000 C
    9 304 19.0000 C
    10 352 22.0000 C
    11 392 24.5000 C
    12 424 26.5000 C
    13 456 28.5000 C
    14 480 30.0000 C
    15 504 31.5000 C

     
    • Anobium

      Anobium - 2020-04-15

      Well... thats not correct.

       
  • Anobium

    Anobium - 2020-04-15

    Here is code, see the sub, to set the resolution to 9,10,11 or 12 bits. Take the .h replace the existing one in your include folder.

    New library sub is:

    DS18B20SetResolution ( in DS18B20SetResolutionValue )

    where

    D18B20SetResolution ( DS18B20_TEMP_9_BIT | DS18B20_TEMP_10_BIT, DS18B20_TEMP_11_BIT, DS18B20_TEMP_12_BIT ) are valid

    Sorry. You may have been stuck in 9bit mode. This will set to 12bit but if it does not work then you have duff a DS18B20 - as this does work on test here, and, I can see the data transmission using the one-wire logic analyser.

    Evan

    #chip 16f18313
    #config MCLR=ON
    #option Explicit
    #include <ds18b20.h>
    
        'Generated by PIC PPS Tool for Great Cow Basic
        'PPS Tool version: 0.0.6.1
        'PinManager data: v1.79.0
        'Generated for 16f18313
        '
        'Template comment at the start of the config file
        '
        #startup InitPPS, 85
        #define PPSToolPart 16f18313
    
        Sub InitPPS
    
                'Module: EUSART
                RA5PPS = 0x0014    'TX > RA5
    
        End Sub
        'Template comment at the end of the config file
    
        'USART settings for USART1
        #define USART_BAUD_RATE 115200
        #define USART_TX_BLOCKING
        #define USART_DELAY OFF
    
        #define LCD_IO 107   'K107
    
    
        ; ----- Constants
        ' DS18B20 port settings
        #define DQ RA4
    
    
    ; ----- Quick Command Reference:
    
     '''Set LCD_10 to 10 for the YwRobot LCD1602 IIC V1 or the Sainsmart LCD_PIC I2C adapter
     '''Set LCD_10 to 12 for the Ywmjkdz I2C adapter with pot bent over top of chip
    
    ; ----- Variables
      dim TempC_100 as LONG   ' a variabler to handle the temperature calculations
      Dim DSdata,WHOLE, FRACT, DIG as word
      Dim CCOUNT, SIGNBIT as Byte
    
    
    ; ----- Main body of program commences here.
    
        ccount = 0
        CLS
        print "GCBasic 2020"
        locate 1,0
        print "DS18B20 Demo"
        wait 2 s
        CLS
    
        DS18B20SetResolution ( DS18B20_TEMP_12_BIT )
    
        do forever
           ' The function readtemp returns the integer value of the sensor
           DSdata = readtemp
    
           ' Display the integer value of the sensor on the LCD
           locate 0,0
           print hex(ccount)
           print " Ceil"
           locate 0,8
           print DSdata
           print chr(223)+"C"
    
    
    
           ' Display the integer and decimal value of the sensor on the LCD
    
           ' The function readtemp12 returns the raw value of the sensor.
           ' The sensor is read as a 12 bit value therefore each unit equates to 0.0625 of a degree
           DSdata = readtemp12
    
    
           SignBit = DSdata / 256 / 128
           If SignBit = 0 Then goto Positive
           ' its negative!
           DSdata = ( DSdata # 0xffff ) + 1 ' take twos comp
    
    
        Positive:
           ' Convert value * 0.0625 by factorisation
           TempC_100 =  DSdata *  625
           Whole = TempC_100 / 10000
           Fract = TempC_100 % 10000
    
    
           If SignBit = 0 Then goto DisplayTemp
           Print "-"
    
        DisplayTemp:
           Locate 3,0
           Print Whole
           Print "."
           Print leftpad( str(Fract),4,"0")
    
           wait 2 s
           ccount++
    
        loop
    

    A debug of the D18B20SetResolution on the wire.

     

    Last edit: Anobium 2020-04-15
  • James Whyte

    James Whyte - 2020-04-16

    Thanks very much for that... that did the trick. All good now, and getting better than 9 bit resolution.
    You weren't to know my devices were in 9 bit mode by default. :-)

    I have been using a HX711 strain guage amplifier and determining its output drift with temperature. The Staircase in the attached graph is due to the 0.5 Deg resolution that I can now improve on. - thanks

     
    • Anobium

      Anobium - 2020-04-16

      Excellent news. I will move the .h to the release.

      Be good of you to post a table of reading for a range of temps (like the one posted previously) with 9bit thru 12bit results. It will help others and I can include in the Help.

      Anobium

       
  • James Whyte

    James Whyte - 2020-04-17

    Typical outputs for 9bit, 10bit, 11bit, 12bit attached.

    Help guide is missing the 'S' in D18B20SetResolution ?
    Maybe in the table of CONSTANT and Resolution add another coloum for temperature resolution of 0.5 Deg C, 0.25 Deg C, 0.125 Deg C, 0.0625 Deg C

    Otherwise Excellent :-)

     
    • Anobium

      Anobium - 2020-04-17

      Excellent . I have updated the Help. I have added your recommended information - a good idea.

      Thanks

       
  • James Whyte

    James Whyte - 2020-04-17

    Oooh, I forgot... and add your extra decimal resolution (above) to the example code for the next release?

    Many thanks for this :-)

     
    • Anobium

      Anobium - 2020-04-17

      Just done it. That was a good idea.

      Anobium

       

Log in to post a comment.