{"id":392,"date":"2021-09-09T05:08:11","date_gmt":"2021-09-09T05:08:11","guid":{"rendered":"https:\/\/blog.embeddedexpert.io\/?p=392"},"modified":"2021-09-09T05:08:15","modified_gmt":"2021-09-09T05:08:15","slug":"working-with-stm32-and-timers-part-4-servo-motor-control","status":"publish","type":"post","link":"https:\/\/blog.embeddedexpert.io\/?p=392","title":{"rendered":"Working with STM32 and Timers part 4: Servo Motor Control"},"content":{"rendered":"\n<div class=\"wp-block-image\"><figure class=\"aligncenter size-large\"><img decoding=\"async\" src=\"https:\/\/components101.com\/sites\/default\/files\/components\/Servo-Motor.jpg\" alt=\"\" \/><figcaption>Servo motor<\/figcaption><\/figure><\/div>\n\n\n\n<p>In pervious PWM guide (<a rel=\"noreferrer noopener\" href=\"https:\/\/blog.embeddedexpert.io\/?p=363\" data-type=\"URL\" data-id=\"https:\/\/blog.embeddedexpert.io\/?p=363\" target=\"_blank\">here<\/a>), discussed how to use TIM2 of STM32F411 to generate 2 PWM signals to fade 2 LEDs. In this guide, we shall use PWM signal to control a servo motor (<strong>SG90<\/strong>).<\/p>\n\n\n\n<p> In this guide, we shall cover the following <\/p>\n\n\n\n<ul class=\"wp-block-list\"><li>What is servo motor and how to control it<\/li><li>Connection<\/li><li>Code<\/li><li>Demo<\/li><\/ul>\n\n\n\n<h2 class=\"wp-block-heading\">1. What is servo motor and how to control it<\/h2>\n\n\n\n<p>A\u00a0<strong>servomotor<\/strong>\u00a0is a\u00a0<a href=\"https:\/\/en.wikipedia.org\/wiki\/Rotary_actuator\">rotary actuator<\/a>\u00a0or\u00a0<a href=\"https:\/\/en.wikipedia.org\/wiki\/Linear_actuator\">linear actuator<\/a>\u00a0that allows for precise control of angular or linear position, velocity and acceleration.<sup><a href=\"https:\/\/en.wikipedia.org\/wiki\/Servomotor#cite_note-1\">[1]<\/a><\/sup>\u00a0It consists of a suitable motor coupled to a sensor for position feedback. It also requires a relatively sophisticated controller, often a dedicated module designed specifically for use with servomotors. (<a href=\"https:\/\/en.wikipedia.org\/wiki\/Servomotor\" data-type=\"URL\" data-id=\"https:\/\/en.wikipedia.org\/wiki\/Servomotor\" target=\"_blank\" rel=\"noreferrer noopener\">Wikipedia link<\/a>).<\/p>\n\n\n\n<p>The servo motor used in our guide has three wires: red, brown and orange.<\/p>\n\n\n\n<figure class=\"wp-block-table aligncenter\"><table><tbody><tr><td>Wire color<\/td><td>Function<\/td><\/tr><tr><td>Red<\/td><td>Vcc (4~6V)<\/td><\/tr><tr><td>Brown<\/td><td>GND<\/td><\/tr><tr><td>Orange<\/td><td>Signal<\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"284\" src=\"https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2021\/09\/Screen-Shot-2021-09-09-at-7.35.58-AM-1024x284.png\" alt=\"\" class=\"wp-image-393\" srcset=\"https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2021\/09\/Screen-Shot-2021-09-09-at-7.35.58-AM-1024x284.png 1024w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2021\/09\/Screen-Shot-2021-09-09-at-7.35.58-AM-300x83.png 300w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2021\/09\/Screen-Shot-2021-09-09-at-7.35.58-AM-768x213.png 768w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2021\/09\/Screen-Shot-2021-09-09-at-7.35.58-AM-1150x319.png 1150w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2021\/09\/Screen-Shot-2021-09-09-at-7.35.58-AM-750x208.png 750w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2021\/09\/Screen-Shot-2021-09-09-at-7.35.58-AM-400x111.png 400w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2021\/09\/Screen-Shot-2021-09-09-at-7.35.58-AM-250x69.png 250w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2021\/09\/Screen-Shot-2021-09-09-at-7.35.58-AM.png 1370w\" sizes=\"(max-width: 1024px) 100vw, 1024px\" \/><\/figure>\n\n\n\n<p>In order to control the angle of the servo motor, a PWM signal of frequency 50Hz (20mS period) needed to be applied to the signal pin on the servo motor. to determine the angle of the servo as following:<\/p>\n\n\n\n<figure class=\"wp-block-table aligncenter\"><table><tbody><tr><td>Angle <\/td><td>Duty Cycle (Period)<\/td><\/tr><tr><td>0<\/td><td>5% (1mS)<\/td><\/tr><tr><td>90<\/td><td>7.5% (1.5mS)<\/td><\/tr><tr><td>180<\/td><td>10%(2mS)<\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<div class=\"wp-block-image\"><figure class=\"aligncenter size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"520\" src=\"https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2021\/09\/Screen-Shot-2021-09-09-at-7.44.51-AM-1024x520.png\" alt=\"\" class=\"wp-image-394\" srcset=\"https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2021\/09\/Screen-Shot-2021-09-09-at-7.44.51-AM-1024x520.png 1024w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2021\/09\/Screen-Shot-2021-09-09-at-7.44.51-AM-300x152.png 300w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2021\/09\/Screen-Shot-2021-09-09-at-7.44.51-AM-768x390.png 768w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2021\/09\/Screen-Shot-2021-09-09-at-7.44.51-AM-1536x780.png 1536w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2021\/09\/Screen-Shot-2021-09-09-at-7.44.51-AM-1150x584.png 1150w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2021\/09\/Screen-Shot-2021-09-09-at-7.44.51-AM-750x381.png 750w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2021\/09\/Screen-Shot-2021-09-09-at-7.44.51-AM-400x203.png 400w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2021\/09\/Screen-Shot-2021-09-09-at-7.44.51-AM-250x127.png 250w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2021\/09\/Screen-Shot-2021-09-09-at-7.44.51-AM.png 1560w\" sizes=\"(max-width: 1024px) 100vw, 1024px\" \/><\/figure><\/div>\n\n\n\n<p>Hence we need to configure the TIM2 to generate 50Hz PWM signal on PA0 pin<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">2. Connection:<\/h2>\n\n\n\n<p>In this guide, we need the following<\/p>\n\n\n\n<ul class=\"wp-block-list\"><li>STM32F411 Nucleo<\/li><li>SG90 microservo<\/li><li>Hock-up wires<\/li><\/ul>\n\n\n\n<div class=\"wp-block-image\"><figure class=\"aligncenter size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"900\" height=\"1024\" src=\"https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2021\/09\/Screen-Shot-2021-09-09-at-7.41.22-AM-900x1024.png\" alt=\"\" class=\"wp-image-395\" srcset=\"https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2021\/09\/Screen-Shot-2021-09-09-at-7.41.22-AM-900x1024.png 900w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2021\/09\/Screen-Shot-2021-09-09-at-7.41.22-AM-264x300.png 264w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2021\/09\/Screen-Shot-2021-09-09-at-7.41.22-AM-768x873.png 768w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2021\/09\/Screen-Shot-2021-09-09-at-7.41.22-AM-1351x1536.png 1351w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2021\/09\/Screen-Shot-2021-09-09-at-7.41.22-AM-1150x1308.png 1150w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2021\/09\/Screen-Shot-2021-09-09-at-7.41.22-AM-750x853.png 750w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2021\/09\/Screen-Shot-2021-09-09-at-7.41.22-AM-400x455.png 400w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2021\/09\/Screen-Shot-2021-09-09-at-7.41.22-AM-250x284.png 250w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2021\/09\/Screen-Shot-2021-09-09-at-7.41.22-AM.png 1370w\" sizes=\"(max-width: 900px) 100vw, 900px\" \/><figcaption>Connection<\/figcaption><\/figure><\/div>\n\n\n\n<div class=\"wp-block-image\"><figure class=\"aligncenter size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"768\" src=\"https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2021\/09\/IMG_6420-1-1024x768.jpg\" alt=\"\" class=\"wp-image-397\" srcset=\"https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2021\/09\/IMG_6420-1-1024x768.jpg 1024w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2021\/09\/IMG_6420-1-300x225.jpg 300w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2021\/09\/IMG_6420-1-768x576.jpg 768w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2021\/09\/IMG_6420-1-1536x1152.jpg 1536w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2021\/09\/IMG_6420-1-2048x1536.jpg 2048w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2021\/09\/IMG_6420-1-1150x863.jpg 1150w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2021\/09\/IMG_6420-1-750x563.jpg 750w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2021\/09\/IMG_6420-1-400x300.jpg 400w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2021\/09\/IMG_6420-1-250x188.jpg 250w\" sizes=\"(max-width: 1024px) 100vw, 1024px\" \/><figcaption>Actual connection<\/figcaption><\/figure><\/div>\n\n\n\n<h2 class=\"wp-block-heading\">3. Code:<\/h2>\n\n\n\n<div class=\"wp-block-codemirror-blocks-code-block code-block\"><pre class=\"CodeMirror\" data-setting=\"{&quot;showPanel&quot;:true,&quot;languageLabel&quot;:&quot;language&quot;,&quot;fullScreenButton&quot;:true,&quot;copyButton&quot;:true,&quot;mode&quot;:&quot;clike&quot;,&quot;mime&quot;:&quot;text\/x-csrc&quot;,&quot;theme&quot;:&quot;dracula&quot;,&quot;lineNumbers&quot;:false,&quot;styleActiveLine&quot;:false,&quot;lineWrapping&quot;:false,&quot;readOnly&quot;:true,&quot;fileName&quot;:&quot;&quot;,&quot;language&quot;:&quot;C&quot;,&quot;maxHeight&quot;:&quot;400px&quot;,&quot;modeName&quot;:&quot;c&quot;}\">#include &quot;stm32f4xx.h&quot;                  \/\/ Device header\nvoid GPIO_Init(void);\nvoid Timer2_init(void);\nvoid delay(int ms );\nvoid servo_write(uint8_t angle);\n\nint pos;\nint main(void)\n{\n\nGPIO_Init();\nTimer2_init();\nwhile(1)\n{\nfor (pos = 0; pos &lt;= 180; pos += 1) { \/\/ goes from 0 degrees to 180 degrees\n    \/\/ in steps of 1 degree\n    servo_write(pos);              \/\/ tell servo to go to position in variable 'pos'\n    delay(15);                       \/\/ waits 15ms for the servo to reach the position\n  }\n  for (pos = 180; pos &gt;= 0; pos -= 1) { \/\/ goes from 180 degrees to 0 degrees\n    servo_write(pos);              \/\/ tell servo to go to position in variable 'pos'\n    delay(15);                       \/\/ waits 15ms for the servo to reach the position\n  }\n\n}\n}\n\nvoid GPIO_Init(void)\n{\nRCC-&gt;AHB1ENR|=RCC_AHB1ENR_GPIOAEN;\nGPIOA-&gt;AFR[0]|=(1&lt;&lt;0);\nGPIOA-&gt;MODER|=(1&lt;&lt;1);\n\n}\nvoid  Timer2_init(void){\nRCC-&gt;APB1ENR|=RCC_APB1ENR_TIM2EN; \/\/enable clock access tto tim2\nTIM2-&gt;PSC=4; \/\/set prescaller to 4 (16000000Hz\/4=4000000Hz)\nTIM2-&gt;ARR=63999; \/\/set the maximum count value \nTIM2-&gt;CNT=0; \/\/seset the current count\nTIM2-&gt;CCMR1=(1&lt;&lt;5)|(1&lt;&lt;6); \/\/configure the pins as PWM\nTIM2-&gt;CCER|=0x1; \/\/enbale channel1 and channel2\nTIM2-&gt;CR1=1; \/\/enable timer\n}\n\n\nvoid delay(int ms)\n\n{\n\nint i;\n\nfor(; ms&gt;0 ;ms--)\n\n{\n\nfor(i =0; i&lt;3195;i++);\n\n}\n\n}\n\nlong map(long x, long in_min, long in_max, long out_min, long out_max)\n{\n  return (x - in_min) * (out_max - out_min) \/ (in_max - in_min) + out_min;\n}\n\n\nvoid servo_write(uint8_t angle)\n\t{\n\t\n\tif(angle&lt;0){angle=0;}\n\tif(angle&gt;180){angle=180;}\n\t\n\t\nTIM2-&gt;CCR1=map (angle,0,180,2500,7000);\n\t\n\t\n\t\n\t}<\/pre><\/div>\n\n\n\n<h2 class=\"wp-block-heading\">4. Demo:<\/h2>\n\n\n\n<figure class=\"wp-block-video\"><video controls src=\"https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2021\/09\/IMG_6421.mp4\"><\/video><\/figure>\n","protected":false},"excerpt":{"rendered":"<p>In pervious PWM guide (here), discussed how to use TIM2 of STM32F411 to generate 2 PWM signals to fade 2 LEDs. In this guide, we shall use PWM signal to control a servo motor (SG90). In this guide, we shall cover the following What is servo motor and how to control it Connection Code Demo [&hellip;]<\/p>\n","protected":false},"author":2,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[2,11,12],"tags":[],"class_list":["post-392","post","type-post","status-publish","format-standard","hentry","category-embedded-systems","category-peripheral-drivers","category-stm32"],"_links":{"self":[{"href":"https:\/\/blog.embeddedexpert.io\/index.php?rest_route=\/wp\/v2\/posts\/392"}],"collection":[{"href":"https:\/\/blog.embeddedexpert.io\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/blog.embeddedexpert.io\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/blog.embeddedexpert.io\/index.php?rest_route=\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/blog.embeddedexpert.io\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=392"}],"version-history":[{"count":2,"href":"https:\/\/blog.embeddedexpert.io\/index.php?rest_route=\/wp\/v2\/posts\/392\/revisions"}],"predecessor-version":[{"id":400,"href":"https:\/\/blog.embeddedexpert.io\/index.php?rest_route=\/wp\/v2\/posts\/392\/revisions\/400"}],"wp:attachment":[{"href":"https:\/\/blog.embeddedexpert.io\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=392"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/blog.embeddedexpert.io\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=392"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/blog.embeddedexpert.io\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=392"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}