Thermocouple conversion comes up so often that I decided to tidy up some code I'd previously developed in the hope it is useful. This uses a Type K thermocouple and works from 0-999 degrees C. The program as written gives 1 degree resolution throughout the range but with some easy interpolation could give 0.2 degrees. Accuracy will depend on the quality of the thermocouple, wiring, board layout etc, but should be pretty good. All data for conversion is held in an external EEPROM so the main program doesn't use any precious table space or onboard EEPROM. Conversion speed is too fast to time and certainly quicker than the ADC.
I use a MCP342x series ADC to read the thermocouple voltage direct. The ADC has an internal 8x gain pre-amplifier which in 16 bit mode gives 5-6 ADC counts per degree. It must be used in this mode to match the conversion tables provided.
To make the conversion easy I've programmed up an EEPROM with ADC values from 0-999 degrees C. I use a DS18B20 to read the cold junction temperature. This must be placed in the same location as the joints between the thermocouple wires and the copper wiring to the ADC.
So the complete circuit is an I2C capable picaxe, a EEPROM (min 16KB), a MCP342x series ADC which in the case of the MCP3424 can read 4 channels, and a DS18B20. To program the EEPROM (a one off activity) you will need a I2C capable picaxe with 4096 bytes of program memory.
The example conversion program below uses just 239 bytes of memory so could be run on a 08M2.
There is direct table lookup for both the thermocouple conversion and the coldjunction compensation - no maths required!
The magic is in the contents of the EEPROM. The load program is:
View attachment eepromload.bas
This programs the EEPROM and does a sanity check to make sure all is OK. It takes about 5 minutes to run.
If you want a MCP3424 ready mounted to play with you can get them from various sources but I've had success with Jeelabs (just ignore their bizarre labelling of the I2C signals)
Hope this is useful
Best regards
Peter
I use a MCP342x series ADC to read the thermocouple voltage direct. The ADC has an internal 8x gain pre-amplifier which in 16 bit mode gives 5-6 ADC counts per degree. It must be used in this mode to match the conversion tables provided.
To make the conversion easy I've programmed up an EEPROM with ADC values from 0-999 degrees C. I use a DS18B20 to read the cold junction temperature. This must be placed in the same location as the joints between the thermocouple wires and the copper wiring to the ADC.
So the complete circuit is an I2C capable picaxe, a EEPROM (min 16KB), a MCP342x series ADC which in the case of the MCP3424 can read 4 channels, and a DS18B20. To program the EEPROM (a one off activity) you will need a I2C capable picaxe with 4096 bytes of program memory.
The example conversion program below uses just 239 bytes of memory so could be run on a 08M2.
Code:
'
' Type K thermocouple measurement using a picaxe, a 16kb eeprom and a MCP342x series ADC
'
#picaxe 28x2
symbol scratch=b25
symbol scratch1=b26
symbol wordlow0 = b0
symbol wordhigh0 = b1
symbol coldjunction=b2
symbol cjconvert=w10
symbol cjconvertlow=b20
symbol cjconverthigh=b21
symbol typek=w11
symbol typeklow=b22
symbol typekhigh=b23
symbol ADCreading=w12
'
' ADC constants
'
symbol ADC = %11011000 ' set to match your hardware, NB base address is same as DS1307
symbol Chan0= %10000000
symbol Chan1= %10100000
symbol Chan2= %11000000
symbol Chan3= %11100000
symbol Gain1=%00000000
symbol Gain2=%00000001
symbol Gain4=%00000010
symbol Gain8=%00000011
symbol Bits12=%00000000
symbol Bits14=%00000100
symbol Bits16=%00001000
symbol ADCtimeout=5' tune the timeout if using faster clock speeds
'
symbol SEEPROM =%10100000
symbol cjtableoffset=$3000
'
gosub I2Cclear' routine to clear jammed i2c bus if system is reset while slave write is ongoing
'
hi2csetup i2cmaster, ADC, i2cslow, i2cbyte 'NB we are going to have to handle the word addressed eeprom in byte mode to match the MCP3424
'
do
'
'
readtemp A.1,coldjunction
if coldjunction>127 then: coldjunction=0:endif 'don't allow a negative cold junction temperature
w0=coldjunction*2+cjtableoffset 'convert to the word address of the lookup table in the EEPROM
'
hi2cout [SEEPROM],(wordhigh0,wordlow0) 'send out the word address
hi2cin [SEEPROM],(cjconverthigh,cjconvertlow)' read in the equivalent thermocouple ADC reading
'
b0= CHAN0 | Gain8 | Bits16 'Must be gain 8 and Bits16 for thermocouple conversion
gosub rADC 'returns reading in w0
'
ADCreading = w0 ' save for printout
w0=w0+cjconvert 'add the cold junction equivalent reading into the thermocouple value
w0=w0*2 ' convert to a word address for lookup in the EEPROM
'
hi2cout [SEEPROM],(wordhigh0,wordlow0)
hi2cin [SEEPROM],(typekhigh,typeklow)
'
sertxd ("Coldjunction: ",#coldjunction," ADC equivalent: ",#cjconvert," ADC reading: ",#ADCreading," Temperature: ",#typek,cr,lf)
'
pause 1000
loop
'
rADC:
' read thermocouple with parameters defined in b0
'
hi2cout [ADC],(b0)
scratch1=ADCtimeout ' tune the timeout if using faster clock speeds
waitADC1:
pause 75
hi2cin [ADC],(wordhigh0,wordlow0,scratch)
scratch =scratch & %10000000
dec scratch1
if scratch != 0 and scratch1 !=0 then waitADC1
if scratch1 <>0 then
' successful conversion do any local processing here if required
else
' error condition here if required
endif
return
'
' clear the i2c bus if jammed
'
I2Cclear:
input c.4
output c.3
high c.3
do while pinc.4=0
low c.3
pause 50
high c.3
pause 50
loop
return
The magic is in the contents of the EEPROM. The load program is:
View attachment eepromload.bas
This programs the EEPROM and does a sanity check to make sure all is OK. It takes about 5 minutes to run.
If you want a MCP3424 ready mounted to play with you can get them from various sources but I've had success with Jeelabs (just ignore their bizarre labelling of the I2C signals)
Hope this is useful
Best regards
Peter
Last edited: