Measuring resistance

Is it possible to measure resistance on the Imp or would it require some sort of a converter. I am toying with the idea of using an RTD sensor over a thermocouple.

I’m fairly certain you can’t measure resistance directly, so would have to convert to voltage first … perhaps with a current source or bridge circuit.

How hard is it to read voltage changes? I am reading another forum that suggests sending a current across the sensor and reading the changes in voltage. From there you would have to convert to temperature.

I wonder how hard it would be to design a Sigma Delta A/D converter?

http://www.embedded.com/design/debug-and-optimization/4406844/The-basics-of-sigma-delta-analog-to-digital-converters-

Perhaps a little more info? Adafruit (and probably others) make nice thermocouple interface boards. thermocouples are the go-to for temperature measurement for a good reason. Is your measurement task something special?

Well thermocouples have to be calibrated quite a bit whereas RTP sensors have much better linearity. I was just seeing what everyone thought about attempting to use RTP vs thermocouples.

The imp card has an analog-to-digital converter built into ever pin, and the imp module has another two ADCs built in on PinA and PinB. Reading an RTD sensor appears to be just as easy as reading a thermistor, which is pretty commonly done (take a look at the tutorial here: http://www.instructables.com/id/TempBug-internet-connected-thermometer/)

While I haven’t tried this out with an RTD, the procedure should be basically the same:

  1. Create a resistive divider between VDD (that’s 3.3V if you’re using an April) and ground. The divider will be the made up of the RTD and another resistor with the same resistance as that of the RTD at your nominal temperature. You can put the RTD on the top or the bottom of the divider, but let’s assume it’s on the top for simplicity’s sake.

  2. Connect the center of the divider to an imp pin with an ADC. Configure the pin as ANALOG_IN.

  3. Call pin.read() to get the ADC value. You’ll get a value between 0 and 65535, where 65535 corresponds with VDD (3.3V). You can get the voltage by multiplying the value by (3.3 / 65535.0). This is the voltage at the center of the divider.

  4. The voltage at the center of the divider is the voltage across the resistor on the low side of the divider. V = I*R, so if we divide this by the resistance, we get the current through the divider. The ADC draws (essentially) 0 current, and the two resistors are in series; the current through the one on the bottom is the same as the current through the one on the top.

  5. The voltages across the two resistors will add up to the voltage across the full divider. Therefore, the voltage across the RTD is 3.3 - (voltage across the bottom resistor). Now you’ve got the voltage and the current for the RTD, so you know it’s resistance:

V = I * R
R = V / I

  1. Now you should be able to derive the temperature according to the RTD’s datasheet.

If you want to get more involved and start trying to remove any error introduced by the leads, you might have a look at the bridge circuits covered in the wikipedia page here: http://en.wikipedia.org/wiki/Resistance_thermometer

Hope this helps and good luck!

I realize you may have something different and unique in mind but for $15 USD you can get a board that connects type K thermocuples

Thermocuple breakout based on Max31855

This handles the linearity ‘issues’ for you. I just wanted to double-check and make sure you were not over-thinking this. I don’t think you would have to calibrate this system but I suppose that depends what kind of work you are doing.

Hey guys thanks for all of the input! I may be over thinking this, I had just read a tutorial on the difference between thermistors vs thermocouples vs RTD. RTD’s are listed as the most accurate and less prone to EMI which could be why some people report issues with thermocouples when the WiFi is enabled. Here is the tutorial for your edification:

http://www.controleng.com/search/search-single-display/temperature-tutorial-thermocouple-vs-rtd-vs-thermistor/aae906fe91.html

Not to mention the ability to use a CIP fitting in my brewing :slight_smile:

http://www.automationdirect.com/static/specs/psrtdprobecip.pdf

@tbyrne Ok I attempted to create the divider similar to the example but I am pretty sure I am doing this wrong. I do get a reading showing 104F (the RTD is at room temp), with a spurious reading of -456. The RTD has 3 leads and I currently have two of them wired to pin 8 which is giving me what I would have to assume are proper readings with bad math applied. Would you use say 2 pins in your example? (say 8 and 9) read both and apply the math accordingly?

The other question I have is the example you cite uses a resistance value at 10kOhm in K. The PT100 I am using cites 0.00385 Ohms/Ohm/OC. Would the 10kOhm resistor be appropriate and should I just be calculating in C.

http://www.intech.co.nz/products/temperature/typert/RTD-Pt100-Conversion.pdf

Also please correct any glaring errors in my assumptions :slight_smile:

OK note from tbyrne that should have gone into the public thread.

tbyrnetbyrne 1:41PM
Ok, that’s the voltage across the bottom of the bridge.

So the voltage across the top of the bridge (the RTD) is 3.3 - 1.51 = 1.79 V.

The current through the bridge is:

V = IR
1.51 V = I * R (bottom side)

I = 1.51 V / R (bottom side)

Now you have the current. Last, the resistance of the RTD:

V = IR

1.79 V = I * R

R = 1.79 / I

R = 1.79 / (1.51 / R(bottom side))

You’ll need to look up the relationship between resistance and temperature on your RTD data sheet.

@tbyrne So according to the calculations I have a resistance of 1.79? I would assume that it’s 1.79 over the 100Ohm@ 0C?

According to the datasheet I should have 100Ohm resistance at 0C. http://www.intech.co.nz/products/temperature/typert.html

On an interesting note, I think I am close to getting an actual reading. Right now, the probe is reading 100-101C with the algorithm I managed to get working. That would indicate I am off by 100 as it is sitting in an ice bath.

Here is the code:
`// assign hardware.pinA to a global variable
therm <- hardware.pinA;
// therm2 <- hardware.pin9;
// configure pin5 to be an ANALOG_IN
therm.configure(ANALOG_IN);
// therm2.configure(ANALOG_IN);

// these constants are particular to the thermistor we’re using
// check your datasheet for what values you should be using
const a_therm = 3.9083;
const b_therm = -5.775;
// const t0_therm = 273.15;

// the resistor in the circuit (100Ω)
const R2 = 100.0;

//set relay variables to off
// relaystrikeState <- false;
relaymashstate <- false;

function MashTemp_C() {
local Vin = hardware.voltage();

local Vout = Vin * therm.read() / 65535.0;
local R_Therm = (Vin / Vout);
local mashresistalgo = ((1+(R_Therm*math.pow(a_therm,-3)))+(math.pow(b_therm,-7)*math.pow(R_Therm,2)));

// local mashtemp_C = (R2math.pow(a_therm,-3)) / (math.pow(a_therm,-3) - R2mashresistalgo)
local mashtemp_C = R2 * mashresistalgo

return mashtemp_C;
}`

Interestingly, if I change to local mashtemp_C = mashresistalgo/R2
it always returns 0C.

OK some success!!

I found this algorithm from another RTD website which gives a simple, albeit not as accurate formula to read temperature on an RTD.

T = (R/R0 - 1) / α where R0 = 100, and α = 0.00385

The more accurate formula is called a cubic fit and I may attempt to implement it:

T = -247.29 + 2.3992 R + .00063962 R2 + 1.0241E-6 R3

So right now I am reading 20C in an ice bath. This means likely that I either have a bad design or I am missing a step somewhere. Here is my latest code:

<`// assign hardware.pinA and hardware.pinB to a global variable
therm <- hardware.pinA;
// therm2 <- hardware.pinB;
// configure pin5 to be an ANALOG_IN
therm.configure(ANALOG_IN);
// therm2.configure(ANALOG_IN);

// these constants are particular to the thermistor we’re using
// check your datasheet for what values you should be using
const a_therm = 0.00385;
const b_therm = -5.775;

// the resistor in the circuit (100Ω)
const R2 = 100.0;

//set relay variables to off
// relaystrikeState <- false;
relaymashstate <- false;

function MashTemp_C() {
local Vin = hardware.voltage();

local Vout = Vin * therm.read() / 65535.0;
local R_Therm = (R2*Vin / Vout) - R2;
local mashtemp_C = (R_Therm/R2 - 1) / a_therm

return mashtemp_C;
}`

Any thoughts would be greatly appreciated!

By jove, I think I’ve got it!

Remembering the rule that anything manufacturing can introduce differences across different manufacturers, I have added in a constant to allow me to normalize the actual RTD I am using at the time.

`// assign hardware.pinA and hardware.pinB to a global variable
therm <- hardware.pinA;
// therm2 <- hardware.pinB;
// configure pin5 to be an ANALOG_IN
therm.configure(ANALOG_IN);
// therm2.configure(ANALOG_IN);

// these constants are particular to the thermistor we’re using
// check your datasheet for what values you should be using
// b_therm value should be adjusted to normalize your RTD to 0C
const a_therm = 0.00385;
const b_therm = 5.5;

// the resistor in the circuit (100Ω)
const R2 = 100.0;

//set relay variables to off
// relaystrikeState <- false;
relaymashstate <- false;

function MashTemp_C() {
local Vin = hardware.voltage();

local Vout = Vin * therm.read() / 65535.0;
local R_Therm = (Vout / R2*Vin) - (R2-b_therm);

// local mashtemp_C = (R_Therm/R2 - 1) / a_therm
local mashtemp_C = (R_Therm/R2 - 1) / a_therm
return mashtemp_C;
}
`