spi_register_bits.ino (9077B)
1 /*************************************************** 2 3 This is an example for how to use Adafruit_BusIO_RegisterBits from Adafruit_BusIO library. 4 5 Designed specifically to work with the Adafruit RTD Sensor 6 ----> https://www.adafruit.com/products/3328 7 uisng a MAX31865 RTD-to-Digital Converter 8 ----> https://datasheets.maximintegrated.com/en/ds/MAX31865.pdf 9 10 This sensor uses SPI to communicate, 4 pins are required to 11 interface. 12 A fifth pin helps to detect when a new conversion is ready. 13 14 Adafruit invests time and resources providing this open source code, 15 please support Adafruit and open-source hardware by purchasing 16 products from Adafruit! 17 18 Example written (2020/3) by Andreas Hardtung/AnHard. 19 BSD license, all text above must be included in any redistribution 20 ****************************************************/ 21 22 #include <Adafruit_BusIO_Register.h> 23 #include <Adafruit_SPIDevice.h> 24 25 #define MAX31865_SPI_SPEED (5000000) 26 #define MAX31865_SPI_BITORDER (SPI_BITORDER_MSBFIRST) 27 #define MAX31865_SPI_MODE (SPI_MODE1) 28 29 #define MAX31865_SPI_CS (10) 30 #define MAX31865_READY_PIN (2) 31 32 33 Adafruit_SPIDevice spi_dev = Adafruit_SPIDevice( MAX31865_SPI_CS, MAX31865_SPI_SPEED, MAX31865_SPI_BITORDER, MAX31865_SPI_MODE, &SPI); // Hardware SPI 34 // Adafruit_SPIDevice spi_dev = Adafruit_SPIDevice( MAX31865_SPI_CS, 13, 12, 11, MAX31865_SPI_SPEED, MAX31865_SPI_BITORDER, MAX31865_SPI_MODE); // Software SPI 35 36 // MAX31865 chip related ********************************************************************************************* 37 Adafruit_BusIO_Register config_reg = Adafruit_BusIO_Register(&spi_dev, 0x00, ADDRBIT8_HIGH_TOWRITE, 1, MSBFIRST); 38 Adafruit_BusIO_RegisterBits bias_bit = Adafruit_BusIO_RegisterBits(&config_reg, 1, 7); 39 Adafruit_BusIO_RegisterBits auto_bit = Adafruit_BusIO_RegisterBits(&config_reg, 1, 6); 40 Adafruit_BusIO_RegisterBits oneS_bit = Adafruit_BusIO_RegisterBits(&config_reg, 1, 5); 41 Adafruit_BusIO_RegisterBits wire_bit = Adafruit_BusIO_RegisterBits(&config_reg, 1, 4); 42 Adafruit_BusIO_RegisterBits faultT_bits = Adafruit_BusIO_RegisterBits(&config_reg, 2, 2); 43 Adafruit_BusIO_RegisterBits faultR_bit = Adafruit_BusIO_RegisterBits(&config_reg, 1, 1); 44 Adafruit_BusIO_RegisterBits fi50hz_bit = Adafruit_BusIO_RegisterBits(&config_reg, 1, 0); 45 46 Adafruit_BusIO_Register rRatio_reg = Adafruit_BusIO_Register(&spi_dev, 0x01, ADDRBIT8_HIGH_TOWRITE, 2, MSBFIRST); 47 Adafruit_BusIO_RegisterBits rRatio_bits = Adafruit_BusIO_RegisterBits(&rRatio_reg, 15, 1); 48 Adafruit_BusIO_RegisterBits fault_bit = Adafruit_BusIO_RegisterBits(&rRatio_reg, 1, 0); 49 50 Adafruit_BusIO_Register maxRratio_reg = Adafruit_BusIO_Register(&spi_dev, 0x03, ADDRBIT8_HIGH_TOWRITE, 2, MSBFIRST); 51 Adafruit_BusIO_RegisterBits maxRratio_bits = Adafruit_BusIO_RegisterBits(&maxRratio_reg, 15, 1); 52 53 Adafruit_BusIO_Register minRratio_reg = Adafruit_BusIO_Register(&spi_dev, 0x05, ADDRBIT8_HIGH_TOWRITE, 2, MSBFIRST); 54 Adafruit_BusIO_RegisterBits minRratio_bits = Adafruit_BusIO_RegisterBits(&minRratio_reg, 15, 1); 55 56 Adafruit_BusIO_Register fault_reg = Adafruit_BusIO_Register(&spi_dev, 0x07, ADDRBIT8_HIGH_TOWRITE, 1, MSBFIRST); 57 Adafruit_BusIO_RegisterBits range_high_fault_bit = Adafruit_BusIO_RegisterBits(&fault_reg, 1, 7); 58 Adafruit_BusIO_RegisterBits range_low_fault_bit = Adafruit_BusIO_RegisterBits(&fault_reg, 1, 6); 59 Adafruit_BusIO_RegisterBits refin_high_fault_bit = Adafruit_BusIO_RegisterBits(&fault_reg, 1, 5); 60 Adafruit_BusIO_RegisterBits refin_low_fault_bit = Adafruit_BusIO_RegisterBits(&fault_reg, 1, 4); 61 Adafruit_BusIO_RegisterBits rtdin_low_fault_bit = Adafruit_BusIO_RegisterBits(&fault_reg, 1, 3); 62 Adafruit_BusIO_RegisterBits voltage_fault_bit = Adafruit_BusIO_RegisterBits(&fault_reg, 1, 2); 63 64 // Print the details of the configuration register. 65 void printConfig( void ) { 66 Serial.print("BIAS: "); if (bias_bit.read() ) Serial.print("ON"); else Serial.print("OFF"); 67 Serial.print(", AUTO: "); if (auto_bit.read() ) Serial.print("ON"); else Serial.print("OFF"); 68 Serial.print(", ONES: "); if (oneS_bit.read() ) Serial.print("ON"); else Serial.print("OFF"); 69 Serial.print(", WIRE: "); if (wire_bit.read() ) Serial.print("3"); else Serial.print("2/4"); 70 Serial.print(", FAULTCLEAR: "); if (faultR_bit.read() ) Serial.print("ON"); else Serial.print("OFF"); 71 Serial.print(", "); if (fi50hz_bit.read() ) Serial.print("50HZ"); else Serial.print("60HZ"); 72 Serial.println(); 73 } 74 75 // Check and print faults. Then clear them. 76 void checkFaults( void ) { 77 if (fault_bit.read()) { 78 Serial.print("MAX: "); Serial.println(maxRratio_bits.read()); 79 Serial.print("VAL: "); Serial.println( rRatio_bits.read()); 80 Serial.print("MIN: "); Serial.println(minRratio_bits.read()); 81 82 if (range_high_fault_bit.read() ) Serial.println("Range high fault"); 83 if ( range_low_fault_bit.read() ) Serial.println("Range low fault"); 84 if (refin_high_fault_bit.read() ) Serial.println("REFIN high fault"); 85 if ( refin_low_fault_bit.read() ) Serial.println("REFIN low fault"); 86 if ( rtdin_low_fault_bit.read() ) Serial.println("RTDIN low fault"); 87 if ( voltage_fault_bit.read() ) Serial.println("Voltage fault"); 88 89 faultR_bit.write(1); // clear fault 90 } 91 } 92 93 void setup() { 94 #if (MAX31865_1_READY_PIN != -1) 95 pinMode(MAX31865_READY_PIN ,INPUT_PULLUP); 96 #endif 97 98 while (!Serial) { delay(10); } 99 Serial.begin(115200); 100 Serial.println("SPI Adafruit_BusIO_RegisterBits test on MAX31865"); 101 102 if (!spi_dev.begin()) { 103 Serial.println("Could not initialize SPI device"); 104 while (1); 105 } 106 107 // Set up for automode 50Hz. We don't care about selfheating. We want the highest possible sampling rate. 108 auto_bit.write(0); // Don't switch filtermode while auto_mode is on. 109 fi50hz_bit.write(1); // Set filter to 50Hz mode. 110 faultR_bit.write(1); // Clear faults. 111 bias_bit.write(1); // In automode we want to have the bias current always on. 112 delay(5); // Wait until bias current settles down. 113 // 10.5 time constants of the input RC network is required. 114 // 10ms worst case for 10kω reference resistor and a 0.1µF capacitor across the RTD inputs. 115 // Adafruit Module has 0.1µF and only 430/4300ω So here 0.43/4.3ms 116 auto_bit.write(1); // Now we can set automode. Automatically starting first conversion. 117 118 // Test the READY_PIN 119 #if (defined( MAX31865_READY_PIN ) && (MAX31865_READY_PIN != -1)) 120 int i = 0; 121 while (digitalRead(MAX31865_READY_PIN) && i++ <= 100) { delay(1); } 122 if (i >= 100) { 123 Serial.print("ERROR: Max31865 Pin detection does not work. PIN:"); 124 Serial.println(MAX31865_READY_PIN); 125 } 126 #else 127 delay(100); 128 #endif 129 130 // Set ratio range. 131 // Setting the temperatures would need some more calculation - not related to Adafruit_BusIO_RegisterBits. 132 uint16_t ratio = rRatio_bits.read(); 133 maxRratio_bits.write( (ratio < 0x8fffu-1000u) ? ratio + 1000u : 0x8fffu ); 134 minRratio_bits.write( (ratio > 1000u) ? ratio - 1000u : 0u ); 135 136 printConfig(); 137 checkFaults(); 138 } 139 140 void loop() { 141 #if (defined( MAX31865_READY_PIN ) && (MAX31865_1_READY_PIN != -1)) 142 // Is converstion ready? 143 if (!digitalRead(MAX31865_READY_PIN)) 144 #else 145 // Warant conversion is ready. 146 delay(21); // 21ms for 50Hz-mode. 19ms in 60Hz-mode. 147 #endif 148 { 149 // Read ratio, calculate temperature, scale, filter and print. 150 Serial.println( rRatio2C( rRatio_bits.read() ) * 100.0f, 0); // Temperature scaled by 100 151 // Check, print, clear faults. 152 checkFaults(); 153 } 154 155 // Do something else. 156 //delay(15000); 157 } 158 159 160 // Module/Sensor related. Here Adafruit PT100 module with a 2_Wire PT100 Class C ***************************** 161 float rRatio2C(uint16_t ratio) { 162 // A simple linear conversion. 163 const float R0 = 100.0f; 164 const float Rref = 430.0f; 165 const float alphaPT = 0.003850f; 166 const float ADCmax = (1u << 15) - 1.0f; 167 const float rscale = Rref / ADCmax; 168 // Measured temperature in boiling water 101.08°C with factor a = 1 and b = 0. Rref and MAX at about 22±2°C. 169 // Measured temperature in ice/water bath 0.76°C with factor a = 1 and b = 0. Rref and MAX at about 22±2°C. 170 //const float a = 1.0f / (alphaPT * R0); 171 const float a = (100.0f/101.08f) / (alphaPT * R0); 172 //const float b = 0.0f; // 101.08 173 const float b = -0.76f; // 100.32 > 101.08 174 175 return filterRing( ((ratio * rscale) - R0) * a + b ); 176 } 177 178 // General purpose ********************************************************************************************* 179 #define RINGLENGTH 250 180 float filterRing( float newVal ) { 181 static float ring[RINGLENGTH] = { 0.0 }; 182 static uint8_t ringIndex = 0; 183 static bool ringFull = false; 184 185 if ( ringIndex == RINGLENGTH ) { ringFull = true; ringIndex = 0; } 186 ring[ringIndex] = newVal; 187 uint8_t loopEnd = (ringFull) ? RINGLENGTH : ringIndex + 1; 188 float ringSum = 0.0f; 189 for (uint8_t i = 0; i < loopEnd; i++) ringSum += ring[i]; 190 ringIndex++; 191 return ringSum / loopEnd; 192 }