Pages: [1]   Go Down
Author Topic: Thermistor Code  (Read 3884 times)
0 Members and 1 Guest are viewing this topic.
B0100111001000011, USA
Offline Offline
Edison Member
*
Karma: 0
Posts: 1503
I'm confused.  Wait, maybe not..
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

I found a code for using a 10k Thermistor in the Playground (link here).  It contains two sketches:  One short sketch that runs the calculations and outputs the temperature to the Serial Monitor, and one that's much longer, and I think all it does is print more information to the serial monitor along with more (mostly useless as far as I can tell) calculations.

Also on that page, the author mentions that his 5V rail is really only 4.86 volts, so he has adjusted the code to work for him.  My question is that I cannot see anywhere in the first (small) code where he used 4.86 volts;  In fact, I can't see where he used 5V...

PS:  Is it possible that the voltage is only needed for his (assumed) pointless calculations?

I think I see it in the longer script, but if someone could point it out that'd be dandy.  Here are the two scripts:

Short Script
Code:
#include <math.h>

double Thermister(int RawADC) {
 double Temp;
 Temp = log(((10240000/RawADC) - 10000));
 Temp = 1 / (0.001129148 + (0.000234125 * Temp) + (0.0000000876741 * Temp * Temp * Temp));
 Temp = Temp - 273.15;            // Convert Kelvin to Celcius
 Temp = (Temp * 9.0)/ 5.0 + 32.0; // Convert Celcius to Fahrenheit
 return Temp;
}

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

void loop() {
 Serial.println(int(Thermister(analogRead(0))));  // display Fahrenheit
 delay(100);
}

Long Script
Code:
#include <math.h>
//Schematic:
// [Ground] ---- [10k-Resister] -------|------- [Thermistor] ---- [+5v]
//                                     |
//                                Analog Pin 0

double Thermistor(int RawADC) {
 // Inputs ADC Value from Thermistor and outputs Temperature in Celsius
 //  requires: include <math.h>
 // Utilizes the Steinhart-Hart Thermistor Equation:
 //    Temperature in Kelvin = 1 / {A + B[ln(R)] + C[ln(R)]^3}
 //    where A = 0.001129148, B = 0.000234125 and C = 8.76741E-08
 long Resistance;  double Temp;  // Dual-Purpose variable to save space.
 Resistance=((10240000/RawADC) - 10000);  // Assuming a 10k Thermistor.  Calculation is actually: Resistance = (1024/ADC)
 Temp = log(Resistance); // Saving the Log(resistance) so not to calculate it 4 times later. // "Temp" means "Temporary" on this line.
 Temp = 1 / (0.001129148 + (0.000234125 * Temp) + (0.0000000876741 * Temp * Temp * Temp));   // Now it means both "Temporary" and "Temperature"
 Temp = Temp - 273.15;  // Convert Kelvin to Celsius                                         // Now it only means "Temperature"

 // BEGIN- Remove these lines for the function not to display anything
  Serial.print("ADC: "); Serial.print(RawADC); Serial.print("/1024");  // Print out RAW ADC Number
  Serial.print(", Volts: "); printDouble((([glow]RawADC*4.860[/glow])/1024.0),3);   // 4.860 volts is what my USB Port outputs.
  Serial.print(", Resistance: "); Serial.print(Resistance); Serial.print("ohms");
 // END- Remove these lines for the function not to display anything

 // Uncomment this line for the function to return Fahrenheit instead.
 //Temp = (Temp * 9.0)/ 5.0 + 32.0; // Convert to Fahrenheit
 return Temp;  // Return the Temperature
}

void printDouble(double val, byte precision) {
  // prints val with number of decimal places determine by precision
  // precision is a number from 0 to 6 indicating the desired decimal places
  // example: printDouble(3.1415, 2); // prints 3.14 (two decimal places)
  Serial.print (int(val));  //prints the int part
  if( precision > 0) {
    Serial.print("."); // print the decimal point
    unsigned long frac, mult = 1;
    byte padding = precision -1;
    while(precision--) mult *=10;
    if(val >= 0) frac = (val - int(val)) * mult; else frac = (int(val) - val) * mult;
    unsigned long frac1 = frac;
    while(frac1 /= 10) padding--;
    while(padding--) Serial.print("0");
    Serial.print(frac,DEC) ;
  }
}

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

