Alternate way to read Resistance temperature detectors (RTDs) with Microcontroller

After reading many posts with difficulties reading a Resistive Temperature Detector (RTD) such as a PT-1000, NTC with e.g. an Arduino, I am wondering if a time based approach could be used:

If I take a 1000uF capacitor and charge it via the RTD to a certain voltage (measured by an analog input), this takes time that varies depending on the R value of the RTC. One digital output of the Controller must be used to charge and discharge all connected R-Cs and to let the Controller determine the exact starting time of charging. Once the analog input reaches the threshold of e.g. 90% V+ the time is stopped and R & T could be determined.

• The obvious disadvantage is that reading T takes time and limits the sampling rate, but seems acceptable for most applications.
• The obvious advantage is the simplicity of the circuit similar to a voltage divider.

Questions:

• Is this idea reasonable at all?
• What could be the accuracy of the reading for a PT-1000?
• What are the tradeoffs in capacitance vs accuracy.

EDIT: Notes: This solution is intended for Arduino projects and not for a high volume products. The 0..1023 resolution 10 bit A/D converter of Arduino UNO's has a poor resolution for resistive devices with voltage divider yielding about 14 steps for 18 Kelvin. This is a theoretical idea and that is why it is posted here.

Update: Andy pointed out that capacitance change of the circuit could be a problem. I looked up that typically "Capacitance increases less than 5% from 25 ºC to the high temperature limit." If the capacitor is kept at room temperature, the problem could be controlled. Initial calibration due to tolerance of the capacitors could be problematic.

• "The obvious advantage is the simplicity of the circuit." How is using a RC charging circiut that has to be continuously measured to verify when it is considerd "charged", requires accurate timing, and a method to discharge the capacitor, simpler than a resistor devider into a ADC pin? – Joren Vaes May 10 '17 at 8:22
• 1. yes. 2. hard to say, but it be affected by the cap. 3. bigger is more precise, but takes longer. Generally though, this is sound; i made a arduino-based resistance meter and it worked more accurately over a larger range with an RC than a voltage divider... – dandavis May 10 '17 at 8:50
• The PT100 is much more accurate than any 1000 microfarad cap .The cap would be bigger than the micro . – Autistic May 10 '17 at 11:41
• All valid comments, but some Microcontrollers with 1024bit A/D resolution are probably better at timing, than A/D conversion. – cat May 11 '17 at 5:41
• There is no micro, or any other chip for that matter, with 1024 bit A/D resolution. – Olin Lathrop May 11 '17 at 11:15

6 Answers

What you are talking about is called charge time measurement. There are even microcontrollers with built-in hardware to assist with this. Usually it is intended for measuring changes in small capacitances, like those of capacitive touch buttons.

While what you propose would work, it would have poor accuracy and more complexity, not less, compared to the traditional approach of using a single resistor and a A/D. Your method uses a capacitance value and a time value as reference. Time can be easily measured with great accuracy and resolution cheaply, and is not a problem. Capacitance, however, is. Even 10% capacitors cost more than "regular" types. %1 capacitors cost a lot more, if you can find them at all.

One advantage of your system is that it can have great resolution. This is basically dependent on how long you are willing to wait and how fast your counter can run in the mean time. Having a counter run at a few 10s of MHz is easily achievable in many modern microcontrollers. So if you're after small temperature changes, but don't care that much about absolute temperature, then this method isn't quite as silly as it would be otherwise.

However, a single fixed resistor so that it and the RTD form a resistor divider, then the result of that into a A/D is simpler and more accurate. If extra high resolution was really needed for some reason, I'd use a external delta-sigma A/D. Those are slower than A/Ds built into microcontrollers, but with much higher resolution. The slowness doesn't matter when you're measuring temperature and the sensor time constant is still many times the 20 ms or so conversion time of a delta-sigma A/D.

