질문게시판 > 답변 : 온도센서 NTC 써미스터로 24도를 맞춰야되는데

TODAY1,543 TOTAL2,170,493
사이트 이용안내
Login▼/회원가입
최신글보기 질문게시판 기술자료 동영상강좌

아두이노 센서 ATMEGA128 PWM LED 초음파 AVR 블루투스 LCD UART 모터 적외선


BASIC4MCU | 질문게시판 | 답변 : 온도센서 NTC 써미스터로 24도를 맞춰야되는데

페이지 정보

작성자 master 작성일2018-06-09 16:10 조회5,363회 댓글0건

본문

	

Reading a Thermistor

This is a function I wrote to convert the value from an analogRead call of a pin with a thermistor connected to it to a temperature. Unlike most other programs that use a look-up table, this function utilizes the Steinhart-Hart Thermistor Equation to convert "Thermistor Resistance" to "Temperature in Degrees Kelvin." I found the equation here, but it can also be found at Wikipedia.

The more simple program shows how little code is necessary to do the conversion, and how much memory and program space can be saved when compared to a large look-up table.

The more elaborate program shows the power of the function. It displays lots of data including the ADC (from 0 to 1023), the voltage on the analog pin (note: ideally, the arduino would be running at 5.0 volts, but my power supply gives it 4.86 volts, so I divide by 4.86. Look at the code to change that to whatever your power supply is giving), the resistance of the Thermistor, and the temperature in Celsius and Fahrenheit. It uses the printDouble routine which I found in a forum post here.

I hope this comes in handy for everyone. Like most of my code, it's freely usable and modifiable, and no credit is needed. Free, like arduino should be.


Navigation


Thermistor Test Schematic

 (Ground) ---- (10k-Resistor) -------|------- (Thermistor) ---- (+5v)
                                     |
                                Analog Pin 0

The Simple Code

 


%box%[@
#include <math.h>

double Thermistor(int RawADC) {
 double Temp;
 Temp = log(10000.0*((1024.0/RawADC-1))); 
//         =log(10000.0/(1024.0/RawADC-1)) // for pull-up configuration
 Temp = 1 / (0.001129148 + (0.000234125 + (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(Thermistor(analogRead(0))));  // display Fahrenheit
 delay(100);
}
 

 


The Elaborate Code

 

#include <math.h>
//Schematic:
// [Ground] ---- [10k-Resistor] -------|------- [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=10000.0*((1024.0/RawADC) - 1);  // Assuming a 10k Thermistor.  Calculation is actually: Resistance = (1024 /ADC -1) * BalanceResistor
// For a GND-Thermistor-PullUp--Varef circuit it would be Rtherm=Rpullup/(1024.0/ADC-1)
 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(((RawADC*4.860)/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
}
@]%%
 

 


The Elaborate Code (cleaned up a bit)

I have taken the liberty of cleaning the code up a bit for more modern versions of the arduino core - printDouble() is not necessary. I have also converted all the doubles to floats because the core only works in floats, but honours the completely useless casts to and from doubles. Altogether this saves ~400 bytes and makes it run a bit faster. I hope the comments make it slightly clearer what is going on.


/*
 * 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
 *
 * These coefficients seem to work fairly universally, which is a bit of a 
 * surprise. 
 *
 * Schematic:
 *   [Ground] -- [10k-pad-resistor] -- | -- [thermistor] --[Vcc (5 or 3.3v)]
 *                                               |
 *                                          Analog Pin 0
 *
 * In case it isn't obvious (as it wasn't to me until I thought about it), the analog ports
 * measure the voltage between 0v -> Vcc which for an Arduino is a nominal 5v, but for (say) 
 * a JeeNode, is a nominal 3.3v.
 *
 * The resistance calculation uses the ratio of the two resistors, so the voltage
 * specified above is really only required for the debugging that is commented out below
 *
 * Resistance = PadResistor * (1024/ADC -1)  
 *
 * I have used this successfully with some CH Pipe Sensors (http://www.atcsemitec.co.uk/pdfdocs/ch.pdf)
 * which be obtained from http://www.rapidonline.co.uk.
 *
 */


#include <math.h>

#define ThermistorPIN 0                 // Analog Pin 0

float vcc = 4.91;                       // only used for display purposes, if used
                                        // set to the measured Vcc.
float pad = 9850;                       // balance/pad resistor value, set this to
                                        // the measured resistance of your pad resistor
float thermr = 10000;                   // thermistor nominal resistance

float Thermistor(int RawADC) {
  long Resistance;  
  float Temp;  // Dual-Purpose variable to save space.

  Resistance=pad*((1024.0 / RawADC) - 1); 
  Temp = log(Resistance); // Saving the Log(resistance) so not to calculate  it 4 times later
  Temp = 1 / (0.001129148 + (0.000234125 * Temp) + (0.0000000876741 * Temp * Temp *Temp));
  Temp = Temp - 273.15;  // Convert Kelvin to Celsius                      

  // 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(", vcc: ");
  //Serial.print(vcc,2);
  //Serial.print(", pad: ");
  //Serial.print(pad/1000,3);
  //Serial.print(" Kohms, Volts: "); 
  //Serial.print(((RawADC*vcc)/1024.0),3);   
  //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 setup() {
  Serial.begin(115200);
}

void loop() {
  float temp;
  temp=Thermistor(analogRead(ThermistorPIN));       // read ADC and  convert it to Celsius
  Serial.print("Celsius: "); 
  Serial.print(temp,1);                             // display Celsius
  //temp = (temp * 9.0)/ 5.0 + 32.0;                  // converts to  Fahrenheit
  //Serial.print(", Fahrenheit: "); 
  //Serial.print(temp,1);                             // display  Fahrenheit
  Serial.println("");                                   
  delay(5000);                                      // Delay a bit... 
}
 

 


Another way to get temperature, based on the idea/code above.

We have found 10k thermistor and wired it with 10k balance resistor as mentioned above.Our thermistor is episco k164. We have wrote function for temperature reading which covers 3 major temperature scales.

 

#include <math.h>
// enumerating 3 major temperature scales
enum {
  T_KELVIN=0,
  T_CELSIUS,
  T_FAHRENHEIT
};

// manufacturer data for episco k164 10k thermistor
// simply delete this if you don't need it
// or use this idea to define your own thermistors
#define EPISCO_K164_10k 4300.0f,298.15f,10000.0f  // B,T0,R0

// Temperature function outputs float , the actual 
// temperature
// Temperature function inputs
// 1.AnalogInputNumber - analog input to read from 
// 2.OuputUnit - output in celsius, kelvin or fahrenheit
// 3.Thermistor B parameter - found in datasheet 
// 4.Manufacturer T0 parameter - found in datasheet (kelvin)
// 5. Manufacturer R0 parameter - found in datasheet (ohms)
// 6. Your balance resistor resistance in ohms  

float Temperature(int AnalogInputNumber,int OutputUnit,float B,float T0,float R0,floatR_Balance)
{
  float R,T;

//  R=1024.0f*R_Balance/float(analogRead(AnalogInputNumber)))-R_Balance;
  R=R_Balance*(1024.0f/float(analogRead(AnalogInputNumber))-1);

  T=1.0f/(1.0f/T0+(1.0f/B)*log(R/R0));

  switch(OutputUnit) {
    case T_CELSIUS :
      T-=273.15f;
    break;
    case T_FAHRENHEIT :
      T=9.0f*(T-273.15f)/5.0f+32.0f;
    break;
    default:
    break;
  };

  return T;
}
// example of use #1
// reading from analog input 1, using episco k164 definition
// and 10k balance, getting result in celsius

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

void loop() {

 Serial.println("*************************");
 Serial.println("10k Balance");
 Serial.println(Temperature(1,T_CELSIUS,EPISCO_K164_10k,10000.0f));
 Serial.println("*************************");

 delay(500);
}

//example of use #2
// using numbers instead of episco k164 definition
// this time reading from analog input 2
// getting result in fahrenheit

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

void loop() {

 Serial.println("*************************");
 Serial.println("10k Balance");
 Serial.println(Temperature(2,T_FAHRENHEIT,4300.0f,298.15f,10000.0f,10000.0f));
 Serial.println("*************************");

 delay(500);
}
 

 

https://playground.arduino.cc/ComponentLib/Thermistor2 

 

  • BASIC4MCU 작성글 SNS에 공유하기
  • 페이스북으로 보내기
  • 트위터로 보내기
  • 구글플러스로 보내기

댓글 0

조회수 5,363

등록된 댓글이 없습니다.

질문게시판HOME > 질문게시판 목록

MCU, AVR, 아두이노 등 전자공학에 관련된 질문을 무료회원가입 후 작성해주시면 전문가가 답변해드립니다.
ATMEGA128PWMLED초음파
아두이노AVR블루투스LCD
UART모터적외선ATMEGA
전체 스위치 센서
질문게시판 목록
제목 작성자 작성일 조회
공지 MCU, AVR, 아두이노 등 전자공학에 관련된 질문은 질문게시판에서만 작성 가능합니다. 스태프 19-01-15 9675
공지 사이트 이용 안내댓글[24] master 17-10-29 29759
질문 로드셀 무게 센서 질문드립니다.댓글[2] 새글 제비고기 15:52 11
질문 adc, uart dma댓글[2] 새글첨부파일 hiㅡO3O 13:10 16
질문 ADC,uart DMA댓글[1] 이미지새글첨부파일 hiㅡO3O 12:23 18
질문 아두이노 스텝모터 리미트 문의드립니다.댓글[1] 이미지새글첨부파일 스트렌져 22-05-24 21
질문 진동센서와 서보모터 연결 코드 질문입니다!댓글[1] 새글 제리 22-05-24 19
질문 atmega128 GPS,블루투스 질문드립니다.댓글[1] 새글 코딩초보1 22-05-24 28
질문 서보모터 제어에 관하여 궁금합니다댓글[2] 이미지새글첨부파일 오소로롯 22-05-24 34
질문 atmega 128 타이머 작성 중 질문 드립니다.댓글[8] 이미지새글 마프하나 22-05-23 46
질문 아두이노와 휴대폰을 HC-06으로 연결시켜서 블루투스연결이 끊기면 부저에서 소리가 나게 할려하는데 어떻게 해…댓글[1] 새글 졸작부수다 22-05-23 145
답변 답변글 답변 : 아두이노와 휴대폰을 HC-06으로 연결시켜서 블루투스연결이 끊기면 부저에서 소리가 나게 할려하는데 … 새글 master 22-05-24 19
질문 보드레이트 질문댓글[1] 새글 죠르디 22-05-23 20
질문 atmega 128 블루투스 질문 입니다댓글[1] yhj2644 22-05-23 37
질문 아트메가 공부중에 질문있습니다..댓글[1] suid82 22-05-23 25
질문 Atmega128 UART통신 echo 반복 질문댓글[2] ming2ming 22-05-23 34
질문 아두이노의 지속 시간에 대해 질문합니다. merry 22-05-23 36
답변 답변글 답변 : 아두이노의 지속 시간에 대해 질문합니다. master 22-05-23 30
질문 초음파+스텝모터 도꺼비 22-05-22 28
답변 답변글 답변 : 초음파+스텝모터 master 22-05-23 32
질문 아두이노 인터럽트 질문있습니다.댓글[1] 띵꽁 22-05-22 36
답변 답변글 답변 : 아두이노 인터럽트 질문있습니다.댓글[3] master 22-05-22 36
질문 atmega128 스톱워치 작성 중 외부 인터럽트 관련 질문 드립니다.댓글[4] 이미지 마프하나 22-05-22 55
답변 답변글 답변 : atmega128 스톱워치 작성 중 외부 인터럽트 관련 질문 드립니다.댓글[1] 이미지 master 22-05-23 33
질문 서보모터제어 해당코드에서 어떤걸 추가해야할까요댓글[3] 이미지첨부파일 오소로롯 22-05-22 39
질문 Atmega128 UART통신에서 ECHO 관련 질문드립니다. dsfdfsa 22-05-22 39
답변 답변글 답변 : Atmega128 UART통신에서 ECHO 관련 질문드립니다.댓글[1] master 22-05-22 31
질문 아두이노 서보모터제어 하나도 모르겠습니다 ㅠ댓글[2] 이미지첨부파일 오소로롯 22-05-21 57
질문 아트메가 128 을 이용해서적외선 센서 코딩 중 물어볼게있습니다!!댓글[5] noster 22-05-21 61
질문 아두이노 에러질문댓글[2] 이미지첨부파일 리니어 22-05-21 59
게시물 검색

2022년 1월 2월 3월 4월 5월 6월 7월 8월 9월 10월 11월 12월
2021년 1월 2월 3월 4월 5월 6월 7월 8월 9월 10월 11월 12월
2020년 1월 2월 3월 4월 5월 6월 7월 8월 9월 10월 11월 12월
2019년 1월 2월 3월 4월 5월 6월 7월 8월 9월 10월 11월 12월
2018년 1월 2월 3월 4월 5월 6월 7월 8월 9월 10월 11월 12월
Privacy Policy
MCU BASIC ⓒ 2020
모바일버전으로보기