[Revised] Working with STM32 and Sensors: Thermocouple TypeK

In this guide, we shall take a look at the thermocouple and how this type of sensor works and use MAX6675 thermocouple to measure the temperature.

In this guide, we shall cover the following:

  • Thermocouple typeK
  • MAX6675.
  • Connection MAX6675 with STM32.
  • Code.
  • Result

1. Thermocouple Type K:

ype K Thermocouple provides widest operating temperature range. It consist of positive leg which is non-magnetic and negative leg which is magnetic.In K Type Thermocouple  traditional base metal is used due to which it can work at high temperature and can provide widest operating temperature range. One of the constituent metal in K Type Thermocouple is Nickel, which is magnetic in nature.

The characteristic shown by K Type Thermocouple is that they undergo a deviation in output when magnetic material reaches its Curie Point, at around  185 °C. K Type  thermocouple  work very well in oxidizing atmosphere at temperatures up to 1260°C (2300°F) and its tolerance class is ± 1.5 K between -40 and 375 °C.

Type K Thermocouple International Color Code

Why To prefer K Type Thermocouple

  • One of the major advantage of K type thermocouple over other thermocouple’s is it can function in rugged environmental condition & in various atmospheres
  • It has integrated composition of Chromel and Alumel wires has a range of -270 °C to 1260°C and an output of -6.4 to 9 mV over maximum temperature range.
  • Also known as general purpose thermocouple due to its wide range of  temperature
  • Type K has a longer life than Type J as in Type J Fe (iron) wire oxidizes rapidly, especially at higher temperature
  • They are inexpensive.
  • Have a fast response
  • Small in size and are reliable.
  • Generally used at temperatures above 540 degrees C

Composition of K Type Thermocouple

In K Type Thermocouple positive leg is composed of 90% nickel, 10%chromium and a negative leg is composed of 95% nickel, 2% aluminum, 2% manganese and 1% silicon. These are the most common general purpose thermocouple with a sensitivity of approx 41µV/°C.

Type K Insulation Material

In Type K Thermocouple mainly two type of insulation is used firstly Ceramic beads  insulation is used as it is a lightweight insulating product. It is made from high purity alumino-silicate materials. It has low thermal mass which means that it does not retain heat, low thermal conductivity and is an extremely effective insulation material as it can withstand high temperature of 1260 °C so it it best suited material for Type K thermocouple.

Secondly compacted mineral insulation and outer metal sheath (MgO) is used. Magnesium Oxide has a high dielectric strength, responds quickly to temperature changes and is very durable. It has typical Composition of the Standard Quality MgO (97%) and the High Purity MgO and AI2O3.

Magnesium Oxide insulation is recommended for K Type thermocouple when Thermocouple are to be immersed in liquids, high moisture, corrosive gases or high pressures. The thermocouple can be formed to reach otherwise inaccessible areas.

Type K Thermocouple Tolerance Class

Temperature Range

To find appropriate range of thermocouple we should use appropriate wire because different wires measure various temperature ranges. Of the four major thermocouple types, type K covers the widest range :

  • Thermocouple grade wire, –454 to 2,300F (–270 to1260°C)
  • Extension wire, 32 to 392F (0 to200°C)

Accuracy (whichever is greater)

  • Standard: +/- 2.2°C or +/-.75%
  • Special Limits of Error: +/– l°C or0.4%

Tolerance Class

Type K Insulation Material

EMF Vs Temperature Graph for K Type Thermocouple

EMF Vs Temperature Graph for K Type Thermocouple

Pros And Cons:

Pros

  • To measure temperature it provide good linearity of emf
  • It provide good resistance aganist oxidation below 1000 °C(1600°F).
  • Highly stable output
  • Comparitively cost effective than other thermocouple.

