Hi,
I figured out how to get a temperature reading from a THMOD-I2C I2C thermocouple reader.
It was more complicated than I expected, with two interpolated lookup tables with numbers gleaned from the datasheet. Anyway I'm there now, so I thought I'd share my efforts with the class. Hope it's of use to someone.
It works by polling the cold junction temperature reading from a thermistor next to the terminals on the THMOD board, and using that to look up a correction factor for the thermocouple voltage reading. Then it looks up the corrected thermocouple voltage from another lookup table, and interpolates from that to find the hot junction temperature.
The lookup tables are stored in program memory at the beginning. There are 3 models of THMOD, each with different temperature ranges and different lookup tables. You'll need to uncomment the one that suits your THMOD.
Enjoy!
#include <Wire.h>
// Pins: Standard: SDA:A4 SCL:A5
// Mega: SDA:D20 SCL:D21
// Lookup tables for THMOD conversion
const int DigitTable[] PROGMEM = {512, 3072, 5632, 8192, 10752, 13312, 15872, 18432, 20992, 23552, 26112, 28672, 31232}; // 300, 800, 1360
//const int CorrectionTable[] PROGMEM = {-1156, -778, -392, 0, 397, 798, 1203, 1612, 2023, 2436, 2851, 3267, 3682}; // 300
//const int CorrectionTable[] PROGMEM = {-578, -389, -196, 0, 199, 399, 602, 806, 1012, 1218, 1426, 1634, 1841}; // 800
const int CorrectionTable[] PROGMEM = {-385, -259, -131, 0, 132, 266, 401, 537, 674, 812, 950, 1089, 1227}; // 1360
//const int TemperatureTable[] PROGMEM = {-150, -100, -50, 0, 50, 100, 200, 300, 400}; // 300
//const int ThermoVoltageTable[] PROGMEM = {6609, 8946, 10611, 12500, 14523, 16596, 20638, 24709, 28897}; // 300
//const int TemperatureTable[] PROGMEM = {-150, -100, -50, 0, 50, 100, 200, 300, 400, 500, 600, 700, 800, 900, 1000, 1100, 1200, 1300}; // 800
//const int ThermoVoltageTable[] PROGMEM = {3305, 4473, 5309, 6250, 7262, 8298, 10319, 12355, 14449, 16572, 18703, 20815, 22888, 24913, 26888, 28810, 30669, 32455}; // 800
const int TemperatureTable[] PROGMEM = {-150, -100, -50, 0, 50, 100, 200, 300, 400, 500, 600, 700, 800, 900, 1000, 1100, 1200, 1300, 1370}; // 1360
const int ThermoVoltageTable[] PROGMEM = {2203, 2982, 3537, 4167, 4841, 5532, 6879, 8236, 9632, 11048, 12468, 13876, 15258, 16609, 17925, 19206, 20446, 21637, 22440}; // 1360
void setup()
{
Serial.begin(9600);
Serial.println("Setup...");
Wire.begin(); // join i2c bus (address optional for master)
PORTC = (1 << PORTC4) | (1 << PORTC5); //enable I2C pullups
}
void loop()
{
float TCTemperature = ThermocoupleRead(0x78);
Serial.print("Temp: ");
Serial.println(TCTemperature);
delay(200);
}
float ThermocoupleRead(char TCAddress)
{
int XHi;
int XLo;
int YHi;
int YLo;
byte a;
// Read thermocouple voltages
Wire.requestFrom(TCAddress, 4);
int ThermoVoltage = Wire.read() * 256;
ThermoVoltage = (ThermoVoltage + Wire.read());
int ColdJunction = Wire.read() * 256;
ColdJunction = (ColdJunction + Wire.read());
Wire.endTransmission();
// Use lookup table for cold junction compensation
XHi = 0;
a = 0;
while (XHi < ColdJunction)
{
XLo = XHi;
YLo = YHi;
XHi = pgm_read_word_near(DigitTable + a);
YHi = pgm_read_word_near(CorrectionTable + a);
a++;
}
ThermoVoltage = ThermoVoltage + ((long)(YHi - YLo) * (long)(ColdJunction - XLo) / (XHi - XLo)) + YLo;
// Use lookup table for thermocouple temperature
XHi = 0;
a = 0;
while (XHi < ThermoVoltage)
{
XLo = XHi;
YLo = YHi;
XHi = pgm_read_word_near(ThermoVoltageTable + a);
YHi = pgm_read_word_near(TemperatureTable + a);
a++;
}
// Return temperature
return ((float)(YHi - YLo) / (float)(XHi - XLo)) * (ThermoVoltage - XLo) + YLo;
}