Shop OBEX P1 Docs P2 Docs Learn Events
Help with shift instruction — Parallax Forums

Help with shift instruction

mynet43mynet43 Posts: 644
edited 2014-03-15 12:32 in Propeller 1
I have a routine that converts a thermistor reading from resistance to temperature.

I tried to be clever by using shift instructions instead of divide and multiply by powers of two.

Somehow the two versions don't give the same answer. Can you help me figure out what is different? The divide/multiply version gives the right answer...
PRI thermistor_temp | i, resistance, adc_val, denom ' interpolate to get temperature (C) from thermistor
  adc_val := adc.average(thermo_adc,4)           ' ADC of voltage of thermistor
  
  denom       := 4096-adc_val  
  resistance  := (10000*adc_val+denom>>1)/denom  ' calculate thermistor resistance from adc_val (rounded)
  temperature := 25                              ' init to 25 in case out of bounds
  
  repeat i from 0 to constant(max_th_table/5+10) ' get table entry range of resistance
    if resistance  =< rt[i]  and  resistance => rt[i+1] 
       temperature := tt[i] + ((((resistance -  rt[i])*(tt[i+1]-tt[i])+(rt[i+1]-rt[i])>>1))<<10)/(((rt[i+1]-rt[i]))>>10) ' BAD CODE

       temperature := tt[i] + ((((resistance -  rt[i])*(tt[i+1]-tt[i])+(rt[i+1]-rt[i])/2))*1024)/((rt[i+1]-rt[i]))/1024   ' GOOD CODE
       quit                                                                 

Thank you for your help.

Jim

Comments

  • kwinnkwinn Posts: 8,697
    edited 2014-03-15 11:09
    Looks like the extra brackets in the last part "/(((rt[i+1]-rt))>>10)" of the bad one are the cause.
  • kwinnkwinn Posts: 8,697
    edited 2014-03-15 11:16
    In the good code you are completing the entire calculation "rt)*(tt[i+1]-tt)+(rt[i+1]-rt)/2))*1024)/((rt[i+1]-rt))" and dividing that result by 1024.

    In the bad code you are calculating "rt)*(tt[i+1]-tt)+(rt[i+1]-rt)/2))*1024)" and dividing that by "(((rt[i+1]-rt))>>10)".
  • mynet43mynet43 Posts: 644
    edited 2014-03-15 12:03
    kwinn

    You are absolutely right. However, I believe I tried it without the extra bracket and got the same bad result.

    It looks like I should include the whole thing in parentheses before I do the shift.

    Does that sound right?

    I'll try it.

    Thanks!

    Jim
  • kwinnkwinn Posts: 8,697
    edited 2014-03-15 12:29
    I'm not sure what the precedence of the >> operator is, but you can try removing the first and last bracket of the "/(((rt[i+1]-rt))>>10)" portion of the calculation. If that does not work add a bracket at the beginning of the entire equation and edit the last bit to be "/(((rt[i+1]-rt)))>>10". The entire equation has to be executed before the >>10 is performed.
  • mynet43mynet43 Posts: 644
    edited 2014-03-15 12:31
    That did it. Accurate temperature now.

    Thanks again.

    Jim
  • mynet43mynet43 Posts: 644
    edited 2014-03-15 12:32
    temperature := tt + (((((resistance - rt)*(tt[i+1]-tt)+(rt[i+1]-rt)>>1))<<10)/(rt[i+1]-rt))>>10
Sign In or Register to comment.