Go Down

### Topic: Thermistor readings... use lookup table? (Read 8192 times)previous topic - next topic

#### sti robot

##### Jul 11, 2007, 06:53 pm
I'm going to be using a couple of thermistors to do wide range (32F - 350F) temperature readings.  The thermistor is going to be in a voltage gate so i can get analog voltage readings from it.  The problem with a  thermistor is that its resistance in relation to temperature does not change in a linear fashion.  Rather, it is a curve that is defined by a complicated formula (Steinhart Hart equation).  Unfortunately this equation makes use "ln()", which is something that is very difficult/slow to implement on the arduino.

So I have two options...
1) Make a lookup table with these values.
2) Fit exponential curves to portions of the curve.  Select the curve based on the inputs.

Currently I'm leaning towards #1.  I would have a 2x318 array that would contain these values.  That would take up approx 2 * 2 * 318 = 1272 bytes.  That's not very good.  Plus I haven't really figured out how i'm going to search for them.  A loop with if-then's doesn't sounds very fast.

#### du

#1
##### Jul 16, 2007, 04:00 am
I actually have exactly the same issue.  What I'm doing is simply storing the voltage values and then letting the mothership do the hard math to convert that to actual temps.  Can you do that?

If not, does the program on the Arduino actually need to know the temps or can you work in exponential space?  Like, instead of turning on the thermostat (or whatever) when the temp hits 75, turn it on when the voltage hits 3.2 (or whatever).

#### sti robot

#2
##### Jul 16, 2007, 04:24 amLast Edit: Jul 16, 2007, 04:26 am by sti_robot Reason: 1
No "mothership" in this project.  Everything is sent directly from the arduino to a 16x2 serial display.  It's a standalone unit.

All the temp values are to be read by human beings so they should show up a degC or degF values.  logarithmic arithmetic is way too difficult to do on the chip itself so I will be using lookup tables.

#### wandrson

#3
##### Jul 17, 2007, 05:14 pm
In the past when I've done this I've use the lookup table approach.

To create the lookup table I graphed the equation. and developed a set of control points that broke the curve into line segments that kept the error below my minimum threshold.  This method works well and has the virtue of keeping the lookup table size small and only requiring linear interperlation in between points.

#### sti robot

#4
##### Jul 17, 2007, 06:14 pm
I went with almost exactly what you did.  Lookup table.  Its only 318 integers in an array.

BTW I'm going to probably have to use your car power supply protection circuit from that other thread.

If anyone is interested in my project it's all document (all ramblings, etc....might want to read it back to front) here: http://www.iwsti.com/forums/showthread.php?t=84794

#### wandrson

#5
##### Jul 17, 2007, 11:46 pm
sti_robot:

Could you post you lookup table and description.  I was surprised that it is so large.  I would have expected something around a 17 element table to cover the 32-350 degree range you specified.  Depending on the curve of the sensor this would yield approximately a 20 degree interporlation range (17 ranges)

#### sti robot

#6
##### Jul 18, 2007, 01:47 am
Oh, I wasn't doing interpolation.  I was doing thresholds.  So if the voltage read by analogRead is between a and b then the temp is c.  So you are taking, say, 30-40 degrees and mapping those to some linear equation then mapping 40-50 (or whatever it is) to another linear equation?

#### sti robot

#7
##### Jul 18, 2007, 03:04 am
Apparently there is an upper bound for array size.  Apparently, I've reached it

I couldn't figure out why my sketch wasn't running.  Then I commented out the lookup table and voila it works.  I guess I'll use your interpolation idea.

#### sti robot

#8
##### Jul 18, 2007, 02:08 pm
I was all set to implement the interpolation style solution you suggested.  However, I figured out the y=mx+b line formula for the first segment and it comes out to something with m or b of 2.033e10 something or other that has to be expressed in scientific notation.  This is a non-starter as we all know that it is difficult to do decimal numbers...especially ones that require scientific notation to state, on the arduino.

Maybe I'll try to fit some exponential curves or something.  Maybe the os x graphic program isn't all that good.  I also tried open office calc but that doesn't solve for equations.

#### bdmatic

#9
##### Jul 18, 2007, 02:30 pm
Here's a lookup table implemented in flash memory:

http://www.arduino.cc/playground/ComponentLib/Thermistor

#### sti robot

#10
##### Jul 18, 2007, 03:07 pm

#include <avr/pgmspace.h>
and "PROGMEM"

This person was able to use the flash as memory for a constant.  Cool.
I may have to do the same sort of thing for a oil temp sender/sensor as well so this works out nicely.

The only concern I have with this is how much space the pgmspace.h takes up.  I guess if it is an issue I could always modify pgmspace.h to be smaller.

Currently the sketch uses about 10k of 14k available.

#### wandrson

#11
##### Jul 18, 2007, 04:36 pm
I would use a lookup table like below (made up values)

100                300              // Using integers it would be easy to use tenth of degrees if that level of precision is
200                500              // 500 => 50.0 degrees
300                700
400                900
500                1100
...

This would be implemented by a search on the ADC value (adc) to find the array value below (a1) and the array value above (a2) and the corresponding temperatures (t1 & t2).  The actual temp would be calculated as

t needs to be a long even if a1,a2,t1, and t2 are integers --to prevent overflow.

t= (((250-200)*(700-500)/(300-200)) + 500 = (((50)*(200)/(100))+500 = (10000/100)+500 = 100+500=600

The equation is the y=mx+b but is reformated to allow for integer mathmatics. If precision is an issue then the values can be multiplied (and longs can be used) to increase precision without the need to use floating point math.  Just watch out for overflows during calculations.

The table can be built from the temperature curve for the device and the best accuracy is obtained by selecting segments that are linear.  The segment size does not have to be the same--some can be larger and others smaller depending upon the shape of the curve.

#### zitron

#12
##### Jul 20, 2007, 01:34 amLast Edit: Jul 20, 2007, 01:35 am by zitron Reason: 1
Seems to me that if you are resigned to use up 1K of flash for your table, you might as well used floating point, which takes up almost as much, and simplifies things massively.

Edit: I don't get what the "poll" is supposed to be?

-Z-

#### sti robot

#13
##### Jul 20, 2007, 04:22 am
No clue why the poll was added.

I am recalculating everything right now.  I think a 470 Ohm resistor might be the best choice for temp range i selected.

I started calculating the lines i'll interpolate from.  Not having excel is a pain...this graphing program on os x is really basic and unwieldy.

#### wandrson

#14
##### Jul 20, 2007, 04:35 am
zitron,
the table approach i suggested only needs about 80 bytes (20 rows) to provide good results.

sti_robot,
if you want a spreadsheet program, look at openoffice.org

it is an open source office suite that can work with excel/word documents.

Go Up