Possible Sparkfun Library Issue: SparkFun Thermocouple Amplifier MCP9600

Sparkfun product: https://www.sparkfun.com/products/16295

Board: Official Arduino Nano

Library: https://github.com/sparkfun/SparkFun_MC … no_Library

I checked out the examples and learned how to use this amplifier before implementing it in my program. I noticed that unless I had a Serial.print immediately before getting the reading, the reading would just return 0. After confirming that it really was because I was removing the serial line, I went back to the sparkfun MCP9600 library example and tried the same. The BasicReadings example works fine, but if you comment out this line the reading will fail:

Serial.print("Thermocouple: ");

I’ve tried replacing it with delays of various lengths and it still fails. It has to be a serial.print with at LEAST 5 characters. Any less and the problem persists so it makes me think it is some kind of timing issue.

Can someone with one of these sensor boards confirm this? Here is the library example:

This code will work:

/*
  Temperature Measurements with the MCP9600 Thermocouple Amplifier
  By: Fischer Moseley
  SparkFun Electronics
  Date: July 8, 2019
  License: This code is public domain but you buy me a beer if you use this and we meet someday (Beerware License).

  This example outputs the ambient and thermocouple temperatures from the MCP9600 sensor.

  Hardware Connections:
  Attach the Qwiic Shield to your Arduino/Photon/ESP32 or other
  Plug the sensor onto the shield
  Serial.print it out at 115200 baud to serial monitor.
*/

#include <SparkFun_MCP9600.h>
MCP9600 tempSensor;

void setup(){
    Serial.begin(115200);
    Wire.begin();
    Wire.setClock(100000);
    tempSensor.begin();       // Uses the default address (0x60) for SparkFun Thermocouple Amplifier
    //tempSensor.begin(0x66); // Default address (0x66) for SparkX Thermocouple Amplifier

    //check if the sensor is connected
    if(tempSensor.isConnected()){
        Serial.println("Device will acknowledge!");
    }
    else {
        Serial.println("Device did not acknowledge! Freezing.");
        while(1); //hang forever
    }

    //check if the Device ID is correct
    if(tempSensor.checkDeviceID()){
        Serial.println("Device ID is correct!");        
    }
    else {
        Serial.println("Device ID is not correct! Freezing.");
        while(1);
    }
}

void loop(){ //print the thermocouple, ambient and delta temperatures every 200ms if available
    if(tempSensor.available()){
        Serial.print("Thermocouple: ");
        Serial.print(tempSensor.getThermocoupleTemp());
        Serial.print(" °C   Ambient: ");
        Serial.print(tempSensor.getAmbientTemp());
        Serial.print(" °C   Temperature Delta: ");
        Serial.print(tempSensor.getTempDelta());
        Serial.print(" °C");
        Serial.println();
        delay(20); //don't hammer too hard on the I2C bus
    }
}

Output:

Device will acknowledge!
Device ID is correct!
Thermocouple: 20.62 c   Ambient: 66.09 c   Temperature Delta: 34.81 c
Thermocouple: 20.50 c   Ambient: 65.86 c   Temperature Delta: 34.81 c
Thermocouple: 20.44 c   Ambient: 65.75 c   Temperature Delta: 34.81 c
Thermocouple: 20.56 c   Ambient: 65.97 c   Temperature Delta: 34.81 c
Thermocouple: 20.44 c   Ambient: 65.75 c   Temperature Delta: 34.81 c
Thermocouple: 20.75 c   Ambient: 66.20 c   Temperature Delta: 34.93 c
Thermocouple: 20.69 c   Ambient: 66.09 c   Temperature Delta: 34.93 c
Thermocouple: 20.69 c   Ambient: 66.09 c   Temperature Delta: 34.93 c
Thermocouple: 20.56 c   Ambient: 65.86 c   Temperature Delta: 34.93 c
Thermocouple: 20.69 c   Ambient: 66.09 c   Temperature Delta: 35.04 c
Thermocouple: 20.69 c   Ambient: 66.09 c   Temperature Delta: 35.04 c
Thermocouple: 20.56 c   Ambient: 65.86 c   Temperature Delta: 35.04 c
Thermocouple: 20.56 c   Ambient: 65.86 c   Temperature Delta: 35.04 c