#define ThermistorPIN 0   // Analog Pin 0
double temp;
void loop() {
 temp=Thermistor(analogRead(ThermistorPIN));           // read ADC and convert it to Celsius
 Serial.print(", Celsius: "); printDouble(temp,3);     // display Celsius
 temp = (temp * 9.0)/ 5.0 + 32.0;                      // converts to Fahrenheit
 Serial.print(", Fahrenheit: "); printDouble(temp,3);  // display Fahrenheit
 Serial.println("");                                   // End of Line
 delay(100);                                           // Delay a bit... for fun, and to not Serial.print faster than the serial connection can output
}

« Last Edit: December 10, 2009, 07:10:31 pm by Tchnclfl » Logged

B0100111001000011, USA
Offline Offline
Edison Member
*
Karma: 0
Posts: 1503
I'm confused.  Wait, maybe not..
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

I'm starting to think maybe this wasn't the best section of the forum to post this in smiley-razz.
Logged

Lancashire, UK
Offline Offline
Edison Member
*
Karma: 9
Posts: 1991
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Code:
Temp = 1 / (0.001129148 + (0.000234125 * Temp) + (0.0000000876741 * Temp * Temp * Temp));

He'll have allowed for the voltage in the numbers in here.  The long sketch has a voltage reading so it needs to know the input voltage.

There are 10k thermistors and 10k thermisitors, the numbers may be miles out for your 10k thermistor........  smiley
Logged


B0100111001000011, USA
Offline Offline
Edison Member
*
Karma: 0
Posts: 1503
I'm confused.  Wait, maybe not..
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Ah... That could be problematic smiley-wink... smiley-razz
Logged

Lancashire, UK
Offline Offline
Edison Member
*
Karma: 9
Posts: 1991
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Dallas DS1820s rule OK.........  smiley
Logged


tytower
Guest
 Bigger Bigger  Smaller Smaller  Reset Reset

Seconded , those analog voltage sensors like LM36 can be up to +-2 degrees C out when used with the arduino and ATMega328 I have found . Put one side of a multimeter to earth and the other to the heat sink of the voltage regulator on th arduino to get the actual voltage supplied to your chip. Mine was 4.8 V  odd when plugged into the computer but it does vary depending on what is fed in.
« Last Edit: December 13, 2009, 08:52:14 pm by tytower » Logged

Alsager, Stoke on Trent
Offline Offline
Newbie
*
Karma: 0
Posts: 46
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

I spent a lot of time playing with thermisters and you are right they all need calibrating to be able to get anywhere close to using basic calculations.
Even if your was the same make as the sketch authors the chances are it still woulgn't match.

I found the best way in the end was to calibrate it against a known temperature over a limited range and then use the readings I got to put into a map command.

You would also be better off using the 3v3 from the arduino cuz that is consistant and can easily handle a couple of 10k or higher thermisters. The top of your second sketch shows the wiring diagram just use 3v3 instead of 5v ( which could be 4.8 one day and 5v the next)
Code:
/*
  Temperature readout to PC
 
 */

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

void loop() {
  // read the analog input into a variable:
  int val2= analogRead(0);
  int val = analogRead(1);
   Serial.println();
  Serial.println();
  Serial.println();
  Serial.println();
    Serial.println();
  Serial.println();
  Serial.println();
  Serial.println();
  Serial.print("Actual Sensor 1 Reading  ");
  Serial.println(val);  //Print the result
  Serial.print("Actual Sensor 2 Reading ");
  Serial.println(val2);
  Serial.println();
  val = map(val, 150, 390, 50, 90);
  val2=map(val2, 150, 390, 50, 90);

  Serial.println();
  Serial.print("Temperature of sensor 1 ");
  Serial.print(val);    //Print actual temp
  Serial.println("c");
  Serial.print("Temperature of sensor 2 ");
  Serial.print(val2);
  Serial.println("c");
  Serial.println();
  Serial.println();
  
  if (val <43)
  {
  Serial.println("          NOTE!  Below 43c Reading loses accuracy");
if (val2 <43)
Serial.print("            Note! Below 43c Reading loses accuracy");
}
  else
  {
  Serial.println();
  Serial.println();
 Serial.println();
  Serial.println();
 Serial.println();
  Serial.println();  

}

  delay(5000);
  
}

