Shop OBEX P1 Docs P2 Docs Learn Events
1-Wire Thermocouple Amplifier - MAX31855 — Parallax Forums

1-Wire Thermocouple Amplifier - MAX31855

anaxcontrolanaxcontrol Posts: 23
edited 2016-06-27 18:52 in BASIC Stamp
I'm using a MAX31855 on a BS2PX24. Its wired and works (confirmed 212 with boiling water and 32 with icebath). I cant seem to get past 650DegF (somewhere in that vicinity) before the values get erratic (jumps to 9000 etc). I believe this is because of the 16bit word size (-32767 to 32767). I don't need to read negative just 0-2500 Deg F. Anyone know how I can do this? My current code wont (below). Any assistance is appreciated as this is driving me nuts (searched everything I could find).

DO
LOW CS ' selelct SPI
SHIFTIN so, Clk, MSBPRE, [MAX_T\16] ' shift in the data, MSB first, MSBPRE for sign bit.
HIGH CS ' enough SPI xfr. Conversions occur in the background
IF MAX_T.BIT0 = 1 THEN Fault ' another way to capture all 3 fault conditons.
MAX_T = MAX_T >> 2 ' drop bits 0 and 1 to isolate the 14 bit result
MAX_T.BIT15 = MAX_T.BIT13 ' extend the sign to bits 14 and 15.
MAX_T.BIT14 = MAX_T.BIT13
MAX_T = MAX_T * 25 ' resolution is 0.25 degC per bit
' DEBUG CR,"degC=",REP "-"\MAX_T.BIT15, DEC ABS MAX_T/100,".",DEC2 ABS MAX_T ' display as sxxxx.xx +/-0.25 degC.
MAX_T = MAX_T + 4000 ' add 40 degC to make it positive.
F_temp = MAX_T ** 52429 + MAX_T - 4000 ' multiply * 1.8 and offset back to -40 degF.
' DEBUG CR,"degF=",REP "-"\F_temp.BIT15, DEC ABS F_temp/100,".",DEC2 ABS F_temp ' display as sxxxx.xx +/-0.45 degF.
SEROUT 0, LcdBaud, TX, [$A3, DEC ABS F_temp/100] ' display as sxxxx degF.
PAUSE 1000
LOOP
END

