Go Down

Topic: MAX31855 library (Read 30396 times) previous topic - next topic

robtillaart

And if you now reconnect the old/first one?
Rob Tillaart

Nederlandse sectie - http://arduino.cc/forum/index.php/board,77.0.html -
(Please do not PM for private consultancy)

Dantos

Tried that, same problem..

I have no idea how these things are connected internally, but it looks like some kind of connection issue.
When I hold it in my hand, the reading goes up right away. (still a few degrees to low)

robtillaart

Can't explain, sorry
Rob Tillaart

Nederlandse sectie - http://arduino.cc/forum/index.php/board,77.0.html -
(Please do not PM for private consultancy)

Dantos

No problem at all.

My only worry is if the chip will prematurely die  if connect the data pins with the 5V of the UNO.

Rudy216

... I split the reading and the fetching of the temperature. So to get a temperature one needs to do 2 calls

status = tc.read();  // workhorse
temp = tc.getTemperature(); // will return same value until a new read.

The reason for this split is 2 fold:
1) more explicit status information -> Adafruit returns NAN when there is a failure
2) The object now automatically is a buffer for the last value read.
Why is this desirable?

robtillaart

It is a design choice to enable a future feature that is waiting for some time and priority :)
Rob Tillaart

Nederlandse sectie - http://arduino.cc/forum/index.php/board,77.0.html -
(Please do not PM for private consultancy)

Declan

Hi Rob,
Thanks for the MAX31855 library - works great.
I would like to use your library to control the heating element of an injection moulding tool.
I am using a Arduino Pro Mini (328P) 3V3 8MHz and the MAX31855 on a custom PCB.
Could I configure/modify your Library to make use of a J-Type thermocouple (This is the standard in our industry).
I would also like to incorporate a PID function/routine - cold you recommend a suitable PID library?

Many Thanks

robtillaart

Hi Rob,
Thanks for the MAX31855 library - works great.
I would like to use your library to control the heating element of an injection moulding tool.
I am using a Arduino Pro Mini (328P) 3V3 8MHz and the MAX31855 on a custom PCB.
Could I configure/modify your Library to make use of a J-Type thermocouple (This is the standard in our industry).
I would also like to incorporate a PID function/routine - cold you recommend a suitable PID library?
Yes feel free to mod it to work for J-TC. The J-TC need an additional scaling of the temperature as the range is slightly different. Should not be a problem as both are quite linear AFAIK, see graph on - https://en.wikipedia.org/wiki/Thermocouple -

The Seebeck coefficient is for J-TC 52uV/C while for K-TC is 41uV/C so the conversion factor = 41/52. At the same temperature the J-TC will output more volts so it must be reduced.
- http://www.analog.com/library/analogDialogue/archives/44-10/thermocouple.html -

So I propose to add the following line to the max31855.h file

double getTemperatureJ(void) { return _temperature * 0.7884615385; };  // 0.7884615385 = 41/52

If you can confirm it to work I will update the library on GitHub accordingly.

Then I will add other too, based upon Seebeck Coefficient  (µV/°C)

E-TC = 61 => 0.6721311475
J-TC = 52 => 0.7884615385
K-TC = 41 => 1
N-TC = 27 => 1.5185185185
R-TC = 9  => 4.5555555556
S-TC = 6  => 6.8333333333
T-TC = 41 => 1


Code: [Select]
double getTemperatureE(void) { return _temperature * 0.6721311475; };
double getTemperatureJ(void) { return _temperature * 0.7884615385; };
double getTemperatureK(void) { return _temperature; };
double getTemperatureN(void) { return _temperature * 1.5185185185; };
double getTemperatureR(void) { return _temperature * 4.5555555556; };
double getTemperatureS(void) { return _temperature * 6.8333333333; };
double getTemperatureT(void) { return _temperature; };  
Rob Tillaart

Nederlandse sectie - http://arduino.cc/forum/index.php/board,77.0.html -
(Please do not PM for private consultancy)

Declan

Thanks Rob,
I have added the line to the MAX31855.h file.
There is a great improvement in the temperature reading using a MAX31855J and J-Type TC.
My temperature on the Serial Monitor is 21.29 Degrees C
Actual ambient, read with Fluke TC instrument meter is 24.6 Degrees C
Could be a calculation issue?

robtillaart

Had a look in the datasheet of the max31855, there were the numbers too for the other TC types. Table 1
The numbers are slightly different, and have more digits, so I adapt the code proposal accordingly

