Coder Social home page Coder Social logo

max31855_rt's Introduction

Arduino CI Arduino-lint JSON check GitHub issues

License: MIT GitHub release PlatformIO Registry

MAX31855_RT

Arduino library for MAX31855 chip for K type thermocouple.

The library has experimental support for other types of thermocouples E, J, N, R, S, T.

Description

The MAX38155 is a chip to convert the reading of a K-type thermocouple to a temperature. The working of thermocouples (TC) is based upon Seebeck effect. Different TC's have a different Seebeck Coefficient (SC) expressed in µV/°C. See http://www.analog.com/library/analogDialogue/archives/44-10/thermocouple.html

For every type of TC there exist an MAX31855 variant, this library is primary developed for the K-type sensor. However it has experimental support for all other types of TC's. See details below.

Library tested with breakout board.

         +---------+
     Vin | o       |
     3V3 | o       |
     GND | o     O | Thermocouple
      D0 | o     O | Thermocouple
      CS | o       |
     CLK | o       |
         +---------+

0.6.0 Breaking change

Version 0.6.0 introduced a breaking change to improve handling the SPI dependency. The user has to call SPI.begin() or equivalent before calling MX.begin(). Optionally the user can provide parameters to the SPI.begin(...)

0.5.0 Breaking change

The version 0.5.0 has breaking changes in the interface. The essence is removal of ESP32 specific code from the library. This makes it possible to support the ESP32-S3 and other processors in the future. Also it makes the library a bit simpler to maintain.

Note the order of the parameters of the software SPI constructor has changed in 0.5.0.

Related

Hardware SPI vs software SPI

Default pin connections. ESP32 can overrule with setGPIOpins().

HW SPI UNO ESP32 VSPI ESP32 HSPI Notes
CLOCKPIN 13 18 14
MISO 12 19 12
MOSI 11 23 13 not used...
SELECT 4 5 15 can be others too.

Performance read() function, timing in us. (ESP32 @240MHz)

mode clock timing UNO timing ESP32 Notes
HW SPI 32000000 ni ~15 less reliable
HW SPI 16000000 ~68 ~16
HW SPI 4000000 ~72 ~23
HW SPI 1000000 ~100 ~51
HW SPI 500000 ~128 ~89
SW SPI bit bang ~500 ~17 (!)

Interface

#include "MAX31855.h"

Constructor

  • MAX31855(uint8_t select, SPIClassRP2040 * mySPI) hardware SPI R2040
  • MAX31855(uint8_t select, SPIClass * mySPI) hardware SPI other
  • MAX31855(uint8_t select, uint8_t miso, uint8_t clock) software SPI
  • void begin() initialize internals

Hardware SPI

To be used only if one needs a specific speed.

  • void setSPIspeed(uint32_t speed) set SPI transfer rate.
  • uint32_t getSPIspeed() returns SPI transfer rate.
  • void setSWSPIdelay(uint16_t del = 0) for tuning SW SPI signal quality. Del is the time in micros added per bit. Even numbers keep the duty cycle of the clock around 50%.
  • uint16_t getSWSPIdelay() get set value in micros.

Reading

To make a temperature reading call read(). It returns the status of the read which is a value between 0..7 The function getStatus() returns the same status value.

Table: values returned from uint8_t read() and uint8_t getStatus()

value Description Action
0 OK
1 Thermocouple open circuit check wiring
2 Thermocouple short to GND check wiring
4 Thermocouple short to VCC check wiring
7 Generic error
128 No read done yet check wiring
129 No communication check wiring

There are six functions to check the individual error conditions mentioned above. These make it easier to check them.

  • bool openCircuit()
  • bool shortToGND()
  • bool shortToVCC()
  • bool genericError()
  • bool noRead()
  • bool noCommunication()

After a uint8_t read() you can get the temperature with float getTemperature() and float getInternal() for the internal temperature of the chip / board itself. Normally these are (almost) equal.

