Thermistors and the Spark Core

100% understand that this is not a spark specific question (well, kind of…its about 3.3v boards), but i feel like the community is so helpful here, im comfortable asking.

i am trying to build a wifi temperature sensor using my spark core. i have previously built ones using the RasPi, but i feel like a spark would be a more elegant solution.

for a thermometer, ive planned on using a Maverick ET-73 since they are so easy to come by. they are thermsistors, so i have one clicked in using a 10k resistor. unfortunately, all the examples i found were built for arduino UNOs (and a 5v board)

since i know enough about these to understand the voltage matters, i modified the code from here:
http://forum.arduino.cc/index.php/topic,7530.0.html

I retrieved a decent A, B, C value set, and then changed the code to the below, but its showing entirely incorrect temps. any ideas where im wrong on this??

// calculate voltage
float voltage = aval / 1024 * 3.3;
Serial.print("voltage = ");
Serial.print(voltage);
Serial.print("\n");

// calculate resistance
float resistance = (10000 * voltage) / (3.3 - voltage);
Serial.print("resistance = ");
Serial.print(resistance);
Serial.print("\n");

// calcuate temperature.  Use these values for A, B, and C till you
// get everything working, and then do some measurements to calibrate
// your thermistor in circuit.
float logcubed = log(resistance);
logcubed = logcubed * logcubed * logcubed;
float kelvin = 1.0 / (2.3067434E-4 + 2.3696596E-4 * log(resistance) - 1.2636414E-7 * (logcubed));

// Convert to Fahrenheit
float f = (kelvin - 273.15) * 9.0/5.0 + 32.0;

return (int) f;

Not sure what kind of values you’re seeing, but I recall from somewhere in the docs (or in a forum post) that since the Spark returns an analogRead value in the 0-4096 range, you need to change instances of where you divide by 1024.

In this case, the

float voltage = aval / 1024 * 3.3;

line should read

float voltage = aval / 4096 * 3.3;

Maybe?

@Avidan what kind of values are you seeing, and how exactly are they off?

4095 is more proper, since that the value that equates to the ADC ref voltage.
Also if you can substitute a measured value for “3.3” (such as 3.28) that would improve your accuracy.

float voltage = aval / 4095 * 3.28;

If you have the exact datasheet for your thermistor, you should be able to pull out the exact coefficients needed for the second order equation they provide. You should not need to experimentally determine them.

Your voltage equation suggests that you have a 10k 1% pull up resistor to 3.3V, and the thermistor is connected to GND. Double check that, and for more accuracy measure your 10k ohm pull up and substitute your actual value.

thanks for the help