Cons

  • Not suitable for reducing atmosphere but can withstand metallic
  • Aging of the emf characteristic, when compared to noble metal thermocouples (B, R, andS).
  • Not suitable for vacuum applications due to vaporization of chromium in the positive element.
  • Green-Rotis phenomenon may occur due to low oxygen level for the thermocouples which are used between 815°C to 1040°C (1500°F to1900°F).
  • Type K thermocouples should not be used in Sulphuric environment since both elements will rapidly corrode and the negative element will eventually fail mechanically due to becoming brittle.

Uses of K Type Thermocouple

They are mostly used for applications at temperatures above 550 °C up to the maximum working pressure of the thermocouple.

  • They are used in many industries like Steel & Iron to monitor temperature & chemistry through out the steel making process
  • Used for testing temperatures associated with process plants e.g. chemical production and petroleum refineries
  • Used for Testing of heating appliance safety
  • Type K is commonly used in nuclear applications because of its relative radiation hardness.

2. MAX6675:

he MAX6675 performs cold-junction compensation and digitizes the signal from a type-K thermocouple. The data is output in a 12-bit resolution, SPI-compatible, read-only format.

This converter resolves temperatures to 0.25°C, allows readings as high as +1024°C, and exhibits thermocouple accuracy of 8 LSBs for temperatures ranging from 0°C to +700°C.

Applications

● Industrial ● Appliances ● HVAC

Features

● Direct Digital Conversion of Type -K Thermocouple Output

● Cold-Junction Compensation
● Simple SPI-Compatible Serial Interface ● 12-Bit, 0.25°C Resolution
● Open Thermocouple Detection

Pin Configuration:

Typical connection:

As seen, it requires minimal external components to make the converter works with our STM32.

Serial Output of MAX6675:

As seen from the picture, the converter requires CLK, CS and SO.

This can be achieved SPI driver.

3. MAX6675 connection with STM32F4:

In this guide, we need the following:

  • STM32F411RE Nucleo64.
  • SSD1306 OLED display.
  • MAX6675 breakout board with Thermocouple Type K.
  • Breadboard.
  • Hookup wires.

The connection as following:

For the SSD1306 driver, refer to this code here.

For SPI configuration, please refer to this guide.

The connection as following:

MAX6675STM32F411
SCKPA5
SOPA6
CSPA9

4. Code:

Since the MAX6675 uses SPI, we shall use SPI1 of STM32F411 to handle the reading of the MCU.

We start off by creating new header file with name of max6675.h header file.

Within the header file:

Include the header guard:

#ifndef MAX6675_H_
#define MAX6675_H_




#endif /* MAX6675_H_ */

Within the header guard, include the following:

#include "stdint.h"

Define NAN to be -1000 for thermocouple not connected:

#define NAN -1000

Declare the following functions:

MAX6675 SPI Initializing:

void max6675_spi_init(void);

Read MAX6675 to get the temperature both in Celsius or Fahrenheit:

float readMax6675_C(void);

float readMax6675_F(void);

Hence, the entire header file as following:

#ifndef MAX6675_H_
#define MAX6675_H_

#include "stdint.h"

#define NAN -1000

void max6675_spi_init(void);

float readMax6675_C(void);

float readMax6675_F(void);

#endif /* MAX6675_H_ */

Thats all for the header file.

Now, create new source file with name of max6675.c source file.

Within the source file, include the following:

#include "max6675.h"
#include "stm32f4xx.h"

Define two macros for CS pin handling as following:

#define CS_LOW()	GPIOA->BSRR|=GPIO_BSRR_BR9

#define CS_HIGH()	GPIOA->BSRR|=GPIO_BSRR_BS9

For the initializing function:

Start with enabling clock access to GPIOA:

	/*Enable Clock Access to GPIOA*/
	RCC->AHB1ENR|=RCC_AHB1ENR_GPIOAEN;

