This project is a piece of content used in my work. I have little talent and knowledge. If there are any omissions, please give me some advice.
First, let’s introduce the TS318_1B0814 thermopile sensor. I uploaded the data used by this sensor on Baidu Cloud. To put it simply, this is an analog sensor. It needs to collect two analog signals, one to determine the sensor’s own temperature, and the other to combine the sensor’s own temperature. Can calculate the temperature of the measured object.
Link: https://pan.baidu.com/s/13zDIR82lZlg7AHqSE7ha1A?pwd=awsl
Extraction code: awsl
The sensor circuit diagram is as follows:
figure 1
Below is the two ends of V1 and R3 representing Pin1 and Pin3. The amplification factor is equal to R5/R4 (the amplification factor here is not the maximum, but the existing resistors on hand are used)
Simulation circuit
Figure II
DC scan results
The abscissa is V1, the ordinate is probe 1
Figure 3
Cadence Schematic
Header4 H2 is plugged into the sensor, and H1 is connected to the development board for power supply and AD collection.
Figure 4
Make a 3cm*3cm board
PCB
Figure 5
stm32 program
c
#include "TS318_1B0814.h" #include "delay.h" /*-------------|---------------- AD PH4 <-> ADC3_INP15 infrared temperature down AD PH5 <-> ADC3_INP16 ambient temperature up ----------------|----------------*/ float VTP_Value_Table[101]={-1.066,-1.028,-0.990,-0.952,-0.914,-0.874,-0.835,-0.795,-0.755,-0.714,-0.673, -0.631,-0.589,-0.546,-0.503,-0.46,-0.416,-0.372,-0.327,-0.282, -0.236,-0.19,-0.143,-0.096,-0.048,0,0.049,0.098,0.147,0.197, 0.248,0.299,0.351,0.403,0.455,0.509,0.562,0.617,0.671,0.726, 0.782,0.839,0.895,0.953,1.011,1.069,1.128,1.188,1.248,1.309, 1.370,1.432,1.495,1.558,1.621,1.685,1.750,1.816,1.882,1.948, 2.015,2.083,2.152,2.221,2.290,2.360,2.431,2.503,2.575,2.648, 2.721,2.795,2.870,2.945,3.021,3.098,3.175,3.253,3.332,3.412, 3.492,3.572,3.654,3.736,3.819,3.902,3.986,4.071,4.157,4.243, 4.330,4.418,4.507,4.596,4.686,4.776,4.868,4.960,5.053,5.147, 5.241};//0-100 degrees float RNI1000_Value_Table[86]={1000.0,1005.5,1011.0,1016.5,1022.0,1027.6,1033.1,1038.7,1044.3,1049.9, 1055.5,1061.1,1066.8,1072.4,1078.1,1083.8,1089.5,1095.2,1100.9,1106.6, 1112.4,1118.1,1123.9,1129.7,1135.5,1141.3,1147.1,1153.0,1158.8,1164.7, 1170.6,1176.5,1182.4,1188.3,1194.2,1200.2,1206.1,1212.1,1218.1,1224.1, 1230.1,1236.1,1242.2,1248.2,1254.3,1260.4,1266.5,1272.6,1278.8,1284.9, 1291.1,1297.2,1303.4,1309.6,1315.8,1322.0,1328.3,1334.5,1340.8,1347.1, 1353.4,1359.7,1366.0,1372.4,1378.7,1385.1,1391.5,1397.9,1404.3,1410.8, 1417.2,1423.7,1430.1,1436.6,1443.1,1449.7,1456.2,1462.8,1469.3,1475.9, 1482.5,1489.1,1495.7,1502.4,1509.1,1515.7};//0-85 degrees float NTC_Value_Table[86]={332.59,315.83,300.02,285.09,270.98,257.66,245.07,233.17,221.29,211.26, 201.18,191.64,182.60,174.05,165.94,158.25,150.96,144.05,137.50,131.28, 125.37,119.76,114.44,109.38,104.57,100.0,95.65,91.52,87.59,83.84, 80.28,76.89,73.66,70.58,67.65,64.85,62.19,59.65,57.22,54.91, 52.70,50.60,48.58,46.66,44.83,43.07,41.40,39.79,38.26,36.80, 35.40,34.05,32.77,31.54,30.37,29.24,28.16,27.13,26.14,25.19, 24.28,23.40,22.57,21.76,20.99,20.25,19.54,18.86,18.21,17.58, 16.97,16.39,15.84,15.30,14.79,14.29,13.81,13.36,12.92,12.49, 12.08,11.69,11.31,10.95,10.60,10.26}; \t\t\t\t\t\t\t\t\t\t\t\t\t\t\t \t\t\t\t\t\t\t\t\t\t\t\t\t\t\t /****************************************************** *************************************************** **** * Function name: TS318_1B0814_Init * Function description: TS318_1B0814 infrared temperature sensor AD function pin initialization *Formal parameters: None * Return value: None *************************************************** *************************************************** *****/ void TS318_1B0814_Init(void) { RCC->AHB4ENR|=1<<24; //Enable ADC3 clock RCC->AHB4ENR|=GPIOH_CLK; //Enable PORTC clock GPIO_Set(GPIOH,PIN4|PIN5,GPIO_MODE_AIN,0,0,GPIO_PUPD_NONE);//PH4 PH5 analog input, without pull-down RCC->AHB1RSTR|=1<<24; //ADC3 reset RCC->AHB1RSTR & amp;=~(1<<24); //Reset ends RCC->D3CCIPR & amp;=~(3<<16); //ADCSEL[1:0] cleared RCC->D3CCIPR|=2<<16; //ADCSEL[1:0]=2, per_ck is used as ADC clock source, hsi_ker_ck is selected as per_ck by default, frequency: 64Mhz ADC3_COMMON->CCR|=1<<18; //PRESC[3:0]=1, the input clock is divided by 2, that is, adc_ker_ck=per_ck/2=64/2=32Mhz (cannot exceed 36Mhz) ADC3->CR=0; //Clear the CR register, clear DEEPPWD, and wake up from deep sleep. ADC3->CR|=1<<28; //ADVREGEN=1, enable ADC regulator delay_ms(10); //Wait for the voltage regulator to start up, about 10us ADC3->CR|=1<<8; //BOOST=1, ADC works in boost mode (when the ADC frequency is greater than 20M, the boost bit must be set) ADC3->CFGR & amp;=~(1<<13); //CONT=0, single conversion mode ADC3->CFGR|=1<<12; //OVRMOD=1, rewrite mode (DR register can be rewritten) ADC3->CFGR & amp;=~(3<<10); //EXTEN[1:0]=0, software trigger ADC3->CFGR & amp;=~(7<<2); //RES[2:0] bits cleared ADC3->CFGR|=0<<2; //RES[2:0]=0,16-bit resolution (0,16-bit;1,14-bit;2,12-bit;3,10-bit;4,8 Bit.) ADC3->CFGR2 & amp;=~((u32)15<<28); //LSHIFT[3:0]=0, no left shift, data is right-aligned. ADC3->CFGR2 & amp;=~((u32)0X3FF<<16);//OSR[9:0]=0, do not use oversampling ADC3->CR & amp;=~((u32)1<<30); //ADCALDIF=0, calibrate single-ended conversion channel ADC3->CR|=1<<16; //ADCALLIN=1, linear calibration ADC3->CR|=(u32)1<<31; //Turn on calibration while(ADC3->CR & amp;((u32)1<<31));//Waiting for calibration to be completed ADC3->SQR1 & amp;=~(0XF<<0); //L[3:0] cleared ADC3->SQR1|=0<<0; //L[3:0]=0, 1 conversion is in the rule sequence, that is, only rule sequence 1 is converted ADC3->SMPR2 & amp;=~(7<<15); //Clear channel 15 sampling time ADC3->SMPR2|=7<<15; //Channel 15 810.5 cycles, increasing the sampling time can improve the accuracy ADC3->SMPR2 & amp;=~(7<<18); //Clear channel 16 sampling time ADC3->SMPR2|=7<<18; //Channel 16 810.5 cycles, increasing the sampling time can improve the accuracy \t ADC3->CR|=1<<0; //Turn on the AD converter } /****************************************************** *************************************************** **** * Function name: Get_Adc3Value * Function description: Get the AD value of the specified channel of ADC3 (16 bits, 0-65535), sample 10 times, remove the maximum and minimum values and average *Formal parameter: Ch specifies the channel * Return value: Returned AD value *************************************************** *************************************************** *****/ u16 Get_Adc3Value(u16 Ch) { u16 Data_Max,Data_Min,Data_Now,AD_Data; u8i; u32 Data=0; ADC3->PCSEL|=1<<Ch; //ADC conversion channel pre-selection ADC3->SQR1 & amp;=~(0X1F<<6*1); //Regular sequence 1 channel cleared ADC3->SQR1|=Ch<<6*1; //Set the conversion channel of rule sequence 1 to ch ADC3->CR|=1<<2; //Start the rule conversion channel while(!(ADC3->ISR & amp;1<<2)); //Wait for the conversion to end Data_Max=ADC3->DR; //Return adc value Data_Min=Data_Max; Data + =Data_Min; for(i=0;i<9;i + + ) { ADC3->PCSEL|=1<<Ch; //ADC conversion channel pre-selection ADC3->SQR1 & amp;=~(0X1F<<6*1); //Regular sequence 1 channel cleared ADC3->SQR1|=Ch<<6*1; //Set the conversion channel of rule sequence 1 to ch ADC3->CR|=1<<2; //Start the rule conversion channel while(!(ADC3->ISR & amp;1<<2)); //Wait for the conversion to end Data_Now=ADC3->DR; if(Data_Max<Data_Now) Data_Max=Data_Now; if(Data_Min>Data_Now) Data_Min=Data_Now; Data + =Data_Now; } Data=Data-Data_Min-Data_Max; AD_Data=Data/8; return AD_Data; } /****************************************************** *************************************************** **** * Function name: Caculate_T_sensor * Function description: Input the resistance value and calculate the sensor temperature based on linear interpolation *Formal parameter: float value * Return value: Generally it should be between 0-85 degrees *************************************************** *************************************************** *****/ float Caculate_T_sensor(float value,u8 sensor) { float T_sensor; \t if(sensor==0) { if(value<=RNI1000_Value_Table[0]) { return 0; } if(value>=RNI1000_Value_Table[85]) { return 85; } for(int i =0;i<86;i + + ) { if((value>RNI1000_Value_Table[i]) & amp; & amp;(value<RNI1000_Value_Table[i + 1])) { T_sensor=(value-RNI1000_Value_Table[i])/(RNI1000_Value_Table[i + 1]-RNI1000_Value_Table[i]) + i; return T_sensor; } } return -1; } \t \t \t if(sensor==1) { if(value<=NTC_Value_Table[0]) { return 0; } if(value>=NTC_Value_Table[85]) { return 85; } for(int i =0;i<86;i + + ) { if((value>NTC_Value_Table[i]) & amp; & amp;(value<NTC_Value_Table[i + 1])) { T_sensor=(value-NTC_Value_Table[i])/(NTC_Value_Table[i + 1]-NTC_Value_Table[i]) + i; return T_sensor; } } return -1; } \t } /****************************************************** *************************************************** **** * Function name: Caculate_Voffs * Function description: Input the temperature and calculate the voltage based on linear interpolation *Formal parameter: float value * Return value: Voffs *************************************************** *************************************************** *****/ float Caculate_Voffs(float value) { float Voffs; for(int i=0;i<101;i + + ) { if(value>=i & amp; & amp;value<i + 1) { \t\t\t float k,b; k=VTP_Value_Table[i + 1]-VTP_Value_Table[i]; b=VTP_Value_Table[i]-k*i; Voffs=k*value + b; return Voffs; } } return -1; } /****************************************************** *************************************************** **** * Function name: Caculate_T_object * Function description: Input voltage, calculate temperature based on linear interpolation *Formal parameter: float value * Return value: temperature in the range of 0-100 *************************************************** *************************************************** *****/ float Caculate_T_object(float value) { float T_object; for(int i=0;i<101;i + + ) { if((value>VTP_Value_Table[i]) & amp; & amp;(value<VTP_Value_Table[i + 1])) { T_object=(value-VTP_Value_Table[i])/(VTP_Value_Table[i + 1]-VTP_Value_Table[i]) + i;; return T_object; } } return -1; } /****************************************************** *************************************************** **** * Function name: Get_temperature * Function description: Calculate the object temperature. If it is too low, it may not be detected. At this time, Sconv can be modified. *Formal parameters: *\tillustrate: No. 1 No. 2 Sconv 0.1385 0.1335 237 lines of constant items 5.8 -4.8 * Return value: temperature in the range of 0-100 *************************************************** *************************************************** *****/ float Get_temperature(void) { float Sconv=0.1335; u16 Adc3_15=Get_Adc3Value(15); u16 Adc3_16=Get_Adc3Value(16); float temp_sen_volt=3.28*Adc3_16/65536; float R_ni1000=1000*temp_sen_volt/3.28f/(1-temp_sen_volt/3.28f); //rni1000 resistance value float T_sensor=Caculate_T_sensor(R_ni1000,0)-4.8f; //Calculate sensor temperature \t\t float Vtp=1000*(3.28f*Adc3_15/65536-1.26f)/(313.65f); //Value before amplification, unit mv \t float Vtpc=(Vtp)/Sconv; \t\t float Tcf=1-((T_sensor-25)*0.0045f); \t\t float Voffs=Caculate_Voffs(T_sensor); //First call \t\t float Voffs_tc=Voffs*Tcf; \t\t\t float Vtp_ref=Vtpc + Voffs_tc; \t\t\t float Vtp_ref_tc=Vtp_ref/Tcf; \t\t float T_object=Caculate_T_object(Vtp_ref_tc); //Second call \t return T_object; }
h
#ifndef __TS318_1B0814_H #define __TS318_1B0814_H #include "sys.h" void TS318_1B0814_Init(void); u16 Get_Adc3Value(u16 Ch); float Caculate_T_sensor(float value ,u8 sensor); float Caculate_Voffs(float value); float Caculate_T_object(float value); float Get_temperature(void); #endif
When using it, just use initialization and the last one in main. When transplanting, you need to consider that your ADC is different from mine, and you need to check the data manual.
One final word
Calculation process
(All from a pdf information on Tyco’s official website)
1Ambient temperature
Table I
After getting the slave sensor, use a multimeter to connect the resistance range 2 and 4. It is normal to have more than 1100 ohms at room temperature. This resistance increases as the temperature rises, which is very linear.
Figure 6
Table II
Just use a voltage divider circuit to measure the resistance value.
2Ambient temperature calibration
After calculating the sensor temperature, check whether the sensor temperature is accurate. You can use a relatively accurate temperature sensor and put the thermopile together with it. The difference is the constant term.
3 Calculate object temperature
Usually the relative position between the thermopile and the measured object in a product is determined, and their relative positions are also different in different products. After measurement, under the same set of parameters, the closer the thermopile is to the measured object, the higher the measured temperature. big. Therefore, we need to fix a distance, keep the sensor at 25 degrees, and check the measured original voltage value VTP1 (mv),
Table 3
VTPC=VTP/(VTP1/5.241f)
The calculation is based on the following
Figure 7
Then just follow the steps below to calculate
Figure 8
There are a few things that need to be explained. First, Vtp is calculated from the 16-bit value (maximum 65535) read by ad. Refer to the previous mutisim curve. Then the LUT and RLUT here are based on Table 2. Do some linear interpolation. .