Fads to Obsessions and Beyond...




Free domain for life, exceptional technical support, website transfer

MAX-31855 Thermocouple Driver

Demonstrate interfacing Microchip PIC18F248 with the MAX31855 Thermocouple Driver to read temperatures from K-type thermocouples. Code also demonstrates multiple connected MAX31855's to enable reading more than one thermocouple.

Both hardware SPI and a 'bit banging' software approach are used, in the case SPI hardware pins not available and/or alternatively used e.g. for I2C. Output to serial monitor/PC.


The MAX31855K Thermocouple Driver is a 14-bit resolution, SPI-compatible, serial interface thermocouple board that makes reading a wide range of temperatures, using a K-type thermocouple typically -200 °C to 1000 °C, relatively simple. A thermocouple works by taking two wires made of dissimilar metal alloy, connecting them at the two ends, and making a temperature gradient between one end and the other (a ‘hot’ end and a ‘cold’ one). Once this is achieved, a voltage potential is formed due to the Seebeck Effect and current flows. The MAX31855 amplifies, digitises and converts this signal and outputs the temperature as a binary data stream via a SPI interface. Details about the necessary circuit connections and coding in regards interfacing to a Microchip PIC18F248 are given below.

The Microchip PIC18F248, although now an 'old' Part, is mainly used as I have these readily available, but these chips are advantageous in terms of small physical size, low cost per GPIO/onboard peripheral provided and still easily available in DIP form (which is generally easier for the DIY PCB). This is particularly good for 'small' DIY projects controlling a single sensor and or output for example, such as temperature monitoring for kilns, furnaces, ovens and other such 'high' temperature applications. The PIC18F248, or similar parts such as the PIC18F452 etc, are still economically available from ebay and/or other more reputable suppliers. So, the demonstration code and circuity below is generally applicable.

First some background about thermocouples (specifically related to use with the MAX31855) and then some specifics about the MAX31855.

As mentioned, thermocouples operate due to two wires of different metal compositions connected at the two ends, with the two ends being placed in differing temperature environments, which generates a voltage potential and current flow (Seebeck Effect). This means that thermocouples are classified by type of metals used, with the most common being type K made from chromel and alumel. These two alloys produce a potential of approximately 41.276 µV/°C. The MAX31855 uses this known potential difference to calculate the temperature. Therefore, it is important that the MAX31855 variant used is the "K" version, to match the type of thermocouple used, otherwise the reported temperature will be incorrect.

Further, thermocouples can be either 'grounded' or 'ungrounded' in construction. When a thermocouple is ungrounded, the junction is detached from the sensor hull and electrically isolated. The detached junction results in slower response times compared to grounded probes. The electrically isolated junction prevents the signal from being interrupted by electrical noise. Thus the accuracy of the temperature measurement is much higher. A grounded thermocouple is a thermocouple where the junction is welded directly to the inside of the hull at the tip of the sensor which results an effective heat transfer thus faster response times. However, grounded thermocouples are prone to induce noise from ground loops which results in a less accurate reading.

The MAX31855 only works with ungrounded thermocouple probes.

MAX31855 Thermocouple Driver

The datasheet (see Bill of Materials Section) gives the full list of the necessary details and specifications.

In brief, the MAX31855 is a thermocouple-to-digital converter with a built-in 14-bit analog-to-digital converter (ADC). The device also contains cold-junction compensation sensing and correction, a digital controller, with an SPI-compatible interface. The device is designed to work in conjunction with an external microcontroller. The MAX31855 is available in several versions, each optimized and trimmed for a specific thermocouple type (K, J, N, T, S, R, or E.). The thermocouple type is indicated in the suffix of the part number (e.g., MAX31855K).

For a K-type thermocouple, the voltage changes by about 41.276 µV/°C, the MAX31855 assumes a linear relationship between temperature and voltage. Because all thermocouples exhibit some level of nonlinearity, you may need to apply appropriate correction to the device’s output data.

The MAX31855 resolves temperatures to 0.25°C, allows readings as high as +1800°C and as low as -270°C (dependant upon thermocouple in use), and exhibits thermocouple accuracy of ±2°C for temperatures ranging from -200°C to +700°C for K-type thermocouples.

Code Library

