Shop OBEX P1 Docs P2 Docs Learn Events
Need a math trick to avoid using Float obj — Parallax Forums

Need a math trick to avoid using Float obj

T ChapT Chap Posts: 4,223
edited 2008-11-13 21:59 in Propeller 1
No cogs to spare but have a decimal to compute.


PUB ReadTemp
     i2c1.i2cstart(i2cSCL1)
     I2C1.I2CWrite(i2cSCL1,TEMPIC + WRITE)         'send device + read mode   0 = WRITE  1 = READ
     I2C1.I2CWrite(i2cSCL1,$00)                    'send command byte, this is the register to act on
     i2c1.i2cstart(i2cSCL1)                             'send new start condition for read
     I2C1.I2CWrite(i2cSCL1,TEMPIC + READ)
     temp := i2c1.i2cRead(i2cSCL1, 0) << 8         'get byte 1  
     temp  |= i2c1.i2cRead(i2cSCL1, 1)                'get byte 2 
     i2c1.i2cstop(i2cSCL1)
     temp <<= 1                                    'get rid of D15 MSB sign byte if present
     temp >>= 4                                    'get rid of D0, D1, D2 unused status bytes if present
     'lcd.gotoxy(0,0)
     'lcd.decf(temp, 8)




Reading a temp sensor IC (Max6634), the output is 1 LSB = .0625 Celcius.

The MSB is the sign bit, so I lose it with bitshift left 1. The 3 most LSB's are flag bits that are ignored, so I lose those with bitshift right 3 (or - 07H). In other words, a read of $08 = .0625 celcius.

I need a math trick to produce whole numbers only, the accuracy needs to only be 1 degree.

In the end, this will get converted (as an optional display) to Fahrenheit using what I have found to be a simple conversion:

( (9 * TempCelcius)/5 ) + 32


Any suggestions appreciated.

Post Edited (Originator) : 11/13/2008 3:09:00 AM GMT

Comments

  • Mike GreenMike Green Posts: 23,101
    edited 2008-11-13 03:20
    0.0625 is 1/16 of a degree Celsius.

    I hope you've declared temp as a word, otherwise the shifts won't work as you might expect.
    Remember that all intermediate results are 32 bits.

    To convert 1/16ths of a degree Celsius to Fahrenheit and keep as much resolution as possible, do:

    temp := ((9 * temp) / 5) + constant(32 * 16)

    This will give you a temperature in 1/16ths of a degree Fahrenheit. To round it to the nearest degree, do:

    temp := (temp + 8) >> 4
  • T ChapT Chap Posts: 4,223
    edited 2008-11-13 03:29
    Thanks Mike! I will try that tonight. Yes Temp is a word. Not quite sure what you meant by 'constant' though.
  • Mike GreenMike Green Posts: 23,101
    edited 2008-11-13 03:41
    Read the Propeller Manual. Look up 'constant' in the index.
  • BradCBradC Posts: 2,601
    edited 2008-11-13 03:48
    Or compile it with bst* and constant folding turned on and it'll do it for you [noparse];)[/noparse]

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    Pull my finger!
  • T ChapT Chap Posts: 4,223
    edited 2008-11-13 19:03
    Mike, the stuff works out great. Many thanks for posting that math. I know what a constant is [noparse]:)[/noparse] but didn't know why you posted it, the temp is correct without any constant where you put it. I put a thermocouple on top of the temp IC and the multi meter reads 82.5F, the math you posted reads 82F, which is more than fine for the application.

    BradC, I thought you were joking, but noticed that you did put that in there, I need to test it to see how it works. I couldn't find an explanation for it in the help menu, I will dig through the thread and look for it.

    MAX6634/6635 is a cool chip for temp.

    EDIT:

    I see what you mean, you meant just use a constant in place of 32 x 16, not some mystery constant that is multiplied by (32 x 16). My bad. Slow in the head sometimes.

    Post Edited (Originator) : 11/13/2008 7:21:06 PM GMT
  • rokickirokicki Posts: 1,000
    edited 2008-11-13 21:59
    The constant() call just evaluates the expression at compile time (the portion inside the constant parens)
    rather than recomputing it at runtime.
Sign In or Register to comment.