Repeated calls to getTemperature() will give the same value until a new read(). The latter fetches a new value from the sensor. Note that if the read() fails the value of getTemperature() can become incorrect. So it is important to check the return value of read().

Offset

The library supports a fixed offset to calibrate the thermocouple. For this the functions float getOffset() and void setOffset(float offset) are available. This offset is "added" in the getTemperature() function.

Notes

  • the offset can be positive or negative.
  • the offset used is a float, so decimals can be used. A typical usage is to call setOffset(273.15) to get ° Kelvin.

Delta analysis

As the tc object holds its last known temperature it is easy to determine the delta with the last known temperature, e.g. for trend analysis.

  float last = tc.getTemperature();
  int state  = tc.read();
  if (state == STATUS_OK)
  {
    float new  = tc.getTemperature();
    float delta = new - last;
    // process data
  }

Last time read

The tc object keeps track of the last time read() is called in the function uint32_t lastRead(). The time is tracked in millis(). This makes it easy to read the sensor at certain intervals.

if (millis() - tc.lastRead() >= interval)
{
  int state = tc.read();
  if (state == STATUS_OK)
  {
    float new = tc.getTemperature();
    // process read value.
  }
  else
  {
    // handle error
  }
}

GetRawData

The function uint32_t getRawData() allows you to get all the 32 bits raw data from the board, after the standard uint8_t tc.read() call.

Example code can be found in the examples folder.

  int state = thermocouple.read();              
  uint32_t value = thermocouple.getRawData();  // Read the raw Data value from the module

This allows one to compact the measurement e.g. for storage or sending over a network.

Pull Up Resistor

To have proper working of the MAX31855 board, you need to add a pull-up resistor (e.g. 4K7 - 1K depending on length of the wires) between the MISO pin (from constructor call) and the VCC (5Volt). This improves the signal quality and will allow you to detect if there is proper communication with the board. Without pull-up one might get random noise that could look like real data.

Note: the MISO pin can be different from each board, please refer to your board datasheet.

If the MAX31855 board is not connected tc.read() will return STATUS_NO_COMMUNICATION.

You can verify this by tc.getRawData() which will give 32 HIGH bits or 0xFFFFFFFF).

You can use a simple code to detect connection error board:

  uint8_t status = thermocouple.read();
  if (status == STATUS_NO_COMMUNICATION)
  {
    Serial.println("NO COMMUNICATION");
  }

or

  uint8_t status = thermocouple.read();
  if (thermocouple.getRawData() == 0xFFFFFFFF)
  {
    Serial.println("NO COMMUNICATION");
  }

Operation

See examples

Experimental part (to be tested)

NOTE: The support for other thermocouples is experimental use at your own risk.

The MAX31855 is designed for K type sensors. It essentially measures a voltage difference and converts this voltage using the Seebeck Coefficient (SC) to the temperature. As the SC is linear in its nature it is possible to replace the K-type TC with one of the other types of TC.

Datasheet Table 1, page 8 SC = Seebeck Coefficient

Sensor type SC in µV/°C Temp Range in °C Material
E_TC 76.373 -270 to +1000 Constantan Chromel
J_TC 57.953 -210 to +1200 Constantan Iron
K_TC 41.276 -270 to +1372 Alumel Chromel
N_TC 36.256 -270 to +1300 Nisil Nicrosil
R_TC 10.506 -50 to +1768 Platinum Platinum/Rhodium
S_TC 9.587 +50 to +1768 Platinum Platinum/Rhodium
T_TC 52.18 -270 to +400 Constantan Copper

The core formula to calculate the temperature is (Datasheet page 8)

Vout = (41.276µV/°C) x (Temp_R - Temp_internal)