Comments

  • The max is returning a two's complement value with a radix point between bits 3 and 4. I would right-shift FOUR bits to get an integer (it would be truncated, not rounded). Make sure it is all working just fine for positive (C) values and then worry about extending the sign, and perhaps rounding rather than truncating.
  • I have been reading up on complement of 2s. I found a good solution (creating a scaled reduction of the equation then taking the resulting number and * by a constant). Made sense because it kept everything within range but honestly it was over my head. I'm not that proficient with PBASIC but learning more each day. I'm assuming your saying changing this MAX_T = MAX_T >> 2 to MAX_T = MAX_T >> 6 then converting to F? I may need some schooling on this. Below is the core of it with nonsense removed. What do I need to REM, add, change?

    DO
    LOW CS
    SHIFTIN so, Clk, MSBPRE, [MAX_T\16]
    HIGH CS
    IF MAX_T.BIT0 = 1 THEN Fault
    MAX_T = MAX_T >> 2
    MAX_T.BIT15 = MAX_T.BIT13
    MAX_T.BIT14 = MAX_T.BIT13
    MAX_T = MAX_T * 25
    MAX_T = MAX_T + 4000
    F_temp = MAX_T ** 52429 + MAX_T - 4000
    SEROUT 0, LcdBaud, TX, [$A3, DEC ABS F_temp/100]
    PAUSE 1000
    LOOP
    END
  • MAX_T = MAX_T >> 4
    

    Puts the radix point to the right of bit 0. Result is degrees C as an integer. As long as it is positive, everything is cool. You can then directly display it as degrees C or convert to F using the 9/5 yada yada. Remember that overflow can occur with intermediate results ( for example, after multiplying by nine and before dividing by five).
    After everything is good with positive temperatures, you can worry about freezing.
  • Tracy AllenTracy Allen Posts: 6,656
    edited 2016-06-27 23:56
    Or, maybe resolve to 0.5 degree Celsius, which is close to 1 degree Fahrenheit for your LCD. Drop 3 lsbs, which gives you 12 bits + sign. The sign is extended to the high bits with one statement, x.nib3 = -x.bit12. Multiplying * 5 instead of 25 gives values up to 25000 (2500.0 degC), which is okay in signed 2's complement, no overflow. Then convert to degF using multiplication by 0.18 (**11796), which gives whole number Fahrenheit (-40 to 4532). The following maintains the sign, might as well.
    DO
      LOW CS ' select SPI
        SHIFTIN so, Clk, MSBPRE, [MAX_T\16] ' shift in the data, MSB first, MSBPRE for sign bit.
      HIGH CS ' enough SPI xfr. Conversions occur in the background
      IF MAX_T.BIT0 = 1 THEN Fault ' another way to capture all 3 fault conditons.
      MAX_T = MAX_T >> 3 ' drop bits 0, 1, 2 to isolate the 12 bit + sign result
      MAX_T.NIB3 = -MAX_T.BIT12 ' extend the sign to bits 13, 14 and 15.
      MAX_T = MAX_T * 5 ' resolution is 0.5 degC per bit
      DEBUG CR,"degC=",REP "-"\MAX_T.BIT15, DEC ABS MAX_T/10,".",DEC1 ABS MAX_T ' display as sxxxx.x +/-0.5 degC.
      MAX_T = MAX_T + 400 ' add 40.0 degC to make it positive.
      F_temp = MAX_T ** 11796 - 40 ' convert to whole degF, multiply * .18, remove offset -72 add 32
      DEBUG CR,"degF=",SDEC F_temp ' display as sxxxx +/-1 degF.
      SEROUT 0, LcdBaud, TX, [$A3, SDEC F_temp] ' display as sxxxx degF.
      PAUSE 1000
     LOOP
     END
    
  • anaxcontrolanaxcontrol Posts: 23
    edited 2016-06-28 14:08
    MAX_T = MAX_T >> 3, Multiplying * 5 instead of 25 gives values up to 25000 (2500.0 degC), Then convert to degF using multiplication by 0.18 (**11796).

    This makes much more sense. I was going the wrong direction with MAX_T = MAX_T >>. question: how is the 11796 derived? Thank you for the fast response. I'm going to give it a test this morning!
  • anaxcontrolanaxcontrol Posts: 23
    edited 2016-06-28 14:07
    I gave it a test this morning and still getting an anomaly. I heated the probe to 1000DegF and works accurately but beyond that or when the temp starts falling- temp goes to 9000 and slowly drops down as it cools but within that new scale. Is this an overflow or something else? If I restart the stamp, it reads accurately again. I'm baffled.
  • tomcrawfordtomcrawford Posts: 1,126
    edited 2016-06-28 15:35
    I think you need to decide for sure whether it is an overflow problem or not. Make the code simple enough that overflow cannot possibly occur:
    DO
      LOW CS ' select SPI
      SHIFTIN so, Clk, MSBPRE, [MAX_T\16]    ' shift in the data, MSB first, MSBPRE for sign bit.
      HIGH CS    ' enough SPI xfr. Conversions occur in the background
      IF MAX_T.BIT0 = 1 THEN Fault    ' another way to capture all 3 fault conditons.
      MAX_T = MAX_T >> 4    ' drop bits 0, 1, 2, 3 to isolate the 11-bit integer
      DEBUG CR,"degC=", DEC MAX_T
      PAUSE 1000
     LOOP
    

    You are always measuring positive degrees. If you can get this program to fail, then you have something other than overflow going on. Edit: If you cannot get this program to mis-behave, then you have working code to add to. endedit
  • Correct- I'm measuring 0-2000 Deg F (no negative temps). Funny thing is its accurate and the code works but when I get over 1000 Deg F (in that vicinity), the temp reading suddenly jumps to 9000 (something) then fluctuate from there. Once its back to room temp (70degF), temp reading 700. Ill try it again with the reduced code set so I can narrow this down but to restate, its definitely accurate (+/- 1 deg) up to around 1000F then something changes.
  • Its not an overflow. I took it up to 900DegC (DEBUG) then added a line (SEROUT) to LCD and took it 1000DegC (1832DegF). This is far past where I could get before. I definitely deduced something though. I both the LCD and DEBUG work flawlessly up to 1000degC then upon cooling down, the DEBUG is accurate but at around 200DegC, the LCD jumped to a higher number and decreased from there (extra digit). So the Debug shows 28 and the LCD 280. Maybe I need to clear the screen or something. I'm definitely closer now. This will be much easier to solve. I'm going to put the original code back and try the same test with debug and lcd so I can observe whats happening and when.
  • kwinnkwinn Posts: 8,697
    Can you output the raw reading from the thermocouple along with the calculated temperature so they can be compared for the working and non working case.
  • kwinn- its definitely a LCD refresh issue. when the temp is going up and reaches 4 digits all is good but if it drops below that to 3 digits (ie <999), the 4th digits stays present in the second position so 999 would look like 9X99 where x is a number from when it was a 4 digit temp. the DEBUG shows accurate. I think I just need to discover the way to keep the field refreshed.
  • kwinnkwinn Posts: 8,697
    kwinn- its definitely a LCD refresh issue. when the temp is going up and reaches 4 digits all is good but if it drops below that to 3 digits (ie <999), the 4th digits stays present in the second position so 999 would look like 9X99 where x is a number from when it was a 4 digit temp. the DEBUG shows accurate. I think I just need to discover the way to keep the field refreshed.

    Output blanks/zeros to blank the entire field immediately before outputting the the temperature. This was a common problem on serial terminals and thought it might be the case here.

  • Put some blanks in before output and that did it. I knew it would be a simple fix but not that simple; go figure. Thank you kindly kwinn
  • Tracy AllenTracy Allen Posts: 6,656
    edited 2016-06-28 19:40
    Ahhh, the ghost in the LCD!

    You asked about the magic number, **11796.

    That amounts to multiplication by 11796/65536 = 0.18. The Stamp divides by 65536 internally, using a 32 bit intermediate value. The ** operator is the Stampese way to multiply accurately by proper fractions. Actually, 11797 works better than 11796. There is a bit of roundoff error, always in the downwards direction. So 11797 will convert 0°C to 32°F, whereas 11796 rounds down to 31°F.

    @Tom, I agree about simplifying to check the output of the sensor in a way that cannot overflow.

    I also recommend checking the math. I know from many experiences how easy it is to get it wrong via basic misconceptions or by simple typos! I check the math by writing a loop that steps thru the range of input values that would be produced by the sensor from -40 to +1800 °C.
  • Awesome thank you Tracy Allen that makes perfect sense. I ran a test with a torch, got the temp to 1900degF, cooled down to room temp and no issues! Now on to RPM and pressure transducers....
Sign In or Register to comment.