max31855

CircuitPython on hardware including Adafruit's boards, and CircuitPython libraries using Blinka on host computers.

Moderators: adafruit_support_bill, adafruit

Please be positive and constructive with your questions and comments.
Locked
User avatar
Crimson0087
 
Posts: 24
Joined: Thu Jul 28, 2022 1:52 pm

max31855

Post by Crimson0087 »

Hello,

I am using a Max31855 thermocouple with the adafruit k type thermocouple with the metal shield. I have this placed into an iron pipe stuffed with aluminum foil and a cartridge heater. The program is supposed to heat the pipe to a set temp then flip a relay on and off to maintain the temp. I used this code (i know its not circuitpython code its micropython) but was wondering if anyone had any ideas as to why it keeps throwing the "thermocouple not connected" error. It will work for a while maybe 5-10 minutes the it throws the error and I have to unplug and replug the rpi. This is inconvenient at best. the iron pipe is getting wet as I am bending wood with it but I dont see why this would cause an issue. No water is getting inside the box with the electronics.... any help appreciated.


Code: Select all


from machine import SPI, Pin
import utime    
import ustruct


class MAX31855:
    """
    Driver for the MAX31855 thermocouple amplifier.
    MicroPython example::
        import max31855
        from machine import SPI, Pin
        spi = SPI(1, baudrate=1000000)
        cs = Pin(15, Pin.OUT)
        s = max31855.MAX31855(spi, cs)
        print(s.read())
    """
    def __init__(self, spi, cs):
        self.spi = spi
        self.cs = cs
        self.data = bytearray(4)

    def read(self, internal=False, raw=False):
        """
        Read the measured temperature.
        If ``internal`` is ``True``, return a tuple with the measured
        temperature first and the internal reference temperature second.
        If ``raw`` is ``True``, return the values as 14- and 12- bit integers,
        otherwise convert them to Celsuius degrees and return as floating point
        numbers.
        """

        self.cs.low()
        try:
            self.spi.readinto(self.data)
        finally:
            self.cs.high()
  # The data has this format:
        # 00 --> OC fault
        # 01 --> SCG fault
        # 02 --> SCV fault
        # 03 --> reserved
        # 04 -. --> LSB
        # 05  |
        # 06  |
        # 07  |
        #      > reference
        # 08  |
        # 09  |
        # 10  |
        # 11  |
        # 12  |
        # 13  |
        # 14  | --> MSB
        # 15 -' --> sign
        #
        # 16 --> fault
        # 17 --> reserved
        # 18 -.  --> LSB
        # 19   |
        # 20   |
        # 21   |
        # 22   |
        # 23   |
        #       > temp
        # 24   |
        # 25   |
 # 26   |
        # 27   |
        # 28   |
        # 29   |
        # 30   | --> MSB
        # 31  -' --> sign
        if self.data[3] & 0x01:
            raise RuntimeError("thermocouple not connected")
        if self.data[3] & 0x02:
            raise RuntimeError("short circuit to ground")
        if self.data[3] & 0x04:
            raise RuntimeError("short circuit to power")
        if self.data[1] & 0x01:
            raise RuntimeError("faulty reading")
        temp, refer = ustruct.unpack('>hh', self.data)
        refer >>= 4
        temp >>= 2
        if raw:
            if internal:
                return temp, refer
            return temp
        if internal:
            return temp / 4, refer * 0.0625
        return temp / 4       
        
        
spi = machine.SPI(0, baudrate=80_000_000, polarity=0, phase=0, bits=8, sck=Pin(6), mosi=Pin(7), miso=Pin(4))
cs = Pin(5, Pin.OUT)
s =MAX31855(spi, cs)


#Variables for pin numbers
relay=22
powerLed=0
tempLed=1

#Temperature Settings
max=150
min=140

#Initialize pins
controller=machine.Pin(relay, machine.Pin.OUT)

power_led=machine.Pin(powerLed,machine.Pin.OUT)

temp_led=machine.Pin(temLed,machine.Pin.OUT)