As we know the internal temperature and the returned temperature from the sensor the library can calculate the Vout measured (as the chip assumes that a K-type thermocouple is connected. Having that Vout we can redo the math for the actual thermocouple type and calculate the real temperature.

The library has two functions setSeebeckCoefficient(float factor) and float getSeebeckCoefficient() to get/set the Seebeck Coefficient (== thermocouple) to be used. One can adjust the values to improve the accuracy of the temperature read.

The float getTemperature() has implemented this algorithm, however as long as one does not set the Seebeck Coefficient it will use the K_TC as default.

Future

Must

Should

  • investigate other TC's

Could

  • move code to .cpp

Wont

Support

If you appreciate my libraries, you can support the development and maintenance. Improve the quality of the libraries by providing issues and Pull Requests, or donate through PayPal or GitHub sponsors.

Thank you,

max31855_rt's People

Contributors

fabiobrondo avatar pmarchini avatar robtillaart avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar

max31855_rt's Issues

Would this work on ESP32-S3?

I have no idea about link pin between ESP32-S3 and MAX31855. ESP32-S3 pin function map is display below. If I ref this project for ESP32-S3, will setGPIOpins() work well like that on ESP32 ?

My pin defined like this: https://github.com/Zanduino
MAX31855

const uint32_t SERIAL_SPEED     = 115200; ///< Set the baud rate for Serial I/O
const uint8_t  SPI_CHIP_SELECT  =     10; ///< Chip-Select PIN for SPI
const uint8_t  SPI_MISO         =     37; ///< Master-In, Slave-Out PIN for SPI
const uint8_t  SPI_SYSTEM_CLOCK =     36; ///< System Clock PIN for SPI

Mentioned github project run well on Arduino uno R3, But the temperature always reported zero on ESP32-S3. :< Is there some guidance? Thanks!

Ambient Temperature is 0.000°C
Probe Temperature is   0.000°C

Ambient Temperature is 0.000°C
Probe Temperature is   0.000°C

ESP32-S3_DevKitC-1_pinlayout_v1 1

Random internal temperature & thermocouple readings

I tested two modules with 3 boards, I get the same readings:
I added 10nF cap between T- and T+, and in one board, I cut the connection between T- and gnd

20:47:19.425 -> Status: STATUS_OK
20:47:19.425 -> RAW: 1100-1000-0100-1100-1000-0100-0101-0000
20:47:19.425 -> Internal: -123.688
20:47:19.425 -> TMP: -891.250
20:47:20.413 -> Status: STATUS_OK
20:47:20.413 -> RAW: 1100-1000-0000-1000-1000-0100-0110-0000
20:47:20.413 -> Internal: -123.625
20:47:20.413 -> TMP: -895.500
20:47:21.405 -> Status: STATUS_OK
20:47:21.405 -> RAW: 1100-0111-1111-0000-1000-0011-1101-0000
20:47:21.405 -> Internal: -124.188
20:47:21.405 -> TMP: -897.000
20:47:22.436 -> Status: STATUS_OK
20:47:22.436 -> RAW: 1100-1000-0000-0100-1000-0011-1111-0000
20:47:22.436 -> Internal: -124.063
20:47:22.436 -> TMP: -895.750
20:47:23.455 -> Status: STATUS_OK
20:47:23.455 -> RAW: 1100-1000-0001-1100-1000-0011-1000-0000
20:47:23.455 -> Internal: -124.500
20:47:23.455 -> TMP: -894.250
20:47:24.435 -> Status: STATUS_OK
20:47:24.435 -> RAW: 1100-1010-1111-1100-1011-0011-0110-0000
20:47:24.435 -> Internal: -76.625
20:47:24.435 -> TMP: -848.250
20:47:25.440 -> Status: STATUS_OK
20:47:25.440 -> RAW: 1100-1011-1111-1000-1100-0011-0001-0000
20:47:25.440 -> Internal: -60.937
20:47:25.440 -> TMP: -832.500
20:47:26.434 -> Status: STATUS_OK
20:47:26.434 -> RAW: 1100-1100-1111-0000-1101-0010-1111-0000
20:47:26.434 -> Internal: -45.062
20:47:26.434 -> TMP: -817.000
20:47:27.432 -> Status: STATUS_OK
20:47:27.432 -> RAW: 1100-1010-1111-1000-1011-0010-1110-0000
20:47:27.432 -> Internal: -77.125
20:47:27.432 -> TMP: -848.500
20:47:28.459 -> Status: STATUS_OK
20:47:28.459 -> RAW: 1100-1011-0010-1000-1011-0010-1110-0000
20:47:28.459 -> Internal: -77.125

Thank you

Random reads on temps

I have exactly the same problem from "#19". All random readings from internal temp and thermocouple temp BUT ok with bitflags control.

photo_2021-12-05_11-57-50
photo_2021-12-05_11-54-54

NOTE: On this image, there is a flag, but when i say it give random temp data all flags is 0.

NodeMCU ESP32 <SPI(sw) 8cm wire lenght> MAX31855 (clone from ebay and cut T- and GND)
Arduino UNO <SPI(sw) 8cm wire lenght> MAX31855 (clone from ebay and cut T- and GND)

I have oscilloscope to check SPI readings (software) and i see good comms. I have tested ok bit flags from erros from the thermocouple (SHORT to GND, SHORT to VCC, no thermocouple). When i see the bits from rawdata and check with oscilloscope, the data match.

ESP32 dont work for me with SPI HW on VSPI nor HSPI.

Oh, i have tested with 3 clones from ebay, and 1 from aliexpress. All same problem.

I have questions:

  • I see on the oscilloscope the CLK inverted (VCC at start) and on the datasheet i see its GND at start. Anyway it take good data when fall CLK.
  • I see on oscilloscope that freq is 2Mhz with sw, and i dont know if it is need to reach 5Mhz.
  • Without thermocouple connected, the internal temp still works?

Thank you for your time :)