This will NOT work:

/*
  Temperature Measurements with the MCP9600 Thermocouple Amplifier
  By: Fischer Moseley
  SparkFun Electronics
  Date: July 8, 2019
  License: This code is public domain but you buy me a beer if you use this and we meet someday (Beerware License).

  This example outputs the ambient and thermocouple temperatures from the MCP9600 sensor.

  Hardware Connections:
  Attach the Qwiic Shield to your Arduino/Photon/ESP32 or other
  Plug the sensor onto the shield
  Serial.print it out at 115200 baud to serial monitor.
*/

#include <SparkFun_MCP9600.h>
MCP9600 tempSensor;

void setup(){
    Serial.begin(115200);
    Wire.begin();
    Wire.setClock(100000);
    tempSensor.begin();       // Uses the default address (0x60) for SparkFun Thermocouple Amplifier
    //tempSensor.begin(0x66); // Default address (0x66) for SparkX Thermocouple Amplifier

    //check if the sensor is connected
    if(tempSensor.isConnected()){
        Serial.println("Device will acknowledge!");
    }
    else {
        Serial.println("Device did not acknowledge! Freezing.");
        while(1); //hang forever
    }

    //check if the Device ID is correct
    if(tempSensor.checkDeviceID()){
        Serial.println("Device ID is correct!");        
    }
    else {
        Serial.println("Device ID is not correct! Freezing.");
        while(1);
    }
}

void loop(){ //print the thermocouple, ambient and delta temperatures every 200ms if available
    if(tempSensor.available()){
        //Serial.print("Thermocouple: ");
        Serial.print(tempSensor.getThermocoupleTemp());
        Serial.print(" °C   Ambient: ");
        Serial.print(tempSensor.getAmbientTemp());
        Serial.print(" °C   Temperature Delta: ");
        Serial.print(tempSensor.getTempDelta());
        Serial.print(" °C");
        Serial.println();
        delay(20); //don't hammer too hard on the I2C bus
    }
}

output:

Device will acknowledge!
Device ID is correct!
20.19 c   Ambient: 65.97 c   Temperature Delta: 34.14 c
0.00 c   Ambient: 65.75 c   Temperature Delta: 32.00 c
0.00 c   Ambient: 65.97 c   Temperature Delta: 34.36 c
0.00 c   Ambient: 65.75 c   Temperature Delta: 34.36 c
0.00 c   Ambient: 65.97 c   Temperature Delta: 34.36 c
0.00 c   Ambient: 65.86 c   Temperature Delta: 34.47 c
0.00 c   Ambient: 65.97 c   Temperature Delta: 34.36 c
0.00 c   Ambient: 65.97 c   Temperature Delta: 34.47 c
0.00 c   Ambient: 65.97 c   Temperature Delta: 32.00 c
0.00 c   Ambient: 65.97 c   Temperature Delta: 34.47 c
0.00 c   Ambient: 65.97 c   Temperature Delta: 34.47 c
0.00 c   Ambient: 65.75 c   Temperature Delta: 34.47 c
0.00 c   Ambient: 65.97 c   Temperature Delta: 34.47 c

What are you trying to accomplish? Why remove the line at all?

Because I have no need to have serial on in my project and would prefer to not have it printing useless stuff out to serial when nothings connected to it.

I implemented the temperature reading in my own program which is how I came across this issue.

It happens with the official spark fun library example, not just my code, so I know it isn’t anything I’ve done wrong.

A functional library should not be dependent on having a serial print before part of it.

The MCP9600 is known for having issues due to clock stretching E.g. look at this old post https://forum.odroid.com/viewtopic.php?t=35437.

In the Sparkfun library, it retries 3 times to read a register before giving up and returning 0. An Arduino Nano normally handles clock stretching very well. Clock stretching is performed by a peripheral as it needs more time to process and I think the issue is that the MCP9600 needs even more time to process the data. Replacing the Serial.print() with a delay (say 50ms) can do the job OR try to reduce the Wire-speed to a lower value of 83Khz as suggested in the old post.

Oooh thanks, that thread does look promising. I had tried adding delays, but I’ll give it another shot. I will also try playing with the bus speed. I’ll be using some I/O expanders along side this, so hopefully they play nicely with a slower speed. Thanks!

Let us know how it works out.

One more thing you can try is to increase the retryattemps before giving up. In SparkFun_MCP9600.h, line 30, change

#define retryAttempts 3 

Increase it from 3 to say 30. (max 255)

Finally getting time to try these out today.

I added a delay in place of the serial print and tried values from 25 to 100 in 25ms increments. 50 was the best and managed to read around half of the time.

Next I tried playing with the Wire.setClock value. I tried 10KHz as suggested in the post you linked to and that worked reliably. Then I tried 83KHz which seemed to be what everyone said worked best but I had problems with it as well.

I increased it one at at time until I found 94KHz to be 100% reliable.

I think I’ll write a sketch that starts at 100KHz and runs until it fails a reading from the temp sensor, then it will log that to serial before resetting itself and trying with 99KHz and so on. That way I get a solid idea of what works and what doesn’t with my setup.

Interesting results from running that trying every speed. Unfortunately I’m out of time for today, I’ll let it run over the weekend to see how it looks.

Miss = failed readings, Get = successful readings.

Speed: 100000 Miss: 5 Get: 0
Speed: 99000 Miss: 5 Get: 0
Speed: 98000 Miss: 5 Get: 0
Speed: 97000 Miss: 5 Get: 0
Speed: 96000 Miss: 5 Get: 24
Speed: 95000 Miss: 1 Get: 1000
Speed: 94000 Miss: 0 Get: 1000
Speed: 93000 Miss: 0 Get: 1000
Speed: 92000 Miss: 0 Get: 1000
Speed: 91000 Miss: 0 Get: 1000
Speed: 90000 Miss: 0 Get: 1000
Speed: 89000 Miss: 0 Get: 1000
Speed: 88000 Miss: 0 Get: 1000
Speed: 87000 Miss: 0 Get: 1000
Speed: 86000 Miss: 0 Get: 1000
Speed: 85000 Miss: 0 Get: 1000
Speed: 84000 Miss: 5 Get: 3
Speed: 83000 Miss: 5 Get: 4
Speed: 82000 Miss: 5 Get: 8
Speed: 81000 Miss: 5 Get: 2
Speed: 80000 Miss: 5 Get: 25
Speed: 79000 Miss: 5 Get: 31
Speed: 78000 Miss: 2 Get: 1000
Speed: 77000 Miss: 0 Get: 1000
Speed: 76000 Miss: 0 Get: 1000
Speed: 75000 Miss: 0 Get: 1000
Speed: 74000 Miss: 0 Get: 1000
Speed: 73000 Miss: 0 Get: 1000
Speed: 72000 Miss: 0 Get: 1000
Speed: 71000 Miss: 0 Get: 1000
Speed: 70000 Miss: 0 Get: 1000
Speed: 69000 Miss: 0 Get: 1000
Speed: 68000 Miss: 0 Get: 1000
Speed: 67000 Miss: 0 Get: 1000
Speed: 66000 Miss: 0 Get: 1000
Speed: 65000 Miss: 0 Get: 1000

Alright, here is a full run. For some reason it seems to lock up whenever the wire speed is below 31000, so it doesn’t include anything below that. Keep in mind that this is with six PCF8574 I/O expanders on the bus, so YMMV.

Speed: 100000 Miss: 5 Get: 0
Speed: 99000 Miss: 5 Get: 0
Speed: 98000 Miss: 5 Get: 0
Speed: 97000 Miss: 5 Get: 1
Speed: 96000 Miss: 5 Get: 145
Speed: 95000 Miss: 1 Get: 1000
Speed: 94000 Miss: 0 Get: 1000
Speed: 93000 Miss: 0 Get: 1000
Speed: 92000 Miss: 0 Get: 1000
Speed: 91000 Miss: 0 Get: 1000
Speed: 90000 Miss: 0 Get: 1000
Speed: 89000 Miss: 0 Get: 1000
Speed: 88000 Miss: 0 Get: 1000
Speed: 87000 Miss: 0 Get: 1000
Speed: 86000 Miss: 0 Get: 1000
Speed: 85000 Miss: 5 Get: 1
Speed: 84000 Miss: 5 Get: 9
Speed: 83000 Miss: 5 Get: 4
Speed: 82000 Miss: 5 Get: 11
Speed: 81000 Miss: 5 Get: 1
Speed: 80000 Miss: 5 Get: 20
Speed: 79000 Miss: 5 Get: 45
Speed: 78000 Miss: 0 Get: 1000
Speed: 77000 Miss: 0 Get: 1000
Speed: 76000 Miss: 0 Get: 1000
Speed: 75000 Miss: 0 Get: 1000
Speed: 74000 Miss: 0 Get: 1000
Speed: 73000 Miss: 0 Get: 1000
Speed: 72000 Miss: 0 Get: 1000
Speed: 71000 Miss: 0 Get: 1000
Speed: 70000 Miss: 0 Get: 1000
Speed: 69000 Miss: 0 Get: 1000
Speed: 68000 Miss: 0 Get: 1000
Speed: 67000 Miss: 0 Get: 1000
Speed: 66000 Miss: 0 Get: 1000
Speed: 65000 Miss: 0 Get: 1000
Speed: 64000 Miss: 5 Get: 7
Speed: 63000 Miss: 5 Get: 1
Speed: 62000 Miss: 5 Get: 2
Speed: 61000 Miss: 5 Get: 3
Speed: 60000 Miss: 5 Get: 8
Speed: 59000 Miss: 5 Get: 2
Speed: 58000 Miss: 0 Get: 1000
Speed: 57000 Miss: 0 Get: 1000
Speed: 56000 Miss: 0 Get: 1000
Speed: 55000 Miss: 0 Get: 1000
Speed: 54000 Miss: 0 Get: 1000
Speed: 53000 Miss: 0 Get: 1000
Speed: 52000 Miss: 0 Get: 1000
Speed: 51000 Miss: 0 Get: 1000
Speed: 50000 Miss: 0 Get: 1000
Speed: 49000 Miss: 0 Get: 1000
Speed: 48000 Miss: 0 Get: 1000
Speed: 47000 Miss: 0 Get: 1000
Speed: 46000 Miss: 0 Get: 1000
Speed: 45000 Miss: 0 Get: 1000
Speed: 44000 Miss: 0 Get: 1000
Speed: 43000 Miss: 0 Get: 1000
Speed: 42000 Miss: 0 Get: 1000
Speed: 41000 Miss: 0 Get: 1000
Speed: 40000 Miss: 0 Get: 1000
Speed: 39000 Miss: 0 Get: 1000
Speed: 38000 Miss: 0 Get: 1000
Speed: 37000 Miss: 0 Get: 1000
Speed: 36000 Miss: 0 Get: 1000
Speed: 35000 Miss: 0 Get: 1000
Speed: 34000 Miss: 0 Get: 1000
Speed: 33000 Miss: 0 Get: 1000
Speed: 32000 Miss: 0 Get: 1000

Here is the test code:

	if (tcamp1.available()){
		int temperatureRead = (int)tcamp1.getThermocoupleTemp(false);
		if (temperatureRead == 32) {
			readingmissed++;
		}
		else {
			//set your temperature variable stuff in here, if needed
			readinggot++;
		}
		if (readingmissed == 5 || readinggot == 1000) { //if we miss 5 or we successfully get 1000, move on.
			Serial.print("Speed: ");
			Serial.print(wirespeed);
			//Serial.print(" temp: ");
			//Serial.print(temperatureRead);
			Serial.print(" Miss: ");
			Serial.print(readingmissed);
			Serial.print(" Get: ");
			Serial.println(readinggot);
			wirespeed = wirespeed - 1000;
			if (wirespeed == 9000) { //low limit, stop at 10KHz
				Serial.println("Test Completed.");
				while(1);
			}
			Wire.setClock(wirespeed);
			readingmissed = 0;
			readinggot = 0;
		}	
	}