Module esp_adc

Analog to digital peripheral support.

Behaviours: gen_server.

Description

Use this module to take ADC (analog voltage) readings. Currently this driver only supports the esp32 family of chips, but support for other platforms is planned in the future. On an ESP32 device ADC unit 1 allows taking reading from pins 32-39. ADC unit2 is disabled by default for the ESP32 classic, but when enabled in the build configuration allows pins 0, 2, 4, 12-15, and 25-27 to be used as long as WiFi is not required by the application. Unit 2 is disabled for ESP32C3 due to its inaccurate results. ADC unit 2 is enabled for all other ESP32 series with more than one ADC unit; there is an arbitrator peripheral that allows ADC unit 2 to be used while WiFI is active. The pins available for ADC use vary by device, check your datasheet for specific hardware support.

There are two sets of APIs for interacting with the ADC hardware, only one set of API may be used by an application.

The core functionality is provided by the low level resource based nif functions. To use the resource based nifs esp_adc:init/0 and esp_adc:deinit/1 will acquire and release the adc unit resource needed for all other functions. A channel resource used to take measurements from a pin can be obtained using esp_adc:acquire/4, and released using esp_adc:release_channel/1. ADC measurements are taken using sample/3.

For convenience a gen_server managed set of APIs using pin numbers are also available. A pin may be configured using esp_adc:start/1,2, measurements are taken using esp_adc:read/1,2, pins can be released individually with esp_adc:stop/1, or the driver can be stopped completely using esp_adc:stop/0.

Data Types

adc_pin()


adc_pin() = non_neg_integer()

ADC capable pins vary by chipset. Consult your datasheet.

adc_rsrc()


adc_rsrc() = {$adc, Resource::binary(), Ref::reference()}

attenuation()


attenuation() = db_0 | db_2_5 | db_6 | db_11 | db_12

The decibel gain determines the maximum safe voltage to be measured. Default is db_11. The specific range of voltages supported by each setting varies by device. Typical voltage ranges are depicted in the table below:

Attenuation Min Millivolts Max Millivolts
db_0 0-100 750-950
db_2_5 0-100 1050-1250
db_6 0-150 1300-1750
bd_11 | db_12 0-150 2450-2500

Consult the datasheet for your device to determine the exact voltage ranges supported by each gain setting. The option db_11 has been superseded by db_12. The optiondb_11 and will be deprecated in a future release, applications should be updated to use db_12 (except for builds with ESP-IDF versions prior to v5.2). To Continue to support older IDF version builds, the default will remain db_11, which is the maximum tolerated voltage on all builds, as db_12 supported builds will automatically use db_12 in place of db_11, when db_11 is deprecated in all builds the default will be changed to db_12.

bit_width()


bit_width() = bit_9 | bit_10 | bit_11 | bit_12 | bit_13 | bit_max

The default bit_max will select the highest value supported by the chipset. Some models only support a single fixed bit width.

pin_option()


pin_option() = {bitwidth, Width::bit_width()} | {atten, Decibels::attenuation()}

pin_options()


pin_options() = [pin_option()]

raw_value()


raw_value() = 0..511 | 0..1023 | 0..2047 | 0..4095 | 0..8191 | undefined

The maximum analog value is determined by bit_width().

read_option()


read_option() = raw | voltage | {samples, 1..100000}

The value of the samples key is the number of samples to be taken and averaged when returning a measurement, default is 64. For optimal stable readings use a 100nF ceramic capacitor input filter, for more info consult Espressif’s “ADC Calibration Driver” documentation. The keys raw and voltage determine if these values are included in the results or returned as undefined.

read_options()


read_options() = [read_option()]

reading()


reading() = {raw_value() | undefined, voltage_reading() | undefined}

voltage_reading()


voltage_reading() = 0..3300 | undefined

The maximum safe millivolt value that can be measured is determined by attenuation(), this value should never exceed the chips maximum input tolerance.

Function Index

acquire/2 Nif to initialize an ADC pin.
acquire/4 Nif to initialize an ADC pin.
deinit/1 Nif to release the ADC unit resource returned from init/0.
init/0 Nif to initialize the ADC unit hardware.
read/1 Take a reading using default values from an ADC pin.
read/2 Take a reading from an ADC pin using the supplied options.
release_channel/1 Nif to deinitialize the specified ADC channel.
sample/2 Nif to take a reading using default values from an ADC channel.
sample/3 Nif to take a reading from an ADC channel.
start/0 Optionally initialize a gen_server managed ADC driver without a pin.
start/1 Initialize a gen_server managed ADC pin with default options.
start/2 Initialize a gen_server managed ADC pin with the supplied options.
stop/0 Stop the ADC driver and release all resources.
stop/1 De-initialize the specified ADC pin.

Function Details

acquire/2


acquire(Pin::adc_pin(), UnitHandle::adc_rsrc()) -> {ok, Channel::adc_rsrc()} | {error, Reason::term()}

Pin: Pin to configure as ADC
UnitHandle: The unit handle returned from init/0

returns: {ok, Channel::adc_rsrc()} | {error, Reason}

Equivalent to acquire(Pin, UnitHandle, bit_max, db_11).

Nif to initialize an ADC pin.

Initializes an ADC pin and returns a channel handle resources.

This is a low level nif that cannot be used in an application that uses the convenience functions.

acquire/4


acquire(Pin::adc_pin(), UnitHandle::adc_rsrc(), BitWidth::bit_width(), Attenuation::attenuation()) -> {ok, Channel::adc_rsrc()} | {error, Reason::term()}

Pin: Pin to configure as ADC
UnitHandle: The unit handle returned from init/0
BitWidth: Resolution in bit to measure
Attenuation: Decibel gain for voltage range

returns: {ok, Channel::adc_rsrc()} | {error, Reason}

Nif to initialize an ADC pin.

The BitWidth value bit_max may be used to automatically select the highest sample rate supported by your ESP chip-set, or choose from a bit width supported by the device.

The Attenuation value can be used to adust the gain, and therefore safe measurement range on voltage the exact range of voltages supported by each db gain varies by chip, consult the data sheet for exact range of your model. For more information see the attenuation() type specification.

Use the returned Channel reference in subsequent ADC operations on the same pin.

This is a low level nif that cannot be used in an application that uses the convenience functions.

deinit/1


deinit(UnitResource::adc_rsrc()) -> ok | {error, Reason::term()}

UnitResource: returned from init/0

returns: ok | {error, Reason}

Nif to release the ADC unit resource returned from init/0.

Stop the ADC driver and free the unit resource. All active ADC channels should be released using release_channel/1 to free each configured channel before freeing the unit resource.

This is a low level nif that cannot be used in an application that uses the convenience functions.

init/0


init() -> {ok, ADCUnit::adc_rsrc()} | {error, Reason::term()}

returns: {ok, ADCUnit :: adc_rsrc()} | {error, Reason}

Nif to initialize the ADC unit hardware.

The returned ADC unit handle resource must be supplied for all future ADC operations.

This is a low level nif that cannot be used in an application that uses the convenience functions.

read/1


read(Pin::adc_pin()) -> {ok, reading()} | {error, Reason::term()}

Pin: The pin from which to take ADC measurement

returns: {ok, {RawValue, MilliVolts}} | {error, Reason}

Equivalent to read(Pin, [raw, voltage, {samples, 64}]).

Take a reading using default values from an ADC pin.

This convenience function is used to take a measurement from a previously started adc pin.

This function cannot be used in an application that uses the low level nif APIs.

read/2


read(Pin::adc_pin(), ReadOptions::read_options()) -> {ok, Result::reading()} | {error, Reason::term()}

Pin: The pin from which to take ADC measurement
ReadOptions: Extra options

returns: {ok, {RawValue, MilliVolts}} | {error, Reason}

Take a reading from an ADC pin using the supplied options.

This convenience function is used to take a measurement from a previously started adc pin, using the supplied read options parameter.

The Options parameter may be used to specify the behavior of the read operation.

If the ReadOptions contains the atom raw, then the raw value will be returned in the first element of the returned tuple. Otherwise, this element will be the atom undefined.

If the ReadOptions contains the atom voltage, then the voltage value will be returned in millivolts in the second element of the returned tuple. Otherwise, this element will be the atom undefined.

You may specify the number of samples to be taken and averaged over using the tuple {samples, Samples::pos_integer()}, the default is 64.

If the error Reason is timeout and the adc channel is on unit 2 then WiFi is likely enabled and adc2 readings may be blocked until there is less network traffic. On and ESP32 classic the results for unit 2 will always be {error, timeout} if wifi is enabled.

This function cannot be used in an application that uses the low level nif APIs.

release_channel/1


release_channel(ChannelResource::adc_rsrc()) -> ok | {error, Reason::term()}

ChannelResource: of the pin returned from acquire/4

returns: ok | {error, Reason}

Nif to deinitialize the specified ADC channel.

In the case that an error is returned it is safe to “drop” the ChannelResource handle from use. After there are no remaining processes with references to the channel resource handle, the calibration profile and any remaining resources associated with the channel will be released as part of the next garbage collection event.

This is a low level nif that cannot be used in an application that uses the convenience functions.

sample/2


sample(ChannelResource::adc_rsrc(), UnitResource::adc_rsrc()) -> {ok, reading()} | {error, Reason::term()}

ChannelResource: of the pin returned from acquire/4
UnitResource: of the pin returned from init/0

returns: {ok, {RawValue, MilliVolts}} | {error, Reason}

Equivalent to sample(ChannelResource,UnitResource,[raw, voltage, {samples, 64}]).

Nif to take a reading using default values from an ADC channel.

This is a low level nif that cannot be used in an application that uses the convenience functions.

sample/3


sample(ChannelResource::adc_rsrc(), UnitResource::adc_rsrc(), ReadOptions::read_options()) -> {ok, Result::reading()} | {error, Reason::term()}

ChannelResource: of the pin returned from acquire/4
UnitResource: of the pin returned from init/0
ReadOptions: extra list of options to override defaults.

returns: {ok, {RawValue, MilliVolts}} | {error, Reason}

Nif to take a reading from an ADC channel.

The Options parameter may be used to specify the behavior of the read operation.

If the ReadOptions contains the atom raw, then the raw value will be returned in the first element of the returned tuple. Otherwise, this element will be the atom undefined.

If the ReadOptions contains the atom voltage, then the voltage value will be returned in millivolts in the second element of the returned tuple. Otherwise, this element will be the atom undefined.

You may specify the number of samples to be taken and averaged over using the tuple {samples, Samples::pos_integer()}.

If the error Reason is timeout and the adc channel is on unit 2 then WiFi is likely enabled and adc2 readings may be blocked until there is less network traffic. On and ESP32 classic the results for unit 2 will always be {error, timeout} if wifi is enabled.

This is a low level nif that cannot be used in an application that uses the convenience functions.

start/0


start() -> {ok, Pid::pid()}

returns: {ok, Pid}

Optionally initialize a gen_server managed ADC driver without a pin.

Use of this function is optional, but may be desired if the drivers pid is needed, or it is desireable to start the driver without configuring an initial ADC channel.

Note: since only one instance of the driver is allowed it is registered with the name adc_driver, which also may be used to directly call the gen_server.

This convenience function cannot be used in an application that uses the low level nif APIs.

start/1


start(Pin::adc_pin()) -> ok | {error, Reason::term()}

Pin: Pin to configure as ADC

returns: ok | {error, Reason}

Equivalent to start(Pin, [{bitwidth, bit_max}, {atten, db_11}]).

Initialize a gen_server managed ADC pin with default options.

This convenience function configures an ADC pin with the default options for use with the optional gen_server APIs. Default options are: [{bitwidth, bit_max}, {atten, db_11}]

This function cannot be used in an application that uses the low level nif APIs.

start/2


start(Pin::adc_pin(), Options::pin_options()) -> ok | {error, Reason::term()}

Pin: Pin to configure as ADC
Options: List of options to override default settings

returns: ok | {error, Reason}

Initialize a gen_server managed ADC pin with the supplied options.

This convenience function configures an ADC pin with the provided options to override the default configuration: [{bitwidth, bit_max}, {atten, db_11}].

For more details about these options see the attenuation() and bit_width() type specifications.

This function cannot be used in an application that uses the low level nif APIs.

stop/0


stop() -> ok | {error, Reason::term()}

returns: ok | {error, Reason}

Stop the ADC driver and release all resources.

This convenience function is used to completely stop the gen_server managed ADC driver and release all resources.

Note: if an error is returned, a full shutdown of the ADC peripheral should still occur, and any remaining resources freed with next VM garbage collection event. Regardless the gen_server will exit normally and the adc peripheral will no longer be usable.

This function cannot be used in an application that uses the low level nif APIs.

stop/1


stop(Pin::adc_pin()) -> ok | {error, Reason::term()}

Pin: the pin to be released

returns: ok | {error, Reason}

De-initialize the specified ADC pin.

This convenience function is used to release a pin from the gen_server managed ADC driver. If an error is returned the ADC channel will still be stopped and release internal resources during the next VM garbage collection event, the pin will immediately no longer be useable in any case.

This function cannot be used in an application that uses the low level nif APIs.