ADC Continuous Read Example

[中文]

Note

This document is automatically translated using AI. Please excuse any detailed errors. The official English version is still in progress.

Example Description

This example demonstrates how to initialize and configure ADC, and how to use ADC to continuously sample analog input signals and process them. For an explanation of the ADC continuous conversion mode, refer to Analog-to-Digital Converter (ADC) Continuous Conversion Mode Driver. Before studying this example, it is recommended to first understand the related content of FreeRTOS semaphores, the basic explanation and API usage examples can be found in the Semaphores and Mutexes document.

Running Method

The complete code of the example can be found in ADC Continuous Read Example. For configuration instructions, build and burn process before running, please refer to the README.md file in the adc directory.

For custom configuration items and default values, refer to the Global Variables/Macro Definitions Description section.

Header File Description

The header files used in this example cover FreeRTOS task management and synchronization mechanisms, common system tools, and ADC continuous sampling drivers and other basic modules. They provide support for task creation, ADC initialization, collection, and processing.

The header files are categorized by function as follows:

  1. FreeRTOS Task Scheduling: Provides task creation, scheduling, and management functions, and supports task synchronization mechanisms to ensure resource sharing and communication in a multi-task environment.

#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "freertos/semphr.h"
  1. System Tools: Provides system configuration files, as well as input and output, string processing, log recording functions, used for program debugging, configuration, and operation management.

#include <string.h>
#include <stdio.h>
#include "sdkconfig.h"
#include "esp_log.h"
  1. ADC Driver: Provides ADC continuous sampling mode initialization, channel configuration, raw data reading, and collection result processing functions.

#include "esp_adc/adc_continuous.h"

Global Variables/Macro Definitions Description

The macro definitions involved in this example are mainly used to define GPIO input and output pins and interrupt flag bits.

The macro definitions are categorized by function as follows:

  1. ADC Unit Selection

  • Defines the ADC unit used. This example uses ADC_UNIT_1, i.e., the ADC1 peripheral.

#define EXAMPLE_ADC_UNIT                    ADC_UNIT_1
  • Converts the ADC unit macro to a string form for log or debug output.

#define _EXAMPLE_ADC_UNIT_STR(unit)         #unit
#define EXAMPLE_ADC_UNIT_STR(unit)          _EXAMPLE_ADC_UNIT_STR(unit)
  1. ADC Parameter Settings

  • Set the ADC conversion mode to use a single ADC unit for sampling.

#define EXAMPLE_ADC_CONV_MODE               ADC_CONV_SINGLE_UNIT_1
  • Set the attenuation of the ADC channel to 0 dB.

#define EXAMPLE_ADC_ATTEN                   ADC_ATTEN_DB_0
  • Set the ADC sampling bit width, usually using the maximum bit width supported by the chip SOC_ADC_DIGI_MAX_BITWIDTH.

#define EXAMPLE_ADC_BIT_WIDTH               SOC_ADC_DIGI_MAX_BITWIDTH
  1. ADC Output Data Format and Access: Choose different data output formats and access paths according to the chip model (whether it is an ESP32 chip or an ESP32-S2 chip).

  • Define the digital output data format of the ADC, choose TYPE1 or TYPE2 for different chips.

  • Define how to get the channel number from the ADC output data structure according to the chip type.

  • Define how to get the original sampling data from the ADC output data structure according to the chip type.

#if CONFIG_IDF_TARGET_ESP32 || CONFIG_IDF_TARGET_ESP32S2
#define EXAMPLE_ADC_OUTPUT_TYPE             ADC_DIGI_OUTPUT_FORMAT_TYPE1    // Output data format
#define EXAMPLE_ADC_GET_CHANNEL(p_data)     ((p_data)->type1.channel)       // Get channel number
#define EXAMPLE_ADC_GET_DATA(p_data)        ((p_data)->type1.data)          // Get original sampling data
#else
#define EXAMPLE_ADC_OUTPUT_TYPE             ADC_DIGI_OUTPUT_FORMAT_TYPE2    // Output data format
#define EXAMPLE_ADC_GET_CHANNEL(p_data)     ((p_data)->type2.channel)       // Get channel number
#define EXAMPLE_ADC_GET_DATA(p_data)        ((p_data)->type2.data)          // Get original sampling data
#endif
  1. Data Collection Length: Define the read length of each data collection as 256, which is used to allocate the size of the buffer.

#define EXAMPLE_READ_LEN                    256
  1. Define global variables:

  • Define the ADC channel array channel[] according to the chip model:

    • When the target chip is ESP32, select ADC_CHANNEL_6 and ADC_CHANNEL_7.

    • When the target chip is other chips, select ADC_CHANNEL_2 and ADC_CHANNEL_3.

  • Define the FreeRTOS task handle variable s_task_handle, which is used to manage or control tasks under the FreeRTOS environment.

Task Function Description

In this example, in order to initialize the ADC continuous sampling mode and successfully complete the sampling and data processing, two related task functions are provided: ADC initialization function and continuous sampling completion callback function.

ADC Initialization Function