Set PA5 to PA5 to alternate function and which alternate function:

	/*Set PA5,PA6 and PA7 alternate function*/
	GPIOA->MODER|=GPIO_MODER_MODE5_1|GPIO_MODER_MODE6_1|GPIO_MODER_MODE7_1;
	GPIOA->MODER&=~(GPIO_MODER_MODE5_0|GPIO_MODER_MODE6_0|GPIO_MODER_MODE7_0);

	#define AF05 0x05

	GPIOA->AFR[0]|=(AF05<<GPIO_AFRL_AFSEL5_Pos)|(AF05<<GPIO_AFRL_AFSEL6_Pos)|(AF05<<GPIO_AFRL_AFSEL7_Pos);

Set PA9 as output:

	/*Set PA0=9 as Output*/
	GPIOA->MODER|=GPIO_MODER_MODE9_0;
	GPIOA->MODER&=~GPIO_MODER_MODE9_1;

Then enable clock access to SPI1 as following:

	/*Enable clock access to SPI1*/
	RCC->APB2ENR|=RCC_APB2ENR_SPI1EN;

Configure the SPI as following:

  • Mode: Master
  • Divide the buad by 16 (to get 3 MHz since the APB2 bus is running at 50MHz and maximum frequency for MAX6675 is 4MHz).
  • Software slave management.
  • Data size to be 16-bit.
  • Finally enable the module.
	/*Set the mode to master*/
	SPI1->CR1|=SPI_CR1_MSTR;

	/*Set Buadrate to be Fclk/16*/
	#define Fclk16	0x03
	SPI1->CR1|=(Fclk16<<SPI_CR1_BR_Pos);

	/*Set the slave for software management*/
	SPI1->CR1|=SPI_CR1_SSM|SPI_CR1_SSI;

	/*Set data to be 16-bit*/
	SPI1->CR1|=SPI_CR1_DFF;

	/*Enable SPI1*/
	SPI1->CR1|=SPI_CR1_SPE;

Hence, the initializing function as following:

void max6675_spi_init(void)
{
	/*Enable Clock Access to GPIOA*/
	RCC->AHB1ENR|=RCC_AHB1ENR_GPIOAEN;

	/*Set PA5,PA6 and PA7 alternate function*/
	GPIOA->MODER|=GPIO_MODER_MODE5_1|GPIO_MODER_MODE6_1|GPIO_MODER_MODE7_1;
	GPIOA->MODER&=~(GPIO_MODER_MODE5_0|GPIO_MODER_MODE6_0|GPIO_MODER_MODE7_0);

	#define AF05 0x05

	GPIOA->AFR[0]|=(AF05<<GPIO_AFRL_AFSEL5_Pos)|(AF05<<GPIO_AFRL_AFSEL6_Pos)|(AF05<<GPIO_AFRL_AFSEL7_Pos);

	/*Set PA0=9 as Output*/
	GPIOA->MODER|=GPIO_MODER_MODE9_0;
	GPIOA->MODER&=~GPIO_MODER_MODE9_1;

	/*Configure SPI1*/

	/*Enable clock access to SPI1*/
	RCC->APB2ENR|=RCC_APB2ENR_SPI1EN;

	/*Set the mode to master*/
	SPI1->CR1|=SPI_CR1_MSTR;

	/*Set Buadrate to be Fclk/16*/
	#define Fclk16	0x03
	SPI1->CR1|=(Fclk16<<SPI_CR1_BR_Pos);

	/*Set the slave for software management*/
	SPI1->CR1|=SPI_CR1_SSM|SPI_CR1_SSI;

	/*Set data to be 16-bit*/
	SPI1->CR1|=SPI_CR1_DFF;

	/*Enable SPI1*/
	SPI1->CR1|=SPI_CR1_SPE;

}

Now, we need a static function that will read the SPI bus as following:

static uint16_t readMax6675(void)
{

	SPI1->DR =0;
	/*Wait for RXNE flag to be set*/
	while(!(SPI1->SR & (SPI_SR_RXNE))){}
	/*Read data from data register*/
	return SPI1->DR;
}

To read the temperature in Celsius:

