-
Notifications
You must be signed in to change notification settings - Fork 9
/
esp_lna_thermocouple_basic.c
executable file
·106 lines (79 loc) · 3.01 KB
/
esp_lna_thermocouple_basic.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
/* ESP32 LNA Thermocouple Basic Example (https://github.com/krzychb/esp32-lna)
This example code is in the Public Domain (or CC0 licensed, at your option.)
Unless required by applicable law or agreed to in writing, this
software is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
CONDITIONS OF ANY KIND, either express or implied.
*/
#include <stdio.h>
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "lna.h"
#include "math.h"
#define ADC_WIDTH_BIT (ADC_WIDTH_BIT_10)
#define ADC_ATTEN (ADC_ATTEN_0db)
#define ADC_SAMPLE_COUNT (256)
#define LNA_STAGE_1_CYCLES (1024)
#define LNA_STAGE_3_CYCLES (64)
#define COLD_JUCTION_TEMPERATURE (29)
/*
LNA Calibration
The purpose of calibration is to establish relationship between signal value
at LNA input and resulting ADC readings. A linear relationship is assumed.
Procedure:
Use a thermocouple or other mV signal source to drive LNA input
1. First apply a signal in a negative mV range to obtain bottom ADC reading
2. Enter obtained ADC reading and mV values in table below
4. Then apply a signal in a positive mV range to obtain top ADC reading
5. Enter obtained ADC reading and mV values in table below
Note: Select signals is a range that do not cause ADC readings
to get steady to 0 or to saturate at the maximum
*/
const adc_mv_cal_t thk_cal = {
-1.000, // bottom mV input signal value
1694, // bottom ADC reading
2.599, // top mV input signal value
3680 // top ADC reading
};
// data source: http://cn.omega.com/learning/ITS-90T-CPoly.html
#define POLY_N (6)
const double poly_k[] = {
0, // 0
2.508e-2, // 1
7.860e-8, // 2
-2.503e-10, // 3
8.315e-14, // 4
-1.228e-17 // 5
};
lna_config_t lna_config = {
.adc_bits_width = ADC_WIDTH_BIT,
.adc_atten = ADC_ATTEN
};
double calc_temperature(float milivolts)
{
double temperature = poly_k[0];
for (int i=1; i<POLY_N; i++) {
temperature += poly_k[i] * pow(1000*milivolts, i);
}
return temperature;
}
void app_main(void)
{
printf("ADC: %d bit, Attenuation: (%d)\n", ADC_WIDTH_BIT+9, ADC_ATTEN);
printf("Initializing LNA...");
esp_err_t result = adc1_lna_init(&lna_config);
printf("%s\n", (result == ESP_OK) ? "done" : "failed");
while (1) {
int adc_sum = 0;
for (int i = 0; i < ADC_SAMPLE_COUNT; i++) {
adc_sum += adc1_lna_get_value(LNA_STAGE_1_CYCLES, LNA_STAGE_3_CYCLES);
}
adc_sum /= ADC_SAMPLE_COUNT;
double milivolts = lna_adc_to_mv(thk_cal, ADC_WIDTH_BIT, adc_sum);
double temperature = calc_temperature(milivolts);
int16_t temperature_cj = COLD_JUCTION_TEMPERATURE;
temperature += temperature_cj;
printf("Thermocouple: %.3f mV, %.0f oC, Cold junction temperature: %d oC, ADC raw count: %d\n",
milivolts, temperature, temperature_cj, adc_sum);
vTaskDelay(1000 / portTICK_PERIOD_MS);
}
}