RTD measurement with Wheatstone Bridge and ADC

Hello,
I've developed a PCB that connects an RTD (PT100) to a Wheatstone bridge, set to 100 ohms at 0°C. The bridge terminals (as seen in the diagram) connect to AIN4 and AIN6 of the nRF52840. However, no matter what devicetree configuration I try (differential mode, single mode, gain, vref, etc), the measurements are very unstable, and I can't calculate a correct temperature value. What could be the cause of this problem?
Schematic (RTD_V1 to AIN6 and RTD_V2 to AIN4):
Device tree snippets:
	channel@4 {
		reg = <4>;
		zephyr,gain = "ADC_GAIN_1_6";
		zephyr,reference = "ADC_REF_INTERNAL";
		zephyr,acquisition-time = <ADC_ACQ_TIME_DEFAULT>;
		zephyr,input-positive = <NRF_SAADC_AIN4>; /* P0.03 */
		zephyr,input-negative = <NRF_SAADC_AIN6>; /* P0.03 */
		zephyr,resolution = <12>;
	};
Application snippets:
#if !DT_NODE_EXISTS(DT_PATH(zephyr_user)) || \
	!DT_NODE_HAS_PROP(DT_PATH(zephyr_user), io_channels)
#error "No suitable devicetree overlay specified"
#endif

#define DT_SPEC_AND_COMMA(node_id, prop, idx) \
	ADC_DT_SPEC_GET_BY_IDX(node_id, idx),


static const struct adc_dt_spec adc_chan4 = ADC_DT_SPEC_GET_BY_IDX(DT_PATH(zephyr_user), 1);

static const struct gpio_dt_spec rtd = GPIO_DT_SPEC_GET(DT_PATH(zephyr_user), rtd_gpios);

