From 60198127ba24e3a1375a6bc377be6eb08edf67f5 Mon Sep 17 00:00:00 2001 From: Alberto Lopez Date: Mon, 29 Jul 2019 17:54:28 -0300 Subject: [PATCH] Added Adafruit MX31865 Library to Repo Added a #define to compensate for low quality PTD probes --- lib/Adafruit_MAX31865-1.1.0-custom | 1 - .../Adafruit_MAX31865.cpp | 286 ++++++++++++++++++ .../Adafruit_MAX31865.h | 99 ++++++ lib/Adafruit_MAX31865-1.1.0-custom/README.md | 2 + lib/Adafruit_MAX31865-1.1.0-custom/README.txt | 16 + .../examples/max31865/max31865.ino | 74 +++++ .../library.properties | 9 + sonoff/my_user_config.h | 1 + sonoff/xsns_47_max31865.ino | 19 +- 9 files changed, 500 insertions(+), 7 deletions(-) delete mode 160000 lib/Adafruit_MAX31865-1.1.0-custom create mode 100644 lib/Adafruit_MAX31865-1.1.0-custom/Adafruit_MAX31865.cpp create mode 100644 lib/Adafruit_MAX31865-1.1.0-custom/Adafruit_MAX31865.h create mode 100644 lib/Adafruit_MAX31865-1.1.0-custom/README.md create mode 100644 lib/Adafruit_MAX31865-1.1.0-custom/README.txt create mode 100644 lib/Adafruit_MAX31865-1.1.0-custom/examples/max31865/max31865.ino create mode 100644 lib/Adafruit_MAX31865-1.1.0-custom/library.properties diff --git a/lib/Adafruit_MAX31865-1.1.0-custom b/lib/Adafruit_MAX31865-1.1.0-custom deleted file mode 160000 index 83027ecdd..000000000 --- a/lib/Adafruit_MAX31865-1.1.0-custom +++ /dev/null @@ -1 +0,0 @@ -Subproject commit 83027ecdd5c8e059510fcca5f230451c55ad078a diff --git a/lib/Adafruit_MAX31865-1.1.0-custom/Adafruit_MAX31865.cpp b/lib/Adafruit_MAX31865-1.1.0-custom/Adafruit_MAX31865.cpp new file mode 100644 index 000000000..984e5572a --- /dev/null +++ b/lib/Adafruit_MAX31865-1.1.0-custom/Adafruit_MAX31865.cpp @@ -0,0 +1,286 @@ +/*************************************************** + This is a library for the Adafruit PT100/P1000 RTD Sensor w/MAX31865 + + Designed specifically to work with the Adafruit RTD Sensor + ----> https://www.adafruit.com/products/3328 + + This sensor uses SPI to communicate, 4 pins are required to + interface + Adafruit invests time and resources providing this open source code, + please support Adafruit and open-source hardware by purchasing + products from Adafruit! + + Written by Limor Fried/Ladyada for Adafruit Industries. + BSD license, all text above must be included in any redistribution + ****************************************************/ + +#include "Adafruit_MAX31865.h" +#ifdef __AVR + #include +#elif defined(ESP8266) + #include +#endif + +#include +#include + +static SPISettings max31865_spisettings = SPISettings(500000, MSBFIRST, SPI_MODE1); + + + +// Software (bitbang) SPI +Adafruit_MAX31865::Adafruit_MAX31865(int8_t spi_cs, int8_t spi_mosi, int8_t spi_miso, int8_t spi_clk) { + setPins( spi_cs, spi_mosi, spi_miso, spi_clk); +} + +void Adafruit_MAX31865::setPins(int8_t spi_cs, int8_t spi_mosi, int8_t spi_miso, int8_t spi_clk) { + _sclk = spi_clk; + _cs = spi_cs; + _miso = spi_miso; + _mosi = spi_mosi; +} + +// Hardware SPI init +Adafruit_MAX31865::Adafruit_MAX31865(int8_t spi_cs) { + _cs = spi_cs; + _sclk = _miso = _mosi = -1; +} + +// Default constructor +Adafruit_MAX31865::Adafruit_MAX31865(void) { + _cs = _sclk = _miso = _mosi = -1; +} + +boolean Adafruit_MAX31865::begin(max31865_numwires_t wires) { + pinMode(_cs, OUTPUT); + digitalWrite(_cs, HIGH); + + if (_sclk != -1) { + //define pin modes + pinMode(_sclk, OUTPUT); + digitalWrite(_sclk, LOW); + pinMode(_mosi, OUTPUT); + pinMode(_miso, INPUT); + } else { + //start and configure hardware SPI + SPI.begin(); + } + + for (uint8_t i=0; i<16; i++) { + // readRegister8(i); + } + + setWires(wires); + enableBias(false); + autoConvert(false); + clearFault(); + + //Serial.print("config: "); Serial.println(readRegister8(MAX31856_CONFIG_REG), HEX); + return true; +} + + +uint8_t Adafruit_MAX31865::readFault(void) { + return readRegister8(MAX31856_FAULTSTAT_REG); +} + +void Adafruit_MAX31865::clearFault(void) { + uint8_t t = readRegister8(MAX31856_CONFIG_REG); + t &= ~0x2C; + t |= MAX31856_CONFIG_FAULTSTAT; + writeRegister8(MAX31856_CONFIG_REG, t); +} + +void Adafruit_MAX31865::enableBias(boolean b) { + uint8_t t = readRegister8(MAX31856_CONFIG_REG); + if (b) { + t |= MAX31856_CONFIG_BIAS; // enable bias + } else { + t &= ~MAX31856_CONFIG_BIAS; // disable bias + } + writeRegister8(MAX31856_CONFIG_REG, t); +} + +void Adafruit_MAX31865::autoConvert(boolean b) { + uint8_t t = readRegister8(MAX31856_CONFIG_REG); + if (b) { + t |= MAX31856_CONFIG_MODEAUTO; // enable autoconvert + } else { + t &= ~MAX31856_CONFIG_MODEAUTO; // disable autoconvert + } + writeRegister8(MAX31856_CONFIG_REG, t); +} + +void Adafruit_MAX31865::setWires(max31865_numwires_t wires ) { + uint8_t t = readRegister8(MAX31856_CONFIG_REG); + if (wires == MAX31865_3WIRE) { + t |= MAX31856_CONFIG_3WIRE; + } else { + // 2 or 4 wire + t &= ~MAX31856_CONFIG_3WIRE; + } + writeRegister8(MAX31856_CONFIG_REG, t); +} + +float Adafruit_MAX31865::rtd_to_temperature(uint16_t rtd, float RTDnominal, float refResistor) { +//float Adafruit_MAX31865::temperature(float RTDnominal, float refResistor) { + // http://www.analog.com/media/en/technical-documentation/application-notes/AN709_0.pdf + + float Z1, Z2, Z3, Z4, Rt, temp; + + Rt = rtd; + Rt /= 32768; + Rt *= refResistor; + + // Serial.print("\nResistance: "); Serial.println(Rt, 8); + + Z1 = -RTD_A; + Z2 = RTD_A * RTD_A - (4 * RTD_B); + Z3 = (4 * RTD_B) / RTDnominal; + Z4 = 2 * RTD_B; + + temp = Z2 + (Z3 * Rt); + temp = (sqrt(temp) + Z1) / Z4; + + if (temp >= 0) return temp; + + // ugh. + Rt /= RTDnominal; + Rt *= 100; // normalize to 100 ohm + + float rpoly = Rt; + + temp = -242.02; + temp += 2.2228 * rpoly; + rpoly *= Rt; // square + temp += 2.5859e-3 * rpoly; + rpoly *= Rt; // ^3 + temp -= 4.8260e-6 * rpoly; + rpoly *= Rt; // ^4 + temp -= 2.8183e-8 * rpoly; + rpoly *= Rt; // ^5 + temp += 1.5243e-10 * rpoly; + + return temp; +} + +float Adafruit_MAX31865::rtd_to_resistance(uint16_t rtd, float refResistor) { + float Rt; + + Rt = rtd; + Rt /= 32768; + Rt *= refResistor; + + return Rt; +} + +float Adafruit_MAX31865::temperature(float RTDnominal, float refResistor) { + uint16_t rtd = readRTD(); + return rtd_to_temperature(rtd, RTDnominal, refResistor); +} + +uint16_t Adafruit_MAX31865::readRTD (void) { + clearFault(); + enableBias(true); + delay(10); + uint8_t t = readRegister8(MAX31856_CONFIG_REG); + t |= MAX31856_CONFIG_1SHOT; + writeRegister8(MAX31856_CONFIG_REG, t); + delay(65); + + uint16_t rtd = readRegister16(MAX31856_RTDMSB_REG); + + // remove fault + rtd >>= 1; + + return rtd; +} + +/**********************************************/ + +uint8_t Adafruit_MAX31865::readRegister8(uint8_t addr) { + uint8_t ret = 0; + readRegisterN(addr, &ret, 1); + + return ret; +} + +uint16_t Adafruit_MAX31865::readRegister16(uint8_t addr) { + uint8_t buffer[2] = {0, 0}; + readRegisterN(addr, buffer, 2); + + uint16_t ret = buffer[0]; + ret <<= 8; + ret |= buffer[1]; + + return ret; +} + + +void Adafruit_MAX31865::readRegisterN(uint8_t addr, uint8_t buffer[], uint8_t n) { + addr &= 0x7F; // make sure top bit is not set + + if (_sclk == -1) + SPI.beginTransaction(max31865_spisettings); + else + digitalWrite(_sclk, LOW); + + digitalWrite(_cs, LOW); + + spixfer(addr); + + //Serial.print("$"); Serial.print(addr, HEX); Serial.print(": "); + while (n--) { + buffer[0] = spixfer(0xFF); + //Serial.print(" 0x"); Serial.print(buffer[0], HEX); + buffer++; + } + //Serial.println(); + + if (_sclk == -1) + SPI.endTransaction(); + + digitalWrite(_cs, HIGH); +} + + +void Adafruit_MAX31865::writeRegister8(uint8_t addr, uint8_t data) { + if (_sclk == -1) + SPI.beginTransaction(max31865_spisettings); + else + digitalWrite(_sclk, LOW); + + digitalWrite(_cs, LOW); + + spixfer(addr | 0x80); // make sure top bit is set + spixfer(data); + + //Serial.print("$"); Serial.print(addr, HEX); Serial.print(" = 0x"); Serial.println(data, HEX); + + if (_sclk == -1) + SPI.endTransaction(); + + digitalWrite(_cs, HIGH); +} + + + +uint8_t Adafruit_MAX31865::spixfer(uint8_t x) { + if (_sclk == -1) + return SPI.transfer(x); + + // software spi + //Serial.println("Software SPI"); + uint8_t reply = 0; + + for (int i=7; i>=0; i--) { + reply <<= 1; + digitalWrite(_sclk, HIGH); + digitalWrite(_mosi, x & (1< https://www.adafruit.com/products/3328 + + This sensor uses SPI to communicate, 4 pins are required to + interface + Adafruit invests time and resources providing this open source code, + please support Adafruit and open-source hardware by purchasing + products from Adafruit! + + Written by Limor Fried/Ladyada for Adafruit Industries. + BSD license, all text above must be included in any redistribution + ****************************************************/ + +#ifndef ADAFRUIT_MAX31865_H +#define ADAFRUIT_MAX31865_H + +#define MAX31856_CONFIG_REG 0x00 +#define MAX31856_CONFIG_BIAS 0x80 +#define MAX31856_CONFIG_MODEAUTO 0x40 +#define MAX31856_CONFIG_MODEOFF 0x00 +#define MAX31856_CONFIG_1SHOT 0x20 +#define MAX31856_CONFIG_3WIRE 0x10 +#define MAX31856_CONFIG_24WIRE 0x00 +#define MAX31856_CONFIG_FAULTSTAT 0x02 +#define MAX31856_CONFIG_FILT50HZ 0x01 +#define MAX31856_CONFIG_FILT60HZ 0x00 + +#define MAX31856_RTDMSB_REG 0x01 +#define MAX31856_RTDLSB_REG 0x02 +#define MAX31856_HFAULTMSB_REG 0x03 +#define MAX31856_HFAULTLSB_REG 0x04 +#define MAX31856_LFAULTMSB_REG 0x05 +#define MAX31856_LFAULTLSB_REG 0x06 +#define MAX31856_FAULTSTAT_REG 0x07 + + +#define MAX31865_FAULT_HIGHTHRESH 0x80 +#define MAX31865_FAULT_LOWTHRESH 0x40 +#define MAX31865_FAULT_REFINLOW 0x20 +#define MAX31865_FAULT_REFINHIGH 0x10 +#define MAX31865_FAULT_RTDINLOW 0x08 +#define MAX31865_FAULT_OVUV 0x04 + + +#define RTD_A 3.9083e-3 +#define RTD_B -5.775e-7 + +#if (ARDUINO >= 100) + #include "Arduino.h" +#else + #include "WProgram.h" +#endif + +typedef enum max31865_numwires { + MAX31865_2WIRE = 0, + MAX31865_3WIRE = 1, + MAX31865_4WIRE = 0 +} max31865_numwires_t; + + +class Adafruit_MAX31865 { + public: + Adafruit_MAX31865(int8_t spi_cs, int8_t spi_mosi, int8_t spi_miso, int8_t spi_clk); + Adafruit_MAX31865(int8_t spi_cs); + Adafruit_MAX31865(void); + + void setPins(int8_t spi_cs, int8_t spi_mosi, int8_t spi_miso, int8_t spi_clk); + boolean begin(max31865_numwires_t x = MAX31865_2WIRE); + + uint8_t readFault(void); + void clearFault(void); + uint16_t readRTD(); + + + void setWires(max31865_numwires_t wires); + void autoConvert(boolean b); + void enableBias(boolean b); + + float temperature(float RTDnominal, float refResistor); + float rtd_to_temperature(uint16_t rtd, float RTDnominal, float refResistor); + float rtd_to_resistance(uint16_t rtd, float refResistor); + + private: + int8_t _sclk, _miso, _mosi, _cs; + + void readRegisterN(uint8_t addr, uint8_t buffer[], uint8_t n); + + uint8_t readRegister8(uint8_t addr); + uint16_t readRegister16(uint8_t addr); + + void writeRegister8(uint8_t addr, uint8_t reg); + uint8_t spixfer(uint8_t addr); +}; + + +#endif diff --git a/lib/Adafruit_MAX31865-1.1.0-custom/README.md b/lib/Adafruit_MAX31865-1.1.0-custom/README.md new file mode 100644 index 000000000..d3b9d2369 --- /dev/null +++ b/lib/Adafruit_MAX31865-1.1.0-custom/README.md @@ -0,0 +1,2 @@ +# Adafruit_MAX31865 +Arduino Library for Adafruit MAX31865 RTD Sensor diff --git a/lib/Adafruit_MAX31865-1.1.0-custom/README.txt b/lib/Adafruit_MAX31865-1.1.0-custom/README.txt new file mode 100644 index 000000000..edace57fd --- /dev/null +++ b/lib/Adafruit_MAX31865-1.1.0-custom/README.txt @@ -0,0 +1,16 @@ +This is the Adafruit MAX31856 Arduino Library + +Tested and works great with the Adafruit Thermocouple Breakout w/MAX31856 + + * http://www.adafruit.com/products/3328 + +These sensors use SPI to communicate, 4 pins are required to +interface + +Adafruit invests time and resources providing this open source code, +please support Adafruit and open-source hardware by purchasing +products from Adafruit! + +Written by Limor Fried/Ladyada for Adafruit Industries. +BSD license, check license.txt for more information +All text above must be included in any redistribution \ No newline at end of file diff --git a/lib/Adafruit_MAX31865-1.1.0-custom/examples/max31865/max31865.ino b/lib/Adafruit_MAX31865-1.1.0-custom/examples/max31865/max31865.ino new file mode 100644 index 000000000..5fc872f54 --- /dev/null +++ b/lib/Adafruit_MAX31865-1.1.0-custom/examples/max31865/max31865.ino @@ -0,0 +1,74 @@ +/*************************************************** + This is a library for the Adafruit PT100/P1000 RTD Sensor w/MAX31865 + + Designed specifically to work with the Adafruit RTD Sensor + ----> https://www.adafruit.com/products/3328 + + This sensor uses SPI to communicate, 4 pins are required to + interface + Adafruit invests time and resources providing this open source code, + please support Adafruit and open-source hardware by purchasing + products from Adafruit! + + Written by Limor Fried/Ladyada for Adafruit Industries. + BSD license, all text above must be included in any redistribution + ****************************************************/ + +#include + +// Use software SPI: CS, DI, DO, CLK +Adafruit_MAX31865 max = Adafruit_MAX31865(10, 11, 12, 13); +// use hardware SPI, just pass in the CS pin +//Adafruit_MAX31865 max = Adafruit_MAX31865(10); + +// The value of the Rref resistor. Use 430.0 for PT100 and 4300.0 for PT1000 +#define RREF 430.0 +// The 'nominal' 0-degrees-C resistance of the sensor +// 100.0 for PT100, 1000.0 for PT1000 +#define RNOMINAL 100.0 + +void setup() { + Serial.begin(115200); + Serial.println("Adafruit MAX31865 PT100 Sensor Test!"); + + max.begin(MAX31865_3WIRE); // set to 2WIRE or 4WIRE as necessary +} + + +void loop() { + uint16_t rtd = max.readRTD(); + + Serial.print("RTD value: "); Serial.println(rtd); + float ratio = rtd; + ratio /= 32768; + Serial.print("Ratio = "); Serial.println(ratio,8); + Serial.print("Resistance = "); Serial.println(RREF*ratio,8); + Serial.print("Temperature = "); Serial.println(max.temperature(RNOMINAL, RREF)); + + // Check and print any faults + uint8_t fault = max.readFault(); + if (fault) { + Serial.print("Fault 0x"); Serial.println(fault, HEX); + if (fault & MAX31865_FAULT_HIGHTHRESH) { + Serial.println("RTD High Threshold"); + } + if (fault & MAX31865_FAULT_LOWTHRESH) { + Serial.println("RTD Low Threshold"); + } + if (fault & MAX31865_FAULT_REFINLOW) { + Serial.println("REFIN- > 0.85 x Bias"); + } + if (fault & MAX31865_FAULT_REFINHIGH) { + Serial.println("REFIN- < 0.85 x Bias - FORCE- open"); + } + if (fault & MAX31865_FAULT_RTDINLOW) { + Serial.println("RTDIN- < 0.85 x Bias - FORCE- open"); + } + if (fault & MAX31865_FAULT_OVUV) { + Serial.println("Under/Over voltage"); + } + max.clearFault(); + } + Serial.println(); + delay(1000); +} diff --git a/lib/Adafruit_MAX31865-1.1.0-custom/library.properties b/lib/Adafruit_MAX31865-1.1.0-custom/library.properties new file mode 100644 index 000000000..f132a890a --- /dev/null +++ b/lib/Adafruit_MAX31865-1.1.0-custom/library.properties @@ -0,0 +1,9 @@ +name=Adafruit MAX31865 library +version=1.0.1 +author=Adafruit +maintainer=Adafruit +sentence=Library for the Adafruit RTD Amplifier breakout with MAX31865 +paragraph=Library for the Adafruit RTD Amplifier breakout with MAX31865 +category=Sensors +url=https://github.com/adafruit/Adafruit_MAX31865 +architectures=* diff --git a/sonoff/my_user_config.h b/sonoff/my_user_config.h index 0f6e07e5f..1db4ce969 100644 --- a/sonoff/my_user_config.h +++ b/sonoff/my_user_config.h @@ -433,6 +433,7 @@ #define MAX31865_PTD_WIRES 2 // PTDs come in several flavors. Pick yours #define MAX31865_PTD_RES 100 // Nominal PTD resistance at 0°C (100Ω for a PT100, 1000Ω for a PT1000, YMMV!) #define MAX31865_REF_RES 430 // Reference resistor (Usually 430Ω for a PT100, 4300Ω for a PT1000) + #define MAX31865_PTD_BIAS -6.6 // To calibrate your not-so-good PTD #endif // -- IR Remote features -------------------------- diff --git a/sonoff/xsns_47_max31865.ino b/sonoff/xsns_47_max31865.ino index e3574fe12..e5d18b609 100644 --- a/sonoff/xsns_47_max31865.ino +++ b/sonoff/xsns_47_max31865.ino @@ -36,7 +36,8 @@ Adafruit_MAX31865 max31865; struct MAX31865_Result_Struct { uint8_t ErrorCode; - uint16_t PtdResistance; + uint16_t Rtd; + float PtdResistance; float PtdTemp; } MAX31865_Result; @@ -62,20 +63,26 @@ void MAX31865_Init(void){ * Acquires the raw data via SPI, checks for MAX31865 errors and fills result structure */ void MAX31865_GetResult(void){ - MAX31865_Result.PtdResistance = max31865.readRTD(); - MAX31865_Result.PtdTemp = max31865.rtd_to_temperature(MAX31865_Result.PtdResistance, MAX31865_PTD_RES, MAX31865_REF_RES); + uint16_t rtd; + + rtd = max31865.readRTD(); + MAX31865_Result.Rtd = rtd; + MAX31865_Result.PtdResistance = max31865.rtd_to_resistance(rtd, MAX31865_REF_RES); + MAX31865_Result.PtdTemp = max31865.rtd_to_temperature(rtd, MAX31865_PTD_RES, MAX31865_REF_RES) + MAX31865_PTD_BIAS; } void MAX31865_Show(bool Json){ char temperature[33]; char resistance[33]; + char srtd[33]; - sprintf(resistance, "%ld", MAX31865_Result.PtdResistance); + sprintf(srtd, "%d", MAX31865_Result.Rtd); + dtostrfd(MAX31865_Result.PtdResistance, Settings.flag2.temperature_resolution, resistance); dtostrfd(MAX31865_Result.PtdTemp, Settings.flag2.temperature_resolution, temperature); if(Json){ - ResponseAppend_P(PSTR(",\"MAX31865\":{\"" D_JSON_TEMPERATURE "\":%s,\"" D_JSON_RESISTANCE "\":%s,\"" D_JSON_ERROR "\":%d}"), \ - temperature, resistance, MAX31865_Result.ErrorCode); + ResponseAppend_P(PSTR(",\"MAX31865\":{\"" D_JSON_TEMPERATURE "\":%s,\"" D_JSON_RESISTANCE "\":%s,\"RTD\":%s,\"" D_JSON_ERROR "\":%d}"), \ + temperature, resistance, srtd, MAX31865_Result.ErrorCode); #ifdef USE_DOMOTICZ if (0 == tele_period) { DomoticzSensor(DZ_TEMP, temperature);