/*************************************************** This is an example for how to use Adafruit_BusIO_RegisterBits from Adafruit_BusIO library. Designed specifically to work with the Adafruit RTD Sensor ----> https://www.adafruit.com/products/3328 uisng a MAX31865 RTD-to-Digital Converter ----> https://datasheets.maximintegrated.com/en/ds/MAX31865.pdf This sensor uses SPI to communicate, 4 pins are required to interface. A fifth pin helps to detect when a new conversion is ready. Adafruit invests time and resources providing this open source code, please support Adafruit and open-source hardware by purchasing products from Adafruit! Example written (2020/3) by Andreas Hardtung/AnHard. BSD license, all text above must be included in any redistribution ****************************************************/ #include #include #define MAX31865_SPI_SPEED (5000000) #define MAX31865_SPI_BITORDER (SPI_BITORDER_MSBFIRST) #define MAX31865_SPI_MODE (SPI_MODE1) #define MAX31865_SPI_CS (10) #define MAX31865_READY_PIN (2) Adafruit_SPIDevice spi_dev = Adafruit_SPIDevice( MAX31865_SPI_CS, MAX31865_SPI_SPEED, MAX31865_SPI_BITORDER, MAX31865_SPI_MODE, &SPI); // Hardware SPI // Adafruit_SPIDevice spi_dev = Adafruit_SPIDevice( MAX31865_SPI_CS, 13, 12, 11, MAX31865_SPI_SPEED, MAX31865_SPI_BITORDER, MAX31865_SPI_MODE); // Software SPI // MAX31865 chip related ********************************************************************************************* Adafruit_BusIO_Register config_reg = Adafruit_BusIO_Register(&spi_dev, 0x00, ADDRBIT8_HIGH_TOWRITE, 1, MSBFIRST); Adafruit_BusIO_RegisterBits bias_bit = Adafruit_BusIO_RegisterBits(&config_reg, 1, 7); Adafruit_BusIO_RegisterBits auto_bit = Adafruit_BusIO_RegisterBits(&config_reg, 1, 6); Adafruit_BusIO_RegisterBits oneS_bit = Adafruit_BusIO_RegisterBits(&config_reg, 1, 5); Adafruit_BusIO_RegisterBits wire_bit = Adafruit_BusIO_RegisterBits(&config_reg, 1, 4); Adafruit_BusIO_RegisterBits faultT_bits = Adafruit_BusIO_RegisterBits(&config_reg, 2, 2); Adafruit_BusIO_RegisterBits faultR_bit = Adafruit_BusIO_RegisterBits(&config_reg, 1, 1); Adafruit_BusIO_RegisterBits fi50hz_bit = Adafruit_BusIO_RegisterBits(&config_reg, 1, 0); Adafruit_BusIO_Register rRatio_reg = Adafruit_BusIO_Register(&spi_dev, 0x01, ADDRBIT8_HIGH_TOWRITE, 2, MSBFIRST); Adafruit_BusIO_RegisterBits rRatio_bits = Adafruit_BusIO_RegisterBits(&rRatio_reg, 15, 1); Adafruit_BusIO_RegisterBits fault_bit = Adafruit_BusIO_RegisterBits(&rRatio_reg, 1, 0); Adafruit_BusIO_Register maxRratio_reg = Adafruit_BusIO_Register(&spi_dev, 0x03, ADDRBIT8_HIGH_TOWRITE, 2, MSBFIRST); Adafruit_BusIO_RegisterBits maxRratio_bits = Adafruit_BusIO_RegisterBits(&maxRratio_reg, 15, 1); Adafruit_BusIO_Register minRratio_reg = Adafruit_BusIO_Register(&spi_dev, 0x05, ADDRBIT8_HIGH_TOWRITE, 2, MSBFIRST); Adafruit_BusIO_RegisterBits minRratio_bits = Adafruit_BusIO_RegisterBits(&minRratio_reg, 15, 1); Adafruit_BusIO_Register fault_reg = Adafruit_BusIO_Register(&spi_dev, 0x07, ADDRBIT8_HIGH_TOWRITE, 1, MSBFIRST); Adafruit_BusIO_RegisterBits range_high_fault_bit = Adafruit_BusIO_RegisterBits(&fault_reg, 1, 7); Adafruit_BusIO_RegisterBits range_low_fault_bit = Adafruit_BusIO_RegisterBits(&fault_reg, 1, 6); Adafruit_BusIO_RegisterBits refin_high_fault_bit = Adafruit_BusIO_RegisterBits(&fault_reg, 1, 5); Adafruit_BusIO_RegisterBits refin_low_fault_bit = Adafruit_BusIO_RegisterBits(&fault_reg, 1, 4); Adafruit_BusIO_RegisterBits rtdin_low_fault_bit = Adafruit_BusIO_RegisterBits(&fault_reg, 1, 3); Adafruit_BusIO_RegisterBits voltage_fault_bit = Adafruit_BusIO_RegisterBits(&fault_reg, 1, 2); // Print the details of the configuration register. void printConfig( void ) { Serial.print("BIAS: "); if (bias_bit.read() ) Serial.print("ON"); else Serial.print("OFF"); Serial.print(", AUTO: "); if (auto_bit.read() ) Serial.print("ON"); else Serial.print("OFF"); Serial.print(", ONES: "); if (oneS_bit.read() ) Serial.print("ON"); else Serial.print("OFF"); Serial.print(", WIRE: "); if (wire_bit.read() ) Serial.print("3"); else Serial.print("2/4"); Serial.print(", FAULTCLEAR: "); if (faultR_bit.read() ) Serial.print("ON"); else Serial.print("OFF"); Serial.print(", "); if (fi50hz_bit.read() ) Serial.print("50HZ"); else Serial.print("60HZ"); Serial.println(); } // Check and print faults. Then clear them. void checkFaults( void ) { if (fault_bit.read()) { Serial.print("MAX: "); Serial.println(maxRratio_bits.read()); Serial.print("VAL: "); Serial.println( rRatio_bits.read()); Serial.print("MIN: "); Serial.println(minRratio_bits.read()); if (range_high_fault_bit.read() ) Serial.println("Range high fault"); if ( range_low_fault_bit.read() ) Serial.println("Range low fault"); if (refin_high_fault_bit.read() ) Serial.println("REFIN high fault"); if ( refin_low_fault_bit.read() ) Serial.println("REFIN low fault"); if ( rtdin_low_fault_bit.read() ) Serial.println("RTDIN low fault"); if ( voltage_fault_bit.read() ) Serial.println("Voltage fault"); faultR_bit.write(1); // clear fault } } void setup() { #if (MAX31865_1_READY_PIN != -1) pinMode(MAX31865_READY_PIN ,INPUT_PULLUP); #endif while (!Serial) { delay(10); } Serial.begin(115200); Serial.println("SPI Adafruit_BusIO_RegisterBits test on MAX31865"); if (!spi_dev.begin()) { Serial.println("Could not initialize SPI device"); while (1); } // Set up for automode 50Hz. We don't care about selfheating. We want the highest possible sampling rate. auto_bit.write(0); // Don't switch filtermode while auto_mode is on. fi50hz_bit.write(1); // Set filter to 50Hz mode. faultR_bit.write(1); // Clear faults. bias_bit.write(1); // In automode we want to have the bias current always on. delay(5); // Wait until bias current settles down. // 10.5 time constants of the input RC network is required. // 10ms worst case for 10kω reference resistor and a 0.1µF capacitor across the RTD inputs. // Adafruit Module has 0.1µF and only 430/4300ω So here 0.43/4.3ms auto_bit.write(1); // Now we can set automode. Automatically starting first conversion. // Test the READY_PIN #if (defined( MAX31865_READY_PIN ) && (MAX31865_READY_PIN != -1)) int i = 0; while (digitalRead(MAX31865_READY_PIN) && i++ <= 100) { delay(1); } if (i >= 100) { Serial.print("ERROR: Max31865 Pin detection does not work. PIN:"); Serial.println(MAX31865_READY_PIN); } #else delay(100); #endif // Set ratio range. // Setting the temperatures would need some more calculation - not related to Adafruit_BusIO_RegisterBits. uint16_t ratio = rRatio_bits.read(); maxRratio_bits.write( (ratio < 0x8fffu-1000u) ? ratio + 1000u : 0x8fffu ); minRratio_bits.write( (ratio > 1000u) ? ratio - 1000u : 0u ); printConfig(); checkFaults(); } void loop() { #if (defined( MAX31865_READY_PIN ) && (MAX31865_1_READY_PIN != -1)) // Is conversion ready? if (!digitalRead(MAX31865_READY_PIN)) #else // Warant conversion is ready. delay(21); // 21ms for 50Hz-mode. 19ms in 60Hz-mode. #endif { // Read ratio, calculate temperature, scale, filter and print. Serial.println( rRatio2C( rRatio_bits.read() ) * 100.0f, 0); // Temperature scaled by 100 // Check, print, clear faults. checkFaults(); } // Do something else. //delay(15000); } // Module/Sensor related. Here Adafruit PT100 module with a 2_Wire PT100 Class C ***************************** float rRatio2C(uint16_t ratio) { // A simple linear conversion. const float R0 = 100.0f; const float Rref = 430.0f; const float alphaPT = 0.003850f; const float ADCmax = (1u << 15) - 1.0f; const float rscale = Rref / ADCmax; // Measured temperature in boiling water 101.08°C with factor a = 1 and b = 0. Rref and MAX at about 22±2°C. // Measured temperature in ice/water bath 0.76°C with factor a = 1 and b = 0. Rref and MAX at about 22±2°C. //const float a = 1.0f / (alphaPT * R0); const float a = (100.0f/101.08f) / (alphaPT * R0); //const float b = 0.0f; // 101.08 const float b = -0.76f; // 100.32 > 101.08 return filterRing( ((ratio * rscale) - R0) * a + b ); } // General purpose ********************************************************************************************* #define RINGLENGTH 250 float filterRing( float newVal ) { static float ring[RINGLENGTH] = { 0.0 }; static uint8_t ringIndex = 0; static bool ringFull = false; if ( ringIndex == RINGLENGTH ) { ringFull = true; ringIndex = 0; } ring[ringIndex] = newVal; uint8_t loopEnd = (ringFull) ? RINGLENGTH : ringIndex + 1; float ringSum = 0.0f; for (uint8_t i = 0; i < loopEnd; i++) ringSum += ring[i]; ringIndex++; return ringSum / loopEnd; }