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 |