The MAX31855 provides the temperature output in the form or a signed 14-bit, SPI-compatible, read-only format. This means the necessary microcontroller code is relatively simple, basically just being the SPI connection to capture the output data, which is 32bits. Then from this 32 bits, strip the 14-bit thermocouple temperature data, the 12-bit internal temperature, and 4-bits of error code.

The CCS C-Compiler is used for generating the Microchip Hex files, and a code library using hardware-SPI and another version using 'bit-banging' is provided below. The 'bit-banging' version enables using alterative I/O pins rather than those multiplexed for hardware SPI (typically the SPI pins are also utilised for I2C connectivity). This enables using Parts such as the PCF8574 port expander which needs I2C connections (e.g., to interface a LCD and or keypad) while still interfacing with the MAX31855.

The code, and particularly the SPI communications and retrieval of the bit data corresponding to the measured temperature, is described more fully in the Testing and Experimental Results Section below.


The circuit consists largely of the usual minimum requirements for a PIC (PIC18F248 dealt with here) that is, power supply, oscillator (external crystal oscillator - 10MHz) and in-circuit serial programming (ICSP).

The majority of the circuit is based upon the DIY PIC Development Board.

Circuit Operation

A "wall wart" power supply was chosen rather than constructing a dedicated DC power supply dropping/converting from an AC wall socket. Surplus chargers from laptops are readily available (in this case supplying 16-24V with 65W max) which provide not only a safer option (compared to construction from a suitable transformer, rectifier, connection to AC etc) but also a much more economical option (generally zero cost for a surplus charger, compared to ten's of dollars for a suitable transformer, let alone cost of ancillary circuitry, PCB etc).

The surplus laptop charger requires a suitable socket connection and a voltage regulator, in this case a LM317T, to provide the regulated 5V generally required by PIC microcontrollers. The power supply circuit is given in the Schematics Section. The LM317T circuit is the standard design direct from the datasheet, with input and output capacitors to provide smoothing and the resistor/potentiometer to provide selection of output voltage.

A MAX232 is used to enable RS-232 communication between the PIC microcontroller and an attached PC, in order to display the measured temperature from the MAX31855.

MAX31855

The most important initial point is that the MAX31855 is a 3.3V device and the appropriate power source will be necessary. In this case, a LM1086IT is used with the standard circuit from the datasheet (R1 = 120 ohm, R2 = 3K potentiometer) to provide a regulated 3.3V. Further, when using the PIC18F248 (or similar) which is a 5V device, the SPI output pins from the PIC microcontroller are 5V which will damage the MAX31855 input pins. Therefore, the appropriate voltage conversion (just simple voltage divider resistors will suffice, as shown on the Schematics) will be necessary. This is assuming the MAX31855 breakout board is an "ebay special". Some more "reputable" versions possibly have input voltage conversion on board.

The Schematics Section gives the wiring diagram for connection of the CLK (clock), SO (data out), and CS (chip select) lines to the PIC microcontroller.

From the data sheet, "because of the small signal levels involved, thermocouple temperature measurement is susceptible to power supply coupled noise. The effects of power-supply noise can be minimized by placing a 0.1 µF ceramic bypass capacitor close to the VCC pin of the device and to GND."

The datasheet also "recommends" to add a 10nF ceramic surface-mount differential capacitor, placed across the T+ and T- pins, in order to filter noise on the thermocouple lines. It is reported online/Youtube Channels that the MAX31855 breakout board "ebay specials" do in fact not actually work if this 10nF capacitor is not placed across the T+ and T- pins. However, I have not observed this to be the case, at least with the particular versions of the MAX31855 I sourced from ebay.

Thermocouple Wires

As previously discussed, thermocouples are made by welding together two wires, the MAX31855 reads the voltage difference between the two. One is the negative (for K-type its made of Alumel) and the other positive (for K-type its made of Chromel). Generally the wires are color coded, and almost all of the time you'll find the Alumel is red and the Chromel is yellow. If the thermocouple temperature goes down instead of up when heated, try swapping the red and yellow wires.


Software/Firmware

The firmware enables connection of the PIC18F248 with a PC via RS-232 and periodic reading of the thermocouple to get the measured temperature in degrees Celsius. The code, and particularly the SPI communications and retrieval of the bit data corresponding to the measured temperature, is described more fully in the Testing and Experimental Results Section below.


Note: Image loading can be slow depending on server load.

  • MAX31855 SchematicMAX31855 Schematic

    Silver Membership registration gives access to full resolution schematic diagrams.

    MAX31855 Schematic

  • multiple MAX31855 Schematicmultiple MAX31855 Schematic

    Silver Membership registration gives access to full resolution schematic diagrams.

    multiple MAX31855 Schematic


This project did not require a PCB.

The construction was done using prototyping board. See the photographs and schematic diagram sections.

Qty Schematic Part-Reference Value Notes
Resistors
1R110K1/4W, 10% 
3R2,R3,R92.2K1/4W, 10% 
3R7,R8,R113.8K1/4W, 10% 
2R4,R53301/4W, 10% 
1R62701/4W, 10% 
1RV15K1/4W, potentiometer 
Capacitors
2C1,C222pFCeramic 
1C30.33uF 
1C40.1uF 
5C6-C101uF 
Diodes
1D11N-4001 
Integrated Circuits
1U1PIC18F248PIC microcontroller  datasheet
2U1,U2MAX31855Thermocouple Driver  datasheet
1U3LM317Linear Voltage Regulator  datasheet
1U4LM1086Linear Voltage Regulator  datasheet
1U5MAX232ERS232 Driver/Receiver datasheet
Miscellaeous
1J1CONN-H55-pin connector for ICSP
1SW1SW-SPDT 
1X110MHzCrystal Oscillator
Description Downloads
MAX471 - Bill of Materials Text File Download

Before connecting the PIC microcontroller to the PC ports, check for any shorts (direct positive voltage to ground connection) as this could damage both the PIC microcontroller and the PC.

The SPI interface provided by the MAX31855 and the digital output of the temperature sensed by the thermocouple probe means temperature measurements with the MAX31855 is relatively straight forward. The following Code Snippet 1 demonstrates using a single MAX31855 to retrieve temperature from a connected thermocouple. Output is directed via the USB/serial port to a connected PC.

The other two sections demostrate using a 'bit-banging' method for interfacing to the MAX31855, and also how to interface to multiple MAX31855 and associated thermocouples.

SPI Interfaced with single MAX31855

Since for a K-type thermocouple, the voltage changes by about 41.276 µV/°C, and the MAX31855 assumes a linear relationship between temperature and voltage, there is no need for 'calibration' as such of the MAX31855 (assuming the thermocouple itself is not damaged/worn-out).

While this will be sufficient for common applications such as kiln or furnance temperature monitoring, for applications requiring more precise temperature measurement, there are polynomial equations defined by the International Temperature Scale of 1990 (ITS-90) standard that correlate the temperature and voltage output. These polynomial equations, and the back calculated thermocouple output voltage, could be utilised by the user/code to provide an alternative method for calculating the output temperature, rather than relying upon the MAX31855 linear approximation across the temperature range.

Code Snippet 1: SPI Interfaced with single MAX31855


#include 
#zero_ram //all variables automatically initialised to 0
int8 readCount = 0;
int8 toggleReadCount = 0;

#define SPI_MODE_0  (SPI_L_TO_H | SPI_XMIT_L_TO_H)
#define SPI_MODE_1  (SPI_L_TO_H)
#define SPI_MODE_2  (SPI_H_TO_L)
#define SPI_MODE_3  (SPI_H_TO_L | SPI_XMIT_L_TO_H)
#define SS PIN_B1
int8 spival[4];

#int_timer1
void timer1_interrupt() { /* Timer1 has wrapped around to 0. */
  toggleReadCount=1;
  set_timer1(3035); //prescaler=8, 10Mhz, preload=3036 -> Freq 5hz, period=0.2sec
}

void readMAX() {
     output_low(SS);
     delay_us(10);
     spival[3]=spi_read(0);
     spival[2]=spi_read(0);
     spival[1]=spi_read(0);
     spival[0]=spi_read(0);
     delay_us(10);
     output_high(SS);
}

int tempFault() { //Returns >0 if FAULT. If necessary do a bitwise analisys to check fault source
     int1 Fvdd=0,Fgnd=0,Fopen=0,fault=0;
     fault=spival[2]&0x01; // pelos menos uma falha
     Fvdd=(spival[0]>>2)&0x01;
     Fgnd=(spival[0]>>1)&0x01;
     Fopen=spival[0]&0x01;
     return (fault*1+Fvdd*2,Fgnd*4,Fopen*8);
}

int16 readExtTemp() { //Returns returns signed temperature in ºC approximately
     int8 aux;
     int16 temp1;
     aux=spival[2]>>2;
     temp1=spival[3];
     temp1<<=6;
     temp1+=aux;
     return temp1/=4;
}

int16 readIntTemp() { //Returns returns signed temperature in ºC approximately
     int8 aux;
     int16 temp2;
     temp2=spival[1];
     temp2<<=4;
     aux=spival[0]>>4;
     temp2=spival[1]<<4;
     temp2+=aux;
     return temp2/=16;
}


void main() {
  setup_timer_1(T1_INTERNAL | T1_DIV_BY_8); //prescaler 8
  setup_spi(SPI_MASTER | SPI_MODE_1 | SPI_CLK_DIV_64);
  enable_interrupts(GLOBAL);
  enable_interrupts(INT_TIMER1);
  printf("\n\rstart\n\r");

  while(TRUE){
    if (toggleReadCount==1) {
        toggleReadCount = 0;
        readCount++;
     }
     if (readCount>=10) { // 10 counts of 0.2sec = read every 2 secs
        output_toggle(PIN_B0);
        readCount = 0;
        toggleReadCount = 0;
        set_timer1(3035); //prescaler=8, 10Mhz, preload=3036 -> Freq 5hz, period=0.2sec
		  readMAX();
		  printf("\n\n Thermocouple: %Ld, Ambient: %Ld\n\r",readExtTemp(),readIntTemp());
     }
  }
}
    				

'Bit banging' with single MAX31855

The 'bit-banging' version enables using alterative I/O pins rather than those multiplexed for hardware SPI. Typically on PIC microcontrollers the SPI pins are also utilised for I2C connectivity, but only one form of connectivity can be used at a time. This enables using Parts such as the PCF8574 port expander, which needs I2C connection, to interface a LCD and or keypad while still enabling interfacing with the MAX31855. This 'bit banging' approach to SPI/MAX31855 enables more flexibility to which I/O pins on the PIC microcontroller are required.

Code Snippet 2: 'Bit banging' with single MAX31855


 #include 
 #zero_ram //all variables automatically initialised to 0
 int8 readCount = 0;
 int8 toggleReadCount = 0;

 #int_timer1
 void timer1_interrupt() { /* Timer1 has wrapped around to 0. */
    toggleReadCount=1;
    set_timer1(3035); //prescaler=8, 10Mhz, preload=3036 -> Freq 5hz, period=0.2sec
 }

 #define TC_CLK    PIN_B2 //clock pin hardware SPI PIN_C3
 #define TC_CS     PIN_B1 //chip select pin
 #define TC_DATA   PIN_B3 //data pin hardware SPI PIN_C4

 #define UPPER     1
 #define LOWER     0
 int1 thermocoupleError,ShortGnd,ShortVcc,OpenCircuit;
 int16 extTemperature, intTemperature;

 union { //global that contains the 32 bits read from the MAX31855
    unsigned int32 allBits;       // 31      allBits     0
    unsigned int16 longInt[2];    // 15      0 |  15     0
 } MAX31855_data;                 // longInt[1]  longInt[0]

 void init_MAX31855(void) {
    output_low(TC_CLK);
    output_high(TC_CS); // Conversions are always being performed in the background.
                        // The fault and temperature data are only be updated when CS is high.
 }

 void read_MAX31855(int CS_pin) {
    int8 i;
    output_low(CS_pin); //Drive CS low and apply a clock signal at SCK to read the results at SO.
    for (i=0;i<32;i++){
       output_high(TC_CLK);
       shift_left(&MAX31855_data.allBits,4,input(TC_DATA)); //reads in 4 bytes from the pin TC_DATA
       // the above shift_left + input() etc needed to be between the change in clock pulse, to get the timing correct for a proper read of the bit state
       output_low(TC_CLK);
    }
    thermocoupleError = bit_test(MAX31855_data.longInt[LOWER],15);
    OpenCircuit = bit_test(MAX31855_data.longInt[LOWER],0);
    ShortGnd = bit_test(MAX31855_data.longInt[LOWER],1);
    ShortVcc = bit_test(MAX31855_data.longInt[LOWER],2);
    output_high(TC_CS); // Conversions are always being performed in the background. The fault and temperature data are only updated when CS is high.
 }

 void externalTemperature() {
    extTemperature = ((MAX31855_data.longInt[UPPER] & 0B0111111111111100) >> 2) * 0.25; // 0.25 degrees celsius per bit from thermocouple
    if (bit_test(MAX31855_data.longInt[UPPER],15)) {extTemperature += - 2048;} // handles the case of negative temperature
 }

 void internalTemperature() {
    intTemperature = ((MAX31855_data.longInt[LOWER] & 0B0111111111110000) >> 4) * 0.0625;
    if (MAX31855_data.longInt[LOWER] & 0B1000000000000000) intTemperature += -128;
 }

 void main() {
    setup_timer_1(T1_INTERNAL | T1_DIV_BY_8); //prescaler 8
    setup_spi(SPI_SS_DISABLED);
    enable_interrupts(GLOBAL);
    enable_interrupts(INT_TIMER1);

    init_MAX31855();
    printf("\n\rstart\n\r");
    while(TRUE) {
      if (toggleReadCount==1) {
          toggleReadCount = 0;
          readCount++;
       }
       if (readCount>=10) { // 10 counts of 0.2sec = read every 2 secs
          output_toggle(PIN_B0);
          readCount = 0;
          toggleReadCount = 0;
          set_timer1(3035); //prescaler=8, 10Mhz, preload=3036 -> Freq 5hz, period=0.2sec
			 read_MAX31855(TC_CS);
			 if(thermocouple_error) {
				 externalTemperature();
			 	internalTemperature();
			 	printf("ext=%Lu",extTemperature);
			 	printf("  ,int=%Lu\r\n",intTemperature);
			} else {
				printf("error\n\r");
			}
       }
    }
 }
      				

Interfacing multiple MAX31855's

Since the MAX31855 supports the SPI interface, there can be multiple connected MAX31855/thermocouples depending upon provision of seperate CS (chip select) lines to the PIC microcontroller for each connected MAX31855. The following code demonstrates utilising two MAX31855/thermocouples. Utilising port expansion chips such as the PCF8574, to handle peripherals such as LCD's and keypads for example, the PIC microcontroller could provide necessary I/O pins to connect many MAX31855/thermocouples if desired.

Code Snippet 3: Interfacing multiple MAX31855's



                 

As a general precauation double check polarity of power connections etc before powering up the circuit.

As discussed in the Background Section, the MAX31855 is a 3.3V device. Which means that the input pins to the MAX31855 will need appropriate voltage conversion (e.g., voltage divider resistors) if using output from 5V devices such as the PIC18F248. This is probably the most common Gotch'ya.

Another common problem is to remember that the MAX31855 only works with ungrounded thermocouple probes.

From the data sheet, "because of the small signal levels involved, thermocouple temperature measurement is susceptible to power supply coupled noise. The effects of power-supply noise can be minimized by placing a 0.1 µF ceramic bypass capacitor close to the VCC pin of the device and to GND."

The datasheet also "recommends" to add a 10nF ceramic surface-mount differential capacitor, placed across the T+ and T- pins, in order to filter noise on the thermocouple lines. It is reported online/Youtube Channels that the MAX31855 breakout board "ebay specials" do in fact not actually work if this 10nF capacitor is not placed across the T+ and T- pins. However, I have not observed this to be the case, at least with the particular versions of the MAX31855 I sourced from ebay.

Finally, as previously discussed, thermocouples are made by welding together two wires, the MAX31855 reads the voltage difference between the two. One is the negative (for K-type its made of Alumel) and the other positive (for K-type its made of Chromel). Generally the wires are color coded, and almost all of the time you'll find the Alumel is red and the Chromel is yellow. If the thermocouple temperature goes down instead of up when heated, try swapping the red and yellow wires.


No video's loaded for this project.

Comments/Questions

No comments yet.

Add Comment/Question

Only Logged-In Members can add comments

"If we could sell our experiences for what they cost us, we'd all be millionaires".

Please donate any amount to help with hosting this web site.

If you subscribe (only $2/annum) you can view the site without advertisements and get emails abouts updates etc.

X

Sorry!

Only logged-in users with correct Membership Level can download.


Membership starts at only $2, so join now!