#include #include #include "BLE_UUID.h" #include "esp_attr.h" #include "esp_err.h" #include "esp_log.h" #include "freertos/FreeRTOS.h" #include "freertos/projdefs.h" #include "freertos/task.h" #include "freertos/portmacro.h" #include "host/ble_uuid.h" #include "spinlock.h" #include "esp_adc/adc_continuous.h" #include "esp_adc/adc_cali.h" #include "esp_adc/adc_cali_scheme.h" #include "hal/adc_types.h" #include "soc/soc_caps.h" #include "nvs_flash.h" #include "sdkconfig.h" #include "BLEh.h" #include "simple_gatt_value_server.h" #include "BLE.h" #define TAG "Main" #define ADC_IN_PIN_NUM 5 static uint8_t channel_index[ADC_IN_PIN_NUM]; static uint32_t meas_res[ADC_IN_PIN_NUM]; static uint32_t meas_nb[ADC_IN_PIN_NUM]; static bool IRAM_ATTR on_conv_done(adc_continuous_handle_t handle, const adc_continuous_evt_data_t *edata, void *user_data){ adc_digi_output_data_t* res = (adc_digi_output_data_t*)edata->conv_frame_buffer; if(res->type2.channel < 0 || res->type2.channel >= ADC_IN_PIN_NUM) return false; //invalid channel int index = channel_index[res->type2.channel]; meas_res[index] += res->type2.data; meas_nb[index]++; return false; } void app_main(void){ adc_continuous_handle_cfg_t adc_h_conf = { .conv_frame_size = SOC_ADC_DIGI_DATA_BYTES_PER_CONV, .max_store_buf_size = SOC_ADC_DIGI_DATA_BYTES_PER_CONV * ADC_IN_PIN_NUM, }; adc_continuous_handle_t adc_handle; ESP_ERROR_CHECK(adc_continuous_new_handle(&adc_h_conf, &adc_handle)); uint8_t adc_pins[] = {CONFIG_OUT_VOLT_PIN, CONFIG_OUT_CURR_PIN, CONFIG_PHASE1_CURR_PIN, CONFIG_PHASE2_CURR_PIN, CONFIG_PHASE3_CURR_PIN}; adc_digi_pattern_config_t adc_pattern[ADC_IN_PIN_NUM]; for(int i = 0; i < ADC_IN_PIN_NUM; i++){ adc_channel_t channel; adc_unit_t unit; adc_continuous_io_to_channel(adc_pins[i], &unit, &channel); if(unit != ADC_UNIT_1){ ESP_LOGE(TAG, "Wrong unit for one of the selected pins"); } channel_index[channel] = i; adc_pattern[i] = (adc_digi_pattern_config_t){ .atten = ADC_ATTEN_DB_0, .bit_width = ADC_BITWIDTH_12, .channel = channel, .unit = ADC_UNIT_1, }; } adc_continuous_config_t adc_conf = { .adc_pattern = adc_pattern, .pattern_num = ADC_IN_PIN_NUM, .conv_mode = ADC_CONV_SINGLE_UNIT_1, .format = ADC_DIGI_OUTPUT_FORMAT_TYPE2, .sample_freq_hz = SOC_ADC_SAMPLE_FREQ_THRES_HIGH, }; ESP_ERROR_CHECK(adc_continuous_config(adc_handle, &adc_conf)); adc_cali_handle_t adc_cali_handles[ADC_IN_PIN_NUM]; for(int i = 0; i < ADC_IN_PIN_NUM; i++){ adc_cali_curve_fitting_config_t conf = { .atten = ADC_ATTEN_DB_0, .bitwidth = ADC_BITWIDTH_12, .unit_id = ADC_UNIT_1, }; ESP_ERROR_CHECK(adc_cali_create_scheme_curve_fitting(&conf, &adc_cali_handles[i])); } spinlock_t adc_res_mutex; spinlock_initialize(&adc_res_mutex); adc_continuous_evt_cbs_t adc_event = { .on_conv_done = &on_conv_done, .on_pool_ovf = NULL, }; nvs_flash_init(); uint32_t raw_mv_meas[ADC_IN_PIN_NUM]; struct char_pres_format mv_char_pres_format = { .format = FORMAT_UINT32, .unit = VOLTS_UNIT_UUID, .exponent = -3, .namespc = 1, .descrH = NSP_DESC_MAIN & 0xff, .descrL = (NSP_DESC_MAIN>>8) & 0xff, }; gatt_value_server_handle_t raw_mv_serve_handle = simple_gatt_value_server(raw_mv_meas, sizeof(uint32_t), ADC_IN_PIN_NUM, mv_char_pres_format, &gatt_svcs[RAW_VALUES_SVC_ID], RAW_VALUES_SVC_ID, BLE_UUID16_DECLARE(VOLTAGE_CHAR)); set_gatt_services(gatt_svcs, SVCS_NUM); initBLE("ALIM"); ESP_ERROR_CHECK(adc_continuous_register_event_callbacks(adc_handle, &adc_event, NULL)); ESP_ERROR_CHECK(adc_continuous_start(adc_handle)); while(1){ uint32_t meas_res_buff[ADC_IN_PIN_NUM]; uint32_t meas_nb_buff[ADC_IN_PIN_NUM]; portENTER_CRITICAL(&adc_res_mutex); for(int i = 0; i < ADC_IN_PIN_NUM; i++){ meas_res_buff[i] = meas_res[i]; meas_nb_buff[i] = meas_nb[i]; meas_res[i] = 0; meas_nb[i] = 0; } portEXIT_CRITICAL(&adc_res_mutex); for(int i = 0; i < ADC_IN_PIN_NUM; i++){ int mv; uint32_t val = meas_res_buff[i] / meas_nb_buff[i]; ESP_ERROR_CHECK(adc_cali_raw_to_voltage(adc_cali_handles[i], val, &mv)); raw_mv_meas[i] = mv; switch(adc_pins[i]){ case CONFIG_OUT_VOLT_PIN: ESP_LOGI(TAG, "Output voltage %d mV", mv); break; case CONFIG_OUT_CURR_PIN: ESP_LOGI(TAG, "Output current %d mV", mv); break; case CONFIG_PHASE1_CURR_PIN: ESP_LOGI(TAG, "Phase 1 current %d mV", mv); break; case CONFIG_PHASE2_CURR_PIN: ESP_LOGI(TAG, "Phase 2 current %d mV", mv); break; case CONFIG_PHASE3_CURR_PIN: ESP_LOGI(TAG, "Phase 3 current %d mV", mv); break; } } simple_gatt_value_server_notify(raw_mv_serve_handle, ADC_IN_PIN_NUM); vTaskDelay(pdMS_TO_TICKS(CONFIG_UPD_DELAY)); } }