arduinoprojects

git clone https://git.tarina.org/arduinoprojects
Log | Files | Refs

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 }