Open the examples
file, create a relays.rs
file, and copy the last iteration of the project code. Clear the critical section
inside the loop
section.
You may also delete the wfi
instruction.
We want to pan the PTZ kit through clockwise (CW) and counterclockwise (CCW) swathes alternatively.
The Relay table from the previous part shows that to pan CW we need to enable Relay 1 while 2 is disabled.
Table of contents
- Requirements
-
Implementation
- Connections
- Pan
- Results
Requirements
- 1 x Raspberry Pico board
- 1 x USB Cable type 2.0
- 1 x HC-05 Bluetooth module
- 18 x M-M Jumper Wires
- 2 x Mini Breadboards
- 2 x SG90 Servo Motor
- 1 x PTZ Kit
- 2 x Relay Modules
Implementation
Connections
The servos are here fitted into the PTZ kit.
Pan
For CW movement Relay 1 is enabled while 2 is disabled.
// Move servo CW: Relay 1 ON, Relay 2 OFF
sio.gpio_out.modify(|r, w| unsafe { w.bits(r.gpio_out().bits() | 1 << 16)});// Set pin 16 high
sio.gpio_out().modify(|r, w| unsafe { w.bits(r.gpio_out().bits() & !(1 << 17))});// Set pin 17 low
For CCW movement Relay 1 is disabled while 2 is enabled.
// Move servo CCW: Relay 2 ON, Relay 1 OFF
sio.gpio_out().modify(|r, w| unsafe { w.bits(r.gpio_out().bits() | 1 << 17)});// Set pin 17 high
sio.gpio_out().modify(|r, w| unsafe { w.bits(r.gpio_out().bits() & !(1 << 16))});// Set pin 16 low
The above can be combined into a single pan function like so:
fn pan(delay: &mut Delay, sio: &mut SIO, direction: Direction) {
match direction {
Direction::Cw => {
// Move servo CW: Relay 1 ON, Relay 2 OFF
sio.gpio_out().modify(|r, w| unsafe { w.bits(r.gpio_out().bits() | 1 << 16)});// Set pin 16 high
delay.delay_ms(10);// delay
// Put servo OFF
sio.gpio_out().modify(|r, w| unsafe { w.bits(r.gpio_out().bits() & !(1 << 16))});// Set pin 16 low
sio.gpio_out().modify(|r, w| unsafe { w.bits(r.gpio_out().bits() & !(1 << 17))});// Set pin 17 low
},
Direction::Ccw => {
// Move servo CCW: Relay 2 ON, Relay 1 OFF
sio.gpio_out().modify(|r, w| unsafe { w.bits(r.gpio_out().bits() | 1 << 17)});// Set pin 17 high
delay.delay_ms(10);// delay
// Put servo OFF
sio.gpio_out().modify(|r, w| unsafe { w.bits(r.gpio_out().bits() & !(1 << 16))});// Set pin 16 low
sio.gpio_out().modify(|r, w| unsafe { w.bits(r.gpio_out().bits() & !(1 << 17))});// Set pin 17 low
},
_ => {},
}
}
The pan
function moves the servo either CW or CCW depending on the selected direction for 10 milliseconds. Add it into our code.
Since we’ll be using SIO
to un/set the relay control pins we need to operate inside a critical section as the application loop
shares it with the interrupts.
Add the following into the loop
section:
cortex_m::interrupt::free(|cs| {
let mut sio = SIO.borrow(cs).borrow_mut();
for i in 0..=100 {
pan(&mut delay, sio.as_mut().unwrap(), Direction::Cw);
if i == 100 {
for _ in (0..=100).rev() {
pan(&mut delay, sio.as_mut().unwrap(), Direction::Ccw);
}
}
}
delay.delay_ms(500);
});
❗ Comment out the
configure_compass
function call at the set up area.
Results
We end up with this final copy of our code.
Running the code in the Pico should pan the servo clockwise and counterclockwise.
You may note again that the indication LED blinks at well after 1 second. This is caused by the
Delay
function we’ve introduced which blocks interrupts.
In the next part we apply these added functions to the main project program