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 ADCUnitHandle
: 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 ADCUnitHandle
: The unit handle returned from init/0
BitWidth
: Resolution in bit to measureAttenuation
: 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 measurementReadOptions
: 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/4UnitResource
: 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/4UnitResource
: of the pin returned from init/0ReadOptions
: 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 ADCOptions
: 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.