Shop OBEX P1 Docs P2 Docs Learn Events
Help with temperature sensor math — Parallax Forums

Help with temperature sensor math

I have a temperature program working which displays readings from DS18B20 sensors on a TV.
What I need help with is calculating by hand how the output from the sensor gets displayed in degrees F on the TV. I've tried to follow the math in the methods but do not come out with anything close. I've included the pertinent parts of the code which does work. I'd like to be able to create a conditional statement, but using the actual displayed value does not work, hence the desire to use the actual readout of the sensor. Thanks, Aaron

A few observations of data are
when output
= 65260 display says 0F 'output is loaded is 3rd to last line of ReadTemperature method
=65397 display says 16F
= 298 display says 65F
OSsensor :=readTemperature(D_temp)   'from main method

PUB readTemperature(addr) | temp,dsOut
  '' Read the temperature from a DSxxxxx sensor, and return it.
  ' Blocks while the conversion is taking place.   
  
  ow.reset
  ow.writeByte(ow#MATCH_ROM)
  ow.writeAddress(addr)    '64 bit address of device being addressed
  
  ow.writeByte(ow#CONVERT_T)
  
  ' Wait for the conversion
  repeat
    waitcnt(clkfreq/100 + cnt)    
    
    if ow.readBits(1)
      'we Have a reading! Read it from the scratchpad.      
      ow.reset
      ow.writeByte(ow#MATCH_ROM)
      ow.writeAddress(addr)   '64 bit address of device being addressed
      
      ow.writeByte(ow#READ_SCRATCHPAD)
      dsOut := ow.readBits(16)
      'degF := (temp << 4)*9/5+32
      output := dsOut
      temp := ~~dsOut * 625           ' extend sign, 0.0001° units       
      
      return  temp 

pub showf(temp,places) | tp,Modulus  'places = number of decimal places to show 

'' Print temperature in degrees Fahrenheight w/(places) number of decimals 
' -- temp is passed in C

  case places                   'this added by AG
    0  : Modulus:=0     'integer only
    1  : Modulus:=10    '1 decimal
    2  : Modulus:=100    '2
    3  : Modulus:=1000    '3
    4  : Modulus:=10_000   '4

  if (temp > 0)
    temp := temp * 9 / 5 + 32_0000
  else
    temp := 32_0000 - (||temp * 9 / 5)
    
  if (temp < 0)     'if negative
    tv.out("-")
    ||temp
    
    'print degrees w/ selectable number of decimal places
  if Modulus==0                                                                                            
    tv.dec(temp / 10_000)     ' print whole portion truncated 
  else
    tv.dec(temp / 10_000)     ' print whole portion
    tv.out(".")                                                                             
    tv.dec(temp // Modulus)  ' print fractional portion 
  tv.out(176)
  tv.str(string("F  "))  

Comments

  • Mark_TMark_T Posts: 1,981
    edited 2019-03-07 12:24
    First thing to note is that 625 = 10000/16.

    The sensor value is in 1/16ths of a degree C, so temp gets set to the value in 0.0001 deg C units.
    temp := temp * 9 / 5 + 32_0000
    
    sets temp to 0.0001 deg F units.

    The fiddling around with signs is probably due to integer rounding issues differing from +ve to -ve values

  • Thanks Mark
    I just figured it out! The dsOUT value needs to be sign extended. output := ~~dsOut Then it works
    T = ~~dsOut*625*9 /5 +320,000 all over 10,000
Sign In or Register to comment.