• Don't forget that charge time will be linear with the resistance over the entire range, while divided voltage will not. – Scott Seidman May 11 '17 at 11:28
• After practical tests with 1000 uF, I did find the accuracy and resolution in the same range (+-1K) as a single sample read of a voltage divider on a 10 bit A/D on Arduino Uno. The interesting thing is that charging 1000uF to exactly 63.2% yields R in Ohms = charge time in ms (see capacitor time constant tau=R*C). Finally T=(R-1000)/3.9 for PT-1000. To determine the 63.2% charge, I used the same 10 bit A/Ds, which is problematic. The system must be calibrated with a known resistor. I could not track small T changes reliably. I need to do more tests. – cat May 12 '17 at 11:56

I'm not sold that the approach is daft. If your microcontroller has a comparator, (or you use an external comparator) and has a low-res ADC, you might get better precision out of a time-based solution in which you charge a cap than you could with an ADC, especially with a slow charge time. You'd also be using a different set of interrupts to do this than you would with an ADC approach, and its not too difficult to see that depending on how your resources are used, you might get nudged in this direction for a particular scenario.

Also, voltage division will not produce a linear output if the RTD (or other resistive device) produces large changes in resistance, but the charging approach does.

It's a tool for your toolbox that you might call upon in the right situation.

Once the analog input reaches the threshold ...

this approach was widely used in the good old days when onboard adc was rare for mcus.

it can be used to measure resistance, capacitance, or input voltage. the basic concept is to charge up a capacitor so the voltage across it will change the state of the input pin, though mostly a GPIO pin (aka in digital mode).

you should be careful, however, in using large capacitance here as the discharging could take a long time, and the discharge current could be excessive.

of e.g. 90% V+

it is OK to allow it to be charged up that much but generally you don't need nor desire that: under a lower threshold, the charge-up mimics more of a constant current source charging up a capacitor, ie better linearity.

The typical sequencing is like this:

1) connect the capacitor via a resistor to a voltage source -> it could be the rail or another gpio pin;

2) configure the read pin as digital output, and output a logic '0' on it.

3) at the start of the measurement, put that read pin to input to allow the capacitor to charge up;

4) count the time until that pin turns to a logic high; and turn the read pin to output to discharge the capacitor.

5) done.

the steps 3/4 can be slightly different depending on how you set up the idle state of the pin. The above assumes that the pin idles low - generally, having it idles low is more desirable. you can also have it idles high as well.

the beauty is in its simplicity: all you do is to turn the read pin to input or output to control the charge / discharge of the capacitor.

this is probably the oldest trick for old embedded engineers.

Yes, you could do this. It's a standard technique. In most commercial implementations the circuit is switched between the unknown resistance and a reference resistance. By calculating the ratio of times, the supply voltage and capacitance and clock frequency cancel out (an unregulated supply and RC clock can even be used, and usually is). There are some chips that have rudimentary hardware built in for this purpose (they tend to be mask programmed).

Back in the 90s we made our own ADC converters a lot, but these days you can buy converters or some MCUs even have high resolution converters built in so its not very attractive even if the engineering cost is amortized over so many units as to be virtually free.

So, I suggest as others have, picking a suitable external ADC and interfacing it.

And what about the capacitor tolerance affecting the measurement times? What about capacitor temperature and excess leakage creating really difficult calibration problems (or maybe you can use another RTD to compensate).

The obvious advantage is the simplicity of the circuit

What is simpler that having a decent quality pull-up resistor to Vcc and taking ratiometric measurements as most of the rest of industry tend to do.

The proposed idea is plain daft.