Error in MAX31855 when using HWSPI on STM32

When I use the original Max31855 library v0.2.4 the temperature display is not correct. (is to high)

Hardware: STM32DUINO STM32F405RGT6
https://www.tindie.com/products/icstation/stm32f4-micropython-stm32-pyboard-module11882/

Hardware SPI:
PA7 // SPI1_MOSI
PA6 // SPI1_MISO
PA5 // SPI1_SCLK
PA4 // SPI1_SS

Temperature not correct

I changed the source code as follows and the temeprature display was correct.

Temperature correct

MAX31855.cpp

uint32_t MAX31855::_read(void)
{
  _rawData = 0;
  
  if (_hwSPI)
  {
    SPI.beginTransaction(SPISettings(16000000, MSBFIRST, SPI_MODE0));
    digitalWrite(_cs, LOW);
	
    for (uint8_t i = 0; i < 4; i++)
    {
      _rawData <<= 8;
      _rawData += SPI.transfer(0);
    }
    digitalWrite(_cs, HIGH);
    SPI.endTransaction();
  }
  else
  {
    digitalWrite(_cs, LOW);
    for (int8_t i = 31; i >= 0; i--)
    {
      _rawData <<= 1;
      digitalWrite(_sclk, LOW);
      // delayMicroseconds(1);  // DUE
      if ( digitalRead(_miso) ) _rawData++;
      digitalWrite(_sclk, HIGH);
      // delayMicroseconds(1);  // DUE
    }
    digitalWrite(_cs, HIGH);
  }
  return _rawData;
}

The CS signal must be between SPI.beginTransaction and SPI.endTransaction. Can anyone confirm this?

if tc.read() fails then the last Temperatures held internally might get corrupted when updated

When the tc.read() is called and the state returned is an error, it might be that the value of the temperature that is held by the tc object is incorrect.

So it seems better to return status as soon as it is detected it is not OK

in code

uint8_t MAX31855::read()
{
   ....
  // process status bit 0-2   
  _status = value & 0x0007;
  if (_status) return _status;   // do not update _temperature and _internal as they might be incorrect.

Improvement Request

Hello Rob!

Could be usefull to have the possibility to take the raw value out from the class.
Is possible to have the rawData keyword to have the raw value from the board?

Also, could be usefull to insert a fourth error status, "No Board", checking if all the bits of the message are == 0.
I'm doing some test but the actual code is not discriminating from no thermocouple and no board at all.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.