-
Hi! Trying to figure out how to read a 10k ohm potentiometer value using an interrupt. My Arduino Uno connections are: The idea is to use an ADC function should handle an interrupt when conversion is complete according to docs. Then should I read the value from the register instead of doing an The code I'm trying for that is: #![no_std]
#![no_main]
#![feature(abi_avr_interrupt)]
use panic_halt as _;
use core::sync::atomic::{AtomicBool, Ordering};
use arduino_hal::prelude::*;
use arduino_hal::adc;
static READ_POT: AtomicBool = AtomicBool::new(false);
#[avr_device::interrupt(atmega328p)]
#[allow(non_snake_case)]
fn ADC() {
READ_POT.store(true, Ordering::SeqCst);
}
fn read_pot() -> bool {
READ_POT.load(Ordering::SeqCst)
}
#[arduino_hal::entry]
fn main() -> ! {
let dp = arduino_hal::Peripherals::take().unwrap();
let pins = arduino_hal::pins!(dp);
let mut serial = arduino_hal::default_serial!(dp, pins, 57600);
dp.ADC.adcsra.write(|w| w.adie().set_bit());
let mut adc = arduino_hal::Adc::new(dp.ADC, Default::default());
let (vbg, gnd, temp) = (
adc.read_blocking(&adc::channel::Vbg),
adc.read_blocking(&adc::channel::Gnd),
adc.read_blocking(&adc::channel::Temperature),
);
ufmt::uwriteln!(&mut serial, "Vbandgap: {}", vbg).unwrap_infallible();
ufmt::uwriteln!(&mut serial, "Ground: {}", gnd).unwrap_infallible();
ufmt::uwriteln!(&mut serial, "Temperature: {}", temp).unwrap_infallible();
let analog_pin = pins.a0.into_analog_input(&mut adc);
unsafe {
avr_device::interrupt::enable();
}
loop {
if read_pot() {
let value = analog_pin.analog_read(&mut adc);
ufmt::uwriteln!(&mut serial, "Analog input 0 value: {}", value).unwrap_infallible();
READ_POT.store(false, Ordering::SeqCst);
}
}
} When I run this code, I can see voltage band gap, ground and temperature values printed. Which means ADC works. But I can't see any When I poll the What am I missing here? Thanks. |
Beta Was this translation helpful? Give feedback.
Replies: 1 comment
-
The problem is that the interrupt enable flag you set here dp.ADC.adcsra.write(|w| w.adie().set_bit());
let mut adc = arduino_hal::Adc::new(dp.ADC, Default::default()); is overwritten again by avr-hal/mcu/atmega-hal/src/adc.rs Lines 59 to 70 in c33114a Ideally, we should expose an As a workaround, you can set the flag again after initialization using unsafe {
(*arduino_hal::pac::ADC::ptr()).adcsra.modify(|_, w| w.adie().set_bit());
} This will break if you call |
Beta Was this translation helpful? Give feedback.
The problem is that the interrupt enable flag you set here
is overwritten again by
Adc::new()
:avr-hal/mcu/atmega-hal/src/adc.rs
Lines 59 to 70 in c33114a