From 998a70237062bf08c8c39f322f2406fea7167a68 Mon Sep 17 00:00:00 2001 From: Aditya YV Date: Sun, 27 Apr 2025 12:58:58 -0500 Subject: [PATCH 1/5] ADC drivers for esp32 --- adc_esp/adc_esp.cpp | 102 ++++++++++++++++++++++++++++++++++++++++++++ adc_esp/adc_esp.h | 65 ++++++++++++++++++++++++++++ 2 files changed, 167 insertions(+) create mode 100644 adc_esp/adc_esp.cpp create mode 100644 adc_esp/adc_esp.h diff --git a/adc_esp/adc_esp.cpp b/adc_esp/adc_esp.cpp new file mode 100644 index 0000000..fd0c61c --- /dev/null +++ b/adc_esp/adc_esp.cpp @@ -0,0 +1,102 @@ +#include "adc_esp.h" +#include + +// Calibration characteristics +static esp_adc_cal_characteristics_t adc_chars; + +esp_err_t esp32_adc_init(ESP32_ADC_Config* config) { + esp_err_t ret = ESP_OK; + + // Configure ADC unit + if (config->unit == ADC_UNIT_1) { + ret = adc1_config_width(config->width); + if (ret != ESP_OK) return ret; + } + + // Characterize ADC for calibration + esp_adc_cal_characterize(config->unit, config->attenuation, + config->width, config->vref, &adc_chars); + + return ESP_OK; +} + +esp_err_t esp32_adc_config_channel(adc_unit_t unit, adc_channel_t channel, adc_atten_t attenuation) { + if (unit == ADC_UNIT_1) { + return adc1_config_channel_atten((adc1_channel_t)channel, attenuation); + } else if (unit == ADC_UNIT_2) { + return adc2_config_channel_atten((adc2_channel_t)channel, attenuation); + } + return ESP_ERR_INVALID_ARG; +} + +int esp32_adc_read_voltage(adc_unit_t unit, adc_channel_t channel, ESP32_ADC_Config* config) { + int raw_value = esp32_adc_read_raw(unit, channel); + if (raw_value < 0) return -1; + + // Convert raw value to voltage + uint32_t voltage = esp_adc_cal_raw_to_voltage(raw_value, &adc_chars); + return voltage; +} + +int esp32_adc_read_raw(adc_unit_t unit, adc_channel_t channel) { + int raw_value; + + if (unit == ADC_UNIT_1) { + // Configure the channel attenuation if not already done + // This should ideally be done during initialization for each channel + adc1_channel_t adc1_channel = (adc1_channel_t)channel; + raw_value = adc1_get_raw(adc1_channel); + } else if (unit == ADC_UNIT_2) { + // ADC2 can't be used when Wi-Fi is active + esp_err_t ret = adc2_get_raw((adc2_channel_t)channel, ADC_WIDTH_BIT_12, &raw_value); + if (ret != ESP_OK) { + return -1; + } + } else { + return -1; // Invalid ADC unit + } + + return raw_value; +} + +float esp32_adc_normalize(int raw_value, ESP32_ADC_Config* config) { + if (raw_value < 0) return -1.0f; + + int max_value; + switch (config->width) { + case ADC_WIDTH_BIT_9: max_value = 511; break; + case ADC_WIDTH_BIT_10: max_value = 1023; break; + case ADC_WIDTH_BIT_11: max_value = 2047; break; + case ADC_WIDTH_BIT_12: max_value = 4095; break; + default: return -1.0f; + } + + return (float)raw_value / max_value; +} + +esp_err_t esp32_adc_gpio_to_channel(int gpio_pin, adc_unit_t* unit, adc_channel_t* channel) { + // Map GPIO pin to ADC channel + // ADC1 channels + if (gpio_pin == 36) { *unit = ADC_UNIT_1; *channel = (adc_channel_t)ADC1_CHANNEL_0; return ESP_OK; } + if (gpio_pin == 37) { *unit = ADC_UNIT_1; *channel = (adc_channel_t)ADC1_CHANNEL_1; return ESP_OK; } + if (gpio_pin == 38) { *unit = ADC_UNIT_1; *channel = (adc_channel_t)ADC1_CHANNEL_2; return ESP_OK; } + if (gpio_pin == 39) { *unit = ADC_UNIT_1; *channel = (adc_channel_t)ADC1_CHANNEL_3; return ESP_OK; } + if (gpio_pin == 32) { *unit = ADC_UNIT_1; *channel = (adc_channel_t)ADC1_CHANNEL_4; return ESP_OK; } + if (gpio_pin == 33) { *unit = ADC_UNIT_1; *channel = (adc_channel_t)ADC1_CHANNEL_5; return ESP_OK; } + if (gpio_pin == 34) { *unit = ADC_UNIT_1; *channel = (adc_channel_t)ADC1_CHANNEL_6; return ESP_OK; } + if (gpio_pin == 35) { *unit = ADC_UNIT_1; *channel = (adc_channel_t)ADC1_CHANNEL_7; return ESP_OK; } + + // ADC2 channels + if (gpio_pin == 4) { *unit = ADC_UNIT_2; *channel = (adc_channel_t)ADC2_CHANNEL_0; return ESP_OK; } + if (gpio_pin == 0) { *unit = ADC_UNIT_2; *channel = (adc_channel_t)ADC2_CHANNEL_1; return ESP_OK; } + if (gpio_pin == 2) { *unit = ADC_UNIT_2; *channel = (adc_channel_t)ADC2_CHANNEL_2; return ESP_OK; } + if (gpio_pin == 15) { *unit = ADC_UNIT_2; *channel = (adc_channel_t)ADC2_CHANNEL_3; return ESP_OK; } + if (gpio_pin == 13) { *unit = ADC_UNIT_2; *channel = (adc_channel_t)ADC2_CHANNEL_4; return ESP_OK; } + if (gpio_pin == 12) { *unit = ADC_UNIT_2; *channel = (adc_channel_t)ADC2_CHANNEL_5; return ESP_OK; } + if (gpio_pin == 14) { *unit = ADC_UNIT_2; *channel = (adc_channel_t)ADC2_CHANNEL_6; return ESP_OK; } + if (gpio_pin == 27) { *unit = ADC_UNIT_2; *channel = (adc_channel_t)ADC2_CHANNEL_7; return ESP_OK; } + if (gpio_pin == 25) { *unit = ADC_UNIT_2; *channel = (adc_channel_t)ADC2_CHANNEL_8; return ESP_OK; } + if (gpio_pin == 26) { *unit = ADC_UNIT_2; *channel = (adc_channel_t)ADC2_CHANNEL_9; return ESP_OK; } + + return ESP_ERR_NOT_FOUND; +} diff --git a/adc_esp/adc_esp.h b/adc_esp/adc_esp.h new file mode 100644 index 0000000..3aedc0d --- /dev/null +++ b/adc_esp/adc_esp.h @@ -0,0 +1,65 @@ +#ifndef ESP32_ADC_H +#define ESP32_ADC_H + +#include +#include + +// ADC configuration struct +typedef struct { + adc_unit_t unit; // ADC unit (ADC1 or ADC2) + adc_bits_width_t width; // ADC bit width (9-12 bits) + adc_atten_t attenuation; // ADC attenuation + uint32_t vref; // Reference voltage in mV (typically 1100mV) +} ESP32_ADC_Config; + +/** + * Initialize ADC with the given configuration + * @param config ADC configuration + * @return ESP_OK on success, error code otherwise + */ +esp_err_t esp32_adc_init(ESP32_ADC_Config* config); + +/** + * Configure a specific ADC channel with the given attenuation + * @param unit ADC unit (ADC1 or ADC2) + * @param channel ADC channel + * @param attenuation Attenuation level + * @return ESP_OK on success, error code otherwise + */ +esp_err_t esp32_adc_config_channel(adc_unit_t unit, adc_channel_t channel, adc_atten_t attenuation); + +/** + * Read ADC value from the specified channel + * @param unit ADC unit (ADC1 or ADC2) + * @param channel ADC channel + * @param config ADC configuration used for calibration + * @return Voltage in millivolts, or -1 on error + */ +int esp32_adc_read_voltage(adc_unit_t unit, adc_channel_t channel, ESP32_ADC_Config* config); + +/** + * Read raw ADC value from the specified channel + * @param unit ADC unit (ADC1 or ADC2) + * @param channel ADC channel + * @return Raw ADC value (0-4095 for 12-bit), or -1 on error + */ +int esp32_adc_read_raw(adc_unit_t unit, adc_channel_t channel); + +/** + * Convert raw ADC value to normalized float (0.0-1.0) + * @param raw_value Raw ADC value + * @param config ADC configuration for bit width + * @return Normalized value between 0.0 and 1.0 + */ +float esp32_adc_normalize(int raw_value, ESP32_ADC_Config* config); + +/** + * Get ADC channel for a GPIO pin + * @param gpio_pin GPIO pin number + * @param unit Pointer to store the ADC unit + * @param channel Pointer to store the ADC channel + * @return ESP_OK if mapping successful, error code otherwise + */ +esp_err_t esp32_adc_gpio_to_channel(int gpio_pin, adc_unit_t* unit, adc_channel_t* channel); + +#endif // ESP32_ADC_H \ No newline at end of file From 9e8f34cb83b9d1232a50e24863bb080c85eb7a45 Mon Sep 17 00:00:00 2001 From: Aditya YV Date: Sun, 27 Apr 2025 13:22:44 -0500 Subject: [PATCH 2/5] Undid ADC2 width hardcoding --- adc_esp/adc_esp.cpp | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/adc_esp/adc_esp.cpp b/adc_esp/adc_esp.cpp index fd0c61c..1e2ab48 100644 --- a/adc_esp/adc_esp.cpp +++ b/adc_esp/adc_esp.cpp @@ -4,6 +4,8 @@ // Calibration characteristics static esp_adc_cal_characteristics_t adc_chars; +adc_bits_width_t adc2_width = ADC_WIDTH_BIT_12; // Since ADC2 can't be configured directly, we set the width here + esp_err_t esp32_adc_init(ESP32_ADC_Config* config) { esp_err_t ret = ESP_OK; @@ -12,6 +14,11 @@ esp_err_t esp32_adc_init(ESP32_ADC_Config* config) { ret = adc1_config_width(config->width); if (ret != ESP_OK) return ret; } + else if (config->unit == ADC_UNIT_2) { + adc2_width = config->width; + } else { + return ESP_ERR_INVALID_ARG; + } // Characterize ADC for calibration esp_adc_cal_characterize(config->unit, config->attenuation, @@ -48,7 +55,7 @@ int esp32_adc_read_raw(adc_unit_t unit, adc_channel_t channel) { raw_value = adc1_get_raw(adc1_channel); } else if (unit == ADC_UNIT_2) { // ADC2 can't be used when Wi-Fi is active - esp_err_t ret = adc2_get_raw((adc2_channel_t)channel, ADC_WIDTH_BIT_12, &raw_value); + esp_err_t ret = adc2_get_raw((adc2_channel_t)channel, adc2_width, &raw_value); if (ret != ESP_OK) { return -1; } From 2ef28dc982367de584dce5270c2bb6606f508e44 Mon Sep 17 00:00:00 2001 From: Aditya YV <131169951+YVishere@users.noreply.github.com> Date: Wed, 22 Oct 2025 21:15:55 -0500 Subject: [PATCH 3/5] Esp32 can implementation (#8) * Add esp32canmanager library * remove debug printout in esp32canmanager.cpp --------- Co-authored-by: bquan0 --- esp32canmanager/esp32canmanager.cpp | 39 +++++++++++++++++++++++++ esp32canmanager/esp32canmanager.h | 45 +++++++++++++++++++++++++++++ 2 files changed, 84 insertions(+) create mode 100644 esp32canmanager/esp32canmanager.cpp create mode 100644 esp32canmanager/esp32canmanager.h diff --git a/esp32canmanager/esp32canmanager.cpp b/esp32canmanager/esp32canmanager.cpp new file mode 100644 index 0000000..be09c55 --- /dev/null +++ b/esp32canmanager/esp32canmanager.cpp @@ -0,0 +1,39 @@ +#include "esp32canmanager.h" + +ESP32CANManager::ESP32CANManager(int8_t tx, int8_t rx, uint16_t tx_queue, uint16_t rx_queue, uint16_t frequency) { + if (ESP32Can.begin(ESP32Can.convertSpeed(frequency), tx, rx, tx_queue, rx_queue)) { + printf("can bus started\n"); + } else { + printf("can bus initialization FAIL\n"); + } +} + +bool ESP32CANManager::sendMessage(uint16_t id, void* data, uint8_t length, uint32_t timeout) { + // create the message + CanFrame obdFrame = { 0 }; + obdFrame.identifier = id; + obdFrame.extd = 0; // use non extended 11 bit ID + obdFrame.data_length_code = length; + memcpy(obdFrame.data, data, length); + // printf("obdFrame: %x\n", obdFrame.data[0]); + + uint32_t start = millis(); + bool send_success = false; + while (!(send_success = ESP32Can.writeFrame(obdFrame)) && millis() - start < timeout){ + this->runQueue(1); + } + + return send_success; +} + +void ESP32CANManager::runQueue(uint16_t duration) { + CanFrame rxFrame; + + uint32_t start = millis(); + + while (millis() - start < duration) { + if(ESP32Can.readFrame(rxFrame, 1)) { + this->readHandler(rxFrame); + } + } +} \ No newline at end of file diff --git a/esp32canmanager/esp32canmanager.h b/esp32canmanager/esp32canmanager.h new file mode 100644 index 0000000..25f21bd --- /dev/null +++ b/esp32canmanager/esp32canmanager.h @@ -0,0 +1,45 @@ +#ifndef __ESP32_CAN_H__ +#define __ESP32_CAN_H__ + +#include +#include + +#define DEFAULT_ESP32_CAN_FREQ 250 + +class ESP32CANManager { + public: + /* frequency: in kHz + * tx: pin number + * rx: pin number + * tx_queue: number of messages in TX queue + * rx_queue: number of messages in RX queue + */ + ESP32CANManager(int8_t tx, int8_t rx, uint16_t tx_queue, uint16_t rx_queue, uint16_t frequency = DEFAULT_ESP32_CAN_FREQ); + + /* Handles data from received messages + * Intended to be implemented by class extension per board + * Called in runQueue() + */ + virtual void readHandler(CanFrame msg) = 0; + + /* Send a message over CAN + * + * id: CAN ID to use to identify the signal + * data: Payload array + * length: Size of data in bytes + * timeout: in milliseconds + * + * @return true if message sent successfully, false otherwise + */ + bool sendMessage(uint16_t id, void* data, uint8_t length, uint32_t timeout = 1); + + + /* Processes CAN (read) messages stored in messageQueue for a set duration. + * THIS IS THE FUNCTION TO CALL FOR PROCESSING CAN READ MESSAGES + * + * duration: time in milliseconds + */ + void runQueue(uint16_t duration); +}; + +#endif \ No newline at end of file From 8e38652a354b68d02dc8c4b836d56d6eec5dd4de Mon Sep 17 00:00:00 2001 From: Aditya YV Date: Sun, 27 Apr 2025 12:58:58 -0500 Subject: [PATCH 4/5] ADC drivers for esp32 --- adc_esp/adc_esp.cpp | 102 ++++++++++++++++++++++++++++++++++++++++++++ adc_esp/adc_esp.h | 65 ++++++++++++++++++++++++++++ 2 files changed, 167 insertions(+) create mode 100644 adc_esp/adc_esp.cpp create mode 100644 adc_esp/adc_esp.h diff --git a/adc_esp/adc_esp.cpp b/adc_esp/adc_esp.cpp new file mode 100644 index 0000000..fd0c61c --- /dev/null +++ b/adc_esp/adc_esp.cpp @@ -0,0 +1,102 @@ +#include "adc_esp.h" +#include + +// Calibration characteristics +static esp_adc_cal_characteristics_t adc_chars; + +esp_err_t esp32_adc_init(ESP32_ADC_Config* config) { + esp_err_t ret = ESP_OK; + + // Configure ADC unit + if (config->unit == ADC_UNIT_1) { + ret = adc1_config_width(config->width); + if (ret != ESP_OK) return ret; + } + + // Characterize ADC for calibration + esp_adc_cal_characterize(config->unit, config->attenuation, + config->width, config->vref, &adc_chars); + + return ESP_OK; +} + +esp_err_t esp32_adc_config_channel(adc_unit_t unit, adc_channel_t channel, adc_atten_t attenuation) { + if (unit == ADC_UNIT_1) { + return adc1_config_channel_atten((adc1_channel_t)channel, attenuation); + } else if (unit == ADC_UNIT_2) { + return adc2_config_channel_atten((adc2_channel_t)channel, attenuation); + } + return ESP_ERR_INVALID_ARG; +} + +int esp32_adc_read_voltage(adc_unit_t unit, adc_channel_t channel, ESP32_ADC_Config* config) { + int raw_value = esp32_adc_read_raw(unit, channel); + if (raw_value < 0) return -1; + + // Convert raw value to voltage + uint32_t voltage = esp_adc_cal_raw_to_voltage(raw_value, &adc_chars); + return voltage; +} + +int esp32_adc_read_raw(adc_unit_t unit, adc_channel_t channel) { + int raw_value; + + if (unit == ADC_UNIT_1) { + // Configure the channel attenuation if not already done + // This should ideally be done during initialization for each channel + adc1_channel_t adc1_channel = (adc1_channel_t)channel; + raw_value = adc1_get_raw(adc1_channel); + } else if (unit == ADC_UNIT_2) { + // ADC2 can't be used when Wi-Fi is active + esp_err_t ret = adc2_get_raw((adc2_channel_t)channel, ADC_WIDTH_BIT_12, &raw_value); + if (ret != ESP_OK) { + return -1; + } + } else { + return -1; // Invalid ADC unit + } + + return raw_value; +} + +float esp32_adc_normalize(int raw_value, ESP32_ADC_Config* config) { + if (raw_value < 0) return -1.0f; + + int max_value; + switch (config->width) { + case ADC_WIDTH_BIT_9: max_value = 511; break; + case ADC_WIDTH_BIT_10: max_value = 1023; break; + case ADC_WIDTH_BIT_11: max_value = 2047; break; + case ADC_WIDTH_BIT_12: max_value = 4095; break; + default: return -1.0f; + } + + return (float)raw_value / max_value; +} + +esp_err_t esp32_adc_gpio_to_channel(int gpio_pin, adc_unit_t* unit, adc_channel_t* channel) { + // Map GPIO pin to ADC channel + // ADC1 channels + if (gpio_pin == 36) { *unit = ADC_UNIT_1; *channel = (adc_channel_t)ADC1_CHANNEL_0; return ESP_OK; } + if (gpio_pin == 37) { *unit = ADC_UNIT_1; *channel = (adc_channel_t)ADC1_CHANNEL_1; return ESP_OK; } + if (gpio_pin == 38) { *unit = ADC_UNIT_1; *channel = (adc_channel_t)ADC1_CHANNEL_2; return ESP_OK; } + if (gpio_pin == 39) { *unit = ADC_UNIT_1; *channel = (adc_channel_t)ADC1_CHANNEL_3; return ESP_OK; } + if (gpio_pin == 32) { *unit = ADC_UNIT_1; *channel = (adc_channel_t)ADC1_CHANNEL_4; return ESP_OK; } + if (gpio_pin == 33) { *unit = ADC_UNIT_1; *channel = (adc_channel_t)ADC1_CHANNEL_5; return ESP_OK; } + if (gpio_pin == 34) { *unit = ADC_UNIT_1; *channel = (adc_channel_t)ADC1_CHANNEL_6; return ESP_OK; } + if (gpio_pin == 35) { *unit = ADC_UNIT_1; *channel = (adc_channel_t)ADC1_CHANNEL_7; return ESP_OK; } + + // ADC2 channels + if (gpio_pin == 4) { *unit = ADC_UNIT_2; *channel = (adc_channel_t)ADC2_CHANNEL_0; return ESP_OK; } + if (gpio_pin == 0) { *unit = ADC_UNIT_2; *channel = (adc_channel_t)ADC2_CHANNEL_1; return ESP_OK; } + if (gpio_pin == 2) { *unit = ADC_UNIT_2; *channel = (adc_channel_t)ADC2_CHANNEL_2; return ESP_OK; } + if (gpio_pin == 15) { *unit = ADC_UNIT_2; *channel = (adc_channel_t)ADC2_CHANNEL_3; return ESP_OK; } + if (gpio_pin == 13) { *unit = ADC_UNIT_2; *channel = (adc_channel_t)ADC2_CHANNEL_4; return ESP_OK; } + if (gpio_pin == 12) { *unit = ADC_UNIT_2; *channel = (adc_channel_t)ADC2_CHANNEL_5; return ESP_OK; } + if (gpio_pin == 14) { *unit = ADC_UNIT_2; *channel = (adc_channel_t)ADC2_CHANNEL_6; return ESP_OK; } + if (gpio_pin == 27) { *unit = ADC_UNIT_2; *channel = (adc_channel_t)ADC2_CHANNEL_7; return ESP_OK; } + if (gpio_pin == 25) { *unit = ADC_UNIT_2; *channel = (adc_channel_t)ADC2_CHANNEL_8; return ESP_OK; } + if (gpio_pin == 26) { *unit = ADC_UNIT_2; *channel = (adc_channel_t)ADC2_CHANNEL_9; return ESP_OK; } + + return ESP_ERR_NOT_FOUND; +} diff --git a/adc_esp/adc_esp.h b/adc_esp/adc_esp.h new file mode 100644 index 0000000..3aedc0d --- /dev/null +++ b/adc_esp/adc_esp.h @@ -0,0 +1,65 @@ +#ifndef ESP32_ADC_H +#define ESP32_ADC_H + +#include +#include + +// ADC configuration struct +typedef struct { + adc_unit_t unit; // ADC unit (ADC1 or ADC2) + adc_bits_width_t width; // ADC bit width (9-12 bits) + adc_atten_t attenuation; // ADC attenuation + uint32_t vref; // Reference voltage in mV (typically 1100mV) +} ESP32_ADC_Config; + +/** + * Initialize ADC with the given configuration + * @param config ADC configuration + * @return ESP_OK on success, error code otherwise + */ +esp_err_t esp32_adc_init(ESP32_ADC_Config* config); + +/** + * Configure a specific ADC channel with the given attenuation + * @param unit ADC unit (ADC1 or ADC2) + * @param channel ADC channel + * @param attenuation Attenuation level + * @return ESP_OK on success, error code otherwise + */ +esp_err_t esp32_adc_config_channel(adc_unit_t unit, adc_channel_t channel, adc_atten_t attenuation); + +/** + * Read ADC value from the specified channel + * @param unit ADC unit (ADC1 or ADC2) + * @param channel ADC channel + * @param config ADC configuration used for calibration + * @return Voltage in millivolts, or -1 on error + */ +int esp32_adc_read_voltage(adc_unit_t unit, adc_channel_t channel, ESP32_ADC_Config* config); + +/** + * Read raw ADC value from the specified channel + * @param unit ADC unit (ADC1 or ADC2) + * @param channel ADC channel + * @return Raw ADC value (0-4095 for 12-bit), or -1 on error + */ +int esp32_adc_read_raw(adc_unit_t unit, adc_channel_t channel); + +/** + * Convert raw ADC value to normalized float (0.0-1.0) + * @param raw_value Raw ADC value + * @param config ADC configuration for bit width + * @return Normalized value between 0.0 and 1.0 + */ +float esp32_adc_normalize(int raw_value, ESP32_ADC_Config* config); + +/** + * Get ADC channel for a GPIO pin + * @param gpio_pin GPIO pin number + * @param unit Pointer to store the ADC unit + * @param channel Pointer to store the ADC channel + * @return ESP_OK if mapping successful, error code otherwise + */ +esp_err_t esp32_adc_gpio_to_channel(int gpio_pin, adc_unit_t* unit, adc_channel_t* channel); + +#endif // ESP32_ADC_H \ No newline at end of file From 4b7614cf0f3893b5099064653ee070a82e69cdf2 Mon Sep 17 00:00:00 2001 From: Aditya YV Date: Sun, 27 Apr 2025 13:22:44 -0500 Subject: [PATCH 5/5] Undid ADC2 width hardcoding --- adc_esp/adc_esp.cpp | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/adc_esp/adc_esp.cpp b/adc_esp/adc_esp.cpp index fd0c61c..1e2ab48 100644 --- a/adc_esp/adc_esp.cpp +++ b/adc_esp/adc_esp.cpp @@ -4,6 +4,8 @@ // Calibration characteristics static esp_adc_cal_characteristics_t adc_chars; +adc_bits_width_t adc2_width = ADC_WIDTH_BIT_12; // Since ADC2 can't be configured directly, we set the width here + esp_err_t esp32_adc_init(ESP32_ADC_Config* config) { esp_err_t ret = ESP_OK; @@ -12,6 +14,11 @@ esp_err_t esp32_adc_init(ESP32_ADC_Config* config) { ret = adc1_config_width(config->width); if (ret != ESP_OK) return ret; } + else if (config->unit == ADC_UNIT_2) { + adc2_width = config->width; + } else { + return ESP_ERR_INVALID_ARG; + } // Characterize ADC for calibration esp_adc_cal_characterize(config->unit, config->attenuation, @@ -48,7 +55,7 @@ int esp32_adc_read_raw(adc_unit_t unit, adc_channel_t channel) { raw_value = adc1_get_raw(adc1_channel); } else if (unit == ADC_UNIT_2) { // ADC2 can't be used when Wi-Fi is active - esp_err_t ret = adc2_get_raw((adc2_channel_t)channel, ADC_WIDTH_BIT_12, &raw_value); + esp_err_t ret = adc2_get_raw((adc2_channel_t)channel, adc2_width, &raw_value); if (ret != ESP_OK) { return -1; }