MAX31855 + k-TC + UNO

I use an Arduino UNO to monitor my in-house wood-fired boiler and display some temperatures on an Nokia 5110 LCD. Currently I’m monitoring four water temperatures with DS18B20:s clamped on to the copper pipes (well insulated). Flue gas temperature is measured with a ungrounded k-type thermocouple with stainless external braiding and MAX31855 to interface with the UNO.

The DS18B20:s works great but I have some issues with the TC. I’ve read a lot about noise cancelling so I added a 100nF ceramic cap to the TC input and a 100nF electrolytic cap to the power supply pins of the MAX31855 breakout board. I use a transistor-based level-shifter for 5V<->3.3V. With this setup I get quite a fluctuating measurement ±2oC, plus intermittent (on average every 2-3 seconds) erroneous measurement (displayed as “–” on my LCD) So I tried to add more capacitance (15uF to the TC input and 100 uF to the VCC) with no difference what so ever. However, I found out that if I removed the TC from the flue gas pipe and let it hang in mid-air, the measurement stabilizes significantly. There is no noise on the measurement itself and the interval between erroneous measurements is increased to 15-20 seconds. The flue gas pipe is made from metal and is not activly connected to PE. I’m powering the Arduino system from a switched 9V wall power adapter. It is double insulated so it has no connection to PE either.

As an additional info I can say that I tried to use a stand-alone TC reader which works flawless.

Any inputs on this? There seems to be some issue with the grounding, which is strange because the outer braiding of the TC is NOT in contact with the TC wires (ungrounded).

I mean, there are also other options for this measurement (PT100 or other NTC:s) but it would be nice to use this setup (fast response due to the little mass of the TC and accurate). I attached the code just in case, I believe it is a hardware problem.

#include <SPI.h>
#include <Adafruit_GFX.h>
#include <Adafruit_PCD8544.h>
#include <Adafruit_MAX31855.h>
#include <OneWire.h>
#include <DallasTemperature.h>

// Software SPI (slower updates, more flexible pin options):
// pin 7 - Serial clock out (SCLK)
// pin 6 - Serial data out (DIN)
// pin 5 - Data/Command select (D/C)
// pin 4 - LCD chip select (CS)
// pin 3 - LCD reset (RST)
Adafruit_PCD8544 display = Adafruit_PCD8544(7, 6, 5, 4, 3);

//MAX31855 Thermocouple setup
#define DO   9
#define CS   10
#define CLK  11
Adafruit_MAX31855 thermocouple(CLK, CS, DO);

#define NUMFLAKES 10
#define XPOS 0
#define YPOS 1
#define DELTAY 2
#define LOGO16_GLCD_HEIGHT 16
#define LOGO16_GLCD_WIDTH  16
#define flow 10 // liter/min
#define cp 4.18 // kJ/kg/K
#define roh 1  //kg/dm3

static const unsigned char PROGMEM logo16_glcd_bmp[] =
{ B00000000, B11000000,
 B00000001, B11000000,
 B00000001, B11000000,
 B00000011, B11100000,
 B11110011, B11100000,
 B11111110, B11111000,
 B01111110, B11111111,
 B00110011, B10011111,
 B00011111, B11111100,
 B00001101, B01110000,
 B00011011, B10100000,
 B00111111, B11100000,
 B00111111, B11110000,
 B01111100, B11110000,
 B01110000, B01110000,
 B00000000, B00110000 };

//Setup av 1-wire bus
// Data wire is plugged into pin 8 on the Arduino
#define ONE_WIRE_BUS 8

// Setup a oneWire instance to communicate with any OneWire devices
OneWire oneWire(ONE_WIRE_BUS);

// Pass our oneWire reference to Dallas Temperature. 
DallasTemperature sensors(&oneWire);  

DeviceAddress Topp = { 0x28, 0x5A, 0xA8, 0xEB, 0x03, 0x00, 0x00, 0xCB }; // Givare "1"
DeviceAddress Bott = { 0x28, 0x39, 0xC2, 0xEB, 0x03, 0x00, 0x00, 0xFD }; // Givare "2"
DeviceAddress Framl = { 0x28, 0xFF, 0x49, 0xAF, 0x64, 0x15, 0x02, 0xF5 }; // Givare "3
DeviceAddress Retur = { 0x28, 0xFF, 0x42, 0xAB, 0x64, 0x15, 0x02, 0x8B }; // Givare "4"

