From 8bd34ccfba2acccfb86b585c168c643b360a6baf Mon Sep 17 00:00:00 2001 From: Leo Foulds Date: Thu, 14 Nov 2024 18:55:07 +0000 Subject: [PATCH 1/7] HP relay Initial --- Cargo.lock | 7 +++++++ lib/control/Cargo.toml | 7 +++++++ lib/control/src/hp_relay.rs | 22 ++++++++++++++++++++++ lib/control/src/lib.rs | 3 +++ 4 files changed, 39 insertions(+) create mode 100644 lib/control/Cargo.toml create mode 100644 lib/control/src/hp_relay.rs create mode 100644 lib/control/src/lib.rs diff --git a/Cargo.lock b/Cargo.lock index d78c302a..0f95d882 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -281,6 +281,13 @@ dependencies = [ "serde_yml", ] +[[package]] +name = "hyped_control" +version = "0.1.0" +dependencies = [ + "hyped_io", +] + [[package]] name = "hyped_core" version = "0.1.0" diff --git a/lib/control/Cargo.toml b/lib/control/Cargo.toml new file mode 100644 index 00000000..20f33560 --- /dev/null +++ b/lib/control/Cargo.toml @@ -0,0 +1,7 @@ +[package] +name = "hyped_control" +version = "0.1.0" +edition = "2021" + +[dependencies] +hyped_io = { path = "../io" } \ No newline at end of file diff --git a/lib/control/src/hp_relay.rs b/lib/control/src/hp_relay.rs new file mode 100644 index 00000000..17519388 --- /dev/null +++ b/lib/control/src/hp_relay.rs @@ -0,0 +1,22 @@ +// need to take in a GPIO pin like Keyence does +// functions: switch_on, switch_off + +use hyped_io::gpio::HypedGpioPin; + +pub struct HighPowerRelay { + gpio: T, +}; + +impl HighPowerRelay { + pub fn new() { + todo!() + } + + pub fn switch_on(&mut self) { + todo!() + } + + pub fn switch_off(&mut self) { + todo!() + } +} diff --git a/lib/control/src/lib.rs b/lib/control/src/lib.rs new file mode 100644 index 00000000..3cffb21c --- /dev/null +++ b/lib/control/src/lib.rs @@ -0,0 +1,3 @@ +#![no_std] + +pub mod hp_relay; \ No newline at end of file From 77ec00e0a338e80c8ed51d117b22c92622dadab4 Mon Sep 17 00:00:00 2001 From: Leo Foulds Date: Thu, 21 Nov 2024 18:43:37 +0000 Subject: [PATCH 2/7] HP relay second draft --- lib/control/src/hp_relay.rs | 44 ++++++++++---------- lib/io/src/gpio.rs | 80 ++++++++++++++++++++++--------------- 2 files changed, 69 insertions(+), 55 deletions(-) diff --git a/lib/control/src/hp_relay.rs b/lib/control/src/hp_relay.rs index 17519388..bd9712ec 100644 --- a/lib/control/src/hp_relay.rs +++ b/lib/control/src/hp_relay.rs @@ -1,22 +1,22 @@ -// need to take in a GPIO pin like Keyence does -// functions: switch_on, switch_off - -use hyped_io::gpio::HypedGpioPin; - -pub struct HighPowerRelay { - gpio: T, -}; - -impl HighPowerRelay { - pub fn new() { - todo!() - } - - pub fn switch_on(&mut self) { - todo!() - } - - pub fn switch_off(&mut self) { - todo!() - } -} +// need to take in a GPIO pin like Keyence does +// functions: switch_on, switch_off + +use hyped_io::gpio::HypedGpioPin; + +pub struct HighPowerRelay { + gpio: T, +} + +impl HighPowerRelay { + pub fn new(gpio: T) -> HighPowerRelay { + HighPowerRelay { gpio } + } + + pub fn switch_on(&mut self) { + self.gpio.switch_on(); + } + + pub fn switch_off(&mut self) { + self.gpio.switch_off(); + } +} diff --git a/lib/io/src/gpio.rs b/lib/io/src/gpio.rs index 15e77079..3ee5f0bb 100644 --- a/lib/io/src/gpio.rs +++ b/lib/io/src/gpio.rs @@ -1,33 +1,47 @@ -/// Abstraction for a GPIO pin so that sensors can be tested with a mock GPIO pin -pub trait HypedGpioPin { - fn is_high(&mut self) -> bool; -} - -pub mod mock_gpio { - use heapless::Vec; - - /// A mock GPIO pin that can be used for testing - pub struct MockGpio { - current_value: bool, - next_values: Vec, - } - - impl crate::gpio::HypedGpioPin for MockGpio { - fn is_high(&mut self) -> bool { - let next_value = self.next_values.pop().unwrap_or(self.current_value); - self.current_value = next_value; - self.current_value - } - } - - impl MockGpio { - pub fn new(values: Vec) -> MockGpio { - let mut next_values = values.clone(); - next_values.reverse(); - MockGpio { - current_value: false, - next_values, - } - } - } -} +/// Abstraction for a GPIO pin so that sensors can be tested with a mock GPIO pin +pub trait HypedGpioPin { + fn is_high(&mut self) -> bool; + fn switch_on(&mut self) -> bool; + fn switch_off(&mut self) -> bool; +} + +pub mod mock_gpio { + use heapless::Vec; + + /// A mock GPIO pin that can be used for testing + pub struct MockGpio { + current_value: bool, + next_values: Vec, + } + + impl crate::gpio::HypedGpioPin for MockGpio { + fn is_high(&mut self) -> bool { + let next_value = self.next_values.pop().unwrap_or(self.current_value); + self.current_value = next_value; + self.current_value + } + + fn switch_on(&mut self) -> bool { + let next_value = self.next_values.pop().unwrap_or(self.current_value); + self.current_value = next_value; + self.current_value + } + + fn switch_off(&mut self) -> bool { + let next_value = self.next_values.pop().unwrap_or(self.current_value); + self.current_value = next_value; + self.current_value + } + } + + impl MockGpio { + pub fn new(values: Vec) -> MockGpio { + let mut next_values = values.clone(); + next_values.reverse(); + MockGpio { + current_value: false, + next_values, + } + } + } +} From b63cfb8f365ab399f4513c8581076f5385388f61 Mon Sep 17 00:00:00 2001 From: David Beechey Date: Tue, 21 Jan 2025 18:28:31 +0000 Subject: [PATCH 3/7] Update with new GPIO implementation --- boards/stm32l432kc/Cargo.lock | 5 +++-- lib/control/src/hp_relay.rs | 10 +++++----- 2 files changed, 8 insertions(+), 7 deletions(-) diff --git a/boards/stm32l432kc/Cargo.lock b/boards/stm32l432kc/Cargo.lock index b7bacccb..5cff0fcf 100644 --- a/boards/stm32l432kc/Cargo.lock +++ b/boards/stm32l432kc/Cargo.lock @@ -581,7 +581,7 @@ dependencies = [ ] [[package]] -name = "hyped_gpio_input" +name = "hyped_gpio" version = "0.1.0" dependencies = [ "heapless", @@ -599,10 +599,11 @@ dependencies = [ name = "hyped_sensors" version = "0.1.0" dependencies = [ + "defmt", "embassy-sync 0.6.0", "heapless", "hyped_core", - "hyped_gpio_input", + "hyped_gpio", "hyped_i2c", ] diff --git a/lib/control/src/hp_relay.rs b/lib/control/src/hp_relay.rs index bd9712ec..ccba38c8 100644 --- a/lib/control/src/hp_relay.rs +++ b/lib/control/src/hp_relay.rs @@ -1,22 +1,22 @@ // need to take in a GPIO pin like Keyence does // functions: switch_on, switch_off -use hyped_io::gpio::HypedGpioPin; +use hyped_gpio::HypedGpioOutputPin; -pub struct HighPowerRelay { +pub struct HighPowerRelay { gpio: T, } -impl HighPowerRelay { +impl HighPowerRelay { pub fn new(gpio: T) -> HighPowerRelay { HighPowerRelay { gpio } } pub fn switch_on(&mut self) { - self.gpio.switch_on(); + self.gpio.set_high(); } pub fn switch_off(&mut self) { - self.gpio.switch_off(); + self.gpio.set_low(); } } From 34f87033a519c7977d615764c456a3a49e99f96c Mon Sep 17 00:00:00 2001 From: David Beechey Date: Tue, 21 Jan 2025 18:30:21 +0000 Subject: [PATCH 4/7] Add documentation --- lib/control/src/hp_relay.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/lib/control/src/hp_relay.rs b/lib/control/src/hp_relay.rs index ccba38c8..17fc3cc5 100644 --- a/lib/control/src/hp_relay.rs +++ b/lib/control/src/hp_relay.rs @@ -1,8 +1,6 @@ -// need to take in a GPIO pin like Keyence does -// functions: switch_on, switch_off - use hyped_gpio::HypedGpioOutputPin; +/// Controls the high power relay by switching it on and off using a GPIO pin. pub struct HighPowerRelay { gpio: T, } @@ -12,10 +10,12 @@ impl HighPowerRelay { HighPowerRelay { gpio } } + /// Switches the relay on by setting the GPIO pin high. pub fn switch_on(&mut self) { self.gpio.set_high(); } + /// Switches the relay off by setting the GPIO pin low. pub fn switch_off(&mut self) { self.gpio.set_low(); } From 8a43b23f3b85fe21166e1f962c41c43898ab4d7a Mon Sep 17 00:00:00 2001 From: David Beechey Date: Tue, 21 Jan 2025 18:31:06 +0000 Subject: [PATCH 5/7] CLRF --- lib/control/src/hp_relay.rs | 44 ++++++++++++++++++------------------- 1 file changed, 22 insertions(+), 22 deletions(-) diff --git a/lib/control/src/hp_relay.rs b/lib/control/src/hp_relay.rs index 17fc3cc5..2768ecfd 100644 --- a/lib/control/src/hp_relay.rs +++ b/lib/control/src/hp_relay.rs @@ -1,22 +1,22 @@ -use hyped_gpio::HypedGpioOutputPin; - -/// Controls the high power relay by switching it on and off using a GPIO pin. -pub struct HighPowerRelay { - gpio: T, -} - -impl HighPowerRelay { - pub fn new(gpio: T) -> HighPowerRelay { - HighPowerRelay { gpio } - } - - /// Switches the relay on by setting the GPIO pin high. - pub fn switch_on(&mut self) { - self.gpio.set_high(); - } - - /// Switches the relay off by setting the GPIO pin low. - pub fn switch_off(&mut self) { - self.gpio.set_low(); - } -} +use hyped_gpio::HypedGpioOutputPin; + +/// Controls the high power relay by switching it on and off using a GPIO pin. +pub struct HighPowerRelay { + gpio: T, +} + +impl HighPowerRelay { + pub fn new(gpio: T) -> HighPowerRelay { + HighPowerRelay { gpio } + } + + /// Switches the relay on by setting the GPIO pin high. + pub fn switch_on(&mut self) { + self.gpio.set_high(); + } + + /// Switches the relay off by setting the GPIO pin low. + pub fn switch_off(&mut self) { + self.gpio.set_low(); + } +} From 88c396cfde8ea01b8a94431c88cfc34d9e96abd2 Mon Sep 17 00:00:00 2001 From: David Beechey Date: Tue, 21 Jan 2025 18:32:18 +0000 Subject: [PATCH 6/7] clippy --- lib/core/src/mqtt.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/core/src/mqtt.rs b/lib/core/src/mqtt.rs index 0ddb6e7d..2ac1924b 100644 --- a/lib/core/src/mqtt.rs +++ b/lib/core/src/mqtt.rs @@ -57,8 +57,8 @@ pub fn initialise_mqtt_config(client_id: &str) -> ClientConfig<'_, 5, CountingRn } // Implement send_message for HypedMqttClient -impl<'a, T: embedded_io_async::Read + embedded_io_async::Write, R: rand_core::RngCore> - HypedMqttClient<'a, T, R> +impl + HypedMqttClient<'_, T, R> { pub async fn connect_to_broker(&mut self) { match self.client.connect_to_broker().await { From 268f4eb8da28098c5ecece3d8245cb527740c0f0 Mon Sep 17 00:00:00 2001 From: David Beechey Date: Thu, 23 Jan 2025 20:45:37 +0000 Subject: [PATCH 7/7] basic tests, GPIO deals in `DigitalSignal` not `bool` --- Cargo.lock | 1 + lib/control/src/hp_relay.rs | 31 +++++++++++++++++++++++++++---- lib/core/src/types.rs | 11 ++++++++++- lib/io/hyped_gpio/Cargo.toml | 4 +++- lib/io/hyped_gpio/src/lib.rs | 23 ++++++++++++----------- lib/sensors/src/keyence.rs | 17 ++++++++++++----- 6 files changed, 65 insertions(+), 22 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 31a14458..cbe581bb 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -337,6 +337,7 @@ name = "hyped_gpio" version = "0.1.0" dependencies = [ "heapless", + "hyped_core", ] [[package]] diff --git a/lib/control/src/hp_relay.rs b/lib/control/src/hp_relay.rs index 2768ecfd..12cddb58 100644 --- a/lib/control/src/hp_relay.rs +++ b/lib/control/src/hp_relay.rs @@ -1,12 +1,12 @@ use hyped_gpio::HypedGpioOutputPin; /// Controls the high power relay by switching it on and off using a GPIO pin. -pub struct HighPowerRelay { - gpio: T, +pub struct HighPowerRelay<'a, T: HypedGpioOutputPin> { + gpio: &'a mut T, } -impl HighPowerRelay { - pub fn new(gpio: T) -> HighPowerRelay { +impl<'a, T: HypedGpioOutputPin> HighPowerRelay<'a, T> { + pub fn new(gpio: &'a mut T) -> HighPowerRelay<'a, T> { HighPowerRelay { gpio } } @@ -20,3 +20,26 @@ impl HighPowerRelay { self.gpio.set_low(); } } + +#[cfg(test)] +mod tests { + use super::HighPowerRelay; + use hyped_core::types::DigitalSignal; + use hyped_gpio::mock_gpio::MockGpioOutputPin; + + #[test] + fn test_switch_on() { + let mut mock_gpio_output_pin = MockGpioOutputPin::default(); + let mut relay = HighPowerRelay::new(&mut mock_gpio_output_pin); + relay.switch_on(); + assert_eq!(mock_gpio_output_pin.get_value(), DigitalSignal::High); + } + + #[test] + fn test_switch_off() { + let mut mock_gpio_output_pin = MockGpioOutputPin::default(); + let mut relay = HighPowerRelay::new(&mut mock_gpio_output_pin); + relay.switch_off(); + assert_eq!(mock_gpio_output_pin.get_value(), DigitalSignal::Low); + } +} diff --git a/lib/core/src/types.rs b/lib/core/src/types.rs index ea7e87c1..4cc8f685 100644 --- a/lib/core/src/types.rs +++ b/lib/core/src/types.rs @@ -1,4 +1,4 @@ -#[derive(PartialEq, Debug)] +#[derive(PartialEq, Debug, Clone, Copy)] pub enum DigitalSignal { High, Low, @@ -14,6 +14,15 @@ impl DigitalSignal { } } +impl From for bool { + fn from(signal: DigitalSignal) -> bool { + match signal { + DigitalSignal::High => true, + DigitalSignal::Low => false, + } + } +} + #[cfg(test)] mod tests { use super::*; diff --git a/lib/io/hyped_gpio/Cargo.toml b/lib/io/hyped_gpio/Cargo.toml index 03e6ceb5..1c1e0dbd 100644 --- a/lib/io/hyped_gpio/Cargo.toml +++ b/lib/io/hyped_gpio/Cargo.toml @@ -4,4 +4,6 @@ version = "0.1.0" edition = "2021" [dependencies] -heapless = "0.8.0" \ No newline at end of file +heapless = "0.8.0" + +hyped_core = { path = "../../core" } \ No newline at end of file diff --git a/lib/io/hyped_gpio/src/lib.rs b/lib/io/hyped_gpio/src/lib.rs index 9d950462..de3db304 100644 --- a/lib/io/hyped_gpio/src/lib.rs +++ b/lib/io/hyped_gpio/src/lib.rs @@ -13,27 +13,28 @@ pub trait HypedGpioOutputPin { pub mod mock_gpio { use heapless::Vec; + use hyped_core::types::DigitalSignal; /// A mock GPIO input pin that can be used for testing pub struct MockGpioInput { - current_value: bool, - next_values: Vec, + current_value: DigitalSignal, + next_values: Vec, } impl crate::HypedGpioInputPin for MockGpioInput { fn is_high(&mut self) -> bool { let next_value = self.next_values.pop().unwrap_or(self.current_value); self.current_value = next_value; - self.current_value + self.current_value.into() } } impl MockGpioInput { - pub fn new(values: Vec) -> MockGpioInput { + pub fn new(values: Vec) -> MockGpioInput { let mut next_values = values.clone(); next_values.reverse(); MockGpioInput { - current_value: false, + current_value: DigitalSignal::Low, next_values, } } @@ -41,16 +42,16 @@ pub mod mock_gpio { /// A mock GPIO output pin that can be used for testing pub struct MockGpioOutputPin { - pub current_value: bool, + pub current_value: DigitalSignal, } impl crate::HypedGpioOutputPin for MockGpioOutputPin { fn set_high(&mut self) { - self.current_value = true; + self.current_value = DigitalSignal::High; } fn set_low(&mut self) { - self.current_value = false; + self.current_value = DigitalSignal::Low; } } @@ -63,17 +64,17 @@ pub mod mock_gpio { impl MockGpioOutputPin { pub fn new() -> MockGpioOutputPin { MockGpioOutputPin { - current_value: false, + current_value: DigitalSignal::Low, } } - pub fn new_with_value(value: bool) -> MockGpioOutputPin { + pub fn new_with_value(value: DigitalSignal) -> MockGpioOutputPin { MockGpioOutputPin { current_value: value, } } - pub fn get_value(&self) -> bool { + pub fn get_value(&self) -> DigitalSignal { self.current_value } } diff --git a/lib/sensors/src/keyence.rs b/lib/sensors/src/keyence.rs index 475f01fc..603f4022 100644 --- a/lib/sensors/src/keyence.rs +++ b/lib/sensors/src/keyence.rs @@ -46,14 +46,16 @@ mod tests { #[test] fn test_keyence_new() { - let gpio = MockGpioInput::new(Vec::from_slice(&[false]).unwrap()); + let gpio = MockGpioInput::new(Vec::from_slice(&[DigitalSignal::Low]).unwrap()); let keyence = Keyence::new(gpio); assert_eq!(keyence.get_stripe_count(), 0); } #[test] fn test_keyence_update_stripe_count_low_to_high() { - let gpio = MockGpioInput::new(Vec::from_slice(&[false, true]).unwrap()); + let gpio = MockGpioInput::new( + Vec::from_slice(&[DigitalSignal::Low, DigitalSignal::High]).unwrap(), + ); let mut keyence = Keyence::new(gpio); keyence.update_stripe_count(); @@ -64,7 +66,9 @@ mod tests { #[test] fn test_keyence_update_stripe_count_high_to_low() { - let gpio = MockGpioInput::new(Vec::from_slice(&[true, false]).unwrap()); + let gpio = MockGpioInput::new( + Vec::from_slice(&[DigitalSignal::High, DigitalSignal::Low]).unwrap(), + ); let mut keyence = Keyence::new(gpio); keyence.update_stripe_count(); @@ -75,7 +79,9 @@ mod tests { #[test] fn test_keyence_update_stripe_count_high_to_high() { - let gpio = MockGpioInput::new(Vec::from_slice(&[true, true]).unwrap()); + let gpio = MockGpioInput::new( + Vec::from_slice(&[DigitalSignal::High, DigitalSignal::High]).unwrap(), + ); let mut keyence = Keyence::new(gpio); keyence.update_stripe_count(); @@ -86,7 +92,8 @@ mod tests { #[test] fn test_keyence_update_stripe_count_low_to_low() { - let gpio = MockGpioInput::new(Vec::from_slice(&[false, false]).unwrap()); + let gpio = + MockGpioInput::new(Vec::from_slice(&[DigitalSignal::Low, DigitalSignal::Low]).unwrap()); let mut keyence = Keyence::new(gpio); keyence.update_stripe_count();