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

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

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


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

페이지 정보

작성자 master 작성일2018-06-09 16:10 조회9,403회 댓글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

조회수 9,403

등록된 댓글이 없습니다.

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

MCU, AVR, 아두이노 등 전자공학에 관련된 질문을 무료회원가입 후 작성해주시면 전문가가 답변해드립니다.
ATMEGA128PWMLED초음파
아두이노AVR블루투스LCD
UART모터적외선ATMEGA
전체 스위치 센서
질문게시판 목록
제목 작성자 작성일 조회
공지 MCU, AVR, 아두이노 등 전자공학에 관련된 질문은 질문게시판에서만 작성 가능합니다. 스태프 19-01-15 19418
공지 사이트 이용 안내댓글[28] master 17-10-29 34131
질문 stm32f767을 이용해서 자이로가속도 센서의 값 받아오기 새글 rlchwjswk 23-06-03 9
질문 아두이노 모터제어 관련해서 질문드립니다!댓글[1] 이미지새글첨부파일 아두이노어렵잖아 23-06-03 21
질문 atmega128 디지털조도센서 코드오류댓글[1] 이미지새글 까미 23-06-02 25
질문 atmega128 디지털 조도 센서댓글[1] 새글 까미 23-06-02 25
질문 적외선리모콘으로 부저를제어 하는방법 질문입니다.댓글[4] 새글 Tell 23-06-02 18
질문 lora 무선 모듈에 관한 질문입니다.댓글[1] 로이스10 23-06-01 18
질문 적외선 송수신기 DC모터2개 제어 질문입니다.댓글[5] Tell 23-06-01 31
질문 스텝모터 제어 코드 질문댓글[4] pmh11 23-05-31 32
질문 초음파 센서를 이용한 인원 카운팅댓글[1] 초음파야 23-05-31 26
질문 모터 Hall 스위치 연결 문의댓글[1] 오후 23-05-31 21
질문 아두이노 lcd 문자 스크롤디스플레이 wnion 23-05-31 22
답변 답변글 답변 : 아두이노 lcd 문자 스크롤디스플레이댓글[1] master 23-05-31 28
질문 아두이노 타이머 인터럽트 미ㅏㄴㅇ 23-05-30 37
답변 답변글 답변 : 아두이노 타이머 인터럽트댓글[6] master 23-05-30 44
질문 THC-Soil Sensor with TTL 모듈 아두이노 센서값 받아오기댓글[1] ppiickle 23-05-30 30
질문 stm32 psd센서구동 질문댓글[2] 수포자 23-05-29 28
질문 앱인벤터 아두이노 보드 LCD 글씨 나타내기 질문댓글[7] 이미지 당찬병아리 23-05-29 41
질문 atmega128 led와 fan댓글[3] 이라 23-05-28 44
질문 stm32f767 스텝모터 속도 질문있습니다 123132 23-05-27 34
답변 답변글 답변 : stm32f767 스텝모터 속도 질문있습니다 master 23-05-28 30
질문 아트메가 128 코딩 오류 질문입니다.댓글[1] 태태킴 23-05-27 31
질문 스텝모터 제어하는 소스파일인데 질문있습니다. Bs드리프터 23-05-27 38
답변 답변글 답변 : 스텝모터 제어하는 소스파일인데 질문있습니다. master 23-05-27 35
질문 모터 컨트롤러와 웜기어 모터 연결 문의 드립니다댓글[1] 오후에 23-05-27 28
답변 답변글 답변 : 모터 컨트롤러와 웜기어 모터 연결 문의 드립니다댓글[1] 첨부파일 오후에 23-05-27 33
질문 아두이노 스텝모터 초음파 결합댓글[2] 결합기원 23-05-26 55
답변 답변글 답변 : 아두이노 스텝모터 초음파 결합 master 23-05-27 28
질문 piezo부저 연결 방법댓글[2] 이미지첨부파일 djwb 23-05-26 34
게시물 검색

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
모바일버전으로보기