float readMax6675_C(void)
{
	/*Set CS to LOW*/
	CS_LOW();

	/*Read Max6675*/
	uint16_t data=readMax6675();

	/*Set CS to HIGH*/
	CS_HIGH();

	float temp;

	if (data & 0x4)return (NAN);
	data >>= 3;

	temp=data*0.20;
	return temp ;
}

In Fahrenheit:

float readMax6675_F(void)
{
	return (readMax6675_C() * 9.0 / 5.0 + 32);
}

Hence, the entire source code as following:

#include "max6675.h"
#include "stm32f4xx.h"


#define CS_LOW()	GPIOA->BSRR|=GPIO_BSRR_BR9

#define CS_HIGH()	GPIOA->BSRR|=GPIO_BSRR_BS9



void max6675_spi_init(void)
{
	/*Enable Clock Access to GPIOA*/
	RCC->AHB1ENR|=RCC_AHB1ENR_GPIOAEN;

	/*Set PA5,PA6 and PA7 alternate function*/
	GPIOA->MODER|=GPIO_MODER_MODE5_1|GPIO_MODER_MODE6_1|GPIO_MODER_MODE7_1;
	GPIOA->MODER&=~(GPIO_MODER_MODE5_0|GPIO_MODER_MODE6_0|GPIO_MODER_MODE7_0);

	#define AF05 0x05

	GPIOA->AFR[0]|=(AF05<<GPIO_AFRL_AFSEL5_Pos)|(AF05<<GPIO_AFRL_AFSEL6_Pos)|(AF05<<GPIO_AFRL_AFSEL7_Pos);

	/*Set PA0=9 as Output*/
	GPIOA->MODER|=GPIO_MODER_MODE9_0;
	GPIOA->MODER&=~GPIO_MODER_MODE9_1;

	/*Configure SPI1*/

	/*Enable clock access to SPI1*/
	RCC->APB2ENR|=RCC_APB2ENR_SPI1EN;

	/*Set the mode to master*/
	SPI1->CR1|=SPI_CR1_MSTR;

	/*Set Buadrate to be Fclk/16*/
	#define Fclk16	0x03
	SPI1->CR1|=(Fclk16<<SPI_CR1_BR_Pos);

	/*Set the slave for software management*/
	SPI1->CR1|=SPI_CR1_SSM|SPI_CR1_SSI;

	/*Set data to be 16-bit*/
	SPI1->CR1|=SPI_CR1_DFF;

	/*Enable SPI1*/
	SPI1->CR1|=SPI_CR1_SPE;

}


static uint16_t readMax6675(void)
{

	SPI1->DR =0;
	/*Wait for RXNE flag to be set*/
	while(!(SPI1->SR & (SPI_SR_RXNE))){}
	/*Read data from data register*/
	return SPI1->DR;
}

float readMax6675_C(void)
{
	/*Set CS to LOW*/
	CS_LOW();

	/*Read Max6675*/
	uint16_t data=readMax6675();

	/*Set CS to HIGH*/
	CS_HIGH();

	float temp;

	if (data & 0x4)return (NAN);
	data >>= 3;

	temp=data*0.20;
	return temp ;
}

float readMax6675_F(void)
{
	return (readMax6675_C() * 9.0 / 5.0 + 32);
}

In main.c:

#include "oled.h"
#include "max6675.h"
#include "stdio.h"
extern void SysClockConfig(void);

char data_print[30];
float temp;
int main(void)
{
	SCB->CPACR |= ((3UL << 10*2)|(3UL << 11*2));
	SysClockConfig();
	SSD1306_Init();
	max6675_spi_init();
	while(1)
	{
		SSD1306_Clear();
		temp=readMax6675_C();
		SSD1306_GotoXY(0,0);
		sprintf(data_print,"T=%0.2fC  ",temp);
		SSD1306_Puts(data_print,&Font_11x18, 1);
		SSD1306_UpdateScreen();
		delay(333);
	}

	}

5. Results:

When you upload the code, you should get the following:

Add Comment

Your email address will not be published. Required fields are marked *