continuous_adc_init() is the ADC initialization function, which is used to initialize the ADC continuous sampling mode and complete the channel configuration, so that the subsequent data collection and processing can proceed smoothly.

Parameter Explanation

Input Parameter

Parameter Function

Parameter Description

channel

Pointer to the ADC channel array

Used to specify the list of channels for continuous sampling. Each element represents an ADC channel number.

channel_num

Number of channels in the channel array

Used to configure the actual number of channels used during ADC continuous sampling.

out_handle

ADC module handle

Output parameter, returns the handle of the initialized ADC continuous sampling module, used for subsequent sampling start, data reading, or module deregistration operations.

The execution logic of this function is:

  1. Initialize ADC sampling module

  2. Configure/Apply sampling parameters

  • The length of the ADC channel mode array is SOC_ADC_PATT_LEN_MAX, which is the maximum channel configuration number supported in ADC digital controller mode.

  • Traverse to configure each channel and print configuration logs for debugging and verification.

  1. Save the ADC sampling module handle generated within the function to the passed parameter out_handle.

Continuous Sampling Completion Callback Function

s_conv_done_cb() is a callback function, mainly used to handle sampling completion events in ADC continuous sampling mode. It is triggered after each ADC continuous sampling completes a predetermined number of conversions.

Parameter Explanation

Input Parameter

Parameter Function

Parameter Description

handle

Handle of the created ADC continuous sampling module

Used to access the configuration and status related to the current ADC continuous sampling, facilitating further operations or management of the sampling task.

edata

Pointer to the ADC continuous sampling event data structure

Used to access sampling data for data processing or other related operations.

user_data

User-defined data

Used to identify task handles or perform task notifications.

The execution logic of this function is:

  1. Define the flag variable mustYield, used to indicate whether a task switch is needed immediately after the callback execution, initialized as pdFALSE.

  2. Call vTaskNotifyGiveFromISR() to send a notification to the specified task, informing that the ADC continuous sampling has completed the specified number of conversions.

  3. Determine whether mustYield is pdTRUE, and return it to the scheduler, so as to switch to a higher priority task execution when necessary.

Main Function Description

This function demonstrates the complete process of ADC continuous sampling mode, including initializing the ADC unit, configuring the sampling channel, registering the sampling completion callback, performing software calibration, and continuously reading and processing sampling data.

  1. Define variables:

  • Create a return value variable ret for error checking and log output, ensuring that the caller can take different actions based on different return values.

  • Create a variable ret_num and initialize it to 0, used to record the data length (in bytes) read each time.

  • Create an array result[] and initialize it to 0xcc, used to store the raw data returned by ADC continuous sampling. The array length is the custom macro EXAMPLE_READ_LEN.

  1. Call xTaskGetCurrentTaskHandle() to get the current task handle for use in the callback function. For further explanation and usage examples, refer to Task Information API.

  2. Initialize the ADC continuous sampling module:

  • Create the ADC continuous sampling module handle handle and initialize it to NULL for subsequent operations on the ADC module.

  • Call continuous_adc_init() to create and configure the ADC continuous sampling module according to the specified ADC channel array, and save the returned handle to handle.

  1. Register event callbacks.

Note

Event callback functions are often used to process sampling results and perform subsequent operations, but they are not essential steps in the ADC continuous sampling module.

  • If you choose to use a callback function, it can automatically process data after each sampling, which is suitable for scenarios that require real-time processing or frequent data processing. The callback function can effectively avoid polling waiting and improve system response efficiency.

  • If you do not use a callback function, you can choose to check whether the sampling is completed by polling, and then manually process the sampling data. This method may be suitable for scenarios that do not need to process data immediately or have simpler control logic.

  1. Start ADC continuous sampling.

Note

Steps 6 and 7 are executed in the data processing loop.

  1. Call ulTaskNotifyTake() to block and wait for callback notification, ensuring data is processed after sampling is completed.

  2. Loop to read data:

  • Continuously call adc_continuous_read() to read ADC buffer data until there is no available data in the buffer (returns ESP_ERR_TIMEOUT). For further introduction and parameter explanation, refer to ADC Driver.

  • Parse the read raw data into the adc_digi_output_data_t structure, and get the channel number and sampling value through the macros EXAMPLE_ADC_GET_CHANNEL and EXAMPLE_ADC_GET_DATA. For specific structure members, refer to ADC Driver.

  • Check the validity of each data, ensure that the channel number does not exceed the maximum channel number, and print the channel number and sampling value through the log.

  • To prevent task watchdog timeout, call vTaskDelay(1) to pause for 1 tick at the end of each loop.

  1. Stop and release the ADC module after the task ends.

  • Call adc_continuous_stop() to stop continuous sampling. For further introduction and parameter description, please refer to ADC Driver.

  • Call adc_continuous_deinit() to release ADC module resources. For further introduction and parameter description, please refer to ADC Driver.

Note

In actual applications, continuous sampling tasks are usually long-running or resident tasks, so this step is generally not executed, but it can be used to prevent potential program abnormalities or memory leaks.