Analog I/O (ADC & DAC)
Relevant source files
The following files were used as context for generating this wiki page:
AtomVM provides support for Analog-to-Digital Conversion (ADC) and Digital-to-Analog Conversion (DAC) peripherals, primarily on micro-controller platforms like the ESP32. This functionality allows Erlang and Elixir applications to interface with the physical world by reading continuous voltage signals or generating analog outputs.
The Analog I/O system is implemented as part of the AtomVM platform integrations, leveraging native SDKs (such as the Espressif IoT Development Framework) to provide high-performance, memory-managed access to hardware peripherals. Sources: doc/src/welcome-to-atomvm.md:55-58, src/platforms/esp32/README.md:19-30
Analog-to-Digital Conversion (ADC)
The ADC implementation in AtomVM for ESP32 is built on the adc_oneshot and adc_calibration components of the ESP-IDF. It supports single-shot readings with configurable attenuation, bit-width, and multi-sample averaging to improve accuracy. Sources: src/platforms/esp32/components/avm_builtins/adc_driver.c:26-30
Architecture and Lifecycle
The ADC driver follows a structured lifecycle: initialization of the ADC unit, acquisition of specific channels (pins), sampling, and eventual deinitialization.
The diagram shows the standard lifecycle of an ADC operation from resource allocation to teardown. Sources: src/platforms/esp32/components/avm_builtins/adc_driver.c:317-570
Resource Management
AtomVM uses Erlang NIF Resources to manage the state of ADC hardware. There are two primary resource types:
- Unit Resource: Manages the hardware ADC unit (e.g., ADC_UNIT_1 or ADC_UNIT_2). Sources: src/platforms/esp32/components/avm_builtins/adc_driver.c:97-101
- Channel Resource: Manages specific pin configurations, including attenuation, bit-width, and calibration handles. Sources: src/platforms/esp32/components/avm_builtins/adc_driver.c:88-95
Calibration Schemes
To improve the accuracy of voltage readings, the driver supports several calibration methods depending on the hardware capabilities:
- Curve Fitting: Used on newer ESP32 variants for higher precision.
- Line Fitting: Uses eFuse values or default Vref (1100mV).
- Estimated: A fallback calculation based on the theoretical maximum voltage and bit-width.
Sources: src/platforms/esp32/components/avm_builtins/adc_driver.c:165-245
Data Flow for Sampling
When a sampling request is made from Erlang/Elixir, the driver performs multiple hardware reads and calculates the average.
The sequence shows how the driver interacts with the hardware to produce a calibrated result for the virtual machine. Sources: src/platforms/esp32/components/avm_builtins/adc_driver.c:486-560
API Reference (ADC)
The ADC functionality is exposed via the esp_adc module (Erlang) or Esp.ADC (Elixir).
Configuration Options
| Parameter | Type | Description | Valid Values |
|---|---|---|---|
bit_width | atom | Resolution of the conversion | bit_9, bit_10, bit_11, bit_12, bit_max |
attenuation | atom | Input voltage scaling | db_0, db_2_5, db_6, db_12 |
samples | integer | Number of reads to average | 1 to 100,000 (Default: 64) |
voltage | boolean | Whether to return calibrated mV | true, false |
Sources: src/platforms/esp32/components/avm_builtins/adc_driver.c:103-125, src/platforms/esp32/components/avm_builtins/adc_driver.c:514-525
Key NIF Functions
init/0: Initializes the ADC unit and returns a unit resource. Sources: src/platforms/esp32/components/avm_builtins/adc_driver.c:317acquire/4: Configures a specific GPIO pin for ADC use. Sources: src/platforms/esp32/components/avm_builtins/adc_driver.c:395sample/3: Performs the analog-to-digital conversion. Sources: src/platforms/esp32/components/avm_builtins/adc_driver.c:486release_channel/1: Cleans up calibration handles and channel resources. Sources: src/platforms/esp32/components/avm_builtins/adc_driver.c:453
Digital-to-Analog Conversion (DAC)
While ADC handles input, DAC allows AtomVM to generate analog voltage levels on supported pins. On the ESP32 platform, this is typically integrated into the built-in components and can be enabled or disabled via menuconfig to optimize image size. Sources: src/platforms/esp32/README.md:39-50
Platform Availability
Analog I/O support varies by platform. While the core virtual machine logic is platform-independent, the hardware drivers are specific to micro-controller builds.
| Platform | ADC Support | DAC Support |
|---|---|---|
| ESP32 | Supported (Full) | Supported |
| STM32 | Ongoing Development | Limited |
| Generic UNIX | Not Supported | Not Supported |
| WebAssembly | Not Supported | Not Supported |
Sources: doc/src/getting-started-guide.md:188-195, doc/src/getting-started-guide.md:435-440
Summary
The Analog I/O system in AtomVM provides a robust bridge between functional code and hardware signals. By utilizing Erlang's resource management system, the ADC and DAC drivers ensure that hardware peripherals are safely initialized, utilized, and released, preventing resource leaks while providing developers with calibrated, high-level access to analog signals.