using iterator for scanning

This commit is contained in:
2025-07-18 20:31:23 +01:00
parent 0bfbec7ecd
commit 7b76a183f1

View File

@@ -2,10 +2,17 @@
#![no_main] #![no_main]
use arduino_hal::{ use arduino_hal::{
adc::channel::{ADC6, ADC7}, adc::{
hal::port::{ channel::{ADC6, ADC7},
PB0, PB1, PB2, PB3, PB4, PC0, PC1, PC2, PC3, PC4, PC5, PD2, PD3, PD4, PD5, PD6, PD7, AdcChannel,
}, },
hal::{
port::{
PB0, PB1, PB2, PB3, PB4, PC0, PC1, PC2, PC3, PC4, PC5, PD2, PD3, PD4, PD5, PD6, PD7,
},
Atmega,
},
pac::ADC,
port::{mode::Output, Pin}, port::{mode::Output, Pin},
prelude::*, prelude::*,
Adc, Adc,
@@ -118,6 +125,20 @@ impl SegmentPins {
} }
} }
struct IOSelect<'p> {
display_no: usize,
pin: &'p mut Pin<Output>,
}
impl IOSelect<'_> {
fn set_on(&mut self) {
self.pin.set_high()
}
fn set_off(&mut self) {
self.pin.set_low()
}
}
struct IOPins([Pin<Output>; 9]); struct IOPins([Pin<Output>; 9]);
impl IOPins { impl IOPins {
@@ -145,23 +166,11 @@ impl IOPins {
]) ])
} }
fn scan_output(&mut self, mut segment: impl FnMut(usize) -> ()) { fn iter_mut(&mut self) -> impl Iterator<Item = IOSelect> {
for (no, d) in self.0.iter_mut().enumerate() { self.0
segment(no); .iter_mut()
d.set_high(); .enumerate()
arduino_hal::delay_ms(1); .map(|(display_no, pin)| IOSelect { display_no, pin })
d.set_low();
}
}
fn scan_input(&mut self, mut segment: impl FnMut(usize) -> ()) {
for (no, d) in self.0.iter_mut().enumerate() {
d.set_high();
arduino_hal::delay_ms(1);
segment(no);
arduino_hal::delay_ms(1);
d.set_low();
}
} }
} }
@@ -276,35 +285,24 @@ impl Default for DispalyState {
} }
} }
impl DispalyState {
fn scan(&self, dp: &mut IOPins, seg: &mut SegmentPins) {
dp.scan_output(|no| {
self.0[no].apply(seg);
});
seg.set_off();
}
}
struct Input<KN, KO> { struct Input<KN, KO> {
kn: KN, kn: KN,
ko: KO, ko: KO,
} }
impl<KN, KO> Input<KN, KO> { impl<KN: AdcChannel<Atmega, ADC>, KO: AdcChannel<Atmega, ADC>> Input<KN, KO> {
fn new(kn: KN, ko: KO) -> Input<KN, KO> { fn new(kn: KN, ko: KO) -> Input<KN, KO> {
Input { kn, ko } Input { kn, ko }
} }
fn scan(&self, io: &mut IOPins, adc: &mut Adc) -> Option<(usize, u16, u16)> { fn read(&self, adc: &mut Adc) -> Option<(u16, u16)> {
let mut out = None; let kn = adc.read_blocking(&self.kn);
io.scan_input(|no| { let ko = adc.read_blocking(&self.ko);
let kn = adc.read_blocking(&ADC7); if kn > 500 || ko > 500 {
let ko = adc.read_blocking(&ADC6); Some((kn, ko))
if kn > 500 || ko > 500 { } else {
out = Some((no, kn, ko)); None
} }
});
out
} }
} }
@@ -359,9 +357,22 @@ fn main() -> ! {
display.0[8] = SegmentState::Num(8, false); display.0[8] = SegmentState::Num(8, false);
loop { loop {
display.scan(&mut io, &mut seg); let mut key: Option<(usize, u16, u16)> = None;
arduino_hal::delay_ms(10); for (mut io_select, ss) in io.iter_mut().zip(display.0.iter()) {
if let Some((no, kn, ko)) = input.scan(&mut io, &mut adc) { ss.apply(&mut seg);
io_select.set_on();
arduino_hal::delay_ms(1);
io_select.set_off();
seg.set_off();
io_select.set_on();
arduino_hal::delay_ms(1);
if let Some((kn, ko)) = input.read(&mut adc) {
key = Some((io_select.display_no, kn, ko))
}
io_select.set_off();
}
if let Some((no, kn, ko)) = key {
ufmt::uwriteln!(&mut serial, "no: {} kn: {} ko: {}", no, kn, ko).unwrap_infallible(); ufmt::uwriteln!(&mut serial, "no: {} kn: {} ko: {}", no, kn, ko).unwrap_infallible();
} }
} }