Code: (proposal1) [Select]

#define E_TC    (41.276/76.373)
#define J_TC    (41.276/57.953)
#define K_TC    (41.276/41.276)
#define N_TC    (41.276/36.256)
#define R_TC    (41.276/10.506)
#define S_TC    (41.276/9.587)
#define T_TC    (41.276/52.18)
...
    double getTemperature(void)const { return _temperature; };

    double getTemperatureE(void)const { return _temperature * E_TC; };
    double getTemperatureJ(void)const { return _temperature * J_TC; };
    double getTemperatureK(void)const { return _temperature * K_TC; };
    double getTemperatureN(void)const { return _temperature * N_TC; };
    double getTemperatureR(void)const { return _temperature * R_TC; };
    double getTemperatureS(void)const { return _temperature * S_TC; };
    double getTemperatureT(void)const { return _temperature * T_TC; };


The list of magic number could be an array of float that can be calibrated runtime. As every instance of MAX31855 only has one TC connected there is no need for all 8 functions, only two methods to get and set a conversion factor.

Code: (proposal2) [Select]

#define E_TC    (41.276/76.373)
#define J_TC    (41.276/57.953)
#define K_TC    (41.276/41.276)
#define N_TC    (41.276/36.256)
#define R_TC    (41.276/10.506)
#define S_TC    (41.276/9.587)
#define T_TC    (41.276/52.18)
...
    double getTemperature(void)const { return _temperature * _TCfactor; };

    void setTCfactor(double TCfactor)const { _TCfactor = TCfactor; };
    double getTCfactor(double TCfactor)const { return _TCfactor; };
 ...
   double _TCfactor = 1.0;


Proposal 2 allows for custom calibration. The defines are good starting values for the user of the class. Note that the returned temperature can always be converted outside the class if one wants a more accurate conversion (e.g. non-linear temperature dependant coefficient). In short this proposal sounds more flexible. I'll update the library accordingly.
Rob Tillaart

Nederlandse sectie - http://arduino.cc/forum/index.php/board,77.0.html -
(Please do not PM for private consultancy)

robtillaart

Thanks Rob,
I have added the line to the MAX31855.h file.
There is a great improvement in the temperature reading using a MAX31855J and J-Type TC.
My temperature on the Serial Monitor is 21.29 Degrees C
Actual ambient, read with Fluke TC instrument meter is 24.6 Degrees C
Could be a calculation issue?

just saw your post, could you redo your experiment with the new magic number (41.276/57.953)?

I'll update the lib and post it a.s.a.p on Github so you can easily tune the configuration factor.
Rob Tillaart

Nederlandse sectie - http://arduino.cc/forum/index.php/board,77.0.html -
(Please do not PM for private consultancy)

robtillaart

#41
Dec 06, 2015, 04:57 pm Last Edit: Dec 06, 2015, 04:58 pm by robtillaart
Updated the MAX31855 library - https://github.com/RobTillaart/Arduino/tree/master/libraries/MAX31855

to version 0.1.08. The intermediate versions 0.1.05/6/7 were partly experimental and are available in git.

Changes:
+ support for a TCfactor to support (1st order) other types of ThermoCouples
+ added a demo to show the TCfactor working.
+ made constructor robust
+ fixed smaller issues

Note that this TCfactor is primary meant to support other TC's as discussed in the last few posts.
However it can also be used to calibrate the K-type TC.

As always remarks and comments are welcome.
Rob Tillaart

Nederlandse sectie - http://arduino.cc/forum/index.php/board,77.0.html -
(Please do not PM for private consultancy)

Declan

Hi Rob,
I am using the new library V0.1.08 with an edited version of sketch max31855_demo6
as follows:

Code: [Select]
//
//    FILE: max31855_demo3.ino
//  AUTHOR: Rob Tillaart
// VERSION: 0.1.03
// PURPOSE: thermocouple lib demo application
//    DATE: 2014-01-02
//     URL:
//
// Released to the public domain
//

#include "MAX31855.h"

const int doPin = 12;
const int csPin = 10;
const int clPin = 13;

MAX31855 tc(clPin, csPin, doPin);

