MAX31865

From Stm32World Wiki
Jump to navigation Jump to search


From the datasheet we can read.

  The MAX31865 is an easy-to-use resistance-to-digital
  converter optimized for platinum resistance temperature
  detectors (RTDs). An external resistor sets the sensitivity
  for the RTD being used and a precision delta-sigma ADC
  converts the ratio of the RTD resistance to the reference
  resistance into digital form. The MAX31865’s inputs are
  protected against overvoltage faults as large as ±45V.
  Programmable detection of RTD and cable open and
  short conditions is included.


Basic software controls

Configuration

There is a single configuration register (0x00). In the C library, that is provided in the max31865_init() function.

   Bit 0    Filter, 0=60Hz, 1=50Hz
   Bit 1:3  Fault Detection, see datasheet for details.
   Bit 4    Mode, 1=3-wire, 0=2- or 4-wire
   Bit 5    One-shot, makes a single conversion, and must then be written again.
   Bit 6    Auto mode 1=On, 0=Off
   Bit 7    VBIAS, 1=On, 0=Off
           

Register list

   0x00    Configuration
   0x01    RTD MSB
   0x02    RTD LSB
   0x03    High Fault Threshold MSB
   0x04    High Fault Threshold LSB
   0x05    Low Fault Threshold MSB
   0x06    Low Fault Threshold LSB
   0x07    Fault

SPI Settings

On STM32, the default SPI configuration should work. That is Motorola frame format, 8 bits data size, MSB first, Clock Polarity Low and Clock Phase 1 edge.

Multiple Register Reads

It doesn't seem like the device allows us to read more than one register at a time.

Operation

  1. Read the RTD MSB (0x01) and RTD LSB (0x02) registers.
  2. Check whether Bit 0 in RTD LSB register is 1, then handle Faults. Otherwise, continue
  3. Convert the raw bits from ADC to resistance
  4. Look up resistance in conversion table (dep on RTD type)
  5. Linerize between two temperature entrances in the table.

Data Offset

The RTD LSB/MSB registers are left-shifted once, and bit0 indicates that there is a fault.

Conversion Algorithm (Java)

   void run() 
   {
       if( ( rtdLsb & 1 ) == 1 )
       {
           // fault detected
           invalidate(input);
       } else
       {
           adc = ( rtdLsb + rtdMsb1 * 256.0 ) / 2.0;
           rtd = ( adc * refResistance ) / 32768;
           double measuredTemperature = convert( sensorType, rtd1 );
           double filtered = input * filter + measuredTemperature * ( 1 - filter );
           input = filtered;
       }
   }
   double convert( SensorType type, double resistance )
   {
       int first = (int) type.first();
       double[] lookupTable = type.lookupTable();
       if( resistance < lookupTable[ 0 ] || resistance > lookupTable[ lookupTable.length - 1 ] )
       {
           throw new IllegalArgumentException( "Measured resistance out of range: " + resistance );
       }
       int step = (int) type.step();
       int index = -first / step;
       int jumpSize = 5;
       double value;
       while( true )
       {
           double lookup1 = lookupTable[ index ];
           if( lookup1 <= resistance )
           {
               double lookup2 = lookupTable[ index + 1 ];
               if( lookup2 > resistance )
               {
                   // found value
                   value = linearize( resistance, ( index + first ) * step, ( index + first + 1 ) * step, lookup1, lookup2 );
                   break;
               } else
               {
                   // jump higher
                   if( jumpSize > 1 )
                   {
                       jumpSize = jumpSize - 1;
                   }
                   index = index + jumpSize;
               }
           } else
           {
               double lookup3 = lookupTable[ index - 1 ];
               if( lookup3 < resistance )
               {
                   // found value
                   value = linearize( resistance, ( index + first ) * step, ( index + first - 1 ) * step, lookup1, lookup3 );
                   break;
               } else
               {
                   // jump lower
                   if( jumpSize > 1 )
                   {
                       jumpSize = jumpSize - 1;
                   }
                   index = index - jumpSize;
               }
           }
       }
       return value;
   }
   double linearize( double input, double y1, double y2, double x1, double x2 )
   {
       double k = ( y1 - y2 ) / ( x1 - x2 );
       double m = y1 - ( k * x1 );
       return input * k + m;
   }

Lookup Tables

Links

MAX31865 Datasheet