Unverified Commit 352af864 authored by Jan Procházka's avatar Jan Procházka Committed by GitHub

Analog Continuous mode API (#8715)

* Adds Analog Continuous mode API

* fix when stopping/starting ADC data are not complete

* Added example

* fix size check

* update frequency in example

* set buffer to NULL if error occurs

* add docs

* set buffer to null on error

* fix example

* update docs

* fix example

* change return value to bool type

* updated adc modes description in docs

* Add empty line at the end of sketch
parent b98b52a1
This diff is collapsed.
......@@ -77,6 +77,56 @@ void analogSetWidth(uint8_t bits);
#endif
/*
* Analog Continuous mode
* */
typedef struct {
uint8_t pin; /*!<ADC pin */
uint8_t channel; /*!<ADC channel */
int avg_read_raw; /*!<ADC average raw data */
int avg_read_mvolts; /*!<ADC average voltage in mV */
} adc_continuos_data_t;
/*
* Setup ADC continuous peripheral
* */
bool analogContinuous(uint8_t pins[], size_t pins_count, uint32_t conversions_per_pin, uint32_t sampling_freq_hz, void (*userFunc)(void));
/*
* Read ADC continuous conversion data
* */
bool analogContinuousRead(adc_continuos_data_t ** buffer, uint32_t timeout_ms);
/*
* Start ADC continuous conversions
* */
bool analogContinuousStart();
/*
* Stop ADC continuous conversions
* */
bool analogContinuousStop();
/*
* Deinitialize ADC continuous peripheral
* */
bool analogContinuousDeinit();
/*
* Sets the attenuation for continuous mode reading
* Default is 11db
* */
void analogContinuousSetAtten(adc_attenuation_t attenuation);
/*
* Sets the read resolution for continuous mode
* Default is 12bit (0 - 4095)
* Range is 9 - 12
* */
void analogContinuousSetWidth(uint8_t bits);
#ifdef __cplusplus
}
#endif
......
......@@ -11,13 +11,17 @@ to a digital form so that it can be read and processed by a microcontroller.
ADCs are very useful in control and monitoring applications since most sensors
(e.g., temperature, pressure, force) produce analogue output voltages.
.. note:: Each SoC or module has a different number of ADC's with a different number of channels and pins availible. Refer to datasheet of each board for more info.
.. note:: Each SoC or module has a different number of ADC's with a different number of channels and pins available. Refer to datasheet of each board for more info.
Arduino-ESP32 ADC API
---------------------
ADC common API
**************
ADC OneShot mode
****************
The ADC OneShot mode API is fully compatible with Arduino's ``analogRead`` function.
When you call the ``analogRead`` or ``analogReadMillivolts`` function, it returns the result of a single conversion on the requested pin.
analogRead
^^^^^^^^^^
......@@ -82,7 +86,7 @@ The measurable input voltage differs for each chip, see table below for detailed
``ADC_ATTEN_DB_0`` 100 mV ~ 950 mV
``ADC_ATTEN_DB_2_5`` 100 mV ~ 1250 mV
``ADC_ATTEN_DB_6`` 150 mV ~ 1750 mV
``ADC_ATTEN_DB_11`` 150 mV ~ 2450 mV
``ADC_ATTEN_DB_11`` 150 mV ~ 3100 mV
===================== ===========================================
.. tab:: ESP32-S2
......@@ -135,13 +139,12 @@ This function is used to set the attenuation for a specific pin/ADC channel. For
* ``pin`` selects specific pin for attenuation settings.
* ``attenuation`` sets the attenuation.
ADC API specific for ESP32 chip
*******************************
analogSetWidth
^^^^^^^^^^^^^^
.. note:: This function is only available for ESP32 chip.
This function is used to set the hardware sample bits and read resolution.
Default is 12bit (0 - 4095).
Range is 9 - 12.
......@@ -149,13 +152,130 @@ Range is 9 - 12.
.. code-block:: arduino
void analogSetWidth(uint8_t bits);
ADC Continuous mode
*******************
ADC Continuous mode is an API designed for performing analog conversions on multiple pins in the background,
with the feature of receiving a callback upon completion of these conversions to access the results.
This API allows you to specify the desired number of conversions per pin within a single cycle, along with its corresponding sampling rate.
The outcome of the ``analogContinuousRead`` function is an array of ``adc_continuous_data_t`` structures.
These structures hold both the raw average value and the average value in millivolts for each pin.
analogContinuous
^^^^^^^^^^^^^^^^
This function is used to configure ADC continuous peripheral on selected pins.
.. code-block:: arduino
bool analogContinuous(uint8_t pins[], size_t pins_count, uint32_t conversions_per_pin, uint32_t sampling_freq_hz, void (*userFunc)(void));
* ``pins[]`` array of pins to be set up
* ``pins_count`` count of pins in array
* ``conversions_per_pin`` sets how many conversions per pin will run each ADC cycle
* ``sampling_freq_hz`` sets sampling frequency of ADC in Hz
* ``userFunc`` sets callback function to be called after adc conversion is done (can be set to ``NULL``)
This function will return ``true`` if configuration is successful.
If ``false`` is returned, error occurs and ADC continuous was not configured.
analogContinuousRead
^^^^^^^^^^^^^^^^^^^^
This function is used to read ADC continuous data to the result buffer. The result buffer is an array of ``adc_continuos_data_t``.
.. code-block:: arduino
typedef struct {
uint8_t pin; /*!<ADC pin */
uint8_t channel; /*!<ADC channel */
int avg_read_raw; /*!<ADC average raw data */
int avg_read_mvolts; /*!<ADC average voltage in mV */
} adc_continuos_data_t;
.. code-block:: arduino
bool analogContinuousRead(adc_continuos_data_t ** buffer, uint32_t timeout_ms);
* ``buffer`` conversion result buffer to read from ADC in adc_continuos_data_t format.
* ``timeout_ms`` time to wait for data in milliseconds.
This function will return ``true`` if reading is successful and ``buffer`` is filled with data.
If ``false`` is returned, reading has failed and ``buffer`` is set to NULL.
analogContinuousStart
^^^^^^^^^^^^^^^^^^^^^
This function is used to start ADC continuous conversions.
.. code-block:: arduino
bool analogContinuousStart();
This function will return ``true`` if ADC continuous is succesfully started.
If ``false`` is returned, starting ADC continuous has failed.
analogContinuousStop
^^^^^^^^^^^^^^^^^^^^
This function is used to stop ADC continuous conversions.
.. code-block:: arduino
bool analogContinuousStop();
This function will return ``true`` if ADC continuous is succesfully stopped.
If ``false`` is returned, stopping ADC continuous has failed.
analogContinuousDeinit
^^^^^^^^^^^^^^^^^^^^^^
This function is used to deinitialize ADC continuous peripheral.
.. code-block:: arduino
bool analogContinuousDeinit();
This function will return ``true`` if ADC continuous is succesfully deinitialized.
If ``false`` is returned, deinitilization of ADC continuous has failed.
analogContinuousSetAtten
^^^^^^^^^^^^^^^^^^^^^^^^
This function is used to set the attenuation for ADC continuous peripheral. For more informations refer to `analogSetAttenuation`_.
.. code-block:: arduino
void analogContinuousSetAtten(adc_attenuation_t attenuation);
* ``attenuation`` sets the attenuation (default is 11db).
analogContinuousSetWidth
^^^^^^^^^^^^^^^^^^^^^^^^
This function is used to set the hardware resolution bits.
Default value for all chips is 12bit (0 - 4095).
.. note:: This function will take effect only for ESP32 chip, as it allows to set resolution in range 9-12 bits.
.. code-block:: arduino
void analogContinuousSetWidth(uint8_t bits);
* ``bits`` sets resolution bits.
Example Applications
********************
Here is an example of how to use the ADC.
Here is an example of how to use the ADC in OneShot mode or you can run Arduino example 01.Basics -> AnalogReadSerial.
.. literalinclude:: ../../../libraries/ESP32/examples/AnalogRead/AnalogRead.ino
:language: arduino
Or you can run Arduino example 01.Basics -> AnalogReadSerial.
Here is an example of how to use the ADC in Continuous mode.
.. literalinclude:: ../../../libraries/ESP32/examples/AnalogReadContinuous/AnalogReadContinuous.ino
:language: arduino
// Define how many conversion per pin will happen and reading the data will be and average of all conversions
#define CONVERSIONS_PER_PIN 5
// Declare array of ADC pins that will be used for ADC Continuous mode - ONLY ADC1 pins are supported
// Number of selected pins can be from 1 to ALL ADC1 pins.
#ifdef CONFIG_IDF_TARGET_ESP32
uint8_t adc_pins[] = {36, 39, 34, 35}; //some of ADC1 pins for ESP32
#else
uint8_t adc_pins[] = {1, 2, 3, 4}; //ADC1 common pins for ESP32S2/S3 + ESP32C3/C6 + ESP32H2
#endif
// Calculate how many pins are declared in the array - needed as input for the setup function of ADC Continuous
uint8_t adc_pins_count = sizeof(adc_pins) / sizeof(uint8_t);
// Flag which will be set in ISR when conversion is done
volatile bool adc_coversion_done = false;
// Result structure for ADC Continuous reading
adc_continuos_data_t * result = NULL;
// ISR Function that will be triggered when ADC conversion is done
void ARDUINO_ISR_ATTR adcComplete() {
adc_coversion_done = true;
}
void setup() {
// Initialize serial communication at 115200 bits per second:
Serial.begin(115200);
// Optional for ESP32: Set the resolution to 9-12 bits (default is 12 bits)
analogContinuousSetWidth(12);
// Optional: Set different attenaution (default is ADC_11db)
analogContinuousSetAtten(ADC_11db);
// Setup ADC Continuous with following input:
// array of pins, count of the pins, how many conversions per pin in one cycle will happen, sampling frequency, callback function
analogContinuous(adc_pins, adc_pins_count, CONVERSIONS_PER_PIN, 20000, &adcComplete);
// Start ADC Continuous conversions
analogContinuousStart();
}
void loop() {
// Check if conversion is done and try to read data
if (adc_coversion_done == true) {
// Set ISR flag back to false
adc_coversion_done = false;
// Read data from ADC
if (analogContinuousRead(&result, 0)) {
// Optional: Stop ADC Continuous conversions to have more time to process (print) the data
analogContinuousStop();
for (int i = 0; i < adc_pins_count; i++) {
Serial.printf("\nADC PIN %d data:", result[i].pin);
Serial.printf("\n Avg raw value = %d", result[i].avg_read_raw);
Serial.printf("\n Avg milivolts value = %d", result[i].avg_read_mvolts);
}
// Delay for better readability of ADC data
delay(1000);
// Optional: If ADC was stopped, start ADC conversions and wait for callback function to set adc_coversion_done flag to true
analogContinuousStart();
}
else {
Serial.println("Error occured during reading data. Set Core Debug Level to error or lower for more informations.");
}
}
}
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment