Reputation: 35
I am working with a few ESP32-S3-DevKitC-1-N8 boards and have a simple program that reads analog data to the serial monitor using the two SAR ADCs (Program below). I am having a problem where the ADC channels are reading values between 50mV and 930mV when connected to nothing. As in no external circuit so the pins should be reading 0 volts. I thought it might be an issue with the board so I tried it with a few others and got the same outcome. My only other thought is that it is a problem with my program. I am coding in VSCode using the ESP-IDF 4.4 CMD to flash my code using the following commands:
idf.py set-target esp32s3
idf.py -p COM4 -b 480600 flash monitor
#include <stdio.h>
#include <driver/adc.h>
#include "sdkconfig.h"
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "esp_system.h"
#include "esp_spi_flash.h"
#include "esp_adc_cal.h"
void app_main(void)
{
printf("Hello world!\n");
/* ADC Configuration and Callibration Documentation: |
------------------------------------------------------
VRef of the ESP32-S3 is 1100 mV |
Right Channel: GPIO 4 ADC1 Channel 3 |
Left Channel: GPIO 11 ADC2 Channel 0 |
ADC Attenuation Options: |
ADC_ATTEN_DB_0 : 0 - 950 mV |
ADC_ATTEN_DB_2_5 : 0 - 1250 mV |
ADC_ATTEN_DB_6 : 0 - 1750 mV |
ADC_ATTEN_DB_11 : 0 - 3100 mV |
ADC Accuracy Options: |
ADC_WIDTH_9Bit |
ADC_WIDTH_10Bit |
ADC_WIDTH_11Bit |
ADC_WIDTH_12Bit |
ADC_WIDTH_BIT_DEFAULT (Max Bit Width) |
-----------------------------------------------------*/
// Configure desired precision and attenuation for ADC pins
adc1_config_width(ADC_WIDTH_BIT_DEFAULT);
adc1_config_channel_atten(ADC1_CHANNEL_0,ADC_ATTEN_DB_0);
adc2_config_channel_atten(ADC2_CHANNEL_3,ADC_ATTEN_DB_0);
// Create ADC channel characteristics structs for use in calibration functions
esp_adc_cal_characteristics_t adc1_chars;
esp_adc_cal_characteristics_t adc2_chars;
esp_adc_cal_characterize(ADC_UNIT_1,ADC_ATTEN_DB_0,ADC_WIDTH_BIT_DEFAULT,1100,&adc1_chars);
esp_adc_cal_characterize(ADC_UNIT_2,ADC_ATTEN_DB_0,ADC_WIDTH_BIT_DEFAULT,1100,&adc2_chars);
int val1;
int val2;
int counter = 0;
while(true){
val1 = adc1_get_raw(ADC1_CHANNEL_0);
adc2_get_raw(ADC2_CHANNEL_3,ADC_WIDTH_BIT_DEFAULT,&val2);
// printf("%d, %d\n",val1,val2);
int adc1_voltage = esp_adc_cal_raw_to_voltage(val1,&adc1_chars);
int adc2_voltage = esp_adc_cal_raw_to_voltage(val2,&adc2_chars);
printf("\n%d, %d",adc1_voltage,adc2_voltage);
vTaskDelay(10);
counter++;
}
}
Upvotes: 0
Views: 1141
Reputation: 521
The unconnected pin has no definitive voltage. It's high impedance, so any noise can change the voltage on this pin. This being said, your reading seems reasonable. Just connect the analogue output to your ADC input, and it should be fine. If you want to calibrate or just test the ADC, connect a potentiometer like this answer:
Then, you can have a reading in the ESP32 and compare it with a calibrated multimeter.
Bear in mind with ADC_ATTEN_DB_0, you can only measure up to 950mV. So, maybe add a current limiting resistor from Vcc to the potentiometer. If you use the ADC_ATTEN_DB_11, you can measure up to 3.1V. But still need that extra resistor to make sure it does not exceed the voltage or limit the current.
Also, the analogue input of the ESP32 is not very good. So you will need to calibrate it. There are hardware and software options to do so. Have a look through their documentation:
ESP32-S3 Analog to Digital Converter (ADC)
Upvotes: 0
Reputation: 126
Currently, your ADC pins are acting like antennae. This is expected behavior, as you don't have strong signal connected to pins; you are receiving just noise.
Upvotes: 0