• A voltage divider with +5V supply voltage would yield something like a 0.5V change for the 300 Ohms difference between 0 and 100 degree of a PT-1000. Mapped on a 1024 bit resolution A/D measuring 0..5V you have lost 90% of the A/Ds resolution. That's why most Arduino solutions report poor results with RTDs. Of course there are hacks with Vref. – cat May 11 '17 at 5:50
• Have you ever heard of averaging to increase resolution? Average 4 samples to get an extra bit of resolution. Sometimes it's called dithering. Link: google.co.uk/… – Andy aka May 11 '17 at 7:20
• Of course you can always use a simple gain of X amplifier with precision resistors - still simpler than your proposal. Or you use an ADC reference that is lower than the supply rail. What options do you have? – Andy aka May 11 '17 at 7:26
• Averaging would increase the resolution from 1 degree to 0.5 degrees. The capacitor averages over 1 second. I do not consider using op-amps as simple circuits. I would need a PCB for that. electronics.stackexchange.com/questions/44895/… – cat May 11 '17 at 9:28
• You very recently added this to your question: "This is a theoretical idea and that is why it is posted here for discussion." This isn't a discussion site - it's a question and answer site. I have answered and I stand by my answer for the reasons given. End of "discussion" from my point of view. – Andy aka May 11 '17 at 9:33

In addition to all other answers, I want to post my own practical tests using an ArduinoUno with 10bit ADC:

Setup: I used a 1000uF capacitor and charged/discharged it using a digital IO pin connected to the resistor R (RTD or fixed) while observing the capacitor's voltage with the built in 10bit ADC (DIGITALOUT - R -ADC- C - GND).

For the RTD, I did find the accuracy and resolution is approximately in the same range (+-1K) as a single sample read of a voltage divider (1kOhms - Pt1000) on a 10 bit A/D. The interesting thing is that charging 1000uF to exactly 63.2% yields R in Ohms equals charge time in ms. This is a result of the capacitor time constant tau=R*C relationship. Finally T=(R-1000)/3.9 for PT-1000. 63.2% charge was when the ADC value exceeded 647 (63.2% of 1024). The system must be calibrated with a known resistor.

In contrary to the expectations, the capacitors charge duration has a standard deviation that does not allow more precise measurements of the actual value of R than a 10bit ADC, despite the time resolution of the Controller could do 1000 times better. I do not believe that the variation of the charge duration can be decreased by buying better parts (e.g. 1% capacitors). Maybe observing the capacitors voltage with better means (12bit ADC, digital input pin) could improve results.

As others pointed out, the capacitor is temperature sensitive. Changes of +- 10 degrees K (simply touching the capacitor) produce visible results and change the measurements.

If a Controller has no builtin ADC one can substitute a digital input to observe the capacitors voltage. This can emulate a ADC, which was done in the past, as others have stated.

The capacitor time constant tau=R*C allows building a really simple measurement tool for capacitance or resistance: deltaT = microsseconds() - startTime; ohms = deltaT/microFarad; OR microFarad = deltaT/ohms;

For the purpose of reading a RTD like the Pt1000 on a 10 bit ADC using a voltage divider (1k - Pt1000) yields 84 discrete steps for a change of 100K, which is as good as the R-C solution, but has fewer disadvantages. Surprisingly it is possible (on ArduinoUno) to improve far beyond the resolution of the ADC using signal averaging over about 200 values (https://en.wikipedia.org/wiki/Signal_averaging). This increases the resolution from (1.2K native 10bit) to about 0.1K(!) (using a constant resistor instead of the Pt1000 for testing). Such a high gain in precision by signal averaging is unexpected and I cannot explain it. This finally is far better than the R-C solution. (Andy pointed this out and referenced this document: http://www.atmel.com/images/doc8003.pdf)

• If the signal is properly dithered one could expect an improvement approaching $\sqrt{200}$ or about 14:1. – Spehro Pefhany May 14 '17 at 12:28
• I got 10 fold improvement without any additional dithering hardware, just with averaging 200 values, which took 25ms. That should not be possible (djerickson.com/arduino). Very strange! One more link about dithering here: edwardmallon.wordpress.com/2017/02/27/… – cat May 15 '17 at 18:51
• If there is sufficient noise (or if you don't bother to try measuring independent linearity) you can get a real or apparent improvement. Obviously if there is zero noise you will get no improvement at all and the summed output will move in steps that are the same percentage of full scale. – Spehro Pefhany May 15 '17 at 19:23