AA

Fork of max31865 by lzbp li

Committer:
ikerbo
Date:
Tue Sep 20 11:32:49 2016 +0800
Revision:
2:9e49d41d43a4
Parent:
1:175f5c2f8d15
sdassdfskkkdfasdaddasdwsdw

Who changed what in which revision?

UserRevisionLine numberNew contents of line
lzbpli 0:ae18c7b91185 1 /**************************************************************************
lzbpli 0:ae18c7b91185 2 * Arduino driver library for the MAX31865.
lzbpli 0:ae18c7b91185 3 *
lzbpli 0:ae18c7b91185 4 * Copyright (C) 2015 Ole Wolf <wolf@blazingangles.com>
lzbpli 0:ae18c7b91185 5 *
lzbpli 0:ae18c7b91185 6 *
lzbpli 0:ae18c7b91185 7 * Wire the circuit as follows, assuming that level converters have been
lzbpli 0:ae18c7b91185 8 * added for the 3.3V signals:
lzbpli 0:ae18c7b91185 9 *
lzbpli 0:ae18c7b91185 10 * Arduino Uno --> MAX31865
lzbpli 0:ae18c7b91185 11 * ------------------------------------
lzbpli 0:ae18c7b91185 12 * CS: any available pin --> CS
lzbpli 0:ae18c7b91185 13 * MOSI: pin 11 --> SDI (mandatory for hardware SPI)
lzbpli 0:ae18c7b91185 14 * MISO: pin 12 --> SDO (mandatory for hardware SPI)
lzbpli 0:ae18c7b91185 15 * SCK: pin 13 --> SCLK (mandatory for hardware SPI)
lzbpli 0:ae18c7b91185 16 *
lzbpli 0:ae18c7b91185 17 *
lzbpli 0:ae18c7b91185 18 * This program is free software: you can redistribute it and/or modify
lzbpli 0:ae18c7b91185 19 * it under the terms of the GNU General Public License as published by
lzbpli 0:ae18c7b91185 20 * the Free Software Foundation, either version 3 of the License, or
lzbpli 0:ae18c7b91185 21 * (at your option) any later version.
lzbpli 0:ae18c7b91185 22 *
lzbpli 0:ae18c7b91185 23 * This program is distributed in the hope that it will be useful,
lzbpli 0:ae18c7b91185 24 * but WITHOUT ANY WARRANTY; without even the implied warranty of
lzbpli 0:ae18c7b91185 25 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
lzbpli 0:ae18c7b91185 26 * GNU General Public License for more details.
lzbpli 0:ae18c7b91185 27 *
lzbpli 0:ae18c7b91185 28 * You should have received a copy of the GNU General Public License
lzbpli 0:ae18c7b91185 29 * along with this program. If not, see <http://www.gnu.org/licenses/>.
lzbpli 0:ae18c7b91185 30 **************************************************************************/
lzbpli 0:ae18c7b91185 31
lzbpli 0:ae18c7b91185 32 //#include <Arduino.h>
lzbpli 0:ae18c7b91185 33 //#include <SPI.h>
lzbpli 0:ae18c7b91185 34 #include <MAX31865.h>
lzbpli 0:ae18c7b91185 35 #include "mbed.h"
lzbpli 0:ae18c7b91185 36
lzbpli 0:ae18c7b91185 37 /**
lzbpli 0:ae18c7b91185 38 * The constructor for the MAX31865_RTD class registers the CS pin and
lzbpli 0:ae18c7b91185 39 * configures it as an output.
lzbpli 0:ae18c7b91185 40 *
lzbpli 0:ae18c7b91185 41 * @param [in] cs_pin Arduino pin selected for the CS signal.
lzbpli 0:ae18c7b91185 42 */
lzbpli 0:ae18c7b91185 43 MAX31865_RTD::MAX31865_RTD( ptd_type type,PinName mosi, PinName miso, PinName sclk, PinName nss)
lzbpli 0:ae18c7b91185 44 :spi( mosi, miso, sclk ),
lzbpli 0:ae18c7b91185 45 nss( nss )
lzbpli 0:ae18c7b91185 46
lzbpli 0:ae18c7b91185 47
lzbpli 0:ae18c7b91185 48 {
lzbpli 0:ae18c7b91185 49 /* Set the type of PTD. */
lzbpli 0:ae18c7b91185 50 this->type = type;
lzbpli 0:ae18c7b91185 51
lzbpli 0:ae18c7b91185 52 spi.format(8,3);
lzbpli 0:ae18c7b91185 53 spi.frequency(1000000);
lzbpli 0:ae18c7b91185 54
lzbpli 0:ae18c7b91185 55 //nss = 1;
lzbpli 0:ae18c7b91185 56 /* CS pin for the SPI device. */
lzbpli 0:ae18c7b91185 57 //this->cs_pin = cs_pin;
lzbpli 0:ae18c7b91185 58 //pinMode( this->cs_pin, OUTPUT );
lzbpli 0:ae18c7b91185 59
lzbpli 0:ae18c7b91185 60 /* Pull the CS pin high to avoid conflicts on SPI bus. */
lzbpli 0:ae18c7b91185 61 //nss = 1;
lzbpli 0:ae18c7b91185 62 //nss = type;
lzbpli 0:ae18c7b91185 63 }
lzbpli 0:ae18c7b91185 64
lzbpli 0:ae18c7b91185 65
lzbpli 0:ae18c7b91185 66
lzbpli 0:ae18c7b91185 67 /**
lzbpli 0:ae18c7b91185 68 * Configure the MAX31865. The parameters correspond to Table 2 in the MAX31865
lzbpli 0:ae18c7b91185 69 * datasheet. The parameters are combined into a control bit-field that is stored
lzbpli 0:ae18c7b91185 70 * internally in the class for later reconfiguration, as are the fault threshold values.
lzbpli 0:ae18c7b91185 71 *
lzbpli 0:ae18c7b91185 72 * @param [in] v_bias Vbias enabled (@a true) or disabled (@a false).
lzbpli 0:ae18c7b91185 73 * @param [in] conversion_mode Conversion mode auto (@a true) or off (@a false).
lzbpli 0:ae18c7b91185 74 * @param [in] one_shot 1-shot measurement enabled (@a true) or disabled (@a false).
lzbpli 0:ae18c7b91185 75 * @param [in] three_wire 3-wire enabled (@a true) or 2-wire/4-wire (@a false).
lzbpli 0:ae18c7b91185 76 * @param [in] fault_detection Fault detection cycle control (see Table 3 in the MAX31865
lzbpli 0:ae18c7b91185 77 * datasheet).
lzbpli 0:ae18c7b91185 78 * @param [in] fault_clear Fault status auto-clear (@a true) or manual clear (@a false).
lzbpli 0:ae18c7b91185 79 * @param [in] filter_50hz 50 Hz filter enabled (@a true) or 60 Hz filter enabled
lzbpli 0:ae18c7b91185 80 * (@a false).
lzbpli 0:ae18c7b91185 81 * @param [in] low_threshold Low fault threshold.
lzbpli 0:ae18c7b91185 82 * @param [in] high_threshold High fault threshold.
lzbpli 0:ae18c7b91185 83 */
lzbpli 0:ae18c7b91185 84 void MAX31865_RTD::configure( bool v_bias, bool conversion_mode, bool one_shot,
lzbpli 0:ae18c7b91185 85 bool three_wire, uint8_t fault_cycle, bool fault_clear,
lzbpli 0:ae18c7b91185 86 bool filter_50hz, uint16_t low_threshold,
lzbpli 0:ae18c7b91185 87 uint16_t high_threshold )
lzbpli 0:ae18c7b91185 88 {
lzbpli 0:ae18c7b91185 89 uint8_t control_bits = 0;
lzbpli 0:ae18c7b91185 90 nss = 1;
lzbpli 0:ae18c7b91185 91 /* Assemble the control bit mask. */
lzbpli 0:ae18c7b91185 92 control_bits |= ( v_bias ? 0x80 : 0 );
lzbpli 0:ae18c7b91185 93 control_bits |= ( conversion_mode ? 0x40 : 0 );
lzbpli 0:ae18c7b91185 94 control_bits |= ( one_shot ? 0x20 : 0 );
lzbpli 0:ae18c7b91185 95 control_bits |= ( three_wire ? 0x10 : 0 );
ikerbo 2:9e49d41d43a4 96 //control_bits |= (fault_cycle & 0b00001100);
lzbpli 0:ae18c7b91185 97 control_bits |= ( fault_clear ? 0x02 : 0 );
lzbpli 0:ae18c7b91185 98 control_bits |= ( filter_50hz ? 0x01 : 0 );
lzbpli 0:ae18c7b91185 99
lzbpli 0:ae18c7b91185 100 /* Store the control bits and the fault threshold limits for reconfiguration
lzbpli 0:ae18c7b91185 101 purposes. */
lzbpli 0:ae18c7b91185 102 this->configuration_control_bits = control_bits;
lzbpli 0:ae18c7b91185 103 this->configuration_low_threshold = low_threshold;
lzbpli 0:ae18c7b91185 104 this->configuration_high_threshold = high_threshold;
lzbpli 0:ae18c7b91185 105
lzbpli 0:ae18c7b91185 106 /* Perform an initial "reconfiguration." */
lzbpli 0:ae18c7b91185 107 reconfigure( );
lzbpli 0:ae18c7b91185 108 }
lzbpli 0:ae18c7b91185 109
lzbpli 0:ae18c7b91185 110
lzbpli 0:ae18c7b91185 111
lzbpli 0:ae18c7b91185 112 /**
lzbpli 0:ae18c7b91185 113 * Reconfigure the MAX31865 by writing the stored control bits and the stored fault
lzbpli 0:ae18c7b91185 114 * threshold values back to the chip.
lzbpli 0:ae18c7b91185 115 */
lzbpli 0:ae18c7b91185 116 void MAX31865_RTD::reconfigure( )
lzbpli 0:ae18c7b91185 117 {
lzbpli 0:ae18c7b91185 118 /* Write the configuration to the MAX31865. */
lzbpli 0:ae18c7b91185 119 nss = 0;
lzbpli 0:ae18c7b91185 120 // wait_us(100);
lzbpli 0:ae18c7b91185 121 spi.write( 0x80 );
lzbpli 0:ae18c7b91185 122 spi.write( this->configuration_control_bits );
lzbpli 0:ae18c7b91185 123 nss = 1;
lzbpli 0:ae18c7b91185 124
lzbpli 0:ae18c7b91185 125 /* Write the threshold values. */
lzbpli 0:ae18c7b91185 126 nss = 0;
lzbpli 0:ae18c7b91185 127 // wait_us(100);
lzbpli 0:ae18c7b91185 128 spi.write( 0x83 );
lzbpli 0:ae18c7b91185 129 spi.write( ( this->configuration_high_threshold >> 8 ) & 0x00ff );
lzbpli 0:ae18c7b91185 130 spi.write( this->configuration_high_threshold & 0x00ff );
lzbpli 0:ae18c7b91185 131 spi.write( ( this->configuration_low_threshold >> 8 ) & 0x00ff );
lzbpli 0:ae18c7b91185 132 spi.write( this->configuration_low_threshold & 0x00ff );
lzbpli 0:ae18c7b91185 133 nss = 1;
lzbpli 0:ae18c7b91185 134
lzbpli 0:ae18c7b91185 135 }
lzbpli 0:ae18c7b91185 136
lzbpli 0:ae18c7b91185 137
lzbpli 0:ae18c7b91185 138
lzbpli 0:ae18c7b91185 139 /**
lzbpli 0:ae18c7b91185 140 * Apply the Callendar-Van Dusen equation to convert the RTD resistance
lzbpli 0:ae18c7b91185 141 * to temperature:
lzbpli 0:ae18c7b91185 142 *
lzbpli 0:ae18c7b91185 143 * \f[
lzbpli 0:ae18c7b91185 144 * t=\frac{-A\pm \sqrt{A^2-4B\left(1-\frac{R_t}{R_0}\right)}}{2B}
lzbpli 0:ae18c7b91185 145 * \f],
lzbpli 0:ae18c7b91185 146 *
lzbpli 0:ae18c7b91185 147 * where
lzbpli 0:ae18c7b91185 148 *
lzbpli 0:ae18c7b91185 149 * \f$A\f$ and \f$B\f$ are the RTD coefficients, \f$R_t\f$ is the current
lzbpli 0:ae18c7b91185 150 * resistance of the RTD, and \f$R_0\f$ is the resistance of the RTD at 0
lzbpli 0:ae18c7b91185 151 * degrees Celcius.
lzbpli 0:ae18c7b91185 152 *
lzbpli 0:ae18c7b91185 153 * For more information on measuring with an RTD, see:
lzbpli 0:ae18c7b91185 154 * <http://newton.ex.ac.uk/teaching/CDHW/Sensors/an046.pdf>.
lzbpli 0:ae18c7b91185 155 *
lzbpli 0:ae18c7b91185 156 * @param [in] resistance The measured RTD resistance.
lzbpli 0:ae18c7b91185 157 * @return Temperature in degrees Celcius.
lzbpli 0:ae18c7b91185 158 */
lzbpli 0:ae18c7b91185 159 double MAX31865_RTD::temperature( ) const
lzbpli 0:ae18c7b91185 160 {
lzbpli 0:ae18c7b91185 161 static const double a2 = 2.0 * RTD_B;
lzbpli 0:ae18c7b91185 162 static const double b_sq = RTD_A * RTD_A;
lzbpli 0:ae18c7b91185 163
lzbpli 0:ae18c7b91185 164 const double rtd_resistance =
lzbpli 0:ae18c7b91185 165 ( this->type == RTD_PT100 ) ? RTD_RESISTANCE_PT100 : RTD_RESISTANCE_PT1000;
lzbpli 0:ae18c7b91185 166
lzbpli 0:ae18c7b91185 167 double c = 1.0 - resistance( ) / rtd_resistance;
lzbpli 0:ae18c7b91185 168 double D = b_sq - 2.0 * a2 * c;
lzbpli 0:ae18c7b91185 169 double temperature_deg_C = ( -RTD_A + sqrt( D ) ) / a2;
lzbpli 0:ae18c7b91185 170
lzbpli 0:ae18c7b91185 171 return( temperature_deg_C );
lzbpli 0:ae18c7b91185 172 }
lzbpli 0:ae18c7b91185 173
lzbpli 0:ae18c7b91185 174
lzbpli 0:ae18c7b91185 175
lzbpli 0:ae18c7b91185 176 /**
lzbpli 0:ae18c7b91185 177 * Read all settings and measurements from the MAX31865 and store them
lzbpli 0:ae18c7b91185 178 * internally in the class.
lzbpli 0:ae18c7b91185 179 *
lzbpli 0:ae18c7b91185 180 * @return Fault status byte
lzbpli 0:ae18c7b91185 181 */
lzbpli 0:ae18c7b91185 182 uint8_t MAX31865_RTD::read_all( )
lzbpli 0:ae18c7b91185 183 {
lzbpli 0:ae18c7b91185 184 uint16_t combined_bytes;
lzbpli 1:175f5c2f8d15 185 reconfigure( );
lzbpli 0:ae18c7b91185 186 /* Start the read operation. */
lzbpli 0:ae18c7b91185 187 nss = 0;
lzbpli 0:ae18c7b91185 188 /* Tell the MAX31865 that we want to read, starting at register 0. */
lzbpli 0:ae18c7b91185 189 spi.write( 0x00 );
lzbpli 0:ae18c7b91185 190
lzbpli 0:ae18c7b91185 191 /* Read the MAX31865 registers in the following order:
lzbpli 0:ae18c7b91185 192 Configuration
lzbpli 0:ae18c7b91185 193 RTD
lzbpli 0:ae18c7b91185 194 High Fault Threshold
lzbpli 0:ae18c7b91185 195 Low Fault Threshold
lzbpli 0:ae18c7b91185 196 Fault Status */
lzbpli 0:ae18c7b91185 197
lzbpli 0:ae18c7b91185 198 this->measured_configuration = spi.write( 0x00 );
lzbpli 0:ae18c7b91185 199
lzbpli 0:ae18c7b91185 200 combined_bytes = spi.write( 0x00 ) << 8;
lzbpli 0:ae18c7b91185 201 combined_bytes |= spi.write( 0x00 );
lzbpli 0:ae18c7b91185 202 this->measured_resistance = combined_bytes >> 1;
lzbpli 0:ae18c7b91185 203
lzbpli 0:ae18c7b91185 204 combined_bytes = spi.write( 0x00 ) << 8;
lzbpli 0:ae18c7b91185 205 combined_bytes |= spi.write( 0x00 );
lzbpli 0:ae18c7b91185 206 this->measured_high_threshold = combined_bytes >> 1;
lzbpli 0:ae18c7b91185 207
lzbpli 0:ae18c7b91185 208 combined_bytes = spi.write( 0x00 ) << 8;
lzbpli 0:ae18c7b91185 209 combined_bytes |= spi.write( 0x00 );
lzbpli 0:ae18c7b91185 210 this->measured_low_threshold = combined_bytes >> 1;
lzbpli 0:ae18c7b91185 211
lzbpli 0:ae18c7b91185 212 this->measured_status = spi.write( 0x00 );
lzbpli 0:ae18c7b91185 213
lzbpli 0:ae18c7b91185 214 nss = 1;
lzbpli 0:ae18c7b91185 215
lzbpli 0:ae18c7b91185 216 /* Reset the configuration if the measured resistance is
lzbpli 0:ae18c7b91185 217 zero or a fault occurred. */
lzbpli 0:ae18c7b91185 218 if( ( this->measured_resistance == 0 )
lzbpli 0:ae18c7b91185 219 || ( this->measured_status != 0 ) )
lzbpli 0:ae18c7b91185 220 {
lzbpli 0:ae18c7b91185 221 reconfigure( );
lzbpli 0:ae18c7b91185 222 }
lzbpli 0:ae18c7b91185 223
lzbpli 0:ae18c7b91185 224 return( status( ) );
lzbpli 0:ae18c7b91185 225 }
lzbpli 0:ae18c7b91185 226
lzbpli 0:ae18c7b91185 227