int main(void)
{
	int err;
	uint32_t count = 0;
	uint16_t buf_1, buf_2;
	struct adc_sequence sequence_1 =
		{
			.buffer = &buf_1,
			/* buffer size in bytes, not number of samples */
			.buffer_size = sizeof(buf_1),};

	int rc;


	rc = gpio_pin_configure_dt(&rtd, GPIO_OUTPUT);
	if (rc < 0)
	{
		printf("Could not configure sw0 GPIO (%d)\n", rc);
		return 0;
	}
	gpio_pin_set_dt(&rtd, 0);


	if (!adc_is_ready_dt(&adc_chan4))
	{
		printk("ADC controller device %s not ready\n", adc_chan4.dev->name);
		return 0;
	}

	err = adc_channel_setup_dt(&adc_chan4);
	if (err < 0)
	{
		printk("Could not setup channel (%d)\n", err);
		return 0;
	}
;
	while (1)
	{
		int32_t val_mv_1 = 0;


		(void)adc_sequence_init_dt(&adc_chan4, &sequence_1);

		err = adc_read_dt(&adc_chan4, &sequence_1);
		if (err < 0)
		{
			printk("Could not read (%d)\n", err);
			continue;
		}

		val_mv_1 = (int32_t)((int16_t)buf_1);
		
		err = adc_raw_to_millivolts_dt(&adc_chan4,
									   &val_mv_1);


			if (err < 0)
		{
			printk(" (value in mV not available)\n");
		}
		else
		{

			printk(" = %d mV\n", val_mv_1);
		}

		k_msleep(1000);
	}
	return 0;
}
RTT:
00> = -4 mV
00> = -9 mV
00> = 10 mV
00> = -13 mV
00> = -9 mV
00> = -4 mV
00> = -8 mV
00> = 0 mV
00> = -6 mV
00> = -4 mV
00> = -2 mV
00> = 1 mV
and go on.
Thanks!!
  • I wrote some extensive code to get very accurate samples from an RTD with SAADC 12-bits effective ENOB using alternate differential measurements; the code is low-level bare-metal, but you can follow the guidance I provide and use either nrfx or zephyr (if you must). The code is valid for nRF52832, nRF52840 and nRF52833:

    seeking-more-information-on-nrf52833-adc-reference-and-buffers

  • UPDATE:

    I have tested on a fixed Rx (real value 99ohm) and the results are much better (64X average):

    Vout(diff) Vin Temp RTD_meas error
    00>  = -0.16mV  vin = 2.71V  temp = -0.78  rtd = 99.70  error: 0.71%
    00>  = -0.08mV  vin = 2.71V  temp = -0.39  rtd = 99.85  error: 0.86%
    00>  = -0.59mV  vin = 2.72V  temp = -2.95  rtd = 98.86  error: -0.14%
    00>  = -0.37mV  vin = 2.71V  temp = -1.87  rtd = 99.28  error: 0.28%
    00>  = -0.28mV  vin = 2.72V  temp = -1.40  rtd = 99.46  error: 0.47%
    00>  = -0.14mV  vin = 2.71V  temp = -0.70  rtd = 99.73  error: 0.74%

    When I test on a real 3 wire RTD, the results are so unstables.

  • The diagram is not clear how the 3-wire RTD is connected, can you post more details? There should be 3 separate wires going to the RTD and it's best to use differential SAADC measurements. Where is the RTD power coming from? Are the remote wires twisted or shielded?

    Typical measured values: 14-bit value of 905.0 Ohm 2-Wire test resistor using 128 samples is 904.9 Ohms with -0.01% error

    // Internal 0.6v Ref 14-bit S0S1 2-Wire RTD actual value 905.0 Ohm (reference 2001.4 Ohm) - Pos-Neg ADC
    // VDD mV Iref uA  RdsOn  V1 mV V2 mV V3 mV    Vrtd    Vref   Rrtd  Error
    // ====== ======= ======  ===== ===== =====  ======  ====== ====== ======
    //   2974    1008     41   2932   911    -3  3108.5  6883.3  903.8 -0.13%
    //   2975    1007     41   2933   912    -2  3108.3  6882.6  903.8 -0.13%
    //   2974    1007     37   2936   913    -2  3107.9  6882.4  903.8 -0.14%
    //   2976    1007     42   2933   914    -2  3108.5  6882.0  904.0 -0.11%
    //   2973    1007     38   2934   911    -2  3108.3  6881.3  904.0 -0.11%
    //   2977    1007     42   2934   911    -1  3110.3  6882.9  904.4 -0.07%
    //   2978    1008     40   2937   913    -1  3110.1  6884.8  904.1 -0.10%
    //   2977    1008     40   2936   913    -1  3109.8  6885.3  903.9 -0.12%
    //
    // Internal 0.6v Ref 14-bit S0S1 2-Wire RTD actual value 905.0 Ohm (reference 2001.4 Ohm) - Neg-Pos ADC
    // VDD mV Iref uA  RdsOn  V1 mV V2 mV V3 mV    Vrtd    Vref   Rrtd  Error
    // ====== ======= ======  ===== ===== =====  ======  ====== ====== ======
    //   2977    1010     41   2935   912    -3  3120.1  6896.4  905.5  0.05%
    //   2976    1009     40   2935   912    -2  3119.5  6893.8  905.7  0.07%
    //   2973    1009     39   2933   912    -2  3119.4  6892.3  905.8  0.09%
    //   2976    1010     40   2935   911     0  3121.9  6896.3  906.0  0.11%
    //   2975    1010     39   2935   913    -2  3120.9  6896.3  905.7  0.08%
    //   2975    1009     40   2934   911    -1  3120.0  6891.4  906.1  0.12%
    //   2976    1009     41   2934   912     0  3118.6  6892.3  905.6  0.07%
    //   2975    1009     38   2936   913    -1  3118.3  6891.4  905.6  0.07%
    //
    // Measured 14-bit value of 905.0 Ohm 2-Wire test resistor using 128 samples is 904.9 Ohms with -0.01% error
    

    Sample circuit; the  RTD is presumably remote:

    // RTD Measurement - 2- and 3-wire Unidirectional current
    //                          + ----------------------------------------------------------------------+
    //                          |  nRF52832/nRF52833/nRF52840                                           |
    //                          |                                                                       |
    //                          |    VDD               VDD                 VDD                          |
    //                          |   --#--             --#--               --#--                         |
    //                          |     |                 |                   |                           |
    //                          |   __|__               |   Excitation      |   Option                  |
    //                          |    / \                +-|   On            +-|   13k                   |
    //                          |   /-+-\                 |<- H0   H1         |<- Pullup                |
    //                          |     |                 +-|   160R 35R      +-|   (not used)            |
    //         Excitation  P0.04|     |                 |                   |                           |
    //         +----------------O-----#------#----------#-------------------#------------ In            |
    //         |                |     |      |          |   Excitation      |   Option                  |
    //         |                |   __|__  -----        +-|   Off           +-|   13k                   |
    //         |                |    / \   -----          |<- L0   L1         |<- Pulldown              |
    //         |                |   /-+-\    |3pF       +-|   160R 35R      +-|   (not used)            |
    //         |                |     |      |          |                   |                           |
    //         |                |   =====  =====      =====               =====                         |
    //         |                |    ===    ===        ===                 ===                          |
    //         |                |     =      =          =                   =                           |
    //         |                |                                                                       |
    //         |                |    VDD                                         VDD                    |
    //         |                |   --#--                                       --#--                   |
    //         |                |   __|__                    Auto-adjust:         |   160k              |
    //         |                |    / \                     Bias inputs at VDD/2 +-| Bias Hi/Lo/Both   |
    //         |                |   /-+-\                     VDD1_2                |<-                 |
    //         |                |     |   PIN_VOLTAGE_1                           +-|                   |
    //         |          P0.28 |     |   AIN4          |----'T'-Mux-P---|        |            P SAADC  |
    //         #--------#-------O-----#------#-------#--+ +----#-------+ +--#-----#------#------#-->    |
    //         |        |       |     |      |       |  | |    |       | |  |     |      |      |       |
    //         |        |       |   __|__  -----     |  ----   +-|    ----- |     +-|   +++     |       |
    //         |        |       |    / \   -----     |   |       |<--+  |   |       |<- | |   -----     |
    //  Rref  +++ 100nF |       |   /-+-\    | 3pF   |   |     +-|   |  |   |     +-|   | |   -----     |
    //  2k0   | |     -----     |     |      |       |   +---- |--------#   |     |     +++     | 2.5pF |
    //  1%    | |     -----     |   =====  =====     |         |     |  |   |     |      |1M0   |       |
    // (0.1%) +++       |       |    ===    ===      |       =====   |  |   |   =====  =====  =====     |
    //         |        |       |     =      =       |        ===    |  |   |    ===    ===    ===      |
    //         |        |       |                    |         =    Select  |     =      =      =       |
    //         |        |       |                    |                      |                           |
    //         |        |       |                    |                      |    VDD                    |
    //         |        |       |                    |  |----'T'-Mux-N---|  |   --#--                   |
    //         |        |       |                    +--+ +----#-------+ +----+   |   160k              |
    //         |        |       |                                           | |   +-| Bias Hi/Lo/Both   |
    //         |        |       |         PIN_VOLTAGE_2                     | |     |<-                 |
    //         |        | P0.29 |         AIN5          |----'T'-Mux-----|  | |   +-|                   |
    //         #--------#-------O-----#------#-------#--+ +----#-------+ +--# |   |            N SAADC  |
    //         |        |       |                    +--+ +----#-------+ +----#---#------#------#-->    |
    //    RTD +++ 100nF |       |                                           | |   |      |      |       |
    //        | |     -----     |                                           | |   +-|   +++     |       |
    //        | |     -----     |          Note V3 can be negative          | |     |<- | |   -----     |
    //        +++       |       |          PIN_VOLTAGE_3                    | |   +-|   | |   -----     |
    //         |        | P0.31 |          AIN7         |----'T'-Mux-----|  | |   |     +++     | 2.5pF |
    //         #--------#-------O-----#------#-------#--+ +----#-------+ +--# |   |      |1M0   |       |
    //         |                |                    +--+ +----#-------+ +----# =====  =====  =====     |
    //         |                |                                           | |  ===    ===    ===      |
    //         |                |                                           | |   =      =      =       |
    //         |        VDD     |    VDD                                    | |                         |
    //         |       --#--    |   --#--                                   | |   P: Single-ended       |
    //         |         |      |     |                                     | |   P&N: Differential     |
    //         |         +------O-----#   PIN_VOLTAGE_0                     | |                         |
    //         |                |     |   AIN_VDD       |----'T'-Mux-----|  | |                         |
    //         |                |     +-----#--------#--+ +----#-------+ +--+ |                         |
    //         |                |                    +--+ +----#-------+ +----#                         |
    //         |                |                                             |                         |
    //         |                |    GND                |----'T'-Mux-----|    |                         |
    //         #----------------O-----#-----------------+ +----#-------+ +----+                         |
    //         |                |     |                                                                 |
    //       =====              |   =====                                                               |
    //        ===               |    ===                                                                |
    //         =                |     =                                                                 |
    //                          +-----------------------------------------------------------------------+
    //
    // Capacitor min value = (3pF+2.5pF)*2^14=80nF
    // Vref = differential voltage V1 and V2 in SAADC counts
    // Vrtd = differential voltage V2 and V3 in SAADC counts
    // Rrtd = (Vrtd * Rref)/Vref Ohms
    

  • Hi! This is the detalied circuit:

    With 1/6 gain, 0.6V ref value, differential ADC and 1024 samples I got an main error of 0.33%, with a standar deviation of 1C. The PT100 is 40cm lenght untwisted. I think wheatstone Bridge, instead of just one ref resistor, generates more noise.

    The measurements has improved when I used ratiometric measurement, measuring VDD to get the variation of the bridge power instead of a fixed 3V value.

    Output (measured RTD with DMM 109.6C):

    00>  adc = 4.67mV, vin = 2.64V, diff = 0.00V, temp = 23.67, main_temp =  24.23, desv_temp =  1.04, rtd = 109.22, error =  0.11%, mov_error =  0.31%
    00>  elapsed_time = 218
    00>  adc = 4.64mV, vin = 2.64V, diff = 0.00V, temp = 23.54, main_temp =  24.23, desv_temp =  1.04, rtd = 109.17, error =  0.06%, mov_error =  0.31%
    00>  elapsed_time = 218
    00>  adc = 5.13mV, vin = 2.64V, diff = 0.01V, temp = 26.00, main_temp =  24.30, desv_temp =  1.04, rtd = 110.12, error =  0.94%, mov_error =  0.33%
    00>  elapsed_time = 218
    00>  adc = 4.85mV, vin = 2.64V, diff = 0.00V, temp = 24.61, main_temp =  24.30, desv_temp =  1.04, rtd = 109.58, error =  0.44%, mov_error =  0.33%
    00>  elapsed_time = 217
    00>  adc = 4.80mV, vin = 2.64V, diff = 0.00V, temp = 24.35, main_temp =  24.29, desv_temp =  1.04, rtd = 109.48, error =  0.35%, mov_error =  0.33%
    00>  elapsed_time = 218
    00>  adc = 4.77mV, vin = 2.64V, diff = 0.00V, temp = 24.16, main_temp =  24.29, desv_temp =  1.04, rtd = 109.41, error =  0.28%, mov_error =  0.33%
    00>  elapsed_time = 218
    00>  adc = 4.85mV, vin = 2.64V, diff = 0.00V, temp = 24.56, main_temp =  24.27, desv_temp =  1.02, rtd = 109.56, error =  0.42%, mov_error =  0.32%
    00>  elapsed_time = 218
    00>  adc = 4.76mV, vin = 2.64V, diff = 0.00V, temp = 24.12, main_temp =  24.30, desv_temp =  1.03, rtd = 109.39, error =  0.27%, mov_error =  0.33%
    00>  elapsed_time = 218
    00>  adc = 4.95mV, vin = 2.64V, diff = 0.00V, temp = 25.09, main_temp =  24.31, desv_temp =  1.04, rtd = 109.77, error =  0.61%, mov_error =  0.34%
    00>  elapsed_time = 218
    00>  adc = 4.74mV, vin = 2.64V, diff = 0.00V, temp = 23.99, main_temp =  24.31, desv_temp =  1.04, rtd = 109.34, error =  0.22%, mov_error =  0.34%
    00>  elapsed_time = 217
    00>  adc = 4.58mV, vin = 2.64V, diff = 0.00V, temp = 23.24, main_temp =  24.28, desv_temp =  1.05, rtd = 109.05, error = -0.05%, mov_error =  0.33%
    00>  elapsed_time = 218
    00>  adc = 4.57mV, vin = 2.64V, diff = 0.00V, temp = 23.13, main_temp =  24.27, desv_temp =  1.06, rtd = 109.01, error = -0.08%, mov_error =  0.32%
    00>  elapsed_time = 218
    00>  adc = 4.57mV, vin = 2.64V, diff = 0.00V, temp = 23.14, main_temp =  24.22, desv_temp =  1.05, rtd = 109.01, error = -0.08%, mov_error =  0.31%
    00>  adc = 5.19mV, vin = 2.64V, diff = 0.01V, temp = 26.34, main_temp =  24.28, desv_temp =  1.04, rtd = 110.26, error =  1.06%, mov_error =  0.33%

    Thanks!

Related