MAX6675 - Thermocouple module
In this video I show you the MAX6675 cold-junction-compensated K-type thermocouple-to-digital converter. The circuit provides readings between 0°C and 1023.75°C, so it is really suitable for high-temperature measurements. The resolution of the device is 0.25°C which is more than enough for general applications. The chip communicates via SPI, so it is really easy to hook it up with a microcontroller. In this video I demonstrate this with an Arduino Nano.
Schematics
This circuit uses an Arduino Nano as the microcontroller. It facilitates both the i2C and the SPI communication channels. The 16x2 LCD uses the i2C (A4: SDA, A5: SCL), and the MAX6675 module uses the SPI (SCK: D13, CS: D12, SO, D12). Both devices use +5 V as the supply voltage.
Arduino source code
//16x2 LCD #include <LiquidCrystal_I2C.h> //SDA = B7[A4], SCL = B6[A5] STM32/[Arduino] LiquidCrystal_I2C lcd(0x27, 16, 2); //16 blocks, 2 lines //-------------------------------------------------------------------------------- #include <SPI.h> //SPI communication int TCRaw = 0; //raw value coming from the thermocouple int avgCounter = 0; //counter for average temperature readings float TCCelsius = 0; //Celsius value float avgTCCelsius = 0; //average temperature float temp_avgTCCelsius = 0; //average temperature for the ongoing calculation const byte CS_pin = 10; //chip select pin void setup() { pinMode(CS_pin, OUTPUT); // define chip select as an output digitalWrite(CS_pin, LOW); //pull chip select low SPI.begin(); //start SPI Serial.begin(115200); //start serial //------------------------------------------------------ lcd.begin(); // initialize the lcd lcd.backlight(); //------------------------------------------------------ lcd.setCursor(0,0); //Defining positon to write from first row, first column . lcd.print("MAX6675"); lcd.setCursor(0,1); //Second row, first column lcd.print("Thermocouple"); delay(2000); //wait 2 seconds lcd.clear(); //clear the whole LCD printLCD(); //print the stationary parts on the screen //------------------------------------------------------ } void loop() { readThermocouple(); //read the thermocouple delay(200); //wait 200 ms -> we average 10 readings: 2s refresh rate for AVG refreshLCD(); //refresh the values } void printLCD() { //These are the values which are not changing during the operation lcd.setCursor(0,0); //1st line, 1st block lcd.print("R:"); //text; R:4096 //---------------------- lcd.setCursor(7,0); //1st line, 8th block lcd.print("T:"); //text //---------------------- lcd.setCursor(0,1); //2nd line, 1st block lcd.print("AVG:"); //text } void refreshLCD() { //These are the values which are changing during the operation lcd.setCursor(2,0); //1st line, 6th block lcd.print(" "); //delete display //- It is always a good idea to overwrite the previous numbers with whitespaces lcd.setCursor(2,0); //1st line, 6th block lcd.print(TCRaw); //raw value //---------------------- lcd.setCursor(9,0); //2nd line, 7th block lcd.print(" "); //delete display lcd.setCursor(9,0); //2nd line, 7th block lcd.print(TCCelsius); //converted value //---------------------- lcd.setCursor(5,1); //2nd line, 1st block lcd.print(" "); //delete display lcd.setCursor(5,1); //2nd line, 1st block lcd.print(avgTCCelsius); //converted value } void readThermocouple() { //bits //15: dummy bit //14-3: MSB to LSB //2: - //1: 0 //0: STATE (three state) SPI.beginTransaction(SPISettings(14000000, MSBFIRST, SPI_MODE0)); //standard Arduino SPI digitalWrite(CS_pin, LOW); //"Force CS low and apply a clock signal at SCK to read the results at SO" delayMicroseconds(1); //just to be sure we wait enough (tcss: 100 ns is needed) TCRaw = SPI.transfer16(0x0000); //16 bit transfer - some dummy data to force the reading digitalWrite(CS_pin, HIGH); //We finished the command sequence, so we switch it back to HIGH SPI.endTransaction(); //close down SPI transaction TCRaw = TCRaw >> 3; //shift out the first 3 bits. //example: 0100000000001ˇ111 >> 3; ˇLSB //010000000000001<-(LSB) //^Dummy, then MSB Serial.print("Raw: "); Serial.println(TCRaw); //print raw data TCCelsius = TCRaw * 0.25; //datasheet, 2nd page, resolution Serial.print("Temp: "); Serial.println(TCCelsius); //print converted data if(avgCounter < 10) //If the counter is less than 10, we enter here { temp_avgTCCelsius = temp_avgTCCelsius + TCCelsius; //add the value to the average Serial.println(avgCounter); //print the counter to see where we are avgCounter++; //increase the value by +1 } else //if the counter reached 10, we enter this branch { avgTCCelsius = temp_avgTCCelsius / 10; //calculate the average (10 because 0....9) Serial.print("Avg: "); //print a text ((w/o linebreak) Serial.println(avgTCCelsius); //print the value with a linebreak after temp_avgTCCelsius = 0; //temporary average is set to zero avgCounter = 0; //counting starts over } }