DEV Community

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

Posted on

Self-Aligning Satellite Dish in Rust: Servo Example

In this part, we'll use the configured PWM from the previous part to sweep a servo motor through 180°.

Create a new project file pwm.rs under examples, copy the contents of the last part into it and empty the loop section.

Table of contents

Requirements

  • 1 x Raspberry Pico board
  • 1 x USB Cable type 2.0
  • 9 x M-M jumper wires
  • 2 x Mini Breadboards
  • 1 x SG90 Servo Motor

Implementation

Connections Diagram

The electrical connections of the modules will be as shown below.

pwm-example-setup

Sweep

Duty cycle in the RP2040 is achieved by writing a value to the PWM's counter compare register. This value is compared to the value we earlier fixed as the TOP wrap around value (50,000 in our case). The duty cycle can be thus compared: Duty Cycle=CCTOP+1Duty\ Cycle = {CC \over TOP + 1} .

We saw in the last part that the SG90 operates within a duty cycle range of 5 - 10% of a 50Hz PWM signal. With a TOP value of 50,000 this translates to a CC value range of 2500 - 5000.

However, this value seems to vary across suppliers. After testing I found my particular servo's range is 3 - 13%, translating to CC value of 1500 - 6500.

Applying these to a servo sweep of 0° to 180° and back.

Add the below example application code under loop.

// Servo sweep trhough 180
for ccv in 1500..=6500 {
    pwm2.cc().modify(|_, w| unsafe { w.a().bits(ccv) });
    delay.delay_ms(1);

    if ccv == 6500 {
    delay.delay_ms(500);
    for ccv in (1500..=6500).rev() {
        pwm2.cc().modify(|_, w| unsafe { w.a().bits(ccv) });
        delay.delay_ms(1);
    }
}

delay.delay_ms(500);
Enter fullscreen mode Exit fullscreen mode

❗ You may have to tweak the above values for your servo.

At this point it we shall have to add the Delay function to our program. We begin by introducing its handle.

let mut delay = Delay::new(cp.SYST, 125_000_000);
Enter fullscreen mode Exit fullscreen mode

Delay is acquired from the cortex-m crate:

use cortex_m::delay::Delay
Enter fullscreen mode Exit fullscreen mode

❗ We shall comment away the configure_compass function call at the setup section of our code to allow the program to run without the compass being physically attached. Otherwise, the blocking writes of I2C we included earlier in the series will stop the code coming after from running.

Flashing the code thus far into the Pico should sweep the servo from 0° to 180° then 180° back to 0° every half a second.

servo-example-results

We can refactor the above above application code into a function sweep as below.

pub fn sweep(pwm: &pwm2, mut degrees: u16) {
    const BASE: u16 = 1500;// here pwm at position 0 degrees

    degrees = BASE + (degrees * 24);// ~28: movt by 1 degree 
    unsafe {
        pwm.cc().modify(|_, w| w.a().bits(degrees) );// move by one degree * no of degrees
    }
}
Enter fullscreen mode Exit fullscreen mode

Import the pwm channel.

use rp2040_pac::pwm::ch::CH;
Enter fullscreen mode Exit fullscreen mode

Our application code will now be:

// Servo sweep through 180
for deg in 0..=180 {
    sweep(pwm2, deg);
    delay.delay_ms(10);

    if deg == 180 {
    delay.delay_ms(500);
    for deg in (0..=180).rev() {
        sweep(pwm2, deg);
        delay.delay_ms(10);
    }
}

delay.delay_ms(500);
Enter fullscreen mode Exit fullscreen mode

Flashing this into the Pico should have the same sweep results as before.

Final Code

The final code up to this point can be found here.

In the next part we apply the PWM in our overall project

Reinvent your career. Join DEV.

It takes one minute and is worth it for your career.

Get started

Top comments (0)

AWS Security LIVE!

Tune in for AWS Security LIVE!

Join AWS Security LIVE! for expert insights and actionable tips to protect your organization and keep security teams prepared.

Learn More

👋 Kindness is contagious

Explore a sea of insights with this enlightening post, highly esteemed within the nurturing DEV Community. Coders of all stripes are invited to participate and contribute to our shared knowledge.

Expressing gratitude with a simple "thank you" can make a big impact. Leave your thanks in the comments!

On DEV, exchanging ideas smooths our way and strengthens our community bonds. Found this useful? A quick note of thanks to the author can mean a lot.

Okay