Temprature conversion --- C to F


Closed Thread
Results 1 to 14 of 14
  1. #1
    Join Date
    Jan 2009
    Location
    California, USA
    Posts
    323

    Post Temprature conversion --- C to F

    --------------------------------------

    I have a temperature sensor (MCP9800) that spits out a 12 bit - 2's compliment number that represents degrees C from - 55 C to + 125 C.

    Name:  temp_reg.gif
Views: 921
Size:  9.4 KB

    12 bits of resolution gives increments of 1/16 degree C and displays to 4 decimal places, like so: 26.1875
    I've got it up and running and successfully displaying temperature in degrees C. With this:

    Code:
    '-----------Read and display temperature from MCP9800-----------
    
    checktemp9800:
        i2cread sda9800,clk9800,adr_R,[T_MSB,T_LSB]           'read the 2 bytes of temperature data
        TempC = abs T_MSB                                      'all the stuff to the left of the decimal point is in the MSB.
        TempCdec = (T_LSB >>4) * 625                          'stuff to the right of the decimal point. Side shift out the unused bits and multiply by 625 for 1/16 degree C resolution.
    
        If T_MSB.7  then                                         'if the sign bit is "1", display a minus sign
            signind = "-"
            else
            signind = "+ "
        endif
    
    
        Lcdout $fe,2, "  ", signind, DEC TempC, "." ,DEC4 TempCdec, 223, " C   "   ' Display the info
    
    return


    By I can't for the life of me figure out how to do the conversion from degrees C to degrees F. !!

    I have NO problem for temperatures ABOVE 32 F (0 C) You just multiply by 1.8 (or 18/10) and add 32. Simple...

    But when the temperature goes BELOW 0 C then my life (and math) falls apart and I can't make it work right. And I'm not even sure what to do when the temp falls even further to less than 0 F.
    I'm not sure why my brain won't do this. It seems like it should be simple enough.

    I want to end up with degrees F available to at least 1 (preferably 2) decimal places, and it should work right over the whole range of -55 C to + 125C (-67 F to +257F)

    Can someone please spin me around and pull the blindfold off?

    Oh, and my "device" is a 16F887, so I'm stuck with 16 bit math.

    Thanks...

  2. #2
    Join Date
    Jan 2005
    Location
    Montreal, Quebec, Canada
    Posts
    2,597


    Did you find this post helpful? Yes | No

    Default Re: Temprature conversion --- C to F

    I haven't touched a PIC in a while, but I vaguely remember a lot of problems with negative math on the 16F family.

    Wasn't there a thread here somewhere about something like DT's interrupt stuff but about negative math?

    (searching...)

    Robert

    EDIT: Like this thread:
    http://www.picbasic.co.uk/forum/showthread.php?t=7777

    "...PBP can't multiply or divide negative numbers. (unless you are using PBPL on an 18F) - DT"
    Last edited by Demon; - 23rd September 2011 at 02:30. Reason: link

  3. #3
    Join Date
    Oct 2009
    Location
    Utah, USA
    Posts
    427


    Did you find this post helpful? Yes | No

    Default Re: Temprature conversion --- C to F

    I feel your pain!! the math was WAY over my head also... luck was in my favor and I stumbled across an INCLUDE file by Darrel Taylor. His routine will convert between C, F, Kelvin and possibly more!!!

    Here is my temperature conversion... after reading a DS18B20 one wire temp sensor.

    bear in mind that this routine is for a One Wire DS18b20 temp sensor... and the value is a two BYTE value that can be programmed for 9-12 bit resolution and the value is initially read in deg C


    Code:
    '=======TEMPERATURE subroutine==============================================
    ShowTemp:
        while PortA.3=0 : wend
        PAUSE 500
        OWOUT  Comm_Pin, 1, [$CC, $4E, 0, 0, DS18B20_9bit]  'set resolution of sensor
    Start_Convert:
        OWOUT  Comm_Pin, 1, [$CC, $44]' Skip ROM search & do temp conversion
    
    Wait_Up:
        OWIN   Comm_Pin, 4, [Busy]    ' Read busy-bit
        IF     Busy = 0 THEN Wait_Up  ' Still busy..?, Wait_Up..!
        OWOUT  Comm_Pin, 1, [$CC, $BE]' Skip ROM search & read scratchpad memory
        OWIN   Comm_Pin, 2, [Raw.LOWBYTE, Raw.HIGHBYTE]' Read two bytes / end comms
    Convert_Temp:
        Sign="+"
        IF Cold_Bit = 1 THEN    'it's below zero Celsius
        C=(ABS Raw>>4)*-10      'so shift the ABS value right and mult X -10
        ELSE
        C=(Raw>>4)*10           'else shift value right and mult X 10
        ENDIF
    
    @ CtoF _C, _F             ; Convert Celsius to Fahrenheit
            'converted value will be X 10, ie. 756=75.6 deg F
            'so devide by 10 to get whole degrees
    
        IF f.15=1 THEN Sign="-" 'if converted value is below zero F then sign is "-"
        TempF = (ABS f)/10      'take tha ABS value and /10
        IF f//10 >4 THEN TempF=TempF+1 'check remainder, if >4 then round up
    
        IF TempF <10 THEN         '1 digit value plus "deg F"
            len=3
        elseif TempF <100 THEN    '2 digit value plus "deg F"
            len=4
        ELSE                      '3 digit value plus "deg F"
            len=5
        ENDIF
        arraywrite msg,[Sign,DEC TempF,"*"] ' *= lookup for "deg F"
        GOSUB Message                       ' display current temp
    
    if intrpt=1 then SleepNow  'if here by interrupt then return to SleepNow
    IF mode=0 THEN Motto        'if here from motto return to motto 
    GOTO Icon                   'else return to icon
    Here are most of the variables associated with the temp conversion routine.

    Code:
    '-------------[variables and constants for temperature routine]--------------
    DS18B20_9bit  CON 011111   ' set resolution on DS18B20 93.75ms, 0.5 C
    Comm_Pin      VAR   PortA.4   ' One-wire Data-Pin "DQ" on PortA.4
    Busy          VAR BIT         ' Busy Status-Bit
    Raw           VAR   WORD      ' RAW Temperature readings
    TempF         VAR WORD        ' Temp in deg F
    Cold_Bit      VAR Raw.BIT11   ' Sign-Bit for +/- Temp. 1 = Below 0 deg C
    Sign          VAR BYTE        ' +/- sign for temp display
    Don't forget to add this line to your program...

    INCLUDE "Temp_Convert_CtoFonly.pbp"

    also you will need to delete the .txt extension off from the attached include file.

    I hope this helps... ask questions if you need to.

    possibly most if what you need is Darrels (as always excellent) include file.
    Attached Files Attached Files
    Last edited by Heckler; - 23rd September 2011 at 02:59.
    Dwight
    These PIC's are like intricate puzzles just waiting for one to discover their secrets and MASTER their capabilities.

  4. #4
    Join Date
    Oct 2009
    Location
    Utah, USA
    Posts
    427


    Did you find this post helpful? Yes | No

    Default Re: Temprature conversion --- C to F

    Here is a link to an article that I wrote that describes reading the ONE WIRE DS18b20 temp sensor...


    http://www.picbasic.co.uk/forum/cont...r-nine-of-them
    Dwight
    These PIC's are like intricate puzzles just waiting for one to discover their secrets and MASTER their capabilities.

  5. #5
    Join Date
    Jan 2009
    Location
    California, USA
    Posts
    323


    Did you find this post helpful? Yes | No

    Default Re: Temprature conversion --- C to F

    Thank You Heckler!

    That looks like exactly what I need!
    I should have known that Darrel had already written something cool to cover it. (Thank You Darrel !!)

    I'll have a read through that stuff this evening and report back tomorrow.

  6. #6
    Join Date
    Oct 2004
    Posts
    440


    Did you find this post helpful? Yes | No

    Default Re: Temprature conversion --- C to F

    F = C * 9 'DO LESS THE BIT.7 NEG/POS BIT
    F = F / 5
    IF T_MSB.7 = 1 THEN 'if the sign bit is "1", is minus C
    F = 32 - F
    else
    F = 32 + F
    ENDIF

    Norm

  7. #7
    Join Date
    Oct 2004
    Posts
    440


    Did you find this post helpful? Yes | No

    Default Re: Temprature conversion --- C to F

    Quote Originally Posted by Normnet View Post
    F = C * 9 'DO LESS THE BIT.7 NEG/POS BIT
    F = F / 5
    IF T_MSB.7 = 1 THEN 'if the sign bit is "1", is minus C
    F = 32 - F
    else
    F = 32 + F
    ENDIF

    Norm
    Try again:
    F = C * 9 'DO LESS THE NEG/POS BIT
    F = F / 5
    IF T_MSB.7 = 1 THEN 'if the sign bit is "1", is minus C
    F = F - 32
    else
    F = F + 32
    ENDIF

  8. #8
    Join Date
    Oct 2009
    Location
    Utah, USA
    Posts
    427


    Did you find this post helpful? Yes | No

    Default Re: Temprature conversion --- C to F

    Hey ByteButcher...
    bear in mind that my code does NOT result in an actual SIGNED value of the Temperature deg F. You end up with the correct temperature in the variable "tempF" and the sign of that value in the variable "sign". It is sutable for display on an LCD or something like that. But you will have to know the value of the "sign" if you want to do further calculations on the value.

    PS. I posted the wrong INCLUDE statement...
    YOU would use ...
    INCLUDE "Temp_Convert.pbp"
    (I tried to modify Darrels code to simplify it to only include the needed code to convert C to F and eliminate the Kelvin part. I was really tight on code space for my project.)


    There is some good informaiton about temperature conversion here (towards the bottom of the page)... http://www.rentron.com/PicBasic/one-wire2.htm

    @Normnet... is it really that simple to convert degrees C to degrees F? across the whole range of -55C to +125C ??
    Last edited by Heckler; - 23rd September 2011 at 15:36.
    Dwight
    These PIC's are like intricate puzzles just waiting for one to discover their secrets and MASTER their capabilities.

  9. #9
    Join Date
    Oct 2004
    Posts
    440


    Did you find this post helpful? Yes | No

    Default Re: Temprature conversion --- C to F

    Quote Originally Posted by Heckler View Post
    @Normnet... is it really that simple to convert degrees C to degrees F? across the whole range of -55C to +125C ??
    I was thinking on the run above but the following is complete.
    C value is * 1000 to hold 4 places.

    Code:
      C VAR LONG
      F VAR LONG
      iSIGN VAR BIT
    
      GOTO MAIN
    
      subC_TO_F:
        F = C * 9
        F = F / 5
        IF iSIGN = 1 THEN 'if the sign bit is "1" is minus C
          IF F > 320000 THEN
            F = F - 320000
            SEROUT2 sSEROUT_PIN,cBAUD,[" -",DEC C/10000,".",DEC4 C," C  = -",DEC F/10000,".",DEC4 F," F",13]
          ELSE
            F = 320000 - F
            SEROUT2 sSEROUT_PIN,cBAUD,[" -",DEC C/10000,".",DEC4 C," C  = ",DEC F/10000,".",DEC4 F," F",13]
          ENDIF
        ELSE
          F = F + 320000
          SEROUT2 sSEROUT_PIN,cBAUD,["  ",DEC C/10000,".",DEC4 C," C  = ",DEC F/10000,".",DEC4 F," F",13]
        ENDIF
      RETURN
    
      MAIN:
    
      SEROUT2 sSEROUT_PIN,cBAUD,[" ",13]
      SEROUT2 sSEROUT_PIN,cBAUD,["START",13]
    
      iSIGN = 1 'NEG
      FOR C = 100 TO 0 STEP -1 '-.0100 C TO 0 C
       GOSUB subC_TO_F
      NEXT
    
      iSIGN = 0 'POS
      FOR C = 0 TO 100 STEP 1 '0 C TO .0100 C
       GOSUB subC_TO_F
      NEXT
    
    
      iSIGN = 1
      FOR C = 550000 TO 0 STEP -10000 '-55.0000 C TO 0 C  'DO STEP -1 FOR COMPLETE BUT FOREVER
       GOSUB subC_TO_F
      NEXT
    
      iSIGN = 0
      FOR C = 0 TO 1250000 STEP 10000 '0 C TO 125.0000 C  'DO STEP 1 FOR COMPLETE BUT FOREVER
       GOSUB subC_TO_F
      NEXT
    
      STOP
    
      END
    Norm

  10. #10
    Join Date
    Oct 2004
    Posts
    440


    Did you find this post helpful? Yes | No

    Default Re: Temprature conversion --- C to F

    Now displays 4 decimals with round up.

    Norm

    Code:
    C VAR LONG
      F VAR LONG
      iSIGN VAR BIT
    
      GOTO MAIN
    
      subC_TO_F:
        F = C * 10
        F = F * 9
        F = F / 5
        IF iSIGN = 1 THEN 'if the sign bit is "1" is minus C
          IF F > 3200000 THEN
            F = F - 3200000
            F = F + 5
            F = F / 10
            SEROUT2 sSEROUT_PIN,cBAUD,[" -",DEC C/10000,".",DEC4 C," C  = -",DEC F/10000,".",DEC4 F," F",13]
          ELSE
            F = 3200000 - F
            F = F + 5
            F = F / 10
            SEROUT2 sSEROUT_PIN,cBAUD,[" -",DEC C/10000,".",DEC4 C," C  = ",DEC F/10000,".",DEC4 F," F",13]
          ENDIF
        ELSE
          F = F + 3200000
          F = F + 5
          F = F / 10
          SEROUT2 sSEROUT_PIN,cBAUD,["  ",DEC C/10000,".",DEC4 C," C  = ",DEC F/10000,".",DEC4 F," F",13]
        ENDIF
      RETURN
    
      MAIN:
      SEROUT2 sSEROUT_PIN,cBAUD,[" ",13]
      SEROUT2 sSEROUT_PIN,cBAUD,["START",13]
    
      iSIGN = 1
      FOR C = 100 TO 0 STEP -1 '-.0100 C TO 0 C
       GOSUB subC_TO_F
      NEXT
    
      iSIGN = 0
      FOR C = 0 TO 100 STEP 1 '0 C TO .0100 C
       GOSUB subC_TO_F
      NEXT
    
    
      iSIGN = 1
      FOR C = 550000 TO 0 STEP -10000 '-55.0000 C TO 0 C  'DO STEP -1 FOR COMPLETE BUT FOREVER
       GOSUB subC_TO_F
      NEXT
    
      iSIGN = 0
      FOR C = 0 TO 1250000 STEP 10000 '0 C TO 125.0000 C  'DO STEP 1 FOR COMPLETE BUT FOREVER
       GOSUB subC_TO_F
      NEXT
    
      STOP
    
      END

  11. #11
    Join Date
    Jan 2009
    Location
    California, USA
    Posts
    323


    Did you find this post helpful? Yes | No

    Default Re: Temprature conversion --- C to F

    Well, I got lost in a world of fire wood this week and haven't had a chance to look through all these great suggestions. But THANKS to everyone for the input so far. Hopefully in the next day or 2 I'll get a chance to try again.

    Norm, you're killing me with those "Longs".... that's going to be tough to implement with my 16F887!

  12. #12
    Join Date
    Oct 2004
    Posts
    440


    Did you find this post helpful? Yes | No

    Default Re: Temprature conversion --- C to F

    Quote Originally Posted by Byte_Butcher View Post
    Well, I got lost in a world of fire wood this week and haven't had a chance to look through all these great suggestions. But THANKS to everyone for the input so far. Hopefully in the next day or 2 I'll get a chance to try again.

    Norm, you're killing me with those "Longs".... that's going to be tough to implement with my 16F887!
    No longs, 2 decimals. no round.
    Enter C value 124.56 as 12456

    Norm
    Code:
      C VAR WORD
      F VAR WORD
      iSIGN VAR BIT
    
      GOTO MAIN
    
      subC_TO_F:
        DISABLE ' Necessary if On Interrupt used
        F = C * 9
        F = DIV32 5
        ENABLE ' Necessary if On Interrupt used
    
        IF iSIGN = 1 THEN 'if the sign bit is "1" is minus C
          IF F > 3200 THEN
            F = F - 3200
            SEROUT2 sSEROUT_PIN,cBAUD,[" -",DEC C/100,".",DEC2 C," C  = -",DEC F/100,".",DEC2 F," F",13]
          ELSE
            F = 3200 - F
            SEROUT2 sSEROUT_PIN,cBAUD,[" -",DEC C/100,".",DEC2 C," C  = ",DEC F/100,".",DEC2 F," F",13]
          ENDIF
        ELSE
          F = F + 3200
          SEROUT2 sSEROUT_PIN,cBAUD,["  ",DEC C/100,".",DEC2 C," C  = ",DEC F/100,".",DEC2 F," F",13]
        ENDIF
      RETURN
    
      MAIN:
      SEROUT2 sSEROUT_PIN,cBAUD,[" ",13]
      SEROUT2 sSEROUT_PIN,cBAUD,["START",13]
    
    
      iSIGN = 1
      FOR C = 100 TO 0 STEP -1 '-1.00 C TO 0 C
       GOSUB subC_TO_F
      NEXT
    
      iSIGN = 0
      FOR C = 0 TO 100 STEP 1 '0 C TO 1.00 C
       GOSUB subC_TO_F
      NEXT
    
    
      iSIGN = 1
      FOR C = 5500 TO 0 STEP -100 '-55.00 C TO 0 C  'DO STEP -1 FOR COMPLETE BUT FOREVER
       GOSUB subC_TO_F
      NEXT
    
      '12500 IS 125.00 * 100 TO HOLD 2 DECIMAL PLACES
      iSIGN = 0
      FOR C = 0 TO 12500 STEP 100 '0 C TO 125.00 C  'DO STEP 1 FOR COMPLETE BUT FOREVER
       GOSUB subC_TO_F
      NEXT
    
      STOP
    
      END

  13. #13
    Join Date
    Jan 2009
    Location
    California, USA
    Posts
    323


    Did you find this post helpful? Yes | No

    Default Re: Temprature conversion --- C to F

    NORM!
    This works great!
    I tested it with my circuit and it works perfect down to at least -20C (-4F) which is as cold as my freezer goes.
    So that should cover the full range of temperature now.

    I really appreciate the help from all of you.
    I've pondered the problem several times over the last few years but never came up with code that worked over the full range of positive and negative temps.

    This is very cool
    THANKS! THANKS! THANKS!

    Code:
      subC_TO_F:
        F = C * 9
        F = DIV32 5
    
        IF C_sign = 1 THEN 'if the sign bit is "1" is minus C
          IF F > 3200 THEN
            F = F - 3200
             lcdout $fe,$2," C = -",DEC C/100,".",DEC2 C,$fe,$c0," F = -",DEC F/100,".",DEC2 F,"   "
          ELSE
            F = 3200 - F
            lcdout $fe,$2," C = -",DEC C/100,".",DEC2 C,$fe,$c0," F = ",DEC F/100,".",DEC2 F,"   "
          ENDIF
        ELSE
          F = F + 3200
          lcdout $fe,$2," C = ",DEC C/100,".",DEC2 C,$fe,$c0," F = ",DEC F/100,".",DEC2 F,"   "
        ENDIF
        pause 200
      RETURN
    Oh, and this is the first time that I've played with "DIV32". Very handy that is....

  14. #14
    Join Date
    Oct 2004
    Posts
    440


    Did you find this post helpful? Yes | No

    Default Re: Temprature conversion --- C to F

    Now with round up, No longs, 2 decimal places.
    Enter C value 124.56 as 12456

    Norm
    Code:
      C VAR WORD
      F VAR WORD
      iSIGN VAR BIT
    
      GOTO MAIN
    
      subC_TO_F:
        F = C * 2
        F = F * 9
        F = DIV32 5
        F = F + 1 'ROUND UP
        F = F / 2
        IF iSIGN = 1 THEN 'if the sign bit is "1" is minus C
          IF F > 3200 THEN
            F = F - 3200
            SEROUT2 sSEROUT_PIN,cBAUD,[" -",DEC C/100,".",DEC2 C," C  = -",DEC F/100,".",DEC2 F," F",13]
          ELSE
            F = 3200 - F
            SEROUT2 sSEROUT_PIN,cBAUD,[" -",DEC C/100,".",DEC2 C," C  = ",DEC F/100,".",DEC2 F," F",13]
          ENDIF
        ELSE
          F = F + 3200
          SEROUT2 sSEROUT_PIN,cBAUD,["  ",DEC C/100,".",DEC2 C," C  = ",DEC F/100,".",DEC2 F," F",13]
        ENDIF
      RETURN
    
      MAIN:
      SEROUT2 sSEROUT_PIN,cBAUD,[" ",13]
      SEROUT2 sSEROUT_PIN,cBAUD,["START",13]
    
      iSIGN = 1
      FOR C = 100 TO 0 STEP -1 '-1.00 C TO 0 C
       GOSUB subC_TO_F
      NEXT
    
      iSIGN = 0
      FOR C = 0 TO 100 STEP 1 '0 C TO 1.00 C
       GOSUB subC_TO_F
      NEXT
    
    
      iSIGN = 1
      FOR C = 5500 TO 0 STEP -100 '-55.00 C TO 0 C  'DO STEP -1 FOR COMPLETE BUT FOREVER
       GOSUB subC_TO_F
      NEXT
    
      '12500 IS 125.00 * 100 TO HOLD 2 DECIMAL PLACES
      iSIGN = 0
      FOR C = 0 TO 12500 STEP 100 '0 C TO 125.00 C  'DO STEP 1 FOR COMPLETE BUT FOREVER
       GOSUB subC_TO_F
      NEXT
    
      STOP
    
      END

Members who have read this thread : 1

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