avr-hal icon indicating copy to clipboard operation
avr-hal copied to clipboard

ADC cannot read from a Pin<Analog> object.

Open bbonenfant opened this issue 5 years ago • 7 comments

Hello, this is a great project. When trying to perform the Adc.read method on a Pin<Analog> object, I receive the following error:

the trait bound `arduino_uno::atmega328p_hal::port::Pin<arduino_uno::atmega328p_hal::port::mode::Analog>: embedded_hal::adc::Channel<arduino_uno::adc::Adc>` is not satisfied
required because of the requirements on the impl of `arduino_uno::prelude::_embedded_hal_adc_OneShot<arduino_uno::adc::Adc, _, arduino_uno::atmega328p_hal::port::Pin<arduino_uno::atmega328p_hal::port::mode::Analog>>` for `arduino_uno::adc::Adc` rustc(E0277)

which cleaned up for you benefit becomes:

the trait bound `Pin<Analog>: Channel<Adc>` is not satisfied
required because of the requirements on the impl of `OneShot<Adc, _, Pin<Analog>>` for `Adc` rustc(E0277)

I believe that this just means that the downgraded/generic Pin<Analog> object needs this OneShot trait implemented? It's a little hard to figure out what is and isn't implemented with all of the procedural macros.


Here is a minimal reproducible example:

#![no_std]
#![no_main]
extern crate panic_halt;
use arduino_uno::prelude::*;
use nb;

#[arduino_uno::entry]
fn main() -> ! {
    let peripherals = arduino_uno::Peripherals::take().unwrap();
    let mut pins = arduino_uno::Pins::new(
        peripherals.PORTB, peripherals.PORTC, peripherals.PORTD
    );

    let mut adc = arduino_uno::adc::Adc::new(
        peripherals.ADC, arduino_uno::adc::AdcSettings::default()
    );
    let analog_pin = pins.a0.into_analog_input(&mut adc).downgrade();
    let val: u16 = nb::block!(adc.read(&mut analog_pin)).void_unwrap();
    loop {}
}

bbonenfant avatar Aug 03 '20 22:08 bbonenfant

From what I can tell, this is not possible to implement due to limitations in embedded-hal. The OneShot trait itself would be easy enough (just delegate to the correct port variant), but OneShot has a bound on Channel, which isn't implementable for the generic Pin, see: https://github.com/rust-embedded/embedded-hal/issues/110. It looks like there was buy-in a year and a half ago to change that API, but there's been no movement since then.

couchand avatar Aug 04 '20 14:08 couchand

Correction: there has been movement in the API, but not in a direction that supports this usage. Ahead of an imminent 1.0 release, the channel() associated function has been removed entirely in favor of an associated constant.

couchand avatar Aug 04 '20 14:08 couchand

We will address this issue when https://github.com/rust-embedded/embedded-hal/pull/242 is merged and this project migrates to embedded-hal version 1.0.0.

Rahix avatar Aug 05 '20 16:08 Rahix

On the next branch we now have a "solution" to this. Check the mega2560-adc example: https://github.com/Rahix/avr-hal/blob/next/examples/arduino-mega2560/src/bin/mega2560-adc.rs

Rahix avatar Mar 15 '21 12:03 Rahix

Is there any workaround for this until the next branch stabilizes?

davystrong avatar Jun 06 '21 22:06 davystrong

@davystrong: I would consider the next branch just as stable (or unstable) as master at this point. So if you need this right now, I would suggest just switching to the next branch already. But of course you'll need to refactor your code quite a bit to work with the new design.

Rahix avatar Jun 09 '21 17:06 Rahix

Ok, thanks, I'll try that.

davystrong avatar Jun 09 '21 17:06 davystrong