Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[ESP32] Inverted ADC Values #1077

Closed
hansingt opened this issue Jan 12, 2024 · 1 comment · Fixed by #1093
Closed

[ESP32] Inverted ADC Values #1077

hansingt opened this issue Jan 12, 2024 · 1 comment · Fixed by #1093
Assignees
Labels
bug Something isn't working peripheral:adc ADC peripheral

Comments

@hansingt
Copy link
Contributor

Hi, I receive unexpected ADC readings from my ESP32-Wrover-E (ESP32-D0WDQ5 revision 3.1) when using the following code:

#![no_std]
#![no_main]

use esp_backtrace as _;
use esp_println::println;
use hal::{
    adc::{Attenuation, ADC, AdcConfig},
    analog::AnalogExt,
    clock::ClockControl,
    peripherals::Peripherals,
    prelude::*,
    system::SystemExt,
    Delay, IO,
};

#[entry]
fn main() -> ! {
    let peripherals = Peripherals::take();
    let system = peripherals.SYSTEM.split();
    let io = IO::new(peripherals.GPIO, peripherals.IO_MUX);
    let analog = peripherals.SENS.split();

    // Configure the system clock
    let clocks = ClockControl::max(system.clock_control).freeze();

    // Configure the ADC
    let mut adc_config = AdcConfig::default();
    let mut adc_pin =
        adc_config.enable_pin(io.pins.gpio25.into_analog(), Attenuation::Attenuation11dB);
    let mut adc = ADC::adc(analog.adc2, adc_config.into()).unwrap();

    let mut delay = Delay::new(&clocks);
    loop {
        let sample = nb::block!(adc.read(&mut adc_pin)).unwrap();
        println!("ADC Value: {sample}");
        delay.delay_ms(200u32);
    }
}

For me, this results in inverted values for the ADC, e.g. 0V being 4095 and 3.3V being 0. Is this expected? I couldn't find any notice in the reference manual. But I found an issue about this in the official esp-idf repo: espressif/esp-idf#4557 this says, that the data inversion bit should be set and that it will be added to the IDF framework on next release.

Doing this, fixes the issue for me. Maybe, this is missing in ADC initialization code for the ESP32?

    peripherals
        .SENS
        .sar_read_ctrl2()
        .modify(|_, w| w.sar2_data_inv().set_bit());

Btw: This happens on both ADCs and on every channel.

@jessebraham jessebraham added bug Something isn't working peripheral:adc ADC peripheral labels Jan 16, 2024
@jessebraham
Copy link
Member

Thanks for the issue. I'm currently working on some refactoring of the analog module anyway, so I will try to get this fixed while I'm at it.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working peripheral:adc ADC peripheral
Projects
Archived in project
Development

Successfully merging a pull request may close this issue.

2 participants