main/task_adc.c

changeset 68
121b3fa6b806
parent 44
e52d11b8f252
child 76
0432d9147682
equal deleted inserted replaced
66:3557b91717d7 68:121b3fa6b806
9 9
10 10
11 #define DEFAULT_VREF 1093 ///< Use adc2_vref_to_gpio() to obtain a better estimate 11 #define DEFAULT_VREF 1093 ///< Use adc2_vref_to_gpio() to obtain a better estimate
12 #define NO_OF_SAMPLES 128 ///< Multisampling 12 #define NO_OF_SAMPLES 128 ///< Multisampling
13 13
14
15 #define PRESSURE_1 (CONFIG_PRESSURE_1) ///< ADC channel pressure sensor 1 14 #define PRESSURE_1 (CONFIG_PRESSURE_1) ///< ADC channel pressure sensor 1
16 #define PRESSURE_2 (CONFIG_PRESSURE_2) ///< ADC channel pressure sensor 2 15 #define PRESSURE_2 (CONFIG_PRESSURE_2) ///< ADC channel pressure sensor 2
17 #define PRESSURE_3 (CONFIG_PRESSURE_3) ///< ADC channel pressure sensor 3 16 #define PRESSURE_3 (CONFIG_PRESSURE_3) ///< ADC channel pressure sensor 3
18 #define BATT_CHANNEL (CONFIG_BATT_CHANNEL) ///< ADC channel half battery voltage 17 #define BATT_CHANNEL (CONFIG_BATT_CHANNEL) ///< ADC channel half battery voltage
19 18
21 static const char *TAG = "task_adc"; 20 static const char *TAG = "task_adc";
22 21
23 SemaphoreHandle_t xSemaphoreADC = NULL; ///< Semaphire ADC task 22 SemaphoreHandle_t xSemaphoreADC = NULL; ///< Semaphire ADC task
24 EventGroupHandle_t xEventGroupADC; ///< Events ADC task 23 EventGroupHandle_t xEventGroupADC; ///< Events ADC task
25 ADC_State *adc_state; ///< Public state for other tasks 24 ADC_State *adc_state; ///< Public state for other tasks
25 bool do_calibration = false;
26
26 27
27 const int TASK_ADC_REQUEST_PRESSURE = BIT0; ///< Request temperature measurements 28 const int TASK_ADC_REQUEST_PRESSURE = BIT0; ///< Request temperature measurements
28 const int TASK_ADC_REQUEST_DONE = BIT1; ///< Request is completed 29 const int TASK_ADC_REQUEST_DONE = BIT1; ///< Request is completed
29 30
31
32 static bool adc_calibration_init(adc_unit_t unit, adc_atten_t atten, adc_cali_handle_t *out_handle);
33 static void adc_calibration_deinit(adc_cali_handle_t handle);
30 34
31 35
32 void request_adc(void) 36 void request_adc(void)
33 { 37 {
34 xEventGroupClearBits(xEventGroupADC, TASK_ADC_REQUEST_DONE); 38 xEventGroupClearBits(xEventGroupADC, TASK_ADC_REQUEST_DONE);
49 /* 53 /*
50 * Task to read pressure sensors and battery voltage on request. 54 * Task to read pressure sensors and battery voltage on request.
51 */ 55 */
52 void task_adc(void *pvParameter) 56 void task_adc(void *pvParameter)
53 { 57 {
54 int i, adc_reading; 58 adc_cali_handle_t adc1_cali_handle = NULL;
55 adc_atten_t atten = ADC_ATTEN_DB_0; 59 adc_unit_t channel;
60
61 adc_oneshot_chan_cfg_t config_adc = {
62 .bitwidth = ADC_BITWIDTH_DEFAULT,
63 .atten = ADC_ATTEN_DB_0,
64 };
56 65
57 ESP_LOGI(TAG, "Starting task ADC sensors"); 66 ESP_LOGI(TAG, "Starting task ADC sensors");
67
58 adc_state = malloc(sizeof(ADC_State)); 68 adc_state = malloc(sizeof(ADC_State));
59 for (i = 0; i < 3; i++) { 69 for (int i = 0; i < 3; i++) {
60 adc_state->Pressure[i].valid = false; 70 adc_state->Pressure[i].valid = false;
61 adc_state->Pressure[i].atten = ADC_ATTEN_DB_0; 71 adc_state->Pressure[i].atten = ADC_ATTEN_DB_0;
62 adc_state->Pressure[i].voltage = 0; 72 adc_state->Pressure[i].voltage = 0;
63 adc_state->Pressure[i].error = ADC_ERR_NONE; 73 adc_state->Pressure[i].error = ADC_ERR_NONE;
64 } 74 }
65 adc_state->Pressure[0].channel = PRESSURE_1; 75 adc_state->Pressure[0].channel = PRESSURE_1;
66 adc_state->Pressure[1].channel = PRESSURE_2; 76 adc_state->Pressure[1].channel = PRESSURE_2;
67 adc_state->Pressure[2].channel = PRESSURE_3; 77 adc_state->Pressure[2].channel = PRESSURE_3;
68 adc_state->Batt_voltage = 0; 78 adc_state->Batt_voltage = 0;
69 adc_state->Batt_error = ADC_ERR_NONE; 79 adc_state->Batt_error = ADC_ERR_NONE;
70 80
71 //Characterize ADC
72 esp_adc_cal_characteristics_t *adc_chars = calloc(1, sizeof(esp_adc_cal_characteristics_t));
73
74 /* event handler and event group for this task */ 81 /* event handler and event group for this task */
75 xEventGroupADC = xEventGroupCreate(); 82 xEventGroupADC = xEventGroupCreate();
76 EventBits_t uxBits; 83 EventBits_t uxBits;
77 84
78 /* 85 /*
83 uxBits = xEventGroupWaitBits(xEventGroupADC, TASK_ADC_REQUEST_PRESSURE, pdFALSE, pdFALSE, portMAX_DELAY ); 90 uxBits = xEventGroupWaitBits(xEventGroupADC, TASK_ADC_REQUEST_PRESSURE, pdFALSE, pdFALSE, portMAX_DELAY );
84 91
85 if (uxBits & TASK_ADC_REQUEST_PRESSURE) { 92 if (uxBits & TASK_ADC_REQUEST_PRESSURE) {
86 93
87 ESP_LOGD(TAG, "Requested ADC readings"); 94 ESP_LOGD(TAG, "Requested ADC readings");
88 adc1_config_width(ADC_WIDTH_BIT_12); 95
89 96 int adc_reading, raw, tmp, voltage;
90 for (i = 0; i < 3; i++) { 97 adc_atten_t atten = ADC_ATTEN_DB_0;
98
99 adc_oneshot_unit_handle_t adc1_handle;
100 adc_oneshot_unit_init_cfg_t init_config1 = {
101 .unit_id = ADC_UNIT_1,
102 };
103
104 for (int i = 0; i < 3; i++) {
105
106 ESP_ERROR_CHECK(adc_oneshot_new_unit(&init_config1, &adc1_handle));
107 atten = config_adc.atten = ADC_ATTEN_DB_0,
108
109 channel = adc_state->Pressure[i].channel;
110 ESP_ERROR_CHECK(adc_oneshot_config_channel(adc1_handle, channel, &config_adc));
91 adc_reading = 0; 111 adc_reading = 0;
92 atten = ADC_ATTEN_DB_0; 112
93
94 /* 113 /*
95 * Autoranging the ADC conversion 114 * Autoranging the ADC conversion
96 */ 115 */
97 while (1) { 116 while (1) {
98 esp_adc_cal_characterize(ADC_UNIT_1, atten, ADC_WIDTH_BIT_12, DEFAULT_VREF, adc_chars); 117
99 adc1_config_channel_atten((adc1_channel_t)adc_state->Pressure[i].channel, atten); 118 config_adc.bitwidth = ADC_BITWIDTH_DEFAULT;
100 int raw = adc1_get_raw((adc1_channel_t)adc_state->Pressure[i].channel); 119 config_adc.atten = atten;
120 adc_oneshot_config_channel(adc1_handle, channel, &config_adc);
121
122 ESP_ERROR_CHECK(adc_oneshot_read(adc1_handle, channel, &raw));
123
124 // ESP_LOGI(TAG, "bottle %d channel %d raw %d atten %d", i, channel, raw, atten);
101 if (atten == ADC_ATTEN_DB_0 && raw > 3700) 125 if (atten == ADC_ATTEN_DB_0 && raw > 3700)
102 atten = ADC_ATTEN_DB_2_5; 126 atten = ADC_ATTEN_DB_2_5;
103 else if (atten == ADC_ATTEN_DB_2_5 && raw > 3700) 127 else if (atten == ADC_ATTEN_DB_2_5 && raw > 3700)
104 atten = ADC_ATTEN_DB_6; 128 atten = ADC_ATTEN_DB_6;
105 else if (atten == ADC_ATTEN_DB_6 && raw > 3700) 129 else if (atten == ADC_ATTEN_DB_6 && raw > 3700)
110 134
111 /* 135 /*
112 * Now that he have the best attenuation, multisample the real value. 136 * Now that he have the best attenuation, multisample the real value.
113 */ 137 */
114 for (int j = 0; j < NO_OF_SAMPLES; j++) { 138 for (int j = 0; j < NO_OF_SAMPLES; j++) {
115 int tmp = adc1_get_raw((adc1_channel_t)adc_state->Pressure[i].channel); 139 if (adc_oneshot_read(adc1_handle, channel, &tmp) == ESP_OK) {
116 if (tmp < 0) {
117 adc_reading = -1;
118 break;
119 }
120 adc_reading += tmp; 140 adc_reading += tmp;
121 } 141 } else {
142 adc_reading = -1;
143 break;
144 }
145 }
146
147 adc1_cali_handle = NULL;
148 do_calibration = adc_calibration_init(ADC_UNIT_1, atten, &adc1_cali_handle);
149
122 if (xSemaphoreTake(xSemaphoreADC, 10) == pdTRUE) { 150 if (xSemaphoreTake(xSemaphoreADC, 10) == pdTRUE) {
123 if (adc_reading < 0) { 151 if (adc_reading < 0) {
124 adc_state->Pressure[i].error = ADC_ERR_READ; 152 adc_state->Pressure[i].error = ADC_ERR_READ;
125 adc_state->Pressure[i].voltage = 0; 153 adc_state->Pressure[i].voltage = 0;
126 } else { 154 } else {
127 adc_reading /= NO_OF_SAMPLES; 155 adc_reading /= NO_OF_SAMPLES;
128 adc_state->Pressure[i].voltage = esp_adc_cal_raw_to_voltage(adc_reading, adc_chars); // voltage in mV 156 adc_cali_raw_to_voltage(adc1_cali_handle, adc_reading, &voltage);
157 adc_state->Pressure[i].voltage = voltage;
158 //adc_state->Pressure[i].voltage = esp_adc_cal_raw_to_voltage(adc_reading, adc_chars); // voltage in mV
159 // ESP_LOGI(TAG, "Voltage %d %d", i, voltage);
129 adc_state->Pressure[i].error = ADC_ERR_NONE; 160 adc_state->Pressure[i].error = ADC_ERR_NONE;
130 } 161 }
131 xSemaphoreGive(xSemaphoreADC); 162 xSemaphoreGive(xSemaphoreADC);
132 } else { 163 } else {
133 ESP_LOGE(TAG, "Missed lock 1"); 164 ESP_LOGE(TAG, "Missed lock 1");
134 } 165 }
135 ESP_LOGI(TAG, "Pressure %d raw: %4d, atten: %d, %.3f volt, error: %d", 166 ESP_LOGI(TAG, "Pressure %d raw: %4d, atten: %d, %.3f volt, error: %d",
136 i, adc_reading, atten, adc_state->Pressure[i].voltage / 1000.0, adc_state->Pressure[i].error); 167 i, adc_reading, atten, (adc_state->Pressure[i].voltage / 1000.0), adc_state->Pressure[i].error);
168
169 //Tear Down
170 ESP_ERROR_CHECK(adc_oneshot_del_unit(adc1_handle));
171 if (do_calibration) {
172 adc_calibration_deinit(adc1_cali_handle);
173 }
174 do_calibration = false;
137 } 175 }
138 176
139 /* 177 /*
140 * Read VDD by reading 1/2 VDD from a precision ladder. 178 * Read VDD by reading 1/2 VDD from a precision ladder.
141 */ 179 */
142 adc_reading = 0; 180 adc_reading = 0;
143 atten = ADC_ATTEN_DB_6; // Don't use DB_11, it has a bad linearity. 181 atten = ADC_ATTEN_DB_6; // Don't use DB_11, it has a bad linearity.
144 esp_adc_cal_characterize(ADC_UNIT_1, atten, ADC_WIDTH_BIT_12, DEFAULT_VREF, adc_chars); 182 adc1_cali_handle = NULL;
145 adc1_config_channel_atten((adc1_channel_t)BATT_CHANNEL, atten); 183 channel = (adc_unit_t)BATT_CHANNEL;
184 ESP_ERROR_CHECK(adc_oneshot_new_unit(&init_config1, &adc1_handle));
185 do_calibration = adc_calibration_init(ADC_UNIT_1, atten, &adc1_cali_handle);
186
187 config_adc.bitwidth = ADC_BITWIDTH_DEFAULT;
188 config_adc.atten = atten;
189 adc_oneshot_config_channel(adc1_handle, (adc_unit_t)BATT_CHANNEL, &config_adc);
190
191 ESP_ERROR_CHECK(adc_oneshot_read(adc1_handle, (adc_unit_t)BATT_CHANNEL, &raw));
192
146 for (int j = 0; j < NO_OF_SAMPLES; j++) { 193 for (int j = 0; j < NO_OF_SAMPLES; j++) {
147 int tmp = adc1_get_raw((adc1_channel_t)BATT_CHANNEL); 194 if (adc_oneshot_read(adc1_handle, channel, &tmp) == ESP_OK) {
148 if (tmp < 0) { 195 adc_reading += tmp;
149 adc_reading = -1; 196 } else {
150 break; 197 adc_reading = -1;
151 } 198 break;
152 adc_reading += tmp; 199 }
153 } 200 }
154 if (xSemaphoreTake(xSemaphoreADC, 10) == pdTRUE) { 201 if (xSemaphoreTake(xSemaphoreADC, 10) == pdTRUE) {
155 if (adc_reading < 0) { 202 if (adc_reading < 0) {
156 adc_state->Batt_voltage = 3.3; 203 adc_state->Batt_voltage = 3.3;
157 adc_state->Batt_error = ADC_ERR_READ; 204 adc_state->Batt_error = ADC_ERR_READ;
158 } else { 205 } else {
159 adc_reading /= NO_OF_SAMPLES; 206 adc_reading /= NO_OF_SAMPLES;
160 adc_state->Batt_voltage = esp_adc_cal_raw_to_voltage(adc_reading, adc_chars) * 2; // Chip supply voltage in mV 207 adc_cali_raw_to_voltage(adc1_cali_handle, adc_reading, &voltage);
208 /* Multiply by 2, measured on a ladder. */
209 adc_state->Batt_voltage = voltage * 2; // Chip supply voltage in mV
161 adc_state->Batt_error = ADC_ERR_NONE; 210 adc_state->Batt_error = ADC_ERR_NONE;
162 } 211 }
163 xSemaphoreGive(xSemaphoreADC); 212 xSemaphoreGive(xSemaphoreADC);
164 } else { 213 } else {
165 ESP_LOGE(TAG, "Missed lock 2"); 214 ESP_LOGE(TAG, "Missed lock 2");
166 } 215 }
167 216
217 ESP_ERROR_CHECK(adc_oneshot_del_unit(adc1_handle));
218 if (do_calibration) {
219 adc_calibration_deinit(adc1_cali_handle);
220 }
221 do_calibration = false;
222
168 xEventGroupClearBits(xEventGroupADC, TASK_ADC_REQUEST_PRESSURE); 223 xEventGroupClearBits(xEventGroupADC, TASK_ADC_REQUEST_PRESSURE);
169 xEventGroupSetBits(xEventGroupADC, TASK_ADC_REQUEST_DONE); 224 xEventGroupSetBits(xEventGroupADC, TASK_ADC_REQUEST_DONE);
170 #if 1 225 #if 1
171 ESP_LOGI(TAG, "Battery raw: %4d, atten: %d %.3f volt, error: %d", adc_reading, atten, adc_state->Batt_voltage / 1000.0, adc_state->Batt_error); 226 ESP_LOGI(TAG, "Battery raw: %4d, atten: %d %.3f volt, error: %d", adc_reading, atten, adc_state->Batt_voltage / 1000.0, adc_state->Batt_error);
172 #endif 227 #endif
173 } 228 }
174 } 229 }
175 } 230 }
176 231
232
233 /*---------------------------------------------------------------
234 ADC Calibration
235 ---------------------------------------------------------------*/
236 static bool adc_calibration_init(adc_unit_t unit, adc_atten_t atten, adc_cali_handle_t *out_handle)
237 {
238 adc_cali_handle_t handle = NULL;
239 esp_err_t ret = ESP_FAIL;
240 bool calibrated = false;
241
242 if (!calibrated) {
243 adc_cali_line_fitting_config_t cali_config = {
244 .unit_id = unit,
245 .atten = atten,
246 .bitwidth = ADC_BITWIDTH_DEFAULT,
247 };
248 ret = adc_cali_create_scheme_line_fitting(&cali_config, &handle);
249 if (ret == ESP_OK) {
250 calibrated = true;
251 }
252 }
253
254 *out_handle = handle;
255 if (ret == ESP_ERR_NOT_SUPPORTED || !calibrated) {
256 ESP_LOGW(TAG, "eFuse not burnt, skip software calibration");
257 } else if (ret != ESP_OK) {
258 ESP_LOGE(TAG, "Invalid arg or no memory");
259 }
260
261 return calibrated;
262 }
263
264
265 static void adc_calibration_deinit(adc_cali_handle_t handle)
266 {
267 ESP_ERROR_CHECK(adc_cali_delete_scheme_line_fitting(handle));
268 }
269

mercurial