void setup()
{
  Serial.begin(115200);
  Serial.print("Start max31855_demo6: ");
  Serial.println(MAX31855_VERSION);
  Serial.println();

  tc.begin();
  tc.read();
  double t1 = tc.getTemperature();
  Serial.print("    temp before:\t");
  Serial.println(t1, 2);

  double tcf = tc.getTCfactor();
  Serial.print("TCfactor before:\t");
  Serial.println(tcf, 4);

  Serial.println("\nDefault adjust for J-type ThermoCouple");
  tc.setTCfactor(J_TC);
  tcf = tc.getTCfactor();
  Serial.print(" TCfactor after:\t");
  Serial.println(tcf, 4);

  tc.read();
  double t2 = tc.getTemperature();
  Serial.print("     temp after:\t");
  Serial.println(t2, 2);

  Serial.print("     temp delta:\t");
  Serial.println(abs(t1 - t2), 2);

  Serial.println("\ndone...");
}
 
void loop()
{
  // this loop returns multiples of about 73mSec (counter multiples of ~143)
  // so the # measurements per second is about 14?
  uint32_t counter = 0;
  double t1 = tc.getTemperature();
  double t2 = t1;

  uint32_t start = micros();
  while (t2 == t1)
  {
    tc.read();
    t1 = tc.getTemperature();
    counter++;
  }
  uint32_t stop = micros();

  Serial.print("change:\t");
  Serial.println(stop - start);
  Serial.print("counter:\t");
  Serial.println(counter);
  Serial.println(t2, 2);
  Serial.println(t1, 2);
  Serial.println();
}


My output received of the Serial Monitor is:

Code: [Select]
Start max31855_demo6: 0.1.08

    temp before: 25.75
TCfactor before: 1.0000

Default adjust for J-type ThermoCouple
 TCfactor after: 0.7122
     temp after: 18.34
     temp delta: 7.41

done...
change: 57424
counter: 61
18.34
18.16

change: 69792
counter: 75
18.16
18.34

change: 1463120
counter: 1573
18.34
18.16

change: 69784
counter: 75
18.16
18.34

change: 802792
counter: 863
18.34
18.16

change: 69776
counter: 75
18.16
18.34

change: 362848
counter: 390
18.34
18.16


The actual ambient temperature as measured with a Fluke instrument is 24.4 deg C.



robtillaart

So apparently the Seebeck coefficient is not that linear (my assumption)

If you change

    tc.setTCfactor(J_TC);
to
    tc.setTCfactor(0.9475);  //   == 24.6/25.75

The value should be around what the fluke says.
Rob Tillaart

Nederlandse sectie - http://arduino.cc/forum/index.php/board,77.0.html -
(Please do not PM for private consultancy)

Declan

OK, with the above change in code, I now have:

Code: [Select]
Start max31855_demo6: 0.1.08

    temp before: 26.25
TCfactor before: 1.0000

Default adjust for J-type ThermoCouple
 TCfactor after: 0.9475
     temp after: 24.87
     temp delta: 1.38

done...
change: 717856
counter: 771
24.87
25.11

change: 68944
counter: 74
25.11
24.87

change: 143400
counter: 154
24.87
25.11

change: 69864
counter: 75
25.11
24.87

change: 2341744
counter: 2516
24.87
25.11

change: 69896
counter: 75
25.11
24.87

change: 436552
counter: 469
24.87
25.11

change: 68920
counter: 74
25.11
24.87

change: 290448
counter: 312
24.87
25.11

change: 68944
counter: 74
25.11
24.87

change: 583584
counter: 627
24.87
25.11

change: 142472
counter: 153
25.11
24.87

change: 69864
counter: 75
24.87
25.11

change: 69864
counter: 75
25.11
24.87

change: 1462240
counter: 1571
24.87
25.11

change: 69896
counter: 75
25.11
24.87

change: 1975520
counter: 2123
24.87
25.11

change: 69856
counter: 75
25.11
24.87

change: 1388872
counter: 1493
24.87
25.11

change: 69856
counter: 75
25.11
24.87

change: 362944
counter: 390
24.87
25.11

change: 69848
counter: 75
25.11
24.87

change: 1902304
counter: 2045
24.87
25.11

change: 68936
counter: 74
25.11
24.87

change: 363776
counter: 391
24.87
25.11

change: 68896
counter: 74
25.11
24.87

change: 2562728
counter: 2755
24.87
25.11

change: 69856
counter: 75
25.11
24.87

change: 1242688
counter: 1336
24.87
25.11

change: 68912
counter: 74
25.11
24.87


and the Fluke shows 25.40 deg C


Go Up