Here is the code I used to calibrate my units.
I was not too interested in absolute accuracy and was only interested in two temperatures (50c and 90c). My readings were quite accurate in between and to some extent outside.
You can miss out the code which says where the in-accuracies are, the rest will be useful to get the readings of YOUR thermister.

The numbers 150 and 390 (map to 50c and 90c) are only relevant for my thermister which was 100k anyway

I used a cup of boiling water then watched it cool. Well wrap up your thermister though.

I would say though the readings at the pin of the arduino fluctuated on succesive readings, you just have accept this.
I think if I needed serious readings then I would use the Dallas chip.
Regards  John
Logged

0
Offline Offline
Newbie
*
Karma: 0
Posts: 12
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Hi,

 I bought this sensor "Arduino Temperature Sensor Module for Sensor Shield " form ebay, and I try to used this sensor with Arduino Pro ATmega328. I download the code form arduino  web side . But I have a problem.  
 The problem is when I open the Serial Monitor I get different symbols  like these;

b¥b¥b¦b¦b¦b[ch134]b[ch134]b[ch134]b[ch134]b[ch134]b[ch134]b[ch134]b[ch134][ch134]b[ch134]b[ch134]b[ch134]b[ch134]b[ch134]b[ch134]b[ch134]b[ch134]b[ch134]b[ch134]b[ch134]b[ch134]b[ch134]b[ch134]b[ch134]b[ch134]b[ch134]bÅbÅb[ch134]bÅbÅbÅbÅbÅbÅbÅbÅbÅbÅbÅbÅbÅbÅbÅbÅbÅbÅbÅbÅbÅbÅbÅbÅbÅbÅbÅbÅbÅbÅbÅbÅb¥bÅb¥b¥b¥b¥b¥b¥b¥b¥b¥b¥b¥


How I can change these to numbers?
Logged

B0100111001000011, USA
Offline Offline
Edison Member
*
Karma: 0
Posts: 1503
I'm confused.  Wait, maybe not..
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Looks like you used Serial.begin() on a different baud rate than your serial monitor is on.  Click on that drop down box for baud rate, and adjust it to whatever the Serial.begin(x) has where X is.
Logged

0
Offline Offline
Newbie
*
Karma: 0
Posts: 12
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

I used this code;

#include <math.h>

double Thermister(int RawADC) {
 double Temp;
 Temp = log(((10240000/RawADC) - 10000));
 Temp = 1 / (0.001129148 + (0.000234125 * Temp) + (0.0000000876741 * Temp * Temp * Temp));
 Temp = Temp - 273.15;            // Convert Kelvin to Celcius
 Temp = (Temp * 9.0)/ 5.0 + 32.0; // Convert Celcius to Fahrenheit
 return Temp;
}

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

void loop() {
 Serial.println(int(Thermister(analogRead(0))));  // display Fahrenheit
 delay(100);
}
Logged

0
Offline Offline
Newbie
*
Karma: 0
Posts: 3
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

I'd like to get my own thermistors to read the temperature in Fahrenheit.
Could you please explain how you came to use this equation in the code?
Code:
Temp = 1 / (0.001129148 + (0.000234125 * Temp) + (0.0000000876741 * Temp * Temp * Temp));

I'm sure it has to do with the Steinhart-Hart equation but I can't piece together the constants you've used. I have some thermistors from Jameco https://www.jameco.com/webapp/wcs/stores/servlet/ProductDisplay?langId=-1&productId=207037&catalogId=10001&storeId=10001&krypto=9x3mj8umRTqleMMp6y634EzengKscOy9sj/Vzk52upmdroCT2STq6lFbkBuOr8j%2BujtmBN5rgtPe%0D%0AOmrmvInqNXccPSMFxtffjH5R/Eofkuh3NapmYzget36uZxtieQcFz4TMXIp%2BZBjyN1KntdRS0UB1%0D%0AAqZ0vS91coT05IEEepIPfL0brFcgtLV8Gj4y9%2BhxjD08GTBGojOLrkPPaSDWMA%3D%3D&ddkey=https:ForgotLogonIdView. The datasheet mentions a "B Constant" of 4038 but that's all I see for numbers.





Logged

Pages: [1]   Go Up
Jump to: