Measuring high temperatures accurately requires more than a simple NTC thermistor or DHT11 sensor. When you need to read temperatures in the range of 200°C to 1024°C — for a kiln, forge, 3D printer hot end, reflow oven, or industrial furnace — the combination of an Arduino thermocouple MAX6675 module and a K-type thermocouple is the go-to solution. This tutorial covers everything from wiring and library setup to calibration, cold-junction compensation, and practical code for a complete temperature logger.
Table of Contents
- How Thermocouples and the Seebeck Effect Work
- The MAX6675 Amplifier IC
- Wiring MAX6675 to Arduino
- Library Installation and Basic Code
- Calibration and Accuracy
- Building a Temperature Data Logger
- Common Problems and Fixes
- Frequently Asked Questions
How Thermocouples and the Seebeck Effect Work
A thermocouple is made of two dissimilar metal wires joined at one end (the hot junction). When the hot junction is at a different temperature from the other ends (the cold junction or reference junction), a small voltage is generated — this is the Seebeck effect. The voltage is proportional to the temperature difference between the two junctions.
A K-type thermocouple uses nickel-chromium (positive leg) and nickel-aluminium (negative leg). It generates approximately 41 µV per degree Celsius at room temperature. The measurable range is –270°C to +1372°C, though for practical Arduino use with the MAX6675, the upper limit is 1024°C.
K-type thermocouples are the most popular because they cover a wide range, are chemically resistant, and are inexpensive. Other types include J-type (iron/constantan, 0 to 760°C), T-type (copper/constantan, cryogenic to 350°C), and S-type (platinum/rhodium, used in precious metal applications).
The key challenge with thermocouples is that the generated voltage is tiny (microvolts per degree) and must be amplified. The reference junction (where the thermocouple connects to your circuit) must also be at a known temperature — a process called cold-junction compensation. The MAX6675 handles both amplification and cold-junction compensation automatically.
The MAX6675 Amplifier IC
The MAX6675 is a cold-junction-compensated K-type thermocouple-to-digital converter made by Maxim Integrated (now Analog Devices). It integrates everything needed to read a K-type thermocouple:
- Cold-junction compensation via onboard temperature sensor
- 14-bit analog-to-digital converter
- 12-bit resolution: 0.25°C steps
- Open thermocouple detection (bit 2 in the output word)
- SPI-compatible serial interface (read-only)
- Supply voltage: 3.3V to 5V
- Temperature range: 0°C to +1024°C (K-type input)
The MAX6675 outputs a 16-bit word over SPI (SCK + CS + SO — read-only, no MOSI needed). Bit 15 is a dummy sign bit (always 0 for K-type). Bits 14–3 are the 12-bit temperature value in 0.25°C increments. Bit 2 is the thermocouple open fault flag. Bits 1–0 are device IDs.
To get temperature in Celsius: read the 16-bit word, check bit 2 for open-circuit faults, then extract bits 14–3 and multiply by 0.25.
The MAX6675 module typically comes as a small green breakout board with the MAX6675 IC, ceramic capacitors, and a screw terminal block for the K-type thermocouple wires. This makes it very easy to connect.
Wiring MAX6675 to Arduino
The MAX6675 module has 5 pins: VCC, GND, SCK, CS, and SO. It does not need MOSI since it is a read-only SPI device.
MAX6675 VCC → Arduino 5V (or 3.3V)
MAX6675 GND → Arduino GND
MAX6675 SCK → Arduino Pin 6 (software SPI)
MAX6675 CS → Arduino Pin 5 (chip select)
MAX6675 SO → Arduino Pin 4 (serial data out)
Note: You can use either hardware SPI pins (13=SCK, 12=MISO) or any digital pins with software SPI. The MAX6675 library supports both modes. The pinout above uses software SPI to avoid conflicts with other SPI devices on hardware SPI pins.
K-type thermocouple wiring to the MAX6675 module: Connect the K-type thermocouple’s positive wire (typically yellow in IEC standard, red in US standard) to the + screw terminal and the negative wire (typically red in IEC, blue or white in US standard) to the – screw terminal on the module. Do not reverse polarity — you will get negative temperature readings at high temperatures.
Important: Keep thermocouple wires away from mains wiring, motors, and other sources of EMI. For long thermocouple runs, use shielded thermocouple extension wire, not ordinary copper wire (which will introduce additional junction voltages).
Library Installation and Basic Code
Install the MAX6675 library by Adafruit in Arduino IDE: go to Sketch → Include Library → Manage Libraries, search for “MAX6675”, and install the “MAX6675 library” by Adafruit.
Basic Temperature Reading Sketch
#include <max6675.h>
// Define SPI pins (software SPI)
int thermoCLK = 6; // SCK
int thermoCS = 5; // CS
int thermoDO = 4; // SO (data out)
MAX6675 thermocouple(thermoCLK, thermoCS, thermoDO);
void setup() {
Serial.begin(9600);
Serial.println("MAX6675 thermocouple test");
// Allow MAX6675 to stabilise
delay(500);
}
void loop() {
float tempC = thermocouple.readCelsius();
float tempF = thermocouple.readFahrenheit();
if (isnan(tempC)) {
Serial.println("ERROR: Thermocouple open circuit or disconnected!");
} else {
Serial.print("Temperature: ");
Serial.print(tempC);
Serial.print(" °C / ");
Serial.print(tempF);
Serial.println(" °F");
}
// MAX6675 requires minimum 250ms between readings
delay(1000);
}
Reading Interval Warning
The MAX6675 requires a minimum of 170ms between consecutive SPI reads. If you read too quickly, you will get repeated values. The datasheet recommends a minimum 250ms delay between readings for reliable data. This also means the MAX6675 cannot be used for fast-changing temperature events — it is designed for slowly varying thermal processes.
Low-Level Reading Without Library
For advanced users who want to understand the raw protocol:
uint16_t readMAX6675Raw(int csPin, int clkPin, int doPin) {
uint16_t result = 0;
digitalWrite(csPin, LOW);
delayMicroseconds(2);
for (int i = 15; i >= 0; i--) {
digitalWrite(clkPin, LOW);
delayMicroseconds(1);
if (digitalRead(doPin)) result |= (1 << i);
digitalWrite(clkPin, HIGH);
delayMicroseconds(1);
}
digitalWrite(csPin, HIGH);
if (result & 0x04) return 0xFFFF; // open fault
return (result >> 3) & 0x0FFF; // 12-bit value
}
// Temperature in °C = rawValue * 0.25
Calibration and Accuracy
The MAX6675 has a specified accuracy of ±2°C to ±6°C depending on temperature range. For most applications this is adequate, but if you need better accuracy, consider calibration.
Two-point calibration: Measure at two known reference temperatures (ice bath at 0°C and boiling water at 100°C for a first calibration). Calculate the slope and offset corrections:
// Two-point calibration
// Measured: 1.5°C at 0°C reference, 102.2°C at 100°C reference
float slope = (100.0 - 0.0) / (102.2 - 1.5); // = 0.985
float offset = 0.0 - (slope * 1.5); // = -1.478
float calibratedTemp = slope * rawTemp + offset;
Cold-junction accuracy: The MAX6675’s internal cold-junction temperature sensor has its own ±3°C accuracy. In environments with large ambient temperature swings (e.g., near furnaces), cold-junction error can add up. For critical measurements, use the MAX31855 (the successor to the MAX6675) which has improved cold-junction compensation and –200°C to +1350°C range.
Thermocouple placement tips:
- Insert the thermocouple tip deep enough to reach thermal equilibrium with the measured medium
- Avoid radiant heat falling directly on the thermocouple sheath in furnace applications
- Use ceramic insulation beads on thermocouple wire in high-temperature zones
- For liquid measurement, ensure the tip is fully submerged (not just touching the liquid surface)
Building a Temperature Data Logger
Combine the MAX6675 with a real-time clock (DS3231) and an SD card module to build a complete temperature data logger that records timestamped measurements to a CSV file.
#include <max6675.h>
#include <SPI.h>
#include <SD.h>
// MAX6675 pins (software SPI)
MAX6675 thermocouple(6, 5, 4); // CLK, CS, DO
// SD card
const int SD_CS = 10;
File dataFile;
unsigned long lastLog = 0;
const unsigned long LOG_INTERVAL = 5000; // log every 5 seconds
void setup() {
Serial.begin(9600);
if (!SD.begin(SD_CS)) {
Serial.println("SD init failed!");
while (1);
}
// Write CSV header
dataFile = SD.open("templog.csv", FILE_WRITE);
if (dataFile) {
dataFile.println("Timestamp_ms,Temperature_C");
dataFile.close();
}
delay(500); // MAX6675 startup
}
void loop() {
unsigned long now = millis();
if (now - lastLog >= LOG_INTERVAL) {
lastLog = now;
float temp = thermocouple.readCelsius();
if (!isnan(temp)) {
dataFile = SD.open("templog.csv", FILE_WRITE);
if (dataFile) {
dataFile.print(now);
dataFile.print(",");
dataFile.println(temp);
dataFile.close();
Serial.print(now);
Serial.print(" ms, ");
Serial.print(temp);
Serial.println(" °C — logged");
}
} else {
Serial.println("Open circuit fault!");
}
}
}
Common Problems and Fixes
Reading is always 0°C or NaN: Check wiring. Verify that CS, SCK, and SO pins match your code. Ensure the thermocouple is properly inserted into the screw terminals and the screws are tightened. A loose connection causes open-circuit faults (bit 2 = 1).
Reading is far too high (e.g., 800°C when ambient): The thermocouple polarity is reversed. Swap the + and – wires at the screw terminal.
Readings fluctuate wildly: EMI interference on the SPI lines or the thermocouple wire. Add a 10nF ceramic capacitor between the T+ and T– inputs on the MAX6675 module. Use twisted-pair thermocouple extension wire. Keep SPI wires short and away from power wires.
Temperature is consistently off by 3–10°C: Cold-junction compensation error. The ambient temperature at the MAX6675 module location is different from what the module expects, or the module’s internal cold-junction sensor has an offset. Perform a two-point calibration as described above.
Can only read every ~250ms: This is normal and by design. The MAX6675’s ADC conversion takes 170ms. Do not try to read faster — you will just get the same value.
Frequently Asked Questions
What is the maximum temperature I can measure with the MAX6675?
The MAX6675 supports K-type thermocouple measurements from 0°C to 1024°C. The thermocouple itself may support higher temperatures, but the MAX6675’s internal ADC saturates at 1024°C. For higher ranges, use the MAX31856 which supports up to 1800°C depending on thermocouple type.
Can I measure negative temperatures with the MAX6675?
No. The MAX6675 is specified for 0°C to 1024°C only. It cannot reliably measure sub-zero temperatures. For cryogenic or cold-chain applications, use the MAX31855 or a platinum RTD (PT100/PT1000) with an appropriate amplifier.
Is MAX6675 compatible with J-type or T-type thermocouples?
No. The MAX6675 is specifically calibrated for K-type thermocouples. Using a different type will give incorrect readings because each thermocouple type has a different Seebeck coefficient (µV/°C). For other thermocouple types, use the MAX31856 which supports B, E, J, K, N, R, S, and T types.
Can I run multiple MAX6675 modules on the same SPI bus?
Yes. Each module needs its own CS (chip select) pin. Keep SCK and SO shared. In your code, create multiple MAX6675 instances, each with the same CLK and DO pins but different CS pins. Pull only the desired CS low when reading that module.
What is the difference between MAX6675 and MAX31855?
The MAX31855 is the improved successor. It has 14-bit resolution (vs 12-bit), supports negative temperatures, has better cold-junction accuracy (±2°C vs ±6°C), provides separate hot-junction and cold-junction temperature readings, and includes more detailed fault detection. For new designs, the MAX31855 is recommended.
The Arduino MAX6675 thermocouple interface is a robust and affordable solution for high-temperature measurement in hobbyist and industrial applications. Whether you are monitoring a forge, a pizza oven, or a 3D printer extruder, this combination provides reliable data with minimal effort.
Add comment