Need help with my Max31856 thermocouple program
Capt. Quirk
Posts: 872
I believe my problem is with how I am sending a byte address and a byte of data to
PUB Config_Data. The max 31856 is intended to work with 8 bit micro-processors.
I think my problem is I am sending byte of hex data, and when it gets to the Config_Data
routine it is converted to a long and Config_Data only reads the first the first 8 bits.
Bill M.
PUB Config_Data. The max 31856 is intended to work with 8 bit micro-processors.
I think my problem is I am sending byte of hex data, and when it gets to the Config_Data
routine it is converted to a long and Config_Data only reads the first the first 8 bits.
Bill M.
CON '' Max31856.spin {{ Copied portions of: * Propeller SPI Engine ... Spin Version v1.0 * * Author: Beau Schwabe * * Copyright (c) 2009 Parallax * * PlayingWithFusion_MAX31856.c ----------------------------------------------------------- Notes: Use Mode 3, Msbpost for Writes and Reads CS0 must idle high !! }} CON _clkmode = xtal1 + pll8x _xinfreq = 10_000_000 ' Write Registers Write_REG_CR0 = $80 ' Config Reg 0 - See Datasheet, pg 19 Write_REG_CR1 = $81 ' Config Reg 1 - averaging and TC type Write_REG_MASK = $82 ' Fault mask register (for fault pin) Write_REG_CJHF = $83 ' Cold Jcn high fault threshold, 1 degC/bit Write_REG_CJLF = $84 ' Cold Jcn low fault threshold, 1 degC/bit Write_REG_LTHFTH = $85 ' TC temp high fault threshold, MSB, 0.0625 degC/bit Write_REG_LTHFTL = $86 ' TC temp high fault threshold, LSB Write_REG_LTLFTH = $87 ' TC temp low fault threshold, MSB, 0.0625 degC/bit Write_REG_LTLFTL = $88 ' TC temp low fault threshold, LSB Write_REG_CJTO = $89 ' Cold Jcn Temp Offset Reg, 0.0625 degC/bit Write_REG_CJTH = $8A ' Cold Jcn Temp Reg, MSB, 0.015625 deg C/bit (2^-6) Write_REG_CJTL = $8B ' Cold Jcn Temp Reg, LSB ' Read Registers Read_REG_CR0_Read = $00 ' Config Reg 0 - See Datasheet, pg 19 Read_REG_CR1_Read = $01 ' Config Reg 1 - averaging and TC type Read_REG_MASK_Read = $02 ' Fault mask register (for fault pin) Read_REG_CJHF_Read = $03 ' Cold Jcn high fault threshold, 1 degC/bit Read_REG_CJLF_Read = $04 ' Cold Jcn low fault threshold, 1 degC/bit Read_REG_LTHFTH_Read = $05 ' TC temp high fault threshold, MSB, 0.0625 degC/bit Read_REG_LTHFTL_Read = $06 ' TC temp high fault threshold, LSB Read_REG_LTLFTH_Read = $07 ' TC temp low fault threshold, MSB, 0.0625 degC/bit Read_REG_LTLFTL_Read = $08 ' TC temp low fault threshold, LSB Read_REG_CJTO_Read = $09 ' Cold Jcn Temp Offset Reg, 0.0625 degC/bit Read_REG_CJTH_Read = $0A ' Cold Jcn Temp Reg, MSB, 0.015625 deg C/bit (2^-6) Read_REG_CJTL_Read = $0B ' Cold Jcn Temp Reg, LSB Read_REG_LTCBH_Read = $0C ' Linearized TC Temp, Byte 2, 0.0078125 decC/bit Read_REG_LTCBM_Read = $0D ' Linearized TC Temp, Byte 1 Read_REG_LTCBL_Read = $0E ' Linearized TC Temp, Byte 0 Read_REG_SR_Read = $0F ' Status Register ' CR0 Configs CMODE_OFF = $00 CMODE_AUTO = $80 ONESHOT_OFF = $00 ONESHOT_ON = $40 OCFAULT_OFF = $00 OCFAULT_10MS = $10 OCFAULT_32MS = $20 OCFAULT_100MS = $30 CJ_ENABLED = $00 CJ_DISABLED = $08 FAULT_AUTO = $00 FAULT_MANUAL = $04 FAULT_CLR_DEF = $00 FAULT_CLR_ALT = $02 CUTOFF_60HZ = $00 CUTOFF_50HZ = $01 ' CR1 Configs AVG_SEL_1SAMP = $00 AVG_SEL_2SAMP = $20 AVG_SEL_4SAMP = $40 AVG_SEL_8SAMP = $60 AVG_SEL_16SAMP = $80 B_TYPE = $00 E_TYPE = $01 J_TYPE = $02 K_TYPE = $03 N_TYPE = $04 R_TYPE = $05 S_TYPE = $06 T_TYPE = $07 {{ MASK Configs CJ_HIGH_MASK = $20 CJ_LOW_MASK = $10 TC_HIGH_MASK = $08 TC_LOW_MASK = $04 OV_UV_MASK = $02 OPEN_FAULT_MASK = $01 ' ----------------------------- Config Details ------------------------------- ' Write_REG_CR0 = $80 ' Config Reg 0 - See Datasheet, pg 19 ' CR0 Configs CMODE_OFF = $00 ONESHOT_ON = $40 OCFAULT_OFF = $00 CJ_ENABLED = $00 FAULT_AUTO = $00 FAULT_CLR_DEF = $00 CUTOFF_60HZ = $00 '---------------------------- ' Address: $80 'REG_CR0 ' Write Data $40 'CR0_Data ' Write_REG_CR1 = $81 ' Config Reg 1 - averaging and TC type ' CR1 Configs AVG_SEL_1SAMP = $00 K_TYPE = $03 '%x000_0011 = $03 '---------------------------- ' Address: $81 'REG_CR1 ' Write Data $03 'CR1_Data Read_REG_LTCBH = $0C ' Linearized TC Temp, Byte 2, 0.0078125 decC/bit Read_REG_LTCBM = $0D ' Linearized TC Temp, Byte 1 Read_REG_LTCBL = $0E ' Linearized TC Temp, Byte 0 CS0 must idle high !! Msbpost for Writes and Reads '' Used for SHIFTIN routines '' MSBPOST = 2 '' MSBPOST - Most Significant Bit first ; data is valid after the clock '' Used for SHIFTOUT routines '' MSBFIRST = 5 '' MSBFIRST - Most Significant Bit first ; data is valid after the clock '------------------- End Config Details ----------------------------------------------------- }} CS0 = 0 'CS1 = 1 'CS2 = 2 'CS3 = 3 CLK = 1 MISO = 2 ' MISO MOSI = 3 ' MOSI ClockDelay = 500 ' spi pulse width C_Konstant = 0.0078125 ' float used to convert data to celsius F_Konstant = 1.8 ' float used to convert celsius to farenhiet '------------------------------------------------------------------------------------------- OBJ pst : "Parallax Serial Terminal" '---------------------------------------------------------------------------------------------- PUB Main | temp, tempC, tempF pst.Start(115_200) ' Start the pst console. waitcnt(clkfreq + cnt) ' min 200us delay outa[CS0] := 1 ' CS0 idles high ' outa[CS0,CS1,CS2,CS3] := 1 ' CS0 has 4 possible inputs on this board made by Playing with Fusion. ' http://www.playingwithfusion.com/productview.php?pdid=70 outa[clk]:= 0 ' clock idles low '' I believe I am sending a long filled with a byte of data, and when "Config_Data" '' runs, it is shifting in the msb of the long and not the msb of the byte I intended '' it too. Config_Data(CS0, $80, $40) ' Configure Address $80; $40 Config Data Config_Data(CS0, $81, $03) ' Configure Address $81; $03 Config Data waitcnt(clkfreq/4 + cnt) ' must have a ~200ms delay before the first conversion ' could change it to: waitcnt(16000000 + cnt) = .2ms Repeat ' Config_Data(CS0, Address, Config) ' Update the current TC, for new data format, like ' 4 read average. pst.clear temp:= Lin_TC_Temp(CS0, $C) ' Pass the IC# and the address ($0C) to be read. ' return the binary 19 bit result if temp == 0 ' A test to see if "Config_Data" was sucessful? pst.str(string("No Data")) ' temp >>= 5 ' Convert 24 bit# into a 19 bit# '' Convert binary output to celsius tempC := C_Konstant * temp ' C_Konstant = .0078125 pst.dec(tempC) ' tempF := (tempC * F_Konstant) + 32 ' F_Konstant = 1.8 pst.dec(tempF) ' must have a ~200ms delay before the next single conversion pst.str(string(pst#NL,"Test Complete")) pst.Chars(pst#NL, 3) waitcnt(clkfreq + cnt) ' Use a 1 second delay while testing. ' -------------------------------------------------------------------------------- PUB Config_Data(_CS, Address, Config) '' Should be OK '' outa[_CS]:= 0 ' Clock idles HIGH repeat 8 ' bits Address <<= 8 ' shift a byte into the ic outa[clk]:=1 outa[MOSI] := (Address <-= 1) & 1 ' config data is loaded to master data out outa[clk]:= 0 ' data is latched inside max31856 pst.hex(Address, 2) repeat 8 ' bits Config <<= 8 ' shift a byte into the ic outa[clk]:=1 outa[MOSI] := (Config <-= 1) & 1 ' config data is loaded to master data out outa[clk]:= 0 ' data is latched inside max31856 pst.hex(Config,2) outa[_CS]:= 1 ' CS0 idles HIGH ' -------------------------------------------------------------------------------- PUB Lin_TC_Temp(_CS, address) | Data ' address is $C ' Clock idles LOW ' CS0 idles HIGH outa[_CS]:= 0 ' CS0 low '' Address is OK '' repeat 8 ' bits Address <<= 8 ' shift a byte into the ic outa[clk]:=1 outa[MOSI] := (Address <-= 1) & 1 ' config data is loaded to master data out outa[clk]:= 0 ' data is latched inside max31856 'waitcnt(clkfreq/10 + cnt) ' delay between each byte write repeat 24 PreClock(clk) data := (data << 1) | ina[MISO] outa[_CS]:= 1 Return Data ' --------------------------------------------------------------------------------------------------- PUB PostClock(_Cpin) waitcnt(ClockDelay + cnt) !outa[_Cpin] waitcnt(ClockDelay + cnt) !outa[_Cpin] ' -------------------------------------------------------------------------------------------------------- PUB PreClock(_Cpin) !outa[_Cpin] waitcnt(ClockDelay + cnt) !outa[_Cpin] waitcnt(ClockDelay + cnt)
pdf
552K
Comments
I've only messed with the MAX31855, which seems to be a completely different beast.
You've also got a problem with mixing floats and integers in your conversions. You either have to convert the integer reading from the MAX31856 into a float, multiply using your floating point constants, and use a float-to-string object to display it; or preferably instead of multiplying the reading by 0.0078125, you'd instead divide it by 128. To convert to Fahrenheit, you cannot use the floating 1.8 constant, but have to multiply by 9 and divide by 5, add 32. In order to not lose any lower bits, you could multiply by 900, divide by 5, and add 3200, yielding degrees F x 100.
I might need help on the accuracy in the future, but right now the temps are close.
Bill M.
I am interested in any suggestions to improve it. I am curious about the CJ temperature function,
and why it may or may not be necessary with this chip? The data sheet says the CJ temp is taken
in account before the TC temp is outputted.
I need to begin testing with tc temp averaging. The chip offers averaging of 2, 4, 8, and 16 samples.
There is no need for the software to be fast, but I do want to fine tune the accuracy, make the code as
reliable as possible, and I need to set-up a data acquisition, with a display asap.
Thanks for taking some time!
Bill M.
Any advice on writing code?
If you're making decisions based on the temperature, it'd be a good idea to read the fault status register before accepting the data.
Not sure why you'd need a waitcnt at the beginning of the object.
A number of methods could be slightly simplified if you only have a single SPI device by hardcoding outa[CS0]~ rather than using a CSpin parameter.
Instead of having code for shifting data out in multiple places, I'd use a single method and call it as needed such as Spin is slow enough that you probably don't need to specify a clock delay.
Nothing too glaring; those are all just personal preferences, the most important thing is if it works.
Good job with the version control; that's something that I struggle with--make a change, save as a new file, and later on forget what the difference is between my dozen or so files.