{"id":146313,"date":"2024-05-23T13:39:31","date_gmt":"2024-05-23T13:39:31","guid":{"rendered":"https:\/\/randomnerdtutorials.com\/?p=146313"},"modified":"2024-05-23T13:46:31","modified_gmt":"2024-05-23T13:46:31","slug":"raspberry-pi-pico-servo-motor-micropython","status":"publish","type":"post","link":"https:\/\/randomnerdtutorials.com\/raspberry-pi-pico-servo-motor-micropython\/","title":{"rendered":"Raspberry Pi Pico: Control a Servo Motor (MicroPython)"},"content":{"rendered":"\n<p>In this guide, you\u2019ll learn how to control hobby servo motors with the Raspberry Pi Pico programmed with MicroPython. Servo motors can be controlled using PWM signals to move with precision to a certain angle. The most common models are the SG90 and the S0009.<\/p>\n\n\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter size-full\"><img data-recalc-dims=\"1\" fetchpriority=\"high\" decoding=\"async\" width=\"1200\" height=\"675\" src=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2024\/05\/Raspberry-Pi-Pico-Control-Servo-Motor-Micropython.jpg?resize=1200%2C675&#038;quality=100&#038;strip=all&#038;ssl=1\" alt=\"Raspberry Pi Pico Control a Servo Motor MicroPython\" class=\"wp-image-155675\" srcset=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2024\/05\/Raspberry-Pi-Pico-Control-Servo-Motor-Micropython.jpg?w=1280&amp;quality=100&amp;strip=all&amp;ssl=1 1280w, https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2024\/05\/Raspberry-Pi-Pico-Control-Servo-Motor-Micropython.jpg?resize=300%2C169&amp;quality=100&amp;strip=all&amp;ssl=1 300w, https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2024\/05\/Raspberry-Pi-Pico-Control-Servo-Motor-Micropython.jpg?resize=1024%2C576&amp;quality=100&amp;strip=all&amp;ssl=1 1024w, https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2024\/05\/Raspberry-Pi-Pico-Control-Servo-Motor-Micropython.jpg?resize=768%2C432&amp;quality=100&amp;strip=all&amp;ssl=1 768w\" sizes=\"(max-width: 1200px) 100vw, 1200px\" \/><\/figure><\/div>\n\n\n<p class=\"rntbox rntclblue\"><strong>New to the Raspberry Pi Pico?<\/strong>&nbsp;Read the following guide:&nbsp;<a href=\"https:\/\/randomnerdtutorials.com\/getting-started-raspberry-pi-pico-w\/\">Getting Started with Raspberry Pi Pico (and Pico W)<\/a>.<\/p>\n\n\n\n<p><strong>Table of Contents:<\/strong><\/p>\n\n\n\n<p>Throughout this tutorial, we\u2019ll cover the following contents:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><a href=\"#servo-motor-intro\" title=\"\">Introducing Servo Motors<\/a><\/li>\n\n\n\n<li><a href=\"#servo-motor-raspberry-pi-pico-wiring\" title=\"\">Wiring a Servo Motor to the Raspberry Pi Pico<\/a><\/li>\n\n\n\n<li><a href=\"#control-servo-motor-pwm-micropython\" title=\"\">Controlling a Servo Motor with PWM &#8211; MicroPython<\/a><\/li>\n\n\n\n<li><a href=\"#control-servo-motor-micropython-module\" title=\"\">The servo.py MicroPython Module<\/a><\/li>\n\n\n\n<li><a href=\"#control-servo-motor-micropython-library\" title=\"\">Controlling a Servo Motor with a Library<\/a><\/li>\n<\/ul>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"prerequisites\">Prerequisites<\/h2>\n\n\n\n<p>Before continuing, make sure you follow the next prerequisites.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"prerequisites\">MicroPython Firmware<\/h3>\n\n\n\n<p>To follow this tutorial you need MicroPython firmware installed in your Raspberry Pi Pico board. You also need an IDE to write and upload the code to your board.<\/p>\n\n\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter size-full is-resized\"><img data-recalc-dims=\"1\" decoding=\"async\" width=\"250\" height=\"250\" src=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2024\/02\/micropython-logo.png?resize=250%2C250&#038;quality=100&#038;strip=all&#038;ssl=1\" alt=\"micorpython logo\" class=\"wp-image-148797\" style=\"width:164px;height:auto\" srcset=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2024\/02\/micropython-logo.png?w=250&amp;quality=100&amp;strip=all&amp;ssl=1 250w, https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2024\/02\/micropython-logo.png?resize=150%2C150&amp;quality=100&amp;strip=all&amp;ssl=1 150w\" sizes=\"(max-width: 250px) 100vw, 250px\" \/><\/figure><\/div>\n\n\n<p>The recommended MicroPython IDE for the Raspberry Pi Pico is Thonny IDE. Follow the next tutorial to learn how to install Thonny IDE, flash MicroPython firmware, and upload code to the board.<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><a href=\"https:\/\/randomnerdtutorials.com\/getting-started-raspberry-pi-pico-w\/#install-thonny-ide\" title=\"\">Programming Raspberry Pi Pico using MicroPython<\/a><\/li>\n<\/ul>\n\n\n\n<p>Alternatively, if you like programming using VS Code, you can start with the following tutorial:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><a href=\"https:\/\/randomnerdtutorials.com\/raspberry-pi-pico-vs-code-micropython\/\">Programming Raspberry Pi Pico with VS Code and MicroPython<\/a><\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\">Parts Required<\/h3>\n\n\n\n<p>You&#8217;ll also need the following parts:<\/p>\n\n\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter size-full\"><img data-recalc-dims=\"1\" decoding=\"async\" width=\"750\" height=\"422\" src=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2024\/01\/servo-motor-raspberry-pi-pico.jpg?resize=750%2C422&#038;quality=100&#038;strip=all&#038;ssl=1\" alt=\"Control Servo Motor Raspberry Pi Pico\" class=\"wp-image-146317\" srcset=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2024\/01\/servo-motor-raspberry-pi-pico.jpg?w=750&amp;quality=100&amp;strip=all&amp;ssl=1 750w, https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2024\/01\/servo-motor-raspberry-pi-pico.jpg?resize=300%2C169&amp;quality=100&amp;strip=all&amp;ssl=1 300w\" sizes=\"(max-width: 750px) 100vw, 750px\" \/><\/figure><\/div>\n\n\n<ul class=\"wp-block-list\">\n<li><a href=\"https:\/\/makeradvisor.com\/tools\/raspberry-pi-pico-w\/\" target=\"_blank\" rel=\"noopener\" title=\"\">Raspberry Pi Pico<\/a><\/li>\n\n\n\n<li><a href=\"https:\/\/makeradvisor.com\/tools\/micro-servo-motor-tool\/\" target=\"_blank\" rel=\"noopener\" title=\"\">Servo Motor<\/a><\/li>\n\n\n\n<li><a href=\"https:\/\/makeradvisor.com\/tools\/jumper-wires-kit-120-pieces\/\" target=\"_blank\" rel=\"noreferrer noopener\">Jumper wires<\/a><\/li>\n\n\n\n<li><a href=\"https:\/\/makeradvisor.com\/tools\/mb-102-solderless-breadboard-830-points\/\" target=\"_blank\" rel=\"noopener\" title=\"\">Breadboard<\/a><\/li>\n<\/ul>\n\n\n<p>You can use the preceding links or go directly to <a href=\"https:\/\/makeradvisor.com\/tools\/?utm_source=rnt&utm_medium=post&utm_campaign=post\" target=\"_blank\">MakerAdvisor.com\/tools<\/a> to find all the parts for your projects at the best price!<\/p><p style=\"text-align:center;\"><a href=\"https:\/\/makeradvisor.com\/tools\/?utm_source=rnt&utm_medium=post&utm_campaign=post\" target=\"_blank\"><img data-recalc-dims=\"1\" decoding=\"async\" src=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2017\/10\/header-200.png?w=1200&#038;quality=100&#038;strip=all&#038;ssl=1\"><\/a><\/p>\n\n\n\n<h1 class=\"wp-block-heading\" id=\"servo-motor-intro\">How to Control a Servo Motor?<\/h1>\n\n\n\n<p>You can position the servo\u2019s shaft at various angles from 0 to 180\u00ba (depending on the model). Servos are controlled using a pulse width modulation (PWM) signal. The PWM signal sent to the motor will determine the shaft\u2019s position.<\/p>\n\n\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter size-full\"><img data-recalc-dims=\"1\" loading=\"lazy\" decoding=\"async\" width=\"500\" height=\"199\" src=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2018\/05\/0-180-degrees.png?resize=500%2C199&#038;quality=100&#038;strip=all&#038;ssl=1\" alt=\"\" class=\"wp-image-61336\" srcset=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2018\/05\/0-180-degrees.png?w=500&amp;quality=100&amp;strip=all&amp;ssl=1 500w, https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2018\/05\/0-180-degrees.png?resize=300%2C119&amp;quality=100&amp;strip=all&amp;ssl=1 300w, https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2018\/05\/0-180-degrees.png?resize=250%2C100&amp;quality=100&amp;strip=all&amp;ssl=1 250w\" sizes=\"(max-width: 500px) 100vw, 500px\" \/><\/figure><\/div>\n\n\n<p>To control the motor you can simply use the <a href=\"https:\/\/randomnerdtutorials.com\/raspberry-pi-pico-pwm-micropython\/\" title=\"\">PWM capabilities of the Raspberry Pi Pico<\/a> by sending a <strong>50Hz signal<\/strong> with the appropriate pulse width.<\/p>\n\n\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter size-full\"><img data-recalc-dims=\"1\" loading=\"lazy\" decoding=\"async\" width=\"750\" height=\"422\" src=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2024\/01\/hobby-servo-motors.jpg?resize=750%2C422&#038;quality=100&#038;strip=all&#038;ssl=1\" alt=\"hobby servo motors\" class=\"wp-image-146287\" srcset=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2024\/01\/hobby-servo-motors.jpg?w=750&amp;quality=100&amp;strip=all&amp;ssl=1 750w, https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2024\/01\/hobby-servo-motors.jpg?resize=300%2C169&amp;quality=100&amp;strip=all&amp;ssl=1 300w\" sizes=\"(max-width: 750px) 100vw, 750px\" \/><\/figure><\/div>\n\n\n<p>Usually, the S0009 or SG90 servo motors (capable of 180\u00ba), the one we\u2019re using in this tutorial, used in most microcontroller projects, has a pulse width range of around <strong>550 to 2400 microseconds<\/strong>:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Minimum Pulse Width (0\u00ba): around 550 microseconds<\/li>\n\n\n\n<li>Maximum Pulse Width (180\u00ba): around 2400 microseconds<\/li>\n<\/ul>\n\n\n\n<p>For servo motors that only travel in the 90\u00ba range, these are usually the pulse width values:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Minimum Pulse Width (0\u00ba): around 1000 microseconds<\/li>\n\n\n\n<li>Maximum Pulse Width (90\u00ba): around 200 microseconds<\/li>\n<\/ul>\n\n\n\n<p>These values can slightly vary between different servo models. Try to search for your servo datasheet or test these values and then adjust accordingly.<\/p>\n\n\n\n<p>In my case, I haven\u2019t found the datasheet for my specific servo, but using the default pulse width values used in most Arduino libraries (550 to 2400 microseconds) works fine for the one we\u2019re using.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Calculating the Duty Cycle<\/h3>\n\n\n\n<p>From those pulse width values, we can calculate the duty cycle to position the motor\u2019s shaft at a certain angle. The duty cycle is the ratio of the pulse-width to the total period of the signal. We can use the following formula:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>Duty cycle (%) = (pulse-width\/period)x100<\/code><\/pre>\n\n\n\n<p>The period is the inverse of the frequency. Our frequency is 50Hz, which corresponds to 1\/50 = 0.02 seconds (20000 microseconds).<\/p>\n\n\n\n<p>So, to put the motor in 0\u00ba position, we need a 2.75% duty cycle:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>Duty cycle = (550\/20000)x100 = 2.75%<\/code><\/pre>\n\n\n\n<p>With the Raspberry Pi Pico, 100% duty cycle value is represented by a digital value of 65535, and 0% is represented by 0 (<a href=\"https:\/\/randomnerdtutorials.com\/raspberry-pi-pico-pwm-micropython\/\" title=\"\">learn more about PWM with the Raspberry Pi Pico here<\/a>). So, we can map the duty cycle values to the Raspberry Pi Pico 0-65535 range as follows:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>Mapped value = Duty cycle x (maximum value\/100)<\/code><\/pre>\n\n\n\n<p>So, the 0\u00ba position, would correspond to:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>Mapped value = 2.75 x (65535\/100) = 1802<\/code><\/pre>\n\n\n\n<p>Doing the same procedure for the other values, we get:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Minimum Pulse Width (0\u00ba) corresponds to 1802<\/li>\n\n\n\n<li>Maximum Pulse Width (180\u00ba) corresponds to 7864<\/li>\n<\/ul>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"servo-motor-raspberry-pi-pico-wiring\">Connecting the Servo Motor to the Raspberry Pi Pico<\/h2>\n\n\n\n<p>Servo motors have three wires: power, ground, and signal. The power is usually red, the GND is black or brown, and the signal wire is usually yellow, orange, or white.<\/p>\n\n\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter size-full\"><img data-recalc-dims=\"1\" loading=\"lazy\" decoding=\"async\" width=\"750\" height=\"422\" src=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2018\/05\/servo-motor-pinout.jpg?resize=750%2C422&#038;quality=100&#038;strip=all&#038;ssl=1\" alt=\"Servo motor pinout\" class=\"wp-image-146288\" srcset=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2018\/05\/servo-motor-pinout.jpg?w=750&amp;quality=100&amp;strip=all&amp;ssl=1 750w, https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2018\/05\/servo-motor-pinout.jpg?resize=300%2C169&amp;quality=100&amp;strip=all&amp;ssl=1 300w\" sizes=\"(max-width: 750px) 100vw, 750px\" \/><\/figure><\/div>\n\n\n<p>When using a small servo like the S0009 (or SG90), you can power it directly from the Raspberry Pi Pico power pin. However, for other models, you may need to apply an external power supply (check your servo datasheet).<\/p>\n\n\n\n<figure class=\"wp-block-table\"><table><tbody><tr><td><strong>Wire<\/strong><\/td><td><strong>Color<\/strong><\/td><td><strong>Raspberry Pi Pico<\/strong><\/td><\/tr><tr><td><strong>Power\/VCC<\/strong><\/td><td>Red<\/td><td>5V (VBUS)<\/td><\/tr><tr><td><strong>GND<\/strong><\/td><td>Black, or brown<\/td><td>GND<\/td><\/tr><tr><td><strong>Signal<\/strong><\/td><td>Yellow, orange, or white<\/td><td>GPIO 0 (or any other PWM Pin)<\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<p>To control the servo motor, you can connect the signal (data) pin to any GPIO that can produce PWM signals. All pins marked on the pinout with a light green color can produce PWM signals (which are basically all GPIOs). We\u2019ll connect it to GPIO 0, but you can use any other GPIO as long as you specify the correct pin on the code.<\/p>\n\n\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter size-full\"><img data-recalc-dims=\"1\" loading=\"lazy\" decoding=\"async\" width=\"1200\" height=\"333\" src=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2024\/01\/servo-raspberry-pi-pico_bb.png?resize=1200%2C333&#038;quality=100&#038;strip=all&#038;ssl=1\" alt=\"Wiring Raspberry Pi Pico to Servo Motor\" class=\"wp-image-146319\" srcset=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2024\/01\/servo-raspberry-pi-pico_bb.png?w=1548&amp;quality=100&amp;strip=all&amp;ssl=1 1548w, https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2024\/01\/servo-raspberry-pi-pico_bb.png?resize=300%2C83&amp;quality=100&amp;strip=all&amp;ssl=1 300w, https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2024\/01\/servo-raspberry-pi-pico_bb.png?resize=1024%2C284&amp;quality=100&amp;strip=all&amp;ssl=1 1024w, https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2024\/01\/servo-raspberry-pi-pico_bb.png?resize=768%2C213&amp;quality=100&amp;strip=all&amp;ssl=1 768w, https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2024\/01\/servo-raspberry-pi-pico_bb.png?resize=1536%2C426&amp;quality=100&amp;strip=all&amp;ssl=1 1536w\" sizes=\"(max-width: 1200px) 100vw, 1200px\" \/><\/figure><\/div>\n\n\n<h2 class=\"wp-block-heading\" id=\"control-servo-motor-pwm-micropython\">Controlling the Servo Motor with PWM<\/h2>\n\n\n\n<p>The servo motor shaft\u2019s position can be controlled by sending a PWM signal with a determined pulse width. We\u2019ve seen previously that:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Minimum Pulse Width (0\u00ba): around 550 microseconds<\/li>\n\n\n\n<li>Maximum Pulse Width (180\u00ba): around 2400 microseconds<\/li>\n<\/ul>\n\n\n\n<p>The following code moves the servo motor to the 0\u00ba position, then to 90\u00ba and finally to 180\u00ba. Then, it repeats and moves again to the 0\u00ba, 90\u00ba, and so on. This is just a simple example for you to understand how to position the servo at specific angles.<\/p>\n\n\n<pre style=\"max-height: 40em; margin-bottom: 20px;\"><code class=\"language-python\"># Rui Santos &amp; Sara Santos - Random Nerd Tutorials\r\n# Complete project details at https:\/\/RandomNerdTutorials.com\/raspberry-pi-pico-servo-motor-micropython\/\r\n\r\nfrom machine import Pin, PWM\r\nfrom time import sleep\r\n\r\n# Set up PWM Pin for servo control\r\nservo_pin = machine.Pin(0)\r\nservo = PWM(servo_pin)\r\n\r\n# Set Duty Cycle for Different Angles\r\nmax_duty = 7864\r\nmin_duty = 1802\r\nhalf_duty = int(max_duty\/2)\r\n\r\n#Set PWM frequency\r\nfrequency = 50\r\nservo.freq (frequency)\r\n\r\ntry:\r\n    while True:\r\n        #Servo at 0 degrees\r\n        servo.duty_u16(min_duty)\r\n        sleep(2)\r\n        #Servo at 90 degrees\r\n        servo.duty_u16(half_duty)\r\n        sleep(2)\r\n        #Servo at 180 degrees\r\n        servo.duty_u16(max_duty)\r\n        sleep(2)    \r\n      \r\nexcept KeyboardInterrupt:\r\n    print(&quot;Keyboard interrupt&quot;)\r\n    # Turn off PWM \r\n    servo.deinit()\r\n<\/code><\/pre>\n\t<p style=\"text-align:center\"><a class=\"rntwhite\" href=\"https:\/\/github.com\/RuiSantosdotme\/Random-Nerd-Tutorials\/raw\/master\/Projects\/Raspberry-Pi-Pico\/MicroPython\/Control_Servo_Motor_PWM.py\" target=\"_blank\">View raw code<\/a><\/p>\n\n\n\n<h3 class=\"wp-block-heading\">How the Code Works<\/h3>\n\n\n\n<p>We start by including the required libraries, including the <span class=\"rnthl rntliteral\">PWM<\/span> class from the <span class=\"rnthl rntliteral\">machine<\/span> module to control the servo motor using PWM.<\/p>\n\n\n\n<pre class=\"wp-block-code language-python\"><code>from machine import Pin, PWM\nfrom time import sleep<\/code><\/pre>\n\n\n\n<p>We initialize PWM on GPIO 0 to control our servo. We call it <span class=\"rnthl rntliteral\">servo<\/span>.<\/p>\n\n\n\n<pre class=\"wp-block-code language-python\"><code># Set up PWM Pin for servo control\nservo_pin = machine.Pin(0)\nservo = PWM(servo_pin)<\/code><\/pre>\n\n\n\n<p>We define the minimum, maximum and half-duty cycles to control the servo motor. We calculated these values in the previous section.<\/p>\n\n\n\n<pre class=\"wp-block-code language-python\"><code># Set Duty Cycle for Different Angles\nmax_duty = 7864\nmin_duty = 1802\nhalf_duty = int(max_duty\/2)<\/code><\/pre>\n\n\n\n<p>Then, we set the PWM frequency to control the servo. As we\u2019ve seen previously, we need a 50Hz frequency. We use the <span class=\"rnthl rntliteral\">freq()<\/span> method on the <span class=\"rnthl rntliteral\">servo<\/span> object to set the frequency.<\/p>\n\n\n\n<pre class=\"wp-block-code language-python\"><code>#Set PWM frequency\nfrequency = 50\nservo.freq (frequency)<\/code><\/pre>\n\n\n\n<p>In the while loop, we use the <span class=\"rnthl rntliteral\">duty_u16()<\/span> method to set the PWM duty cycle. We first put the servo at the 0\u00ba angle:<\/p>\n\n\n\n<pre class=\"wp-block-code language-python\"><code>#Servo at 0 degrees\nservo.duty_u16(min_duty)\nsleep(2)<\/code><\/pre>\n\n\n\n<p>Then, at 90\u00ba and finally at 180\u00ba.<\/p>\n\n\n\n<pre class=\"wp-block-code language-python\"><code>#Servo at 90 degrees\nservo.duty_u16(half_duty)\nsleep(2)\n#Servo at 180 degrees\nservo.duty_u16(max_duty)\nsleep(2)    <\/code><\/pre>\n\n\n\n<p>When the program is stopped by the user, we turn off PWM using the <span class=\"rnthl rntliteral\">deinit()<\/span> method.<\/p>\n\n\n\n<pre class=\"wp-block-code language-python\"><code># Turn off PWM \nservo.deinit()<\/code><\/pre>\n\n\n\n<h2 class=\"wp-block-heading\">Testing the Code<\/h2>\n\n\n\n<p>Run the previous code on your Raspberry Pi Pico. If you&#8217;re using Thonny IDE, click on the green Run icon.<\/p>\n\n\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter size-full\"><img data-recalc-dims=\"1\" loading=\"lazy\" decoding=\"async\" width=\"470\" height=\"114\" src=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2023\/12\/thonny-ide-run-button.png?resize=470%2C114&#038;quality=100&#038;strip=all&#038;ssl=1\" alt=\"Run micropython program Thonny IDE\" class=\"wp-image-144594\" srcset=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2023\/12\/thonny-ide-run-button.png?w=470&amp;quality=100&amp;strip=all&amp;ssl=1 470w, https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2023\/12\/thonny-ide-run-button.png?resize=300%2C73&amp;quality=100&amp;strip=all&amp;ssl=1 300w\" sizes=\"(max-width: 470px) 100vw, 470px\" \/><\/figure><\/div>\n\n\n<p>The motor should go to the 0\u00ba position and stay there for two seconds. Then, it will go to 90\u00ba for another two seconds and finally to the 180\u00ba position for two seconds. This will be repeated indefinitely until you stop the program.<\/p>\n\n\n\n<div class=\"wp-block-jetpack-tiled-gallery aligncenter is-style-rectangular\"><div class=\"\"><div class=\"tiled-gallery__gallery\"><div class=\"tiled-gallery__row\"><div class=\"tiled-gallery__col\" style=\"flex-basis:50.00000%\"><figure class=\"tiled-gallery__item\"><img decoding=\"async\" srcset=\"https:\/\/i2.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2024\/01\/control-servo-pico-2.jpg?strip=info&#038;w=600&#038;ssl=1 600w, https:\/\/i2.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2024\/01\/control-servo-pico-2.jpg?strip=info&#038;w=750&#038;ssl=1 750w\" alt=\"Control Servo Motor Raspberry Pi Pico\" data-height=\"422\" data-id=\"146321\" data-link=\"https:\/\/randomnerdtutorials.com\/?attachment_id=146321#main\" data-url=\"https:\/\/randomnerdtutorials.com\/wp-content\/uploads\/2024\/01\/control-servo-pico-2.jpg\" data-width=\"750\" src=\"https:\/\/i2.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2024\/01\/control-servo-pico-2.jpg?ssl=1\" data-amp-layout=\"responsive\"\/><\/figure><\/div><div class=\"tiled-gallery__col\" style=\"flex-basis:50.00000%\"><figure class=\"tiled-gallery__item\"><img decoding=\"async\" srcset=\"https:\/\/i1.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2024\/01\/control-servo-rpi-pico-1.jpg?strip=info&#038;w=600&#038;ssl=1 600w, https:\/\/i1.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2024\/01\/control-servo-rpi-pico-1.jpg?strip=info&#038;w=750&#038;ssl=1 750w\" alt=\"Control Servo Motor Raspberry Pi Pico\" data-height=\"422\" data-id=\"146322\" data-link=\"https:\/\/randomnerdtutorials.com\/?attachment_id=146322#main\" data-url=\"https:\/\/randomnerdtutorials.com\/wp-content\/uploads\/2024\/01\/control-servo-rpi-pico-1.jpg\" data-width=\"750\" src=\"https:\/\/i1.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2024\/01\/control-servo-rpi-pico-1.jpg?ssl=1\" data-amp-layout=\"responsive\"\/><\/figure><\/div><\/div><\/div><\/div><\/div>\n\n\n\n<p>If you hear a <em>weird buzz sound<\/em> at the 0 or 180\u00ba angles, it means that you\u2019re trying to control the servo outside its pulse width limits. In that case, you should try to adjust the minimum and\/or maximum values until it stops making noise. Those values work well for my specific servo, but some adjustments might need to be done for other models.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"control-servo-motor-micropython-module\">Controlling the Servo Motor using a Library<\/h2>\n\n\n\n<p>Having to calculate the specific duty cycle values for a specific angle might be a tedious task and might cause errors and typos when writing the code. To make things easier we can create a function, or even better, use a library.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Uploading the servo.py library<\/h3>\n\n\n\n<p>We\u2019re using the library found at the following link:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><a href=\"https:\/\/raw.githubusercontent.com\/RuiSantosdotme\/Random-Nerd-Tutorials\/master\/Projects\/Raspberry-Pi-Pico\/MicroPython\/servo.py\" target=\"_blank\" rel=\"noopener\" title=\"\">servo.py library<\/a><\/li>\n<\/ul>\n\n\n<pre style=\"max-height: 40em; margin-bottom: 20px;\"><code class=\"language-python\"># Rui Santos &amp; Sara Santos - Random Nerd Tutorials\r\n# Complete project details at https:\/\/RandomNerdTutorials.com\/raspberry-pi-pico-servo-motor-micropython\/\r\n\r\nfrom machine import Pin, PWM\r\n\r\nclass Servo:\r\n    __servo_pwm_freq = 50\r\n    __min_u16_duty = 1802\r\n    __max_u16_duty = 7864\r\n    min_angle = 0\r\n    max_angle = 180\r\n    current_angle = 0.001\r\n\r\n\r\n    def __init__(self, pin):\r\n        self.__initialise(pin)\r\n\r\n\r\n    def update_settings(self, servo_pwm_freq, min_u16_duty, max_u16_duty, min_angle, max_angle, pin):\r\n        self.__servo_pwm_freq = servo_pwm_freq\r\n        self.__min_u16_duty = min_u16_duty\r\n        self.__max_u16_duty = max_u16_duty\r\n        self.min_angle = min_angle\r\n        self.max_angle = max_angle\r\n        self.__initialise(pin)\r\n\r\n\r\n    def move(self, angle):\r\n        # round to 2 decimal places, so we have a chance of reducing unwanted servo adjustments\r\n        angle = round(angle, 2)\r\n        # do we need to move?\r\n        if angle == self.current_angle:\r\n            return\r\n        self.current_angle = angle\r\n        # calculate the new duty cycle and move the motor\r\n        duty_u16 = self.__angle_to_u16_duty(angle)\r\n        self.__motor.duty_u16(duty_u16)\r\n    \r\n    def stop(self):\r\n        self.__motor.deinit()\r\n    \r\n    def get_current_angle(self):\r\n        return self.current_angle\r\n\r\n    def __angle_to_u16_duty(self, angle):\r\n        return int((angle - self.min_angle) * self.__angle_conversion_factor) + self.__min_u16_duty\r\n\r\n\r\n    def __initialise(self, pin):\r\n        self.current_angle = -0.001\r\n        self.__angle_conversion_factor = (self.__max_u16_duty - self.__min_u16_duty) \/ (self.max_angle - self.min_angle)\r\n        self.__motor = PWM(Pin(pin))\r\n        self.__motor.freq(self.__servo_pwm_freq)<\/code><\/pre>\n\t<p style=\"text-align:center\"><a class=\"rntwhite\" href=\"https:\/\/github.com\/RuiSantosdotme\/Random-Nerd-Tutorials\/raw\/master\/Projects\/Raspberry-Pi-Pico\/MicroPython\/servo.py\" target=\"_blank\">View raw code<\/a><\/p>\n\n\n\n<p>This library assumes your servo motor rotates within the 0 to 180\u00ba range and that the minimum and maximum duty cycle values are the ones we calculated previously (<em>maximum:7864, and minimum:1802<\/em>). If you have different values, you should adjust them on the library file right on the following lines.<\/p>\n\n\n\n<pre class=\"wp-block-code language-python\"><code>from machine import Pin, PWM\n\nclass Servo:\n<strong>    __servo_pwm_freq = 50\n    __min_u16_duty = 1802\n    __max_u16_duty = 7864\n<\/strong>    min_angle = 0\n    max_angle = 180\n    current_angle = 0.001<\/code><\/pre>\n\n\n\n<p>Save the library file on your Raspberry Pi Pico with the name <strong><em>servo.py<\/em><\/strong>. You can follow the next steps:<\/p>\n\n\n\n<ol class=\"wp-block-list\">\n<li>Download the library code. You can find the <em>servo.py<\/em> file <a href=\"https:\/\/raw.githubusercontent.com\/RuiSantosdotme\/Random-Nerd-Tutorials\/master\/Projects\/Raspberry-Pi-Pico\/MicroPython\/servo.py\" target=\"_blank\" rel=\"noopener\" title=\"\">here<\/a>.<\/li>\n\n\n\n<li>Copy the code to a file on Thonny IDE;<\/li>\n\n\n\n<li>Go to <strong>File<\/strong> &gt; <strong>Save as\u2026<\/strong> and select Raspberry Pi Pico;<\/li>\n\n\n\n<li>Save the file with the name <em>servo.py<\/em> (don\u2019t change the name)<\/li>\n<\/ol>\n\n\n\n<p>Now, that you\u2019ve uploaded the library to the Raspberry Pi Pico, we can use the library functionalities in our code.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"control-servo-motor-micropython-library\">Controlling the Servo Motor &#8211; MicroPython<\/h3>\n\n\n\n<p>The following code does the same thing as the previous example but uses the library methods that are more intuitive to use. Additionally, you can use the specific angle value to where you want to move the motor.<\/p>\n\n\n<pre style=\"max-height: 40em; margin-bottom: 20px;\"><code class=\"language-python\"># Rui Santos &amp; Sara Santos - Random Nerd Tutorials\r\n# Complete project details at https:\/\/RandomNerdTutorials.com\/raspberry-pi-pico-servo-motor-micropython\/\r\n\r\nfrom servo import Servo\r\nfrom time import sleep\r\n\r\n# Create a Servo object on pin 0\r\nservo=Servo(pin=0)\r\n\r\ntry:\r\n    while True:\r\n        #Servo at 0 degrees\r\n        servo.move(0)\r\n        sleep(2)\r\n        #Servo at 90 degrees\r\n        servo.move(90)\r\n        sleep(2)\r\n        #Servo at 180 degrees\r\n        servo.move(180)\r\n        sleep(2)\r\n        \r\nexcept KeyboardInterrupt:\r\n    print(&quot;Keyboard interrupt&quot;)\r\n    # Turn off PWM \r\n    servo.stop()<\/code><\/pre>\n\t<p style=\"text-align:center\"><a class=\"rntwhite\" href=\"https:\/\/github.com\/RuiSantosdotme\/Random-Nerd-Tutorials\/raw\/master\/Projects\/Raspberry-Pi-Pico\/MicroPython\/Control_Servo_Motor_Module.py\" target=\"_blank\">View raw code<\/a><\/p>\n\n\n\n<h2 class=\"wp-block-heading\">How the Code Works<\/h2>\n\n\n\n<p>You start by importing the <span class=\"rnthl rntliteral\">Servo<\/span> class from the <span class=\"rnthl rntliteral\">servo<\/span> library.<\/p>\n\n\n\n<pre class=\"wp-block-code language-python\"><code>from servo import Servo<\/code><\/pre>\n\n\n\n<p>Then, you create a <span class=\"rnthl rntliteral\">Servo<\/span> object on GPIO 0. If you\u2019re using a different GPIO, you just need to modify the following line.<\/p>\n\n\n\n<pre class=\"wp-block-code language-python\"><code># Create a Servo object on pin 0\nservo=Servo(pin=0)<\/code><\/pre>\n\n\n\n<p>Then, in the loop, we just need to use the <span class=\"rnthl rntliteral\">move()<\/span> method on the servo object and pass as argument the position to where we want to move the motor in degrees. For example:<\/p>\n\n\n\n<pre class=\"wp-block-code language-python\"><code>#Servo at 0 degrees\nservo.move(0)\nsleep(2)\n#Servo at 90 degrees\nservo.move(90)\nsleep(2)\n#Servo at 180 degrees\nservo.move(180)\nsleep(2)<\/code><\/pre>\n\n\n\n<p>Adjust the code and try with different angle values.<\/p>\n\n\n\n<p>Finally, when the user interrupts the code, we stop the motor using the <span class=\"rnthl rntliteral\">stop()<\/span> method. This will stop PWM on the pin connected to the motor.<\/p>\n\n\n\n<pre class=\"wp-block-code language-python\"><code>except KeyboardInterrupt:\n    print(\"Keyboard interrupt\")\n    # Turn off PWM \n    servo.stop()<\/code><\/pre>\n\n\n\n<h3 class=\"wp-block-heading\">Testing the Code<\/h3>\n\n\n\n<p>Upload or run the previous code to the Raspberry Pi Pico. The servo motor should behave exactly like in the previous example. But this time, it is more intuitive to move the servo to a certain position in our code.<\/p>\n\n\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter size-full\"><img data-recalc-dims=\"1\" loading=\"lazy\" decoding=\"async\" width=\"750\" height=\"422\" src=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2024\/01\/Raspberry-Pi-Pico-Control-Servo-Motor.jpg?resize=750%2C422&#038;quality=100&#038;strip=all&#038;ssl=1\" alt=\"Controlling a Servo Motor with a Raspberry Pi Pico\" class=\"wp-image-146324\" srcset=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2024\/01\/Raspberry-Pi-Pico-Control-Servo-Motor.jpg?w=750&amp;quality=100&amp;strip=all&amp;ssl=1 750w, https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2024\/01\/Raspberry-Pi-Pico-Control-Servo-Motor.jpg?resize=300%2C169&amp;quality=100&amp;strip=all&amp;ssl=1 300w\" sizes=\"(max-width: 750px) 100vw, 750px\" \/><\/figure><\/div>\n\n\n<p>If you want to run this code on your Raspberry Pi Pico when it is not connected to your computer, you must save the code on a file called <em>main.py<\/em> and upload it to your board (<strong>File <\/strong>&gt; <strong>Save as..<\/strong>. &gt; <strong>Raspberry Pi Pico<\/strong>).<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Wrapping Up<\/h2>\n\n\n\n<p>In this guide, you learned how to control a hobby servo motor with the Raspberry Pi Pico programmed with MicroPython. We&#8217;ve shown you how to control it by simply using PWM signals with the right pulse length and using a library.<\/p>\n\n\n\n<p>If you want to interface other motors with the Raspberry Pi Pico, check the tutorials below:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><a href=\"https:\/\/randomnerdtutorials.com\/raspberry-pi-pico-dc-motor-micropython\/\">Raspberry Pi Pico: Control DC Motor with L298N Motor Driver (MicroPython)<\/a><\/li>\n\n\n\n<li><a href=\"https:\/\/randomnerdtutorials.com\/raspberry-pi-pico-stepper-motor-micropython\/\">Raspberry Pi Pico: Control a Stepper Motor (MicroPython)<\/a><\/li>\n<\/ul>\n\n\n\n<p>We hope you&#8217;ve found this tutorial useful. If you would like to learn more about the Raspberry Pi Pico, make sure you check all our guides:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><a href=\"https:\/\/randomnerdtutorials.com\/raspberry-pi-pico-w-micropython-ebook\/\"><strong>Learn Raspberry Pi Pico with MicroPython (eBook)<\/strong><\/a><\/li>\n\n\n\n<li><a href=\"https:\/\/randomnerdtutorials.com\/projects-raspberry-pi-pico\/\">Raspberry Pi Pico Tutorials and Guides<\/a><\/li>\n<\/ul>\n\n\n\n<p>Thanks for reading.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>In this guide, you\u2019ll learn how to control hobby servo motors with the Raspberry Pi Pico programmed with MicroPython. Servo motors can be controlled using PWM signals to move with &#8230; <\/p>\n<p class=\"read-more-container\"><a title=\"Raspberry Pi Pico: Control a Servo Motor (MicroPython)\" class=\"read-more button\" href=\"https:\/\/randomnerdtutorials.com\/raspberry-pi-pico-servo-motor-micropython\/#more-146313\" aria-label=\"Read more about Raspberry Pi Pico: Control a Servo Motor (MicroPython)\">CONTINUE READING \u00bb<\/a><\/p>\n","protected":false},"author":5,"featured_media":155675,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"jetpack_post_was_ever_published":false,"_jetpack_newsletter_access":"","_jetpack_dont_email_post_to_subs":true,"_jetpack_newsletter_tier_id":0,"_jetpack_memberships_contains_paywalled_content":false,"_jetpack_memberships_contains_paid_content":false,"footnotes":""},"categories":[324,326],"tags":[],"class_list":["post-146313","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-raspberry-pi-pico","category-raspberry-pi-pico-micropython"],"aioseo_notices":[],"jetpack_featured_media_url":"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2024\/05\/Raspberry-Pi-Pico-Control-Servo-Motor-Micropython.jpg?fit=1280%2C720&quality=100&strip=all&ssl=1","jetpack_sharing_enabled":true,"_links":{"self":[{"href":"https:\/\/randomnerdtutorials.com\/wp-json\/wp\/v2\/posts\/146313","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/randomnerdtutorials.com\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/randomnerdtutorials.com\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/randomnerdtutorials.com\/wp-json\/wp\/v2\/users\/5"}],"replies":[{"embeddable":true,"href":"https:\/\/randomnerdtutorials.com\/wp-json\/wp\/v2\/comments?post=146313"}],"version-history":[{"count":8,"href":"https:\/\/randomnerdtutorials.com\/wp-json\/wp\/v2\/posts\/146313\/revisions"}],"predecessor-version":[{"id":155783,"href":"https:\/\/randomnerdtutorials.com\/wp-json\/wp\/v2\/posts\/146313\/revisions\/155783"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/randomnerdtutorials.com\/wp-json\/wp\/v2\/media\/155675"}],"wp:attachment":[{"href":"https:\/\/randomnerdtutorials.com\/wp-json\/wp\/v2\/media?parent=146313"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/randomnerdtutorials.com\/wp-json\/wp\/v2\/categories?post=146313"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/randomnerdtutorials.com\/wp-json\/wp\/v2\/tags?post=146313"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}