DEV Community

Cover image for Self-Aligning Satellite Dish in Rust: Pan Example
Ian Ndeda
Ian Ndeda

Posted on

Self-Aligning Satellite Dish in Rust: Pan Example

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

  • 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

relays-example-setup

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
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

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
        },
        _ => {},
    }
}
Enter fullscreen mode Exit fullscreen mode

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);
});
Enter fullscreen mode Exit fullscreen mode

❗ 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.

relays-app-results

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

Top comments (0)