The Pico/W In C: Servos
Written by Harry Fairhead   
Tuesday, 05 November 2024
Article Index
The Pico/W In C: Servos
Complete Program

Here is a complete program, including a simple main program that moves the servo between two positions, the minimum and the maximum. You again need to add hardware_pwm to CMakeLists.txt:

#include "pico/stdlib.h"
#include "hardware/pwm.h"
typedef struct { uint gpio; uint slice; uint chan; uint speed; uint resolution; bool on; bool invert; } Servo;
uint32_t pwm_set_freq_duty(uint slice_num, uint chan,
uint32_t f, int d)
{
uint32_t clock = 125000000; uint32_t divider16 = clock / f / 4096 + (clock % (f * 4096) != 0);
if (divider16 / 16 == 0) divider16 = 16; uint32_t wrap = clock * 16 / divider16 / f - 1; pwm_set_clkdiv_int_frac(slice_num, divider16 / 16,
divider16 & 0xF);
pwm_set_wrap(slice_num, wrap); pwm_set_chan_level(slice_num, chan, wrap * d / 100);
return wrap;
}
uint32_t pwm_get_wrap(uint slice_num) { valid_params_if(PWM, slice_num >= 0 && slice_num < NUM_PWM_SLICES); return pwm_hw->slice[slice_num].top; }
void ServoInit(Servo *s, uint gpio, bool invert) {
gpio_set_function(gpio, GPIO_FUNC_PWM); s->gpio = gpio; s->slice = pwm_gpio_to_slice_num(gpio); s->chan = pwm_gpio_to_channel(gpio); pwm_set_enabled(s->slice, false); s->on = false; s->speed = 0; s->resolution = pwm_set_freq_duty(s->slice,
s->chan, 50, 0); pwm_set_dutyH(s->slice, s->chan, 250); if (s->chan) { pwm_set_output_polarity(s->slice, false, invert); } else { pwm_set_output_polarity(s->slice, invert, false); } s->invert = invert; }
void pwm_set_dutyH(uint slice_num, uint chan, int d) { pwm_set_chan_level(slice_num, chan, pwm_get_wrap(slice_num) * d / 10000);
}
void ServoOn(Servo *s) {
pwm_set_enabled(s->slice, true); s->on = true; } void ServoOff(Servo *s) {
pwm_set_enabled(s->slice, false); s->on = false; }
void ServoPosition(Servo *s, uint p) { pwm_set_dutyH(s->slice, s->chan, p * 10 + 250); }
int main() { Servo s1; ServoInit(&s1, 20, false); ServoOn(&s1); while (true) {
ServoPosition(&s1, 0); sleep_ms(500); ServoPosition(&s1, 100); sleep_ms(500); }
return 0; }

If you run the program using the circuit given earlier, you will discover that the servo does nothing at all, apart perhaps from vibrating. The reason is that the transistor voltage driver is an inverter. When the PWM line is high the transistor is fully on and the servo's pulse line is effectively grounded. When the PWM line is low the transistor is fully off and the servo's pulse line is pulled high by the resistor. The solution is to use an inverted output from the GPIO line using:

ServoInit(&s1, 20, true);

It is worth mentioning that servos make good low-cost DC motors, complete with gearboxes. All you have to do is open the servo, unsolder the motor from the control circuits and solder two wires to the motor. If you want to use the forward/reverse electronics you can remove the end stops on the gearbox, usually on the large gearwheel, and replace the potentiometer with a pair of equal value resistors, 2.2kΩ, say.

In chapter but not in this extract

  • Brushless DC Motors
  • Stepper Motors
  • Stepper Motor Driver
  • Stepper Motor Rotation – Using Timers

Summary

  • There are a number of different types of electric motor, but DC brushed or brushless motors are the most used in the IoT.

  • Brushed motors can be speed controlled using a single transistor driver and a PWM signal.

  • For bidirectional control you need an H‑bridge. In this case you need two PWM signals.

  • Servo motors set their position in response to the duty cycle of a PWM signal.

  • Brushless DC motors are very powerful and best controlled using off-the-shelf electronic modules. They are very powerful and thus dangerous if used incorrectly. They can be driven using a simple PWM signal.

  • Stepper motors are a special case of a Brushless DC motor. They move in discrete steps in response to energizing different coils.

  • A unipolar motor has coils that can be driven in the same direction for every step. A bipolar motor has coils that need to be driven in reverse for some steps.

  • Bipolar motors need two H‑bridges to operate and four GPIO lines.

  • You can easily create a stepper motor driver using four GPIO lines.

Programming the Raspberry Pi Pico In C

By Harry Fairhead

picoC2E360

Buy from Amazon.

Contents

  • Preface
  • Chapter 1 The Raspberry Pi Pico – Before We Begin
  • Chapter 2 Getting Started
  • Chapter 3 Getting Started With The GPIO
  • Chapter 4 Simple Output
  • Chapter 5 Some Electronics
  • Chapter 6 Simple Input
        Extract:   GPIO Input ***NEW!
  • Chapter 7 Advanced Input – Events and Interrupts
  • Chapter 8 Pulse Width Modulation
        Extract: Basic PWM
  • Chapter 9 Controlling Motors And Servos
  • Chapter 10 Getting Started With The SPI Bus
  • Chapter 11 A-To-D and The SPI Bus
  • Chapter 12 Using The I2C Bus
  • Chapter 13 Using The PIO
        Extract: A 1-Wire PIO Program  
  • Chapter 14 The DHT22 Sensor Implementing A Custom Protocol
  • Chapter 15 The 1‑Wire Bus And The DS1820
  • Chapter 16 The Serial Port
  • Chapter 17 Using the Pico W
       Extract: Simple Web Client
       Extract:A Better Connect
  • Chapter 18 The Pico/W In C: Direct To Hardware 

Extra: Adding WiFi To The Pico 2

<ASIN:1871962803>

<ASIN:187196279X>

To be informed about new articles on I Programmer, sign up for our weekly newsletter, subscribe to the RSS feed and follow us on Twitter, Facebook or Linkedin.

Banner


IBM Updates Granite Models
28/10/2024

IBM has released new Granite models that it says provide state-of-the-art performance relative to model size. The Granite 3.0 collection includes a new, instruction-tuned, dense decoder-only LLM.



Python 3.13 Is Here
09/10/2024

As time ticks on, the changes to the Python language become fewer and this makes it easier to upgrade. With this release the emphasis is on performance rather than new features.


More News

espbook

 

Comments




or email your comment to: comments@i-programmer.info



Last Updated ( Tuesday, 05 November 2024 )