void setup()   {
 Serial.begin(9600);
 delay(500);
 //Initiera LCD:n
 display.begin();
 display.setContrast(47);

 //Initiera DS18B20
 sensors.begin();
 sensors.setResolution(Topp, 12);
 sensors.setResolution(Bott, 12);
 sensors.setResolution(Framl, 12);
 sensors.setResolution(Retur, 12);

}


void loop() {
 display.clearDisplay();
 printText();
 printTemps();
 display.display();
}

void printTemps() {
 //Print temps
 //TC temp:
    double c = thermocouple.readCelsius();
  if (isnan(c)||c==0) {
    display.setCursor(61,0);
    display.println("--");
  } else {
   if (c < 100) {
    display.setCursor(61,0);
    display.println(round(c));
   }
   if (c>=100){
    display.setCursor(55,0);
    display.println(round(c));
   }
  }
  

 sensors.requestTemperatures();
 
 float tempC = sensors.getTempC(Topp);
 if (tempC == -127.00) {
   display.setCursor(61,8);
   display.println("--");
 } else {
   display.setCursor(61,8);
   display.println(round(tempC));
 } 
 
 tempC = sensors.getTempC(Bott);
 if (tempC == -127.00) {
   display.setCursor(61,16);
   display.println("--");
 } else {
   display.setCursor(61,16);
   display.println(round(tempC));
 } 
 
 tempC = sensors.getTempC(Framl);
 if (tempC == -127.00) {
   display.setCursor(61,24);
   display.println("--");
 } else {
   display.setCursor(61,24);
   display.println(round(tempC));
 } 
 
 tempC = sensors.getTempC(Retur);
 if (tempC == -127.00) {
   display.setCursor(61,32);
   display.println("--");
 } else {
   display.setCursor(61,32);
   display.println(round(tempC));
 } 

 float tempC1 = sensors.getTempC(Topp);
 float tempC2 = sensors.getTempC(Bott);
 if (tempC1 == -127.00) {
   display.setCursor(61,40);
   display.println("--");
 } else {
   if (tempC2 == -127.00) {
     display.setCursor(61,40);
     display.println("--");
   }
   else {
     double ladd =  (tempC1-tempC2);
     if(ladd <0 && ladd > -10) {
       display.setCursor(49,40);
     display.println(ladd, 1);
       }
     if(ladd <= -10) {
     display.setCursor(43,40);
     display.println(ladd, 1);
       }
     if (ladd >= 0 && ladd <10){
     display.setCursor(55,40);
     display.println(ladd, 1);
     }
     if (ladd >= 10) {
     display.setCursor(49,40);
     display.println(ladd, 1);
     }
   }
 }   
}


void printText() {
 //Print static text
 display.setTextSize(1);
 display.setTextColor(BLACK);
 display.setCursor(0,0);
 display.println("RGT:");
 display.setCursor(78,0);
 display.println("C");
 display.drawCircle(75, 1, 1, BLACK);
 
 display.setCursor(0,8);
 display.println("Topp:");
 display.setCursor(78,8);
 display.println("C");  
 display.drawCircle(75, 9, 1, BLACK);
   
 display.setCursor(0,16);
 display.println("Bott:");
 display.setCursor(78,16);
 display.println("C");
 display.drawCircle(75, 17, 1, BLACK);  

 display.setCursor(0,24);
 display.println("Framl:");
 display.setCursor(78,24);
 display.println("C");
 display.drawCircle(75, 25, 1, BLACK);

 display.setCursor(0,32);
 display.println("Retur:");
 display.setCursor(78,32);
 display.println("C");
 display.drawCircle(75, 33, 1, BLACK);
  
 display.setCursor(0,40);
 display.println("Ladd:");
 display.setCursor(78,40);
 display.println("C");
 display.drawCircle(75, 41, 1, BLACK);  
}

Please use code tags when posting code. You can Modify your post, highlight the code, and press the </> button in the editor.

Thank you for the instruction, post updated.

I suppose you are using Adafruit module

Are u using choke inductors to minimize noise?
Datasheet say nothing about that but look the evaluation kit MAX31855EVKIT

Thermocouple must be 1 meter maxim max.

Look at that! I'm not using any inductors on the input as in the EV-kit. Anyway, I have in total 5 meter (1m TC and 4m extension) between the system and the point of measurements. So clearly out of spec. Interestingly is that it is much better when the TC do not touch the flue gas pipe. But with the 1m constraint, I have to go for another type of sensor.

Thermocouple must be 1 meter maxim max.

I read that on Adafruit webpage.

Take a look at MAX31855 VALUATION KIT about chokes.