#Turn on Power LED
power_led.high()

while True:
    current_temp=s.read()
    
    if current_temp>45:
        temp_led.high()
        if current_temp<min:
            controller.high()
        elif current_temp>max:
            controller.low()
    elif current_temp<=45:
        temp_led.low()
        if current_temp<min:
            controller.high()
        elif current_temp>max:
            controller.low()
    time.sleep(5)

User avatar
adafruit_support_bill
 
Posts: 88098
Joined: Sat Feb 07, 2009 10:11 am

Re: max31855

Post by adafruit_support_bill »

Make sure that both thermocouple wires are securely clamped in the screw-terminals. The wires are pretty thin and if one of them worked loose you could get that error.

User avatar
Crimson0087
 
Posts: 24
Joined: Thu Jul 28, 2022 1:52 pm

Re: max31855

Post by Crimson0087 »

They are definitely secure.

User avatar
adafruit_support_bill
 
Posts: 88098
Joined: Sat Feb 07, 2009 10:11 am

Re: max31855

Post by adafruit_support_bill »

Do you see any correlation between the error occurrence and anything else - such as temperature, relay activation or application of the wet wood to the pipe?

The Max31855 is pretty sensitive to grounding issues. Even a very indirect connection from the thermocouple to the circuit ground can cause problems. But that usually shows up as an SCG fault.

Another possible issue might be interference due to inductive spikes from relay activation.

User avatar
Crimson0087
 
Posts: 24
Joined: Thu Jul 28, 2022 1:52 pm

Re: max31855

Post by Crimson0087 »

At first it was happening because I had grounded the iron pipe. I learned quickly not to ground the pipe and removed the ground. I have noticed that it doesnt seem to occur when I am not touching it with the wet wood but I really dont see how that could affect anything b/c water cant be getting to the thermocouple. Maybe it has to do with the movement of everything while I am working? I will plug it in and see how long it can go without me touching it. Also I am new to coding so a lot of this is confusing. The code I posted I got the max31855 class offline from someone else. I only wrote the loop and the gpio stuff at the bottom. That being said is there a way that when it throws the error to write the program so that it just ignores it and continues and tries to get the temp again because literally as soon as it throws the error if I stop the program and restart it without changing anything else it works. That would make me think that if I could write it in such a way that it basically says "Ok there was an error so lets go again and check another temp and keep going" instead of "heres an error.....shut everything down." Any ideas how I would do that? Also when I grounded it it still said "thermocouple disconnected" it never said short circuit to ground

User avatar
adafruit_support_bill
 
Posts: 88098
Joined: Sat Feb 07, 2009 10:11 am

Re: max31855

Post by adafruit_support_bill »

At first it was happening because I had grounded the iron pipe. I learned quickly not to ground the pipe and removed the ground. I have noticed that it doesnt seem to occur when I am not touching it with the wet wood but I really dont see how that could affect anything b/c water cant be getting to the thermocouple.
...
Also when I grounded it it still said "thermocouple disconnected" it never said short circuit to ground
Wet wood is conductive, and even a very indirect path to ground can cause an error on the 31855. (We have seen cases where the error occurs when a kiln heats up to about 1000C - because at that temperature, even the air becomes very slightly conductive.)

I'm not a MicroPython expert, but the reason the system halts on the error is because of this statement:

Code: Select all

raise RuntimeError("thermocouple not connected")
Since that exception is not handled in your main loop, the program halts.

You should be able to add exception handling to the main loop.

Something like this:

Code: Select all

while True:
  try:
    current_temp=s.read()
  except:
    print("Read Error")
  else:
    if current_temp>45:
        temp_led.high()
        if current_temp<min:
            controller.high()
        elif current_temp>max:
            controller.low()
    elif current_temp<=45:
        temp_led.low()
        if current_temp<min:
            controller.high()
        elif current_temp>max:
            controller.low()
    time.sleep(5)

Locked
Please be positive and constructive with your questions and comments.

Return to “Adafruit CircuitPython”