{"id":1156,"date":"2017-08-01T17:57:28","date_gmt":"2017-08-01T16:57:28","guid":{"rendered":"http:\/\/ofalcao.pt\/blog\/?p=1156"},"modified":"2018-09-06T10:52:55","modified_gmt":"2018-09-06T09:52:55","slug":"rc-servo-motors-with-linux","status":"publish","type":"post","link":"https:\/\/ofalcao.pt\/blog\/2017\/rc-servo-motors-with-linux","title":{"rendered":"RC servo motors with linux"},"content":{"rendered":"<div class=\"seriesmeta\">This post is part 1 of 2 of \u00a0<a href=\"https:\/\/ofalcao.pt\/blog\/series\/lego-compatible-rc-servos\" class=\"series-342\" title=\"LEGO-compatible RC servos\">LEGO-compatible RC servos<\/a><\/div><p>You can use RC servo motors with any Arduino. Even with a Raspberry Pi, no need for special hardware &#8211; just connect the signal wire to a free GPIO and send a short every 20 ms or so, where the position of the motor is proportional to the length of the pulse (usually between 0 and 2 ms).<\/p>\n<p>A &#8220;normal&#8221; computer doesn&#8217;t have GPIO pins so some kind of controller is needed. I have a <a href=\"https:\/\/www.pololu.com\/docs\/0J40\/1.b\">Pololu Mini Maestro<\/a> that can control several RC servo motors at once through USB or UART &#8211; in my case up to 24 motors.<\/p>\n<p>It works great with linux &#8211; the Maestro Control Center is a .Net Framework application that runs fine with Mono but after initial setup a simple bash script is enough.<\/p>\n<p>So the fastest (not the best) walk through:<\/p>\n<p>Connect the Maestro with an USB cable and run &#8216;dmesg&#8217; to see if it was recognized &#8211; two virtual serial ports should be created:<\/p>\n<pre>[ 1611.444253] usb 1-3: new full-speed USB device number 7 using xhci_hcd\r\n[ 1611.616717] usb 1-3: New USB device found, idVendor=1ffb, idProduct=008c\r\n[ 1611.616724] usb 1-3: New USB device strings: Mfr=1, Product=2, SerialNumber=5\r\n[ 1611.616728] usb 1-3: Product: Pololu Mini Maestro 24-Channel USB Servo Controller\r\n[ 1611.616732] usb 1-3: Manufacturer: Pololu Corporation\r\n[ 1611.616735] usb 1-3: SerialNumber: 00094363\r\n[ 1611.646820] cdc_acm 1-3:1.0: ttyACM0: USB ACM device\r\n[ 1611.649542] cdc_acm 1-3:1.2: ttyACM1: USB ACM device\r\n[ 1611.651109] usbcore: registered new interface driver cdc_acm\r\n[ 1611.651112] cdc_acm: USB Abstract Control Model driver for USB modems and ISDN adapters<\/pre>\n<p>The first one (&#8216;\/dev\/ttyACM0&#8217;) is the &#8216;Command Port&#8217; and the second one (&#8216;\/dev\/ttyACM&#8217;1) is the &#8216;TTL Serial Port&#8217;.<\/p>\n<p>We download and extract the <a href=\"https:\/\/www.pololu.com\/file\/download\/maestro-linux-150116.tar.gz?file_id=0J315\">Maestro Servo Controller Linux Software<\/a> from Pololu site. To run it we need Mono and libusb, the (excellent!) <a href=\"https:\/\/www.pololu.com\/docs\/0J40\/\">User Guide<\/a> gives this command:<\/p>\n<pre>sudo apt-get install libusb-1.0-0-dev mono-runtime libmono-winforms2.0-cil<\/pre>\n<p>I already had libusb and with current Ubuntu (17.04) the Mono packages are different:<\/p>\n<pre>Package libmono-winforms2.0-cil is not available, but is referred to by another package.\r\nThis may mean that the package is missing, has been obsoleted, or\r\nis only available from another source\r\nHowever the following packages replace it:\r\n mono-reference-assemblies-2.0 mono-devel<\/pre>\n<p>so I ran instead<\/p>\n<pre>sudo apt install mono-devel<\/pre>\n<p>It will work but it will give an access error to the device. We can follow the manual and create an udev rule or just use sudo:<\/p>\n<pre>sudo mono MaestroControlCenter<\/pre>\n<p>We will probably find our Maestro ruuning in default serial mode, i.e. &#8216;UART, fixed baud rate: 9600&#8217; but we change that to &#8216;USB Dual Port&#8217; so we can control our servos directly from the shell without the Maestro Control Center:<a href=\"https:\/\/i0.wp.com\/ofalcao.pt\/blog\/wp-content\/uploads\/2017\/08\/maestro01.png\"><img data-recalc-dims=\"1\" loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-1157\" src=\"https:\/\/i0.wp.com\/ofalcao.pt\/blog\/wp-content\/uploads\/2017\/08\/maestro01.png?resize=686%2C741\" alt=\"\" width=\"686\" height=\"741\" \/><\/a>But now that we are here let&#8217;s also see Status:<\/p>\n<p><a href=\"https:\/\/i0.wp.com\/ofalcao.pt\/blog\/wp-content\/uploads\/2017\/08\/maestro02.png\"><img data-recalc-dims=\"1\" loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-1158\" src=\"https:\/\/i0.wp.com\/ofalcao.pt\/blog\/wp-content\/uploads\/2017\/08\/maestro02.png?resize=686%2C741\" alt=\"\" width=\"686\" height=\"741\" \/><\/a>We can control our servos from here if we want.<\/p>\n<p>Now back to the command line &#8211; in &#8216;USB Dual Port Mode&#8217; we can control our servos sending commands to the Command Port (i.e. &#8216;\/dev\/ttyACM0&#8217;). There are several protocols available, let&#8217;s just see the Compact Protocol:<\/p>\n<pre>echo -n -e \"\\x84\\x00\\x70\\x2E\" &gt; \/dev\/ttyACM0<\/pre>\n<p>Four bytes are used:<\/p>\n<ul>\n<li>the first byte is always &#8220;84h&#8221; and it means we are using the &#8220;set target&#8221; command<\/li>\n<li>the second byte is the channel number so my Maestro can accept a number between 0 and 23<\/li>\n<li>the third and fourth bytes is the length of the pulse but in a special format:<\/li>\n<\/ul>\n<p>The value is in quarters of microseconds. So for a 1.5 ms (1500 \u00b5s) we will use 6000. Usually this is the middle (center) position of the servo.<\/p>\n<p>Also \u00abthe lower 7 bits of the third data byte represent bits 0\u20136 of the target (the lower 7 bits), while the lower 7 bits of the fourth data byte represent bits 7\u201313 of the target\u00bb. So<\/p>\n<p>So 6000d = 1770h<\/p>\n<p>The third byte is calculated with a bitwise AND:<\/p>\n<p>1770h &amp; 7Fh = 70h<\/p>\n<p>And the fourth byte is calcultated with a shift and an AND:<\/p>\n<p>1770h &gt;&gt; 7 = 2Eh<\/p>\n<p>2Eh &amp; 7Fh = 2Eh<\/p>\n<p>So 1500 \u00b5s is represented as 70h 2Eh<\/p>\n<p>Pololu makes life easier with a bash script, &#8216;maestro-set-target.sh&#8217;:<\/p>\n<pre>#!\/bin\/bash\r\n# Sends a Set Target command to a Pololu Maestro servo controller\r\n# via its virtual serial port.\r\n# Usage: maestro-set-target.sh DEVICE CHANNEL TARGET\r\n# Linux example: bash maestro-set-target.sh \/dev\/ttyACM0 0 6000\r\n# Mac OS X example: bash maestro-set-target.sh \/dev\/cu.usbmodem00234567 0 6000\r\n# Windows example: bash maestro-set-target.sh '\\\\.\\USBSER000' 0 6000\r\n# Windows example: bash maestro-set-target.sh '\\\\.\\COM6' 0 6000\r\n# CHANNEL is the channel number\r\n# TARGET is the target in units of quarter microseconds.\r\n# The Maestro must be configured to be in USB Dual Port mode.\r\nDEVICE=$1\r\nCHANNEL=$2\r\nTARGET=$3\r\n\r\nbyte() {\r\n printf \"\\\\x$(printf \"%x\" $1)\"\r\n}\r\n\r\nstty raw -F $DEVICE\r\n\r\n{\r\n byte 0x84\r\n byte $CHANNEL\r\n byte $((TARGET &amp; 0x7F))\r\n byte $((TARGET &gt;&gt; 7 &amp; 0x7F))\r\n} &gt; $DEVICE<\/pre>\n<p>So instead of echo&#8217;ing &#8220;\\x84\\x00\\x70\\x2E&#8221;\u00a0 to the Command Port we can also use<\/p>\n<pre>.\/maestro-set-target.sh \/dev\/ttyACM0 0 6000<\/pre>\n<p>So now we can control a servo with common bash commands. For example this script makes the servo rotate from left to right then back in 20 increments then repeats it 4 times:<\/p>\n<pre>#!\/bin\/bash\r\n\r\nsleep 5\r\nfor j in `seq 1 5`;\r\ndo\r\n  for i in `seq 4000 200 8000`;\r\n  do\r\n    .\/maestro-set-target.sh \/dev\/ttyACM0 0 $i\r\n    sleep 0.1\r\n  done\r\n  for i in `seq 8000 -200 4000`;\r\n  do\r\n    .\/maestro-set-target.sh \/dev\/ttyACM0 0 $i\r\n    sleep 0.1 \r\n  done\r\ndone<\/pre>\n<div class=\"jetpack-video-wrapper\"><iframe loading=\"lazy\" title=\"Pololu Mini Maestro\" width=\"840\" height=\"473\" src=\"https:\/\/www.youtube.com\/embed\/2rORYV27Z8o?feature=oembed\" frameborder=\"0\" allow=\"accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share\" referrerpolicy=\"strict-origin-when-cross-origin\" allowfullscreen><\/iframe><\/div>\n<p>So we can now control up to 24 servo motors.<\/p>\n<p>So let&#8217;s control a special servo motor, more related to my hobby:<\/p>\n<p><img data-recalc-dims=\"1\" decoding=\"async\" src=\"https:\/\/i0.wp.com\/www.4dbrix.com\/documentation\/arduino\/1.02.001\/1.02.001.png?w=840&#038;ssl=1\" \/><\/p>\n<p>That&#8217;s a <a href=\"https:\/\/www.4dbrix.com\/documentation\/arduino\/1.02.001\/\">4DBrix Standard Servo Motor<\/a>, a motor that 4DBrix sells for controlling LEGO train or monorail models. They also sell their own USB controller but since it is in fact a pretty common RC micro servo inside a 3D printed LEGO-compatible ABS housing we can also use the Maestro:<\/p>\n<p>The same script:<\/p>\n<div class=\"jetpack-video-wrapper\"><iframe loading=\"lazy\" title=\"Pololu Maestro and 4DBrix Servo Motor\" width=\"840\" height=\"473\" src=\"https:\/\/www.youtube.com\/embed\/2weMXFjmDUc?feature=oembed\" frameborder=\"0\" allow=\"accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share\" referrerpolicy=\"strict-origin-when-cross-origin\" allowfullscreen><\/iframe><\/div>\n<p>These motors work fine with 4DBrix LEGO-compatible monorail parts:<\/p>\n<div class=\"jetpack-video-wrapper\"><iframe loading=\"lazy\" title=\"Pololu Maestro and 4DBrix motors and monorail parts\" width=\"840\" height=\"473\" src=\"https:\/\/www.youtube.com\/embed\/NaIXOm-8uwI?feature=oembed\" frameborder=\"0\" allow=\"accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share\" referrerpolicy=\"strict-origin-when-cross-origin\" allowfullscreen><\/iframe><\/div>\n<p>But better yet&#8230; the Maestro also works fine with ev3dev:<\/p>\n<div class=\"jetpack-video-wrapper\"><iframe loading=\"lazy\" title=\"Pololu Maestro and MINDSTORMS EV3\" width=\"840\" height=\"473\" src=\"https:\/\/www.youtube.com\/embed\/03Js88W6DdE?feature=oembed\" frameborder=\"0\" allow=\"accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share\" referrerpolicy=\"strict-origin-when-cross-origin\" allowfullscreen><\/iframe><\/div>\n<p>I now realize it wasn&#8217;t very clever to show motors rotating slowly when the monorail switches only have two functional states so this new video looks a little better, with the three 4DBrix servo motors and the LEGO EV3 medium motor changing the state of the monorail switches every second:<\/p>\n<div class=\"jetpack-video-wrapper\"><iframe loading=\"lazy\" title=\"MINDSTORMS controlling monorail\" width=\"840\" height=\"473\" src=\"https:\/\/www.youtube.com\/embed\/k7gFy-sgrKQ?feature=oembed\" frameborder=\"0\" allow=\"accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share\" referrerpolicy=\"strict-origin-when-cross-origin\" allowfullscreen><\/iframe><\/div>\n<p>So I can now control 24 RC Servo motors with my MINDSTORMS EV3.<\/p>\n<p>Even better: we can add several Maestros through an USB hub&#8230; so why just 24 motors? With 126 Mini Maestros 24ch and an USB hub we could use\u00a0<strong>3024<\/strong> motors \ud83d\ude42<\/p>\n","protected":false},"excerpt":{"rendered":"<div class=\"seriesmeta\">This post is part 1  of 2 of \u00a0<a href=\"https:\/\/ofalcao.pt\/blog\/series\/lego-compatible-rc-servos\" class=\"series-342\" title=\"LEGO-compatible RC servos\">LEGO-compatible RC servos<\/a><\/div><p>You can use RC servo motors with any Arduino. Even with a Raspberry Pi, no need for special hardware &#8211; just connect the signal wire to a free GPIO and send a short every 20 ms or so, where the position of the motor is proportional to the length of the pulse (usually between 0 &hellip; <a href=\"https:\/\/ofalcao.pt\/blog\/2017\/rc-servo-motors-with-linux\" class=\"more-link\">Continuar a ler<span class=\"screen-reader-text\"> &#8220;RC servo motors with linux&#8221;<\/span><\/a><\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_jetpack_memberships_contains_paid_content":false,"footnotes":"","jetpack_publicize_message":"","jetpack_publicize_feature_enabled":true,"jetpack_social_post_already_shared":true,"jetpack_social_options":{"image_generator_settings":{"template":"highway","enabled":false},"version":2}},"categories":[154,18,158,19,148,20,299],"tags":[312,169,261,130],"series":[342],"class_list":["post-1156","post","type-post","status-publish","format-standard","hentry","category-lego-en","category-lego","category-lego-mindstorms-en","category-lego-mindstorms","category-linux-en","category-linux","category-mindstorms","tag-controller","tag-rc","tag-servo-pt","tag-usb","series-lego-compatible-rc-servos"],"jetpack_publicize_connections":[],"jetpack_featured_media_url":"","jetpack_sharing_enabled":true,"jetpack_shortlink":"https:\/\/wp.me\/p2Mhyv-iE","_links":{"self":[{"href":"https:\/\/ofalcao.pt\/blog\/wp-json\/wp\/v2\/posts\/1156","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/ofalcao.pt\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/ofalcao.pt\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/ofalcao.pt\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/ofalcao.pt\/blog\/wp-json\/wp\/v2\/comments?post=1156"}],"version-history":[{"count":0,"href":"https:\/\/ofalcao.pt\/blog\/wp-json\/wp\/v2\/posts\/1156\/revisions"}],"wp:attachment":[{"href":"https:\/\/ofalcao.pt\/blog\/wp-json\/wp\/v2\/media?parent=1156"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/ofalcao.pt\/blog\/wp-json\/wp\/v2\/categories?post=1156"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/ofalcao.pt\/blog\/wp-json\/wp\/v2\/tags?post=1156"},{"taxonomy":"series","embeddable":true,"href":"https:\/\/ofalcao.pt\/blog\/wp-json\/wp\/v2\/series?post=1156"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}