i found this guy who was using the same thermistor as i am, and im using his A,B,C values (http://hruska.us/tempmon/)

A = 2.3067434E-4;
B = 2.3696596E-4;
C = 1.2636414E-7;

It also seems that he is using 22k resistors. would that effect those values?

@zach, i am seeing analogRead values around 250-260 at room temp…but something bizarre is happening. the first equation to happen is the voltage calculation. i changed it at @BDub recommended, but for someone bizarre reason, the voltage float variable is equal to 0…even though it should be .20
i am using this printFloats function arduino printFloats

i can confirm the function is working, since i threw analogRead(0)/100 at it, and its printed the float just fine…maybe im just missing a semicolon :innocent:

Serial.print("analogread = ");
printFloat((float)aval, 6);
Serial.print("\n");

// calculate voltage
float voltage = aval / 4095 * 3.28;
Serial.print("voltage = ");
printFloat(voltage, 6);
Serial.print("\n");

and here is the output

analogread = 208.000000
voltage = 0.000000

Try type casting:

float voltage = (float)aval / 4095 * 3.28;

Also, only use 3.28 if that’s what you measured from the 3.3* pin to GND pin.

22.2k is significant only if you are using that as well. Just go with whatever you are using. Depending on the range of temperatures you are expecting, you can calculate the range of resistance you’ll expect from the thermistor… and then you can select an appropriate fixed resistor for the divider that gives you the best resolution over that range. At the same time you want to ensure you don’t push too much current through the thermistor and cause self heating.

good call. type casting worked perfectly.
i did measure and got 3.28 / 3.29

im pretty sure 10k is good, since i used them previously for a RasPi based project with the same thermistors and had good results.

now that i can follow the math, i am getting closer to figuring out where my math is wrong. here is some sample output. maybe my A,B,C values are off?

analogread = 220.000
voltage = 0.177
resistance = 567.742
log resistance = 6.342
log cubed = 255.041
kelvin = 587.818
fahrenheit = 598.403

its clearly not 600 degress in my office. do the other numbers look wrong?? they mathematically pencil…

Looking around the internet for temp constants for the Maverick ET-73 is a joke and a half.

First question, do you need a meat probe such as the ET-73? If not, get a thermistor that comes with constants and an equation to go with it. If you do need it… then you may have to calibrate it yourself if this doesn’t work, and probably should even if this seems close.

Second question, does your probe all by itself actually measure 567 ohms at room temp?

If so preceed… heh heh

Try these values:

A = 0.00524521
B = -0.00052519684
C = 0.0000041635158

excel equation:
= 1 / (0.00524521 + (-0.00052519684 * LOG(A3)) - (0.0000041635158 * LOG(A3) * LOG(A3) * LOG(A3)))

Around the middle of this page you can see how to calculate the constants if you have 3 data points.
http://www.facstaff.bucknell.edu/mastascu/eLessonsHTML/Sensors/TempR.html

Data points can be boiling water (100C), ice water (0C) and room temp (use your wall thermostat whatever you have to find it)

Linear math… FUN… -_-

1 Like

excellent. thanks for the info.
i do need to use the ET-73, because im trying to measure the temperature of meat! (this is a smoker project)

answer to the second question. nope. it reads 192 ohms.

time to boil some water…

bizarre. i followed a process outlined here (half way down the page)
i used a multimeter and a thermapen to come up with the following values.

Celsius : Ohms
61.944444 --> 51600
54.777778 --> 66000
46.222222 --> 89400
42.7778 --> 100500

Then, I put them in a text file and I used gnuplot

gnuplot> c(x) = A + B*x - C*x**3
gnuplot> fit c(x) "therm.txt" using (log($2)):(1.0/(273.15+$1)) via A,B,C

and i got

Final set of parameters Asymptotic Standard Error
======================= ==========================

A = 0.00168828 +/- 0.0009397 (55.66%)
B = 5.03271e-05 +/- 0.0001261 (250.5%)
C = -5.86979e-07 +/- 3.358e-07 (57.21%)

But when I use those values of A, B, C…i get some really wacky numbers

So then I went to a project that I know uses the ET-73 successfully (HeaterMeter) and I looked at what their default for the ET-73 is:
A: 0.00023067431
B: 0.00023696594
C: 1.2636415e-7

Still no luck. Does this equation really result in Kelvin??

This is my current code:

float voltage = (float)analogvalue / 4095 * 3.3;
float resistance = (10000 * voltage) / (3.3 - voltage);
float kelvin = 1 / (0.00023067431 + (0.00023696599 * log(resistance)) - (1.2636415e-7 * log(resistance) * log(resistance) * log(resistance)));
float fahrenheit = (kelvin - 273.15) * 9.0/5.0 + 32.0;

and this is the output at room temp
analogread = 3722.000
resistance = 99785.546
kelvin = 361.584
fahrenheit = 191.180

I know this is getting ridiculous, and I apologize to anyone stumbling into this crazy thread, which is probably going to be a forehead slapping wiring issue. But any and all help is appreciated.
I have confirmed the A, B, C values are correct (every sample using the ET-73 has them listed).

Is my wiring OK? BTW, I switched to a 22k resistor

This is the output im currently seeing at room temp.
Analog Reading: 3617
Resistance: 167635.49
Temperature: 85

Here is my current source code

#include <math.h>

void setup()
{
    Serial.begin(57600);
}

void loop()
{
    thermister_temp(analogRead(4));
    delay(1000);
}

void thermister_temp(int aval)
{
	double R, T;

    Serial.print("Analog Reading:");
	Serial.println(aval);

	R = (1 / ((4096 / (double) aval) - 1)) * (double) 22200;
	Serial.print("Resistance:");
	Serial.println(R);

    R = log(R);

	// Compute degrees C
	T = (1 / ((2.3067434E-4) + (2.3696596E-4) * R + (1.2636414E-7) * R * R * R)) - 273.25;
	// return degrees F
	Serial.print("Temperature:");
    Serial.println((int) ((T * 9.0) / 5.0 + 32.0));
}

Not sure why you changed your R calc, but should be:

voltage = (double) aval / 4095 * 3.3;
R = (22000 * voltage) / (3.3 - voltage);

I checked this before and it worked out correctly with a 22k pullup.

Also not a biggie but 273.15

Also double check your jumper wires that you soldered to that jack. They are known to OPEN and look still connected under the black overmolding. Never solder these! :smile: EDIT: closer look, maybe they are just crimped… solder some real wires on there :sunglasses:

BDub, that threw me off too but I think it reduces to the same thing.

I would try to use the multimeter to verify assumptions about what is going on in the circuit.

  • measure the resistance of your 22k resistor if you didn’t already
  • measure the resistance of your probe from A4 to GND and see if it’s actually close to 167,635 Ohms
  • Also measure the resistance of the probe from the ends of the plug connector – those connections look pretty loose from the photo.

With the the core powered on and the circuit as shown,

  • measure the voltage between 3.3V* and GND
  • measure the voltage across the 22k resistor, it should be (3617 / 4096) * 3.3 = 2.91479V if your analogRead value is accurate and 3.3V* is supplying the correct voltage

You’re right @amanfredi, I ran the numbers through and it’s perfect for Voltage = 1.1V, Aval = 1365… but only slightly off when I calculated using Analog Reading: 3617, Resistance: 167635.49 probably due to normalizing the 3.3V value.

@avidan did you try the boiling and ice water? Not sure if you can calculate the whole curve based on 42C to 62C

thanks for the feedback @amanfredi and @BDub
measure the resistance of your 22k resistor if you didn’t already — its actually 20.8k when i measure. i updated the formula to R = (1 / ((4095 / (double) aval) - 1)) * (double) 20800;

measure the resistance of your probe from A4 to GND and see if it’s actually close to 167,635 Ohms – confirmed
Also measure the resistance of the probe from the ends of the plug connector – those connections look pretty loose from the photo. — yep, i soldered them since photographing, and the resistance measure is much more stable

measure the voltage between 3.3V* and GND – 3.26
measure the voltage across the 22k resistor, it should be (3617 / 4096) 3.3 = 2.91479V if your analogRead value is accurate and 3.3V is supplying the correct voltage – yes, its 2.94

Still seeing some fluctuations…here is the thermistor in 50degree water

Analog Reading:3727
Resistance:212682.07
Temperature:74

Analog Reading:3733
Resistance:216555.25
Temperature:73

Analog Reading:3733
Resistance:216555.25
Temperature:73

That’s not much of a fluctuation. If your calculated resistance agrees with the multimeter measured resistance at a given temperature, the circuit is correct and the problem has to be in the resistance to temperature equation.

I think he means some “temperature discrepancies” … 50 degree water… 73 degree reading. I agree with you though, it’s the resistance to temp calc.

Need to calibrate it properly with boiling water, and ice water… and 50 degree water.

BTW how do you know it’s 50 degree water? Another accurate temp probe?

If you have an IR non-contact temp probe… those things are pretty crappy and no super accurate. Better to use a K-Type thermocouple if you can get your hands on a DMM that has a temperature input.

I have one of these:

…and the probe unplugs. Might be worth taking a stab at trying to come up with constants for mine to see how the process goes.

BTW, I don’t really enjoy using mine. It’s seems to say it’s done when there’s no way it’s up to temp yet. I think the probe conducts too much heat from the ring at the end down into where the actual sensor is (supposedly at the tip, but who knows). Or it might just be way off like yours… fancy gadgets with no accuracy equals garbage.

You have motivated me to make this device useful! … (throw away the wireless crap it came with, and replace it with the Spark Core :spark: and an OLED LCD for when I just want an instant reading, no phone/computer needed)

He mentioned a thermapen, which is supposed to be very good. I agree, take resistance measurements from 0 to 100 C and try generating your constants again.

If that doesn’t sound like fun, just subtract 24 degrees from your reading :stuck_out_tongue:

@BDub I am beyond excited that you are inspired…i am more of a culinary hacker than an electrical engineer, so getting others working on a similar project only makes it more amazing.

Here is a video as to why I think my constants are OK ( i used the defaults from heatermeter)

The blue box is a heatermeter. Here is the schematic

As you can see in the video, the Thermapen and Heatermeter are pretty close in temp.
But at the same time Spark reads:

Analog Reading:3760
Resistance:235701.49
Temperature:69