I'm working on building a few chemical dispensers on some ESP32-C6 devices. Each device has a different configuration (different number of pumps, with different chemicals, dispense rates, etc). However I want to be able to reuse the code for each so that the only thing that differs is an array of config structs.
For example:
struct DispenserConfig {
name: &'static str,
ratio: f32,
pump_pin: u8,
}
static DISPENSER_CONFIGS: [DispenserConfig; 2] = [
DispenserConfig {
name: "citric acid",
ratio: 0.1,
pump_pin: 22,
},
DispenserConfig {
name: "chlorine",
ratio: 0.05
pump_pin: 23,
}
]
Where I'd like to then iterate through DISPENSER_CONFIGS
to get everything going.
The problem is that ESP stores each pin as a separate field on a Pins
struct.
Plus ESP uses a generic for each pin, rather than a single type which stores the pin as struct field, but that can be solved by using degrade()
to convert to an AnyPin
type.
I thought about trying to just build a mapping of all possible pin integers, such as:
for dispenser_config in DISPENSER_CONFIGS.iter() {
let pump_pin = match dispenser_config.pump_pin {
22 => io.pins.gpio22.into_push_pull_output().degrade(),
23 => io.pins.gpio23.into_push_pull_output().degrade(),
_ => panic!("invalid pin"),
}
...
}
However this errors because of:
error[E0382]: use of moved value: `io.pins.gpio22`
--> src/main.rs:190:19
|
190 | 22 => io.pins.gpio22.into_push_pull_output().degrade(),
| ^^^^^^^^^^^^^^ ----------------------- `io.pins.gpio22` moved due to this method call, in previous iteration of loop
|
note: `GpioPin::<MODE, GPIONUM>::into_push_pull_output` takes ownership of the receiver `self`, which moves `io.pins.gpio22`
--> /home/phemmer/.cargo/registry/src/index.crates.io-6f17d22bba15001f/esp-hal-0.16.1/src/gpio.rs:1170:34
|
1170 | pub fn into_push_pull_output(self) -> GpioPin<Output<PushPull>, GPIONUM> {
| ^^^^
= note: move occurs because `io.pins.gpio22` has type `GpioPin<esp_hal::gpio::Unknown, 22>`, which does not implement the `Copy` trait
I'm guessing this is because even though I know that no 2 dispenser configs will reuse the same pin, rust doesn't.
Is there any way I can get this working?