Skip to content

Commit 8b5e72e

Browse files
FischerMoseleyfischermoseley
andcommitted
Created .h and .cpp, added coeffecient and thermocouple type setting
Co-Authored-By: fischermoseley <fischermoseley@users.noreply.github.com>
1 parent a0c2390 commit 8b5e72e

File tree

5 files changed

+379
-0
lines changed

5 files changed

+379
-0
lines changed
Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
/*
2+
Temperature Measurements with the MCP9600 Thermocouple Amplifier
3+
By: Fischer Moseley
4+
SparkFun Electronics
5+
Date: July 8, 2019
6+
License: This code is public domain but you buy me a beer if you use this and we meet someday (Beerware License).
7+
8+
This example outputs the ambient and thermocouple temperatures from the MCP9600 sensor.
9+
10+
Hardware Connections:
11+
Attach the Qwiic Shield to your Arduino/Photon/ESP32 or other
12+
Plug the sensor onto the shield
13+
Serial.print it out at 115200 baud to serial monitor.
14+
*/
15+
16+
#include <SparkFun_MCP9600.h>
17+
MCP9600 tempSensor;
18+
19+
void setup(){
20+
Serial.begin(115200);
21+
22+
//check if the sensor is connected
23+
if(tempSensor.isConnected()){
24+
Serial.println("Device will acknowledge!");
25+
}
26+
else {
27+
Serial.println("Device did not acknowledge! Freezing.");
28+
while(1); //hang forever
29+
}
30+
31+
//check if the Device ID is correct
32+
if(tempSensor.checkDeviceID()){
33+
Serial.println("Device ID is correct!");
34+
}
35+
else {
36+
Serial.println("Device ID is not correct! Freezing.");
37+
while(1);
38+
}
39+
}
40+
41+
void loop(){ //print the thermocouple, ambient and delta temperatures every 200ms
42+
Serial.print("Thermocouple: ");
43+
Serial.print(tempSensor.thermocoupleTemp());
44+
Serial.print(" °C Ambient: ");
45+
Serial.print(tempSensor.ambientTemp());
46+
Serial.print(" °C Temperature Delta: ");
47+
Serial.print(tempSensor.tempDelta());
48+
Serial.print(" °C");
49+
Serial.println();
50+
delay(200);
51+
}
Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
/*
2+
Setting Thermocouple Type with the MCP9600 Thermocouple Amplifier
3+
By: Fischer Moseley
4+
SparkFun Electronics
5+
Date: July 8, 2019
6+
License: This code is public domain but you buy me a beer if you use this and we meet someday (Beerware License).
7+
8+
This example outputs the ambient and thermocouple temperatures from the MCP9600 sensor, but allows for a non
9+
K-type thermocouple to be used.
10+
11+
Hardware Connections:
12+
Attach the Qwiic Shield to your Arduino/Photon/ESP32 or other
13+
Plug the sensor onto the shield
14+
Serial.print it out at 115200 baud to serial monitor.
15+
*/
16+
17+
#include <SparkFun_MCP9600.h>
18+
MCP9600 tempSensor;
19+
20+
void setup(){
21+
Serial.begin(115200);
22+
23+
//check if the sensor is connected
24+
if(tempSensor.isConnected()){
25+
Serial.println("Device will acknowledge!");
26+
}
27+
else {
28+
Serial.println("Device did not acknowledge! Freezing.");
29+
while(1); //hang forever
30+
}
31+
32+
//check if the Device ID is correct
33+
if(tempSensor.checkDeviceID()){
34+
Serial.println("Device ID is correct!");
35+
}
36+
else {
37+
Serial.println("Device ID is not correct! Freezing.");
38+
while(1);
39+
}
40+
41+
Serial.println("Setting Thermocouple Type!");
42+
43+
if(tempSensor.setThermocoupleType(Stype) == 0){
44+
Serial.println("Thermocouple Type set sucessfully!");
45+
}
46+
47+
else{
48+
Serial.println("Setting Thermocouple Type failed!");
49+
}
50+
}
51+
52+
void loop(){ //print the thermocouple, ambient and delta temperatures every 200ms
53+
Serial.print("Thermocouple: ");
54+
Serial.print(tempSensor.thermocoupleTemp());
55+
Serial.print(" °C Ambient: ");
56+
Serial.print(tempSensor.ambientTemp());
57+
Serial.print(" °C Temperature Delta: ");
58+
Serial.print(tempSensor.tempDelta());
59+
Serial.print(" °C");
60+
Serial.println();
61+
delay(200);
62+
}
Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
/*
2+
Setting Filter Coeffecients with the MCP9600 Thermocouple Amplifier
3+
By: Fischer Moseley
4+
SparkFun Electronics
5+
Date: July 8, 2019
6+
License: This code is public domain but you buy me a beer if you use this and we meet someday (Beerware License).
7+
8+
This example outputs the ambient and thermocouple temperatures from the MCP9600 sensor, but allows the filtering
9+
onboard the MCP9600 to be controlled. The MCP9600 implements an exponential running average filter, the
10+
"strength" of which is programmable! The setFilterCoeffecients function takes a coeffecient between 0 and 7,
11+
where 0 disables the filter, 1 corresponds to minimum filtering, and 7 enables maximum filtering. The "strength"
12+
of the filter just refers to how long it takes for the filter to respond to a step function input.
13+
14+
Hardware Connections:
15+
Attach the Qwiic Shield to your Arduino/Photon/ESP32 or other
16+
Plug the sensor onto the shield
17+
Serial.print it out at 115200 baud to serial monitor.
18+
*/
19+
20+
#include <SparkFun_MCP9600.h>
21+
MCP9600 tempSensor;
22+
23+
void setup(){
24+
Serial.begin(115200);
25+
26+
//check if the sensor is connected
27+
if(tempSensor.isConnected()){
28+
Serial.println("Device will acknowledge!");
29+
}
30+
else {
31+
Serial.println("Device did not acknowledge! Freezing.");
32+
while(1); //hang forever
33+
}
34+
35+
//check if the Device ID is correct
36+
if(tempSensor.checkDeviceID()){
37+
Serial.println("Device ID is correct!");
38+
}
39+
else {
40+
Serial.println("Device ID is not correct! Freezing.");
41+
while(1);
42+
}
43+
44+
//print the filter coeffecient that's about to be set
45+
uint8_t coeffecient = 4;
46+
Serial.print("Setting Filter Coeffecient to ");
47+
Serial.print(coeffecient);
48+
Serial.println("!");
49+
50+
//tell us if the coeffecient was set sucessfully
51+
if(tempSensor.setFilterCoeffecients(coeffecient) == 0){
52+
Serial.println("Filter Coeffecients set sucessfully!");
53+
}
54+
55+
else{
56+
Serial.println("Setting filter coeffecient failed!");
57+
}
58+
}
59+
60+
void loop(){ //print the thermocouple, ambient and delta temperatures every 200ms
61+
Serial.print("Thermocouple: ");
62+
Serial.print(tempSensor.thermocoupleTemp());
63+
Serial.print(" °C Ambient: ");
64+
Serial.print(tempSensor.ambientTemp());
65+
Serial.print(" °C Temperature Delta: ");
66+
Serial.print(tempSensor.tempDelta());
67+
Serial.print(" °C");
68+
Serial.println();
69+
delay(200);
70+
}

src/SparkFun_MCP9600.cpp

Lines changed: 121 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,121 @@
1+
/******************************************************************************
2+
SparkFun_MCP9600.h
3+
SparkFun_MCP9600 Library Source File
4+
Fischer Moseley @ SparkFun Electronics
5+
Original Creation Date: July 8, 2019
6+
https://github.com/sparkfunX/Qwiic_MCP9600_Thermocouple
7+
8+
This file implements the MCP9600 class, prototyped in SparkFun_MCP9600.cpp.
9+
10+
Development environment specifics:
11+
IDE: Arduino 1.8.9
12+
Hardware Platform: Arduino Uno/SparkFun Redboard
13+
MCP9600 Breakout Version: 1.0.0
14+
15+
This code is beerware; if you see me (or any other SparkFun employee) at the
16+
local, and you've found our code helpful, please buy us a round!
17+
18+
Distributed as-is; no warranty is given.
19+
******************************************************************************/
20+
#include <Wire.h>
21+
#include <SparkFun_MCP9600.h>
22+
23+
#if defined(ARDUINO) && ARDUINO >= 100
24+
#include "Arduino.h"
25+
#else
26+
#include "WProgram.h"
27+
#endif
28+
29+
MCP9600::MCP9600(uint8_t address, TwoWire &wirePort){
30+
_deviceAddress = address; //grab the address that the sensor is on
31+
_i2cPort = &wirePort; //grab the port that the user wants to use
32+
_i2cPort->begin();
33+
_i2cPort->setClock(10000);
34+
}
35+
36+
bool MCP9600::isConnected(){
37+
_i2cPort->beginTransmission(_deviceAddress);
38+
return (_i2cPort->endTransmission() == 0);
39+
}
40+
41+
uint16_t MCP9600::deviceID(){
42+
return readDoubleRegister(DEVICE_ID);
43+
}
44+
45+
bool MCP9600::checkDeviceID(){
46+
return (highByte(deviceID()) == DEV_ID_UPPER);
47+
}
48+
49+
float MCP9600::thermocoupleTemp(){
50+
int16_t raw = readDoubleRegister(HOT_JUNC_TEMP);
51+
return ((float)raw * DEV_RESOLUTION);
52+
}
53+
54+
float MCP9600::ambientTemp(){
55+
int16_t raw = readDoubleRegister(COLD_JUNC_TEMP);
56+
return ((float)raw * DEV_RESOLUTION);
57+
}
58+
59+
float MCP9600::tempDelta(){
60+
int16_t raw = readDoubleRegister(DELTA_JUNC_TEMP);
61+
return ((float)raw * DEV_RESOLUTION);
62+
}
63+
64+
uint8_t MCP9600::setThermocoupleType(thermocoupleType type){
65+
uint8_t config = readSingleRegister(THERMO_SENSOR_CONFIG);
66+
bitClear(config, 4); //clear the necessary bits so that they can be set
67+
bitClear(config, 5);
68+
bitClear(config, 6);
69+
config |= (type << 4); //set the necessary bits in the config register
70+
if(writeSingleRegister(THERMO_SENSOR_CONFIG, config) != 0) return 1; //if write fails, return 1
71+
if(readSingleRegister(THERMO_SENSOR_CONFIG) != config) return 2; //if the register didn't take the new value, return 2
72+
73+
return 0; //otherwise return 0
74+
}
75+
76+
uint8_t MCP9600::setFilterCoeffecients(uint8_t coeffecient){
77+
if(coeffecient > 7) return 3; //return immediately if the value is too big
78+
79+
uint8_t config = readSingleRegister(THERMO_SENSOR_CONFIG);
80+
bitClear(config, 0); //clear the necessary bits so that they can be set
81+
bitClear(config, 1);
82+
bitClear(config, 2);
83+
config |= coeffecient; //set the necessary bits in the config register
84+
if(writeSingleRegister(THERMO_SENSOR_CONFIG, config) != 0) return 1; //if the write fails, return 1
85+
if(readSingleRegister(THERMO_SENSOR_CONFIG) != config) return 2; //if the register didn't take the new value, return 2
86+
87+
}
88+
89+
uint8_t MCP9600::readSingleRegister(MCP9600_Register reg){
90+
for(uint8_t attempts; attempts <= retryAttempts; attempts++){
91+
_i2cPort->beginTransmission(DEV_ADDR);
92+
_i2cPort->write(reg);
93+
_i2cPort->endTransmission();
94+
if(_i2cPort->requestFrom(DEV_ADDR, 1) != 0){
95+
return _i2cPort->read();
96+
}
97+
}
98+
return;
99+
}
100+
101+
uint16_t MCP9600::readDoubleRegister(MCP9600_Register reg){
102+
for(byte attempts; attempts <= retryAttempts; attempts++){
103+
_i2cPort->beginTransmission(DEV_ADDR);
104+
_i2cPort->write(reg);
105+
_i2cPort->endTransmission();
106+
107+
if(_i2cPort->requestFrom(DEV_ADDR, 2) != 0){
108+
uint16_t data = _i2cPort->read() << 8;
109+
data |= _i2cPort->read();
110+
return data;
111+
}
112+
}
113+
return;
114+
}
115+
116+
uint8_t MCP9600::writeSingleRegister(MCP9600_Register reg, uint8_t data){
117+
_i2cPort->beginTransmission(_deviceAddress);
118+
_i2cPort->write(reg);
119+
_i2cPort->write(data);
120+
return _i2cPort->endTransmission();
121+
}

src/SparkFun_MCP9600.h

Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
/******************************************************************************
2+
SparkFun_MCP9600.h
3+
SparkFun_MCP9600 Library Header File
4+
Fischer Moseley @ SparkFun Electronics
5+
Original Creation Date: July 8, 2019
6+
https://github.com/sparkfunX/Qwiic_MCP9600_Thermocouple
7+
8+
This file prototypes the MCP9600 class, implemented in SparkFun_MCP9600.cpp.
9+
10+
Development environment specifics:
11+
IDE: Arduino 1.8.9
12+
Hardware Platform: Arduino Uno/SparkFun Redboard
13+
MCP9600 Breakout Version: 1.0.0
14+
15+
This code is beerware; if you see me (or any other SparkFun employee) at the
16+
local, and you've found our code helpful, please buy us a round!
17+
18+
Distributed as-is; no warranty is given.
19+
******************************************************************************/
20+
21+
#ifndef __SparkFun_MCP9600_H__
22+
#define __SparkFun_MCP9600_H__
23+
24+
#include <Wire.h>
25+
#include <Arduino.h>
26+
27+
#define DEV_ADDR 0x66 //device address of the MCP9600
28+
#define DEV_ID_UPPER 0x40 //value of the upper half of the device ID register. lower half is used for device revision
29+
#define DEV_RESOLUTION 0.0625 //device resolution (temperature in C that the LSB represents)
30+
#define retryAttempts 3 //how many times to attempt to read a register from the thermocouple before giving up
31+
32+
// register pointers for various device functions
33+
enum MCP9600_Register {
34+
HOT_JUNC_TEMP = 0x00,
35+
DELTA_JUNC_TEMP = 0x01,
36+
COLD_JUNC_TEMP = 0x02,
37+
STATUS = 0x04,
38+
THERMO_SENSOR_CONFIG = 0x05,
39+
DEVICE_CONFIG = 0x06,
40+
DEVICE_ID = 0x20,
41+
};
42+
43+
enum thermocoupleType {
44+
Ktype = 0b000,
45+
Jtype = 0b001,
46+
Ttype = 0b010,
47+
Ntype = 0b011,
48+
Stype = 0b100,
49+
Etype = 0b101,
50+
Btype = 0b110,
51+
Rtype = 0b111,
52+
};
53+
54+
class MCP9600{
55+
public:
56+
MCP9600(uint8_t address = DEV_ADDR, TwoWire &wirePort = Wire); //Class constructor
57+
bool isConnected(); //Returns true if the thermocouple will acknowledge over I2C, and false otherwise
58+
uint16_t deviceID(); //Returns the contents of the device ID register. The upper 8 bits are constant, but the lower contain revision data.
59+
bool checkDeviceID(); //Returns true if the constant upper 8 bits in the device ID register are what they should be according to the datasheet.
60+
61+
float thermocoupleTemp(); //Returns the thermocouple temperature in degrees Celcius
62+
float ambientTemp(); //Returns the ambient (IC die) temperature in degrees Celcius
63+
float tempDelta(); //Returns the difference in temperature between the thermocouple and ambient junctions, in degrees Celcius
64+
65+
uint8_t setThermocoupleType(thermocoupleType type); //Sets the type of thermocouple connected to the MCP9600. Supported types are KJTNSEBR.
66+
uint8_t setFilterCoeffecients(uint8_t coeffecient); //Sets how heavy of an exponential moving average filter to use. Set this to 0 for no filter, 1 for minimum filter, and 7 for maximum filter.
67+
68+
private:
69+
TwoWire *_i2cPort; //Generic connection to user's chosen I2C port
70+
uint8_t _deviceAddress; //I2C address of the MCP9600
71+
uint8_t readSingleRegister(MCP9600_Register reg); //Attempts to read a single register, will keep trying for retryAttempts amount of times
72+
uint16_t readDoubleRegister(MCP9600_Register reg); //Attempts to read two registers, will keep trying for retryAttempts amount of times
73+
uint8_t writeSingleRegister(MCP9600_Register reg, uint8_t data); //Attempts to write data into a single 8-bit register. Does not check to make sure it was written successfully.
74+
};
75+
#endif

0 commit comments

Comments
 (0)