5 Fun Projects for Raspberry Pi 3 A publication of The Linux Foundation Training and Linux.com Tutorials by Ruth Suehle, Swapnil Bhartiya, and Ben Martin The Linux Foundation Training Publication www.training.linuxfoundation.org © Copyright 2016 The Linux Foundation. All rights reserved. The training materials provided or developed by The Linux Foundation in connection with the training services are protected by copyright and other intellectual property rights. At The Linux Foundation, we believe the best way to learn is by doing. Dive in and try it. Learn from your mistakes. Tinker until it works. And most important: have fun. Then share what you’ve learned with the community! It’s the open source way. The Raspberry Pi was founded on these educational principles, which is why we’re giving it to anyone who takes one of our foundational e-learning courses. It’s a great way to learn Linux and embedded systems or to advance your understanding through tinkering. Potential projects range from simple software installs and home automation, to complex robotics and supercomputing. Use it for anything you can imagine or desire. This e-book will give you a starting point and help you make the most of your Raspberry Pi. Here you’ll find an insider’s guide to getting started from Ruth Suehle, author of O’Reilly’s Raspberry Pi Hacks, as well as five fun handson tutorials from Linux.com writers Swapnil Bhartiya and Ben Martin. We hope you’ll enjoy tinkering with your new Pi, and learn some valuable skills along the way. Thank you for choosing The Linux Foundation Training! Copyright 2016, The Linux Foundation. All rights reserved. The training materials provided or developed by The Linux Foundation in connection with the training services are protected by copyright and other intellectual property rights. Open source code incorporated herein may have other copyright holders and is used pursuant to the applicable open source license. Although third-party application software packages may be referenced herein, this is for demonstration purposes only and shall not constitute an endorsement of any of these software applications. All The Linux Foundation training, including all the material provided herein, is supplied without any guarantees from The Linux Foundation. The Linux Foundation assumes no liability for damages or legal action arising from the use or misuse of contents or details contained herein. Linux is a registered trademark of Linus Torvalds. Other trademarks within this course material are the property of their respective owners. If you believe The Linux Foundation materials are being used, copied, or otherwise improperly distributed, please email [email protected] or call +1-415-723-9709(USA). Contents Getting Started With Raspberry Pi 4 Power it up 6 Add a reset switch 6 Meet the GPIO 7 Find a project 8 How to Build a Minecraft Server with Raspberry Pi 3 9 Build Your Own Netflix and Pandora With Raspberry Pi 3 14 Turn Raspberry Pi 3 Into a Powerful Media Player With RasPlex 20 How to Set Up a Remote-Controlled Holiday Music and Light Show 27 Build an Off-Road Raspberry Pi Robot 41 Conclusion 65 Getting Started With Raspberry Pi By Ruth Suehle Nearly five years after the first Raspberry Pi boards shipped, the device continues to far surpass its expected popularity, spreading well beyond its originally intended purpose as an educational tool. Though creator Eben Ubton originally hoped to sell at most 10,000 boards, more than 10 million are now in the hands of students, teachers, and makers. In addition to three generations of the Raspberry Pi, you can also now have the even smaller Raspberry Pi Zero, as well as several additional products, from the Compute Module to the specially designed cameras, touchscreen, and assorted HATs (Hardware Attached on Top boards). With so much available and so many possibilities, it can be intimidating to know where to start. Use these tips to learn some basic information about starting your own project. This article assumes you know what a Raspberry Pi is, how to connect things like a keyboard and a display, and how to use a Linux command line, but not much else. (See the official Raspberry Pi help videos for the basics.) WHICH PI DO I HAVE? If you’ve had a Raspberry Pi sitting in your desk drawer for so long that you’re not even sure any more what version it is, you’re not alone. Whenever I give a talk on the Raspberry Pi, I ask how many people have one, and generally most of the room confesses to owning one while only a handful have actually used it. Beyond the amount of RAM, which is the most obvious difference in the earlier boards, or big changes like the additional GPIO in later boards (which is easily apparent), there are some minor distinctions that can be useful to know as you plan your project or troubleshoot problems. With some visual examination, you can generally figure out which board you have by looks alone, but there’s an easier way using the command line. Start your Pi, open a terminal, and run the command cat /proc/cpuinfo | grep ‘Revision’ The output should be a four- or six-character string that indicates which board you have: 0002, 0003, 004, 0005, 0006 Model B with 256 MB RAM 0007, 0008, 0009 Model A with 256 MB RAM 000d, 000e, 000f Model B with 512 MB RAM 0010, 0013 Model B+ 0012, 0015 Model A+ a01040, a01041, a21041 Raspberry Pi 2 a02082, a22082 Raspberry Pi 3 If you see a very long number that starts with “1000,” the part after that is the revision number, and the “1000” indicated that your board has been overvolted. The following will give you a quick comparison of the major features across the various boards: If you would like to see even more information about your board from the command line, try the following commands: • Hardware: cat /proc/cpuinfo • Version: cat /proc/version • Memory: cat /proc/memory • SD card partitions: cat /proc/cpuinfo Power it up You’re probably accustomed to some general truths about the electronics in your house. You plug them into the wall, flip an on/off switch, and they work. The Raspberry Pi is not one of these electronics. Getting a good power supply and cable that provide clean, adequate, consistent power is crucial to your Pi’s performance. And there’s no on/off switch. But that’s ok--you can make one. HOW MUCH POWER IS ENOUGH? If you think that insufficient power may be a problem (and if you’re having problems with a Pi, there’s a good chance it’s the power), you can check the actual voltage to see if you’re right. On an older Model B, you’re looking for small holes on top of the board marked TP1 and TP2. On a Model B+ or Raspberry Pi 2 or 3, there are spots on the bottom of the board on the side with the SD card slot that are marked PP3 and PP7. First, plug in all of the peripherals you’ll be using for your project. Use a multimeter set to 20 volts. Touch the red lead to TP1 or PP3 and the black lead to TP2 or PP7. The multimeter should read something close to 5 volts. Anything more than .25 volts variance is a problem, and the closer to 5, the better. If you find your voltage is low, there are two most likely culprits: • Your power cable. The good news about the Raspberry Pi is that if you use an Android phone, you almost certainly already have a multitude of micro USB cables ready to power your Pi. The bad news is that if you picked that cable up from the discount bin, it may give your phone a slow drip that’s enough for a phone recharge, but your Pi won’t be amused by the dribble of electricity you’re offering. • Your devices. All those USB peripherals you’re plugging into it--even your lowly keyboard--are hungry for power. You should use a powered USB hub to help out. Add a reset switch Now that you know some basics, and you’ve tested your power source, you’re ready for a quick and easy project that will make your Pi feel more like the rest of the electronics you have. You’re going to add a simple reset switch. Most of the electronics you own come with on/off switches. Because the Pi doesn’t, to restart it, you have to pull the power cable out altogether and reinsert it. The following instructions will let you start or reboot the Pi quickly without having to do so. You’re looking for two holes on the board next to each other. One has a circular edge and the other a square. On the original Model B, they’re marked “P6” and are found near the HDMI port. On later Raspberry Pis, they’re marked “RUN” and can be found closer to the GPIO pins. You can purchase strips of breakaway pin headers from anywhere you get other electronics supplies. Solder two of these pins into the P6/RUN holes, and you’ve created a CPU reset switch. All you have to do is touch a piece of metal across both pins. From here, you can get as creative as you’d like about what to attach to use as the actual button. The simplest solution is to attach a 2-pin switch cable on the pins you attached. Meet the GPIO Aside from its low price point, the GPIO options on the Raspberry Pi are one of its most appealing features. They are also the part most likely to intimidate new users. (And if you think stepping on an errant Lego brick hurts, don’t leave your Pi with the GPIO side up on the floor!) GPIO stands for “general purpose input/output,” which is exactly what these pins do. Nearly all of the awesome projects you’ve seen built with Raspberry Pis take advantage of these pins in some fashion. Their flexibility is their strength! The earlier boards had 26 GPIO pins, while the Raspberry Pi 2 and 3 have 40. (Technically only 17 of the 26 and 28 of the 40 are GPIO, while the rest are power or ground pins.) They are referred to with pin numbers. The numbers aren’t in any logical order, so you need a diagram to make sure you’re using the right ones. (To add to the confusion, you will sometimes see them referred to by their physical pin numbers, which is the pins counted in order.) If you’re going to be using the GPIO frequently, I recommend Simon Monk’s Raspberry Leaf project, which is a tiny printout of the pins you can lay over them for reference. If you have a 26-pin Pi, you can print one yourself on Monk’s website, or if you have a 40-pin Pi, you can buy them from Adafruit in paper and hard versions. Now that you know which is which, you’ll need a way to tell the pins what you want them to do, which is going to require a bit of programming. If you’re a beginner, the Pi part of the Raspberry Pi name comes from its original intent as a tool to teach Python, so in a way, you’re using the Pi for its original purpose! (Even if your endpoint is an automated coffeepot or killer robot.) Of course, teaching you Python is well beyond the scope of this article, but there are plenty of resources waiting. Sparkfun and Adafruit both have starter tutorials for how to use the GPIO, and the Raspberry Pi Foundation’s learning resources include a Python Intro. If you prefer to go more in-depth with a book, there are a few options, including Learning Python with Raspberry Pi and Programming the Raspberry Pi: Getting Started with Python, written by the aforementioned Simon Monk. Finally, Pinout.xyz can serve throughout your project as a reference tool for each of the pins. Find a project The best thing you can do now is start making something. Even if you’ve never written a line of code or touched a soldering iron, the Raspberry Pi is a perfect learning tool for those things and more. But what to build? If you’re still nervous and want to have something useful that requires writing no code nor touching the GPIO, I recommend setting up Kodi (previously called XBMC). In minutes, you can turn your Pi into a functioning media center. Once you’ve done that and you’re ready to get braver, think about what interests you. Video games? Home automation? Photography? Whatever it is, chances are good that someone has built something similar and offered their instructions online. Follow them. Make your own changes. Find improvements, or fix problems in the original version. That’s the best way to learn. And once you’ve done so, don’t forget to share what you’ve done with others. To get you started on ideas, here are a few of my favorite projects for a variety of interests: • The Cupcade is the easiest way to build your own tiny gaming system. There are tons of video game build tutorials out there, but if you’re more interested in starting with a kit, this provides all the pieces you need for a satisfying project. (If you’re more of a builder and would like to go bigger, take a look at the Coffee Table Pi.) • Homebrewers who would like to take their brewing to the next level should try BrewPi. • If you have access to a 3D printer and would like an amusing but not terribly useful device where all the code’s been written for you, try the Pi Ball. • One of the most popular Pi projects is the MagicMirror. It’s customizable to your interests, useful to have in your house, and all of the code is on Github. • If you’d like to try robotics, the options are broad. Start with this DIY Hacking tutorial. Adafruit has an introductory robot tutorial as well. From there, the possibilities are up to you! How to Build a Minecraft Server with Raspberry Pi 3 By Swapnil Bhartiya The beauty of the Raspberry Pi 3 is that you can tinker and do fun stuff to your heart’s content. This tiny $35 computer lets you do anything. The Pi I have runs Raspbian for other uses. I keep several micro SD cards, each with different applications and swap them to get more out of the same Pi. In this tutorial, you’ll learn how to set up a Minecraft machine on the Pi 3 from scratch. Minecraft is a fun game that lets you build whole worlds however you want, by yourself or with friends. Having your own Minecraft server gives you full control over the game. I set up a Minecraft server because we don’t watch TV but we have one TV in the kids’ area that I have hooked a Pi to it so my son can play Minecraft. In the next two tutorials, you’ll learn how to transform your Pi 3 into your own custom Netflix/Pandora-like streaming service with Plex Media Server and then how to use the Pi as a Plex media player to stream content directly to your HDMI-enabled TV. What you need • Raspberry Pi 3 • HDMI enabled monitor • Keyboard+mouse • HDMI cable • Power adapter for Pi • Micro SD card (I am using 32GB capacity) • Ethernet or Wireless connectivity We are using the ‘NOOBS’ distribution installer, just to make things easier for new users. Download ‘NOOBS’ from the official site and extract the content. Now plug in the micro SD card and format it as FAT32. Then copy all the extracted files to the root of the SD card. Note: Don’t copy the entire folder, copy the content of the folder. Plug the card into Raspberry Pi , connect the monitor via HDMI, connect the mouse/keyboard and plug in the power supply. If everything goes well, you will see the ‘NOOBS’ window where you can choose the OS that you want to install; I recommend Raspbian. Once installed it will reboot and you are logged into your brand new Raspbian OS running on Raspberry Pi 3. Now connect the network (I recommend ethernet to get faster download speed) and update the system: sudo apt-get update sudo apt-get dist-upgrade If you want you can also change the user password. The default username is ‘pi’ and password is ‘raspberry’. Change the password by typing the command, and then the new password at the prompt: passwd pi Now install these packages for OpenGL Driver for improved graphics: sudo apt-get -y install xcompmgr libgl1-mesa-dri && sudo apt-get -y install libalut0 libalut-dev && sudo apt-get -y install mesa-utils Now it’s time to enable OpenGL drivers: sudo raspi-config Here you will see the option to expand the file system and change the password. We don’t need either of those because NOOBS automatically expands the file system and we have already changed the password. Skip everything and go to the advanced option. Scroll down to find ‘AB GL Driver’, hit enter and then select ‘yes’ to enable. (note: the mouse won’t work, so use arrow keys). Reboot the system. Once rebooted, check if OpenGL is enabled, run ‘glxgears’ in the terminal and you should see gears turning. INSTALL MINECRAFT PACKAGES First we need to create directories for Minecraft: mkdir -p ~/Minecraft/Natives Change directory to Minecraft: cd ~/Minecraft/ Now log into your Minecraft account and download the Minecraft.jar file for Linux to the Minecraft directory that we created. Install the launcher and log into your account: java -jar Minecraft.jar Click on the ‘edit profile’ option and select version ‘1.8.9’ from the list, save the profiles. If you get any error (there is a possibility of an error related to ‘execstack’) please close Minecraft and run these commands to patch some files: cd ~/Minecraft/Natives wget https://www.dropbox.com/s/4oxcvz3ky7a3x6f/liblwjgl.so wget https://www.dropbox.com/s/m0r8e01jg2og36z/libopenal.so Then update the libraries: cd /home/pi/.minecraft/libraries/org/lwjgl/lwjgl/lwjgl/2.9.4-nightly-20150209 rm lwjgl-2.9.4-nightly-20150209.jar wget https://www.dropbox.com/s/mj15sz3bub4dmr6/lwjgl-2.9.4-nightly-20150209.jar Change directory to Minecraft folder: cd ~/Minecraft/ And download the ‘run’ script: wget https://www.dropbox.com/s/jkhr58apwa7pt1w/run.sh Make it executable: sudo chmod +x run.sh Now either browse to this script from the file manager and open it by clicking on it or run it from the terminal and you will have Minecraft running on your machine (image below) cd ~/Minecraft/ ./run.sh That’s it! Once it’s installed, you can start playing Minecraft on your your system. Build new worlds, invite your friends to play on your server, and keep on tinkering with your new Pi 3. Build Your Own Netflix and Pandora With Raspberry Pi 3 By Swapnil Bhartiya Do you have a huge collection of movies, TV shows, and music that you purchased over the years but it’s collecting digital dust on your hard drives? How about creating your very own Netflix- and Pandora-like set-up using the free Plex Media Server software? No you don’t have to buy an expensive, bulky PC. All you need is a Raspberry Pi 3, a hard drive, an SD card and a mobile charger. It should all cost less than $100. What you need • PC or laptop • Raspberry Pi 3 • Micro SD card • A powered hard drive • 5v 2A power supply for Pi • Monitor, HDMI cable, keyboard and mouse (only for initial setup) • I also recommend a heat sink for Pi chips as multimedia consumption does make them hot • Ethernet cable (optional) I will be using it in a headless manner, but we do need a monitor with an HDMI cable for initial setup. On your PC/ laptop, download the ‘NOOBS’ distribution installer from the official site. It’s a zip file, which you’ll extract using the unzip command. Insert the Micro SD card and format it as FAT32 using Gnome Disk Utility. Then change directory to the Micro SD card: cd /path _ of _ USB And unzip the NOOBS file into the Micro SD card: unzip PATH _ OF _ NOOBS In my case it was unzip /home/swapnil/Downloads/NOOBS _ v1 _ 9 _ 2.zip Just ensure that all the content of the NOOBS folder is in the root directory of the Micro SD card. Now plug the monitor, keyboard and mouse into the Pi, insert the Micro SD card and connect the power supply. The system will boot up to NOOBS where you can choose the operating system you want to install. Choose Raspbian. Once the installation is finished, it will reboot into your brand new Raspbian OS. It will also automatically resize the file system to use all available space on the SD card. If you can use an ethernet cable, I would recommend that as it will give you faster speed compared to the wifi on board. If not, then use the wifi utility in Raspbian to connect to the wireless network. Once you are online, open the terminal and run the following command to find the IP address of your Pi: if config Once you have the IP address, open the terminal on your PC/laptop and ssh into your Pi: ssh pi@IP _ ADDRESS _ OF _ PI The default password for pi is ‘raspberry.’ If you want to change the password, run the following command and enter the new password after the prompt: passwd pi Now let’s update the system before we install Plex. This is a best practice for all fresh distro and software installations: sudo apt-get update sudo apt-get dist-upgrade Once updated, connect the external hard drive to your Pi using one of the USB ports. It’s best to use a hard drive that has been formatted in the ext4 file system for better compatibility with Linux. Mount it and create an entry in the ‘fstab’ so that it auto mounts between reboots. Now it’s time to install Plex Media Server. We are using packages created by a third-party developer so let’s add their GPG key: wget -O - https://dev2day.de/pms/dev2day-pms.gpg.key | sudo apt-key add - Now add repos to the source list file: echo “deb https://dev2day.de/pms/ jessie main” | sudo tee /etc/apt/sources.list.d/pms. list Now update the system: sudo apt-get update And then install Plex Media Server: sudo apt-get install -t jessie plexmediaserver -y Now run it: service plexmediaserver start That’s it. You have Plex Media Server running on your Raspberry Pi 3. SET UP YOUR MEDIA SERVER Plex Makes it extremely easy to set up your Plex Media Center. Now you need to point your Plex Media Center towards the media files: movies, music, and TV shows. You can do it from any PC in your local network. Just type this address into a web browser, filling in your own Pi’s IP address: IP_ADDRESS_OF_PI:32400/web/index.html# In my case it was: 10.0.0.26:32400/web/index.html# It will open the Plex Media Server interface. The greatest feature of Plex is metadata that it pulls from the internet and attaches to your media files. But it’s extremely important to categorize your media otherwise Plex won’t detect it. So create these folders on your hard drive and store appropriate media inside the folders: movies, tv_shows, music, home_videos, photos. Now copy movies to the movies folder, TV shows to the tv_shows folder, any videos that you take from your phone or camera to home_video folder and so on. If you copy TV shows or home videos to movies or vice versa, those files won’t show up on Plex and you won’t be able to play them. Once you have taken care of your media files, open the movie tab on the Plex Media Center interface and browse to add the ‘movies’ folder from your hard drive. Repeat the step for each media type. Once done give Plex some time to scan and process those files. Another interesting thing that you can do with your Plex is add online video channels such as CNN, PBS, History… Just go to the ‘Channels’ option and install channels that you like. Now all of these channels, in addition to your movies, tv shows, music and photos are accessible through your Plex server running on the Pi. ACCESS YOUR PLEX MEDIA SERVER There are many ways to access your Plex Media Center: 1) If you are on the local network open this URL in the web browser: IP_ADDRESS_OF_PI:32400/web/index.html# In my case it was: 10.0.0.26:32400/web/index.html# It will open the Plex Media Player interface, just log into your media server and start playing content. You can also manage your Plex Media Server from this interface. 2) You can access your Plex Media Server from mobile devices using the official Plex app that’s available for both Android and iOS. 3) Or you can set up a Plex Media Player device (such as RasPlex) and turn any HDMI-enabled TV into your very own entertainment system. (See the next tutorial on how to do this!) If you want to be able to access Plex outside of your home network then you can purchase PlexPass which allows you to stream your content across devices over the internet. Since Plex also remembers playback history and where you are in any content, you can also add family members, just like Netflix, so that you can maintain your own viewing history. All of this for just under $100, and you got to build it yourself. Isn’t it fun? Turn Raspberry Pi 3 Into a Powerful Media Player With RasPlex By Swapnil Bhartiya I have hundreds of movies, TV shows and music that I have bought over the years. They all reside on my Plex Media Server. Just like books, I tend to buy these works and watch them once in awhile, instead of relying on ‘streaming’ services like Netflix where content isn’t always available forever. If you already have Plex Media Server running, then you can build an inexpensive Plex Media Player using Raspberry Pi 3 and RasPlex. Plex Media Server is based on open source Kodi (formerly XBMC), but is not fully open source. Plex Media Center has a friendly interface and it’s very easy to set up a media center (See our previous tutorial on how to install it on a Raspberry Pi 3 or on another dedicated Linux machine). One of the best ways I’ve used my Raspberry Pi 3 was turning it into an extremely inexpensive media player. I get more out of my $35 Pi 3 than Chromecast, which costs almost the same. And if you already have a Plex Media Server running, it makes a lot of sense to turn those ‘dumb’ TV sets into powerful Plex Media players, without putting a hole in your pocket. What you need • A Raspberry Pi 3 • Micro SD card (minimum 8GB storage) • A Linux PC to prepare the Micro SD card • Monitor, keyboard and mouse for initial setup • 5V 2A micro USB mobile charger • Heat sink (Multimedia playback will get the chips hot. You can buy them online on Amazon.com) • A free Plex account (and paid PlexPass if you want to access it over the internet) • A TV with HDMI input • HDMI cable. Plug in your Micro SD card to the Linux system and download RasPlex installer from the official site. Open a terminal and go to the directory where the .bin file or RasPlex is downloaded. In my case it was in the ‘Downloads’ folder: cd /home/swapnil/Downloads Now make the file executable: sudo chmod +x GetRasplex-debian64.1.0.1.bin And then execute the file: sudo ./GetRasplex-debian64.1.0.1.bin (Note: The version number may change, so don’t just copy this command.) Now it will open the RasPlex SD card writer utility. Insert the Micro SD card to your Linux PC and hit the refresh button so it can detect the card. Once detected, choose Raspberry Pi 2 from the model number and version 1.6.2 (or the latest version) from the RasPlex. (Even if the image is for Pi2 it worked fine with Pi3). Next click on the ‘Download’ button to download the version of RasPlex. Once the image is downloaded, the ‘Write SD Card’ button will become active. Just hit the button and it will start writing the image to the card. Please install the heat sink on the chips (as shown below) so they absorb extra heat created while the Pi 3 is churning out HD videos. Plug your Raspberry Pi 3 into the TV using the HDMI cable. Connect the keyboard and insert the RasPlex Micro SD Card and power the device with your 5V mobile charger. You will see RasPlex on the screen. Let it install on the card and configure. Once configuration and installation is finished, you will see the welcome screen for the set-up wizard (below). If you are using a wireless network, then during the first set-up you can configure the wireless. [Image: Networking during RasPlex set up.] In case you want to change the wireless connection, you can always do that post installation from System Settings. [Image: Network system settings in RasPlex.] Once you are connected to the internet you can log into your Plex account. To make things easier, RasPlex asks you to open this URL (www.plex.tv/pin) in a browser on any device and enter the PIN shown on the RasPlex screen. Once you enter the PIN, RasPlex gets access to your Plex Media Server. Now you are ready to enjoy your Plex Media Server (running on another machine - perhaps another Pi 3!) on any TV in your house that has HDMI input. You can further fine tune RasPlex from the settings. If you have a modern TV or AV system that supports HDMI-CEC then you can control RasPlex from the TV or AV remote. I manage my RasPlex server from the remote of my Yamaha AV system. If you have an older TV, then you can either get remote modules or use a mini keyboard, something I use with my Smart TV, Xbox and other devices as it makes it easier to enter usernames, passwords, and the like. [Indiana Jones playing on RasPlex on my 4K Samsung TV, I am using a remote for the Yamaha AV system for navigation.] SLICK EXPERIENCE You can see an ultra high-definition (UHD) movie playing on my 4K Samsung TV in the image above (keep in mind that unlike Pine 64, Raspberry Pi 3 doesn’t support 4K video). Initially I was skeptical as ultra high-definition videos never played smoothly on the $35 Raspberry Pi 3, even when playing from local storage. Since Plex does all transcoding at the server side, RasPlex offers a very slick experience. Videos, even full HD play really smoothly: no jitters, no lag whatsoever. I am enjoying my RasPlex quite a lot given that I ‘built’ it myself. So if you are like me and love to tinker with everything Linux, this project is for you. How to Set Up a Remote-Controlled Holiday Music and Light Show By Swapnil Bhartiya My son just turned 4 and he is super excited about Halloween and zombies. So I planned to create a haunted houselike experience for him. The biggest challenge was to get audio-visual effects. I wanted spooky music synchronized with well-placed lighting. Instead of buying some expensive Halloween decorations, I wanted to build it myself. I also wanted to be able to control it over the network. I looked around and didn’t find the perfect solution, so I did what DIY people do the best: pick and choose different pieces to create what I needed. In this tutorial I am going to share how you can build a board with Raspberry Pi and open source software that synchronizes music with lights for less than $20. You can place this board inside a plastic pumpkin decoration, for example, or attach LEDs to props and create displays for Halloween or other holidays. Be creative! What you need • A Raspberry Pi 3 (v3 comes with Wifi & Bluetooth) • 32 GB Micro SD card (minimum 16GB) • A PC monitor with HDMI port for initial set-up • Keyboard and mouse (I recommend Logitech Wireless Touch Keyboard K400 with Built-In Multi-Touch Touchpad) • 5v 2A power supply (If you want full mobility then get a 5V battery bank for smartphones) • LEDs (minimum of eight, or more as desired) • 220 Ohm resistors (one per LED, minimum of eight) • Speakers (get portable Logitech speakers) • Assembled Pi Cobbler Plus - Breakout Cable for Raspberry Pi A+ / B+ (I recommend this one from Adafruit as it has clear pin numbers) • Breadboard and wires (and a basic knowledge of how to use it) • Solderable breadboard (optional) SOFTWARE We are using Linux-based Raspbian as the base operating system for this project. The easiest way to install Raspbian on your Pi is using NOOBs. Plug in your Micro SD card to your PC and format it as FAT32 using Gnome Disk Utility. Then change directory to the Micro SD card: cd /path _ of _ USB And unzip the NOOBS file into the Micro SD card: unzip PATH _ OF _ NOOBS In my case it was unzip /home/swapnil/Downloads/NOOBS _ v1 _ 9 _ 2.zip Ensure that all the content of the NOOBS folder is in the root directory of the Micro SD card. ls /path_of_micro_SD_card/ You should see all these files there: PREPARE YOUR PI Connect the Pi to the monitor using an HDMI cable and then connect the keyboard. Connect one end of the GPIO 40 Pin cable to the Pi and the other end to the breadboard using Adafruit Assembled Pi T-Cobbler Plus - GPIO Breakout board. Now plug in the Micro SD card and connect the power supply. When NOOBS boots, you will see the option to connect to the wireless network. Since we will be using our Pi outside as a Halloween decoration we need it to be wireless. Click on the wireless option and select the desired wireless network from the list. NOOBS will offer several operating systems to choose from, select Raspbian and let the installation finish. Once the installation is finished, reboot the system. Once you boot into Raspbian update your system: sudo apt-get update sudo apt-get dist-upgrade In order to use the sound output from the 3.5mm jack of Raspberry Pi, run the following command to open the configuration file of Raspbian: sudo raspi-config Then go to Advanced>Audio and set audio out from 3.5mm jack. INSTALL LIGHTSHOW SOFTWARE We are using the open source Lightshowpi project to control music and lights. Clone the project on your local machine: git clone https://[email protected]/togiles/lightshowpi.git Change directory to the newly created ‘/home/pi/lightshowpi’ folder cd lightshowpi And grab the stable branch git fetch && git checkout stable Install lightshowpi: sudo ./install.sh Reboot the system. sudo reboot INSTALL LEDS ON THE BREADBOARD We need to set-up the LED lights on the breadboard, for initial testing. Now we need to find the right PIN of GPIO board for LED connections. I heavily recommend Adafruit’s Assembled Pi Cobbler Plus - Breakout Cable for Raspberry Pi. This cable comes with clearly marked PIN numbers which will make it easier to connect to each corresponding PIN. Since we are going to use 8 LEDs for our set-up, let’s find out which PINs are we going to use. Here is a picture of the Adafruit’s breakout cable: Each audio channel is represented by a number, starting from 0. Since we are using 8 channels, we have 0,1,2,3,4,5,6,7 channels for each LED. The GPIO pins we are going to use are: #4. #17, #18 #22, #23, #24, #25 Connect the LED for each channel with each GPIO PIN in this ways: GPIO CHANNEL / LED LED #17 0 RED #18 1 BLUE #27 2 GREEN #22 3 PURPLE #23 4 YELLOW #24 5 WHITE #25 6 ORANGE #4 7 RED We now need to connect LEDs with the corresponding GPIO pins on the bread board. Here is a picture of the breadboard: And this is how the holes are connected internally. We are using 220Ω resistor with each LED and connecting the anode of each LED to the GPIO pins whereas cathode goes to negative. Here is a simple circuit diagram. Tips: Long legs of LEDs are anodes, which are connected to positive supply, whereas short legs are cathode that’s connected to negative supply. And here is the final set-up on the breadboard: Here you can see +5v (red wire) is coming from the 5v GPIO pin and negative (black wire) coming from the ground pin of GIOP and we plugged these wires into the positive and negative strip on breadboard (blue stripe is negative and red stripe is positive). Then we inserted small legs of the LEDs to the negative strips. We then used wires to connect the GPIO pins with each LED in series with 220Ω resistor. Our circuit is now complete. Let’s check if the LEDs are working properly. Run the following command (from the lightshowpi directory) sudo python py/hardware _ controller.py --state=flash You will see the output of each pin number in the terminal and the corresponding LED should blink. If all eight LEDs flash properly we are on the right track. Exit the command with ‘ctrl+x’ or ‘ctrl+c’. SET UP AUDIO Now let’s test the music-light synchronization. Lightshowpi comes with two mp3 sample files stored in the ‘music’ directory of the lightshowpi folder. Let’s play one of the two files: sudo python py/synchronized _ lights.py --file=/home/pi/lightshowpi/music/sample/ ovenrake _ deck-the-halls.mp3 If everything is configured correctly, you will get audio output that’s synchronized with the LEDs. You will see different LEDs lighting up responding to different audio frequencies. You can see a video of the setup that I uploaded to YouTube. UPLOAD YOUR MUSIC TO THE PI You can simply copy songs to the music folder of lightshowpi and play the desired songs from the above command, but we are going to use a web-based interface that will allow us to control our Halloween lights from the web browser of our mobile phones. We are going to use webui project to achieve that. The webui script is written by Stephen Burning which is also available as open source. First install some dependencies: sudo aptitude install python-webpy sudo pip install glob2 Then fetch the webui package: git fetch && git checkout webui ./install.sh (Type A to accept all) We need to edit the ‘py/webapp.py’ script to provide it with the IP address of our Pi. nano py/webapy.py Go to this line: Then visit it on your local network (replace with your RPi’s IP address): http://192.168.X.Y/ And put the IP of your Raspberry Pi there. In my case the IP was ‘http://10.0.0.26/’ so my my file looked like this: Then visit it on your local network (replace with your RPi’s IP address): http://10.0.0.26/ Save and close the file and then run the script: sudo python py/webapp.py If everything is configured correctly you will see this output: http://0.0.0.0:8080 It works only on the local network, so ensure that your mobile phone is on the same network as is your Pi. Open a web browser on your phone and enter the IP address of your Pi with port 8080: 10.0.0.26:8080 You should see this page: Check if LEDs turn on and off by clicking on those buttons. Then click on songs and play your desired song and enjoy a light and music show. You can add more music files to your collection by clicking on ‘choose’ files which will upload the music files to the music directory of the lightshowpi folder. You can also create a playlist so those songs will play automatically. Once the whole set-up is complete, you can either put the entire thing inside a ziplock bag and put inside a pumpkin or use long wires to control where you want to install LEDs inside the pumpkin. Just wrap long wire around LED legs and cover it with hot shrink sleeves or electrical tape to avoid shorting. I used a 5V iPhone battery bank and JBL GO Portable Wireless Bluetooth Speaker to achieve complete mobility. Just make sure that the Pumpkin is within the wireless range of your router so you can manage the song tracks from your phone. Happy Halloween! CREDIT WHERE DUE This project is a great example of open source, so many individuals have helped create this amazing experience. The project would not have been possible without the incredible work of Google software engineer Todd Giles and many other individuals have done around the the LighShowPi project. That’s the greatness of open source, you learn and benefit from each other. So special thanks to Tom Enos, Stephen Burning, Benjamin Ellis and many more… Build an Off-Road Raspberry Pi Robot By Ben Martin Take your Raspberry Pi into the wild with the Mantis robot kit. In this intermediate-to-advanced tutorial, I’ll discuss the process of building, powering, connecting, and controlling your own Mantis robot using the Raspberry Pi. And I’ll also point out some potential pitfalls. This is a great base platform with which to start playing with perception and semi-autonomous robot control. Delving deeper, you might like to add some feedback mechanism to the wheels of your Mantis so that you know how far you have traveled. You might also like to run a robotics platform such as ROS on top of an Ubuntu Linux installation on your Mantis. The Mantis is available in four- and six-wheel configurations and includes an electric motor to drive each wheel with potentially a little over 2 foot-pounds of torque. Generating such torque allows the Mantis to run over uneven terrain, such as loose rocks, small logs, and other obstacles, and climb some reasonable hills. Figure 1: The Mantis kit. The Mantis kit (Figure 1) includes all the mechanical components to build the robot. This includes all the channels, the shock absorbers, the wheels, tires, wheel mounts (Figure 2), motors, motor mounts, and some rubber grommets to help with routing your motor cables. What you need • A Mantis kit • A Raspberry Pi • Bluetooth dongle for Raspberry Pi • A RoboClaw motor controller board • One or more sufficient batteries • Wiring • Mounts to attach all of this to the Mantis • Keyboard • PS3 joystick Figure 2: Wheel mounts. The two 18-inch Actobotics channels that form the body of the Mantis robot have many holes to provide attachment points for anything you want to put on the robot (Figure 2). ServoCity also has mounts for attaching things to the Actobotics channel used in the Mantis. These mounts are made for batteries, Raspberry Pi, RoboClaw controllers, and more — such as cameras, bearing mounts, tubing, shafts, servos, arms, robotic claws, etc. Although there are general purpose headers on the Raspberry Pi to allow you to communicate with other hardware, you can’t run large electric motors directly from those headers. Motors want higher voltages than the Raspberry Pi can directly supply and will draw far more current than the Raspberry Pi can directly provide. As mentioned in a previous Linux.com article, you will want to use a motor controller chip or board to interface with electric motors. The motors on the Mantis are rated to draw up to 20 amps of power each. So, I will use a RoboClaw motor controller board that is rated to deliver up to 45 amps per channel (Figure 3). Figure 3: RoboClaw motor controller. Running a Raspberry Pi on a mobile robot changes what you might want to connect to the Pi itself. Most Raspberry Pi machines do not move around, so they use an Ethernet cable to talk to the network and get power from a microUSB cable, which is generally connected to a small power supply, which in turn is connected to a wall socket in the building. To run a Linux machine on a robot, you probably want to obtain a stable power supply from a battery, and will likely want to talk to your Raspberry Pi through a WiFi adapter. Other input and output, such as how to control the speed and direction of the robot and being able to see how much battery power remains, call for some form of wireless connection. The RoboClaw includes a Battery Eliminator Circuit (BEC) that lets you run the entire robot from a single battery. A large battery that can handle the current draw of the motors is attached to the RoboClaw. This single battery will usually be a two- or three-cell LiPo battery that will run at 7.4 or 11.1 Volts (V). The actual voltage from the battery will change over time as you draw power from the battery, and it discharges. The BEC on the 45A RoboClaw controller offers up to 3 amps at a stable 5V which is fine to run the Raspberry Pi. The only difficulty here is that the BEC on the RoboClaw uses dupont headers, much like the connecting cables on breadboards, while the Raspberry Pi wants to draw its power from a microUSB cable. I opted to create my own custom cable by wiring the positive and negative pins of a microUSB cable to half of a breadboard cable. For each motor on the Mantis to generate its maximum torque, it might want to use 20 amps of current. You should have a battery that can deliver at least 80 or 120 amps of current depending whether you have the four- or six-wheel Mantis. If you are running the motors on 10V, then you might potentially draw over 1 kilowatt of power. It is good to know the worst-case power draw for the motors on a robot so you can work out the battery requirements, and what cabling you want to use to connect to the motors so that the system does not burn up cables or suffer a catastrophic battery failure. The latter can occur if you try to draw more current from a battery than it is rated to deliver. High power batteries can also fail if they have been charged incorrectly or physically damaged. Be sure to familiarize yourself with the procedures for safely using your batteries. BUILDING THE MANTIS ServoCity has an assembly video on YouTube showing how to put the Mantis kit together. I soldered silicon-coated wire to the motors before mounting them to the Mantis and routed the wires through to the top of the Mantis before securing the top channel to the bottom channel. Each motor mount has four beams that attach back to the main channel. Two of each of these beams have a “90 Degree Dual Side Mount D” at each end of it. Given the number of items to connect, having a ratchet that can handle the 6-32 locknuts will make these all go together much more quickly. Figure 4: The Mantis body after assembly. Also, try to route your motor cables so that they are not near where the shock absorbers will connect to the upper channel. Getting both sets of the shock absorbers attached to the channel takes a little patience and not having to contend with motor wires will help. Figure 4 shows the initial build with each motor wire routed out of the top of the Mantis kit. The wires and velcro ties use on the wires are not included in the Mantis kit but the rest of the robot is. ATTACHING MOTORS AND THE ROBOCLAW CONTROLLER Next, I’ll show how to attach the motors, connect the RoboClaw to your Raspberry Pi through a USB port, and supply the RoboClaw with its own power source to talk to the Pi over USB. The Roboclaw series of motor controller starts with a model that can control two motors at up to 7 amps each and ranges up to controlling two motors at 160 amps each with many models in between. I’ll be using the 45-amp model, which is available in two versions: one with pin heads for rotary encoders and the other with screw terminals for those connections. You might be wondering how the motors on the Mantis will be driven using a motor controller that has two outputs. All of the motors on the left side of the Mantis use one motor output and all of the motors on the right side use the other output. To turn left, all the motors on the left side will be set to turn at the same slower rate than all the motors on the right side of the Mantis. Because each of the x motors on one side of the Mantis is connected to the same motor controller output in parallel, in a worst-case scenario if all the motors on the left side stall, they will each draw 20 amps, and the potential draw from the motor controller is 20x amps. For the four-wheel Mantis, I used the 45-amp RoboClaw controller so the controller was happy to serve up enough power to run all the motors in a stalled state. In the course of this build, I clarified some things with ON Motion Control (ionmc) who make the RoboClaw board. According to ionmc, each Roboclaw will handle over-current cases automatically. The maximum current that can be supplied is limited by the temperature of the RoboClaw board. “For example under 85 C (degrees Celsius) the 2x45amp and 2x30amp [RoboClaw] can output up to 60 amps (the amount will vary on a linear slope from 25 V to 85C. Once 85C is reached the current limit is at the rated current(eg 45a or 30a per channel). Once temperature goes over 85 C there is an over temperature current limit which will reduce the maximum current down to 0 amps when it reaches 100 C,” ionmc said. Never leave an electric motor in a stalled state. It will generate a lot of heat and likely damage the motor. With the Mantis, one of the motors could stall for a bit as the tire it is driving encounters an obstacle on the ground. That’s ok, as long as the Mantis gets over that obstacle; then the motor will revert to drawing significantly less current and not become damaged. Looking at the above quote, the 30 amp RoboClaw controller might be able to drive a sixwheel Mantis -- even though the three wheels on a single output might draw 60 amps if they all stall. As long as the RoboClaw doesn’t heat up to 100C, it should still provide power. If a stall is prolonged, then the RoboClaw might just heat up to 100C and stop supplying power to the motors automatically. Figure 5: Mounted motors. Because the RoboClaw has one output for each motor channel it can control, I used a 60-amp terminal block to connect the motors in parallel (Figure 5). Once the motors are connected to a terminal block, two wires per channel can be run up through the Actobotics channel to the screw terminals on the RoboClaw controller. This let me mount the terminal block itself inside the channel to leave the robot with a neat and tidy appearance. OTHER CONNECTIONS TO THE ROBOCLAW A USB port on the RoboClaw allows easy connection to the Raspberry Pi, but the USB port on the RoboClaw cannot power the RoboClaw. So, you will have to supply the RoboClaw with its own power source to talk to it over USB. There are two ways to do this: either having an explicit logic power supply on the “LB IN” pins or by installing the jumper on the LB-MB (logic battery from main battery) jumper header. My RoboClaw came with the jumper on the LB-MB header already. The RoboClaw has many input modes that let you tell the RoboClaw what to do using wireless receivers, serial commands over TTL serial, or the USB port on the RoboClaw. The default mode of the RoboClaw is 7, which allows you to control it over USB. Mode 7 is packet serial control at address 0x80. You must make sure to connect any battery to the RoboClaw with the correct orientation. Reversing the ground and power leads will result in hardware damage or worse. Connecting a 9V battery over the battery input terminals and connecting the microUSB to the Raspberry Pi resulted in the following when looking at the output of dmesg. root@pi:~# dmesg | tail ... [ 3585.758555] cdc _ acm 1-1.4:1.0: ttyACM0: USB ACM device [ 3585.760209] usbcore: registered new interface driver cdc _ acm [ 3585.760229] cdc _ acm: USB Abstract Control Model driver for USB modems and ISDN adapters root@pi:~# ls -l /dev/*ACM* crw-rw---T 1 root dialout 166, 0 Dec 22 07:16 /dev/ttyACM0 root@pi:~# lsusb -v > /tmp/lsusb.txt root@pi:~# emacs /tmp/lsusb.txt ... idVendor 0x03eb Atmel Corp. idProduct 0x2404 bcdDevice 1.00 iManufacturer 1 iProduct 2 USB Roboclaw 2x45A This output tells you that the RoboClaw should be at /dev/ttyACM0. Instead of using that magic value, it can be convenient to have udev create a link for you to the correct device file. The below 99-roboclaw.rules file will have a /dev/roboclaw device created whenever you connect the RoboClaw to a USB port on the Raspberry Pi. A huge advantage here is that, if you connect something else to a USB port that creates a /dev/ttyACM device, you don’t have to wonder if the RoboClaw is now at /dev/ttyACM0 or /dev/ttyACM1; it should still be available at /dev/roboclaw. root@pi:~# cat /etc/udev/rules.d/99-roboclaw.rules ACTION==”add”, ATTRS{idProduct}==”2404”, ATTRS{idVendor}==”03eb”, SYMLINK+=”roboclaw” root@pi:~# l /dev/roboclaw lrwxrwxrwx 1 root root 15 Dec 22 07:24 /dev/roboclaw -> bus/usb/001/005 TALKING TO THE ROBOCLAW FROM THE RASPBERRY PI To ensure that the connection to the RoboClaw is working, a good test is to ask the RoboClaw what version board it is and what firmware it is running. The command number 21 does this. Because you can have multiple RoboClaw controllers on a single bus, each command starts with the address of the RoboClaw you want to talk to. The default RoboClaw address is 0x80 -- which is what I’m using in the example. The RoboClaw address is mainly useful if you want to have multiple RoboClaw controllers connected to the same TTL serial interface. If you are connecting to the RoboClaw over USB, then each RoboClaw can have the default address of 0x80, because each will have a different serial device on the Linux machine. Boost is a common collection of libraries used in C++ programming. It includes support for many things, such as intrusive reference counting, collections, graph library, parser generator, and more. The following C++ source code uses boost and boost::asio to talk to the RoboClaw over the USB cable and get the version from the RoboClaw. The boost::asio lets you talk to networks and low-level I/O, which is used below to perform serial communication over the USB port. #include <boost/asio.hpp> #include <boost/asio/serial _ port.hpp> #include <boost/bind.hpp> #include <boost/integer.hpp> using namespace boost; using namespace boost::asio; #include <string> #include <iostream> using namespace std; int main( int argc, char** argv ) { std::string serialDev = “/dev/roboclaw”; const uint8 _ t roboclawAddress = 0x80; if( argc > 1 ) { serialDev = argv[1]; } cerr << “serialDevice:” << serialDev << endl; boost::asio::io _ service io; boost::asio::serial _ port serial( io, serialDev ); // issue the “Read Firmware Version” command 21 // to the RoboClaw at 0x80 uint8 _ t commands[] = { roboclawAddress, 21 }; write( serial, boost::asio::buffer(commands, 2)); // give the RoboClaw heaps of time to reply. sleep(1); // read the result string ver = “”; char c = 0; bool reading = true; while( reading ) { asio::read(serial,asio::buffer(&c,1)); switch(c) { case ‘\0’: // also read the crc asio::read(serial,asio::buffer(&c,1)); asio::read(serial,asio::buffer(&c,1)); reading = false; break; default: ver+=c; } } cout << “version: “ << ver << endl; return 0; } The getversion command should give you something like the following result. pi@pi ~/src/roboclaw $ ./getversion serialDevice:/dev/roboclaw version: USB Roboclaw 2x45a v4.1.13 POTENTIAL MODIFICATIONS In the rest of this tutorial, I’ll extend the communication with the RoboClaw motor controller, leading to a program to control the robot with a keyboard. I will then move on to using a PS3 joystick to control the robot over Bluetooth. This should give you a powerful robot base that can happily adventure outdoors. But first, I want to mention a couple of modifications that you might want to consider. One very useful addition to a Mantis kit is to get two more 18-inch channels with the screw plates and use two 3-inch channels to separate the 18inch sides from each other. On top of that, some 1-inch standoffs can separate three 4.5x6-inch flat channels to give a nice surface that you can connect things to (Figure 6). Figure 6: Dual rail with standoffs. Also, if you do get some spare channels and some standoffs, you can then side-load the batteries to give a lower center of gravity (Figure 7). Some foam at the base (and sides) is a good investment to protect the battery from damage. Figure 7: You can sideload batteries for a lower center of gravity. COMMUNICATING WITH ROBOCLAW: THE ROBOCLAW CLASS It is convenient to encapsulate the communication with the RoboClaw controller into a RoboClaw class that provides nice methods and uses types that are expected on a computer rather than a microcontroller. For example, you might like to know the current voltage of the main battery as a floating point value to treat as a voltage rather than as an integer, which is a value in 0.1V or 0.01V. The following code is a rewrite of the getversion command using the new RoboClaw class. The getVersion method will be issuing the same command 21 to the RoboClaw, but it is much simpler and more natural for the C++ program to simply call getVersion(). #include <boost/asio.hpp> #include <boost/asio/serial _ port.hpp> #include <boost/bind.hpp> #include <boost/integer.hpp> using namespace boost; using namespace boost::asio; #include <string> #include <iostream> using namespace std; #include “RoboClaw.h” int main( int argc, char** argv ) { std::string serialDev = “/dev/roboclaw”; if( argc > 1 ) { serialDev = argv[1]; } cerr << “serialDevice: “ << serialDev << endl; boost::asio::io _ service io; RoboClaw rc( io, serialDev ); for( int i=0; i<10; i++ ) { cout << “version : “ << rc.getVersion() << endl; cout << “battery voltage: “ << rc.getBatteryVoltageMain() << endl; cout << “temperature : “ << rc.getTemperature() << endl; sleep(1); } return 0; } The RoboClaw::getBatteryVoltageMain() is code we haven’t seen before. It uses the private issueCommandU16() method to send a command that expects a 16-bit number as the result. The getVersion() method just issues the command and returns the result read from the RoboClaw. Communication with the RoboClaw is protected with a two-byte CRC. For getVersion(), I just read those bytes and didn’t bother to check that they were valid. For issueCommandU16(), the CRC is calculated locally and compared with the CRC read from the RoboClaw after issuing the command. If these CRCs do not match, then something very bad has happened, and we should know about that rather than continuing to drive the robot assuming that everything is fine. To track the CRC, the issueCommandU16() method uses writeTrackCRC() instead of directly calling write(). The writeTrackCRC() will first zero the CRC member variable and then calculate it for every byte it writes. The read2() method by default updates the CRC member variable to include each byte that was read. The crcOK can then read the two-byte CRC from the RoboClaw (without updating the CRC member variable) and throw an exception if the read CRC does not match the expected value. float RoboClaw::getBatteryVoltageMain() { float ret = issueCommandU16( 24 ); return ret / 10.0; } uint16 _ t RoboClaw::issueCommandU16( uint8 _ t cmd ) { uint8 _ t commands[] = { roboclawAddress, cmd }; writeTrackCRC( boost::asio::buffer(commands, 2)); uint16 _ t ret = read2(); crcOK(); return ret; } CONTROLLING THE ROBOT WITH A KEYBOARD The above RoboClaw class and driver program can be extended to allow the motors to be controlled from the keyboard. The main() driver program below uses the new MantisMovement and InputTimeoutHandler classes. The console program uses curses to present the robot state to the user and to read keys from the keyboard without blocking. You also get handing of the keyboard arrows using the keypad() curses function. The screen is set up using the code shown below. A window ‘w’ is created so that specific settings can be applied to the window. initscr(); noecho(); w = newwin( 0, 0, 0, 0 ); keypad( w, true ); timeout(1); wtimeout(w,1); This setup is the same as getversion2 above, but we create instances of MantisMovement and InputTimeoutHandler for later use. boost::asio::io _ service io; RoboClaw rc( io, serialDev ); MantisMovement mm; InputTimeoutHandler timeoutHandler; The main loop begins by checking how long it has been since a keyboard input was received from the user. After 1 second, we clear the display of the last movement command from the screen. After 5 seconds, it is assumed that there is a problem with input and the robot is stopped before the program exits. Notice that the rampDown() call takes the current power level that is used for the left and right wheels. The rampDown() method will gradually, but over a fairly short time interval, slow down each motor to a stop. This is to make a nicer stop if the robot happened to be running at full speed when communications were lost, it’s better to try to stop gradually than to tell the motors to stop instantly. while( true ) { uint32 _ t diff = timeoutHandler.diff(); if( diff > 1 ) { mvwprintw( w,1,1,” “ ); } if( diff > 5 ) { mvwprintw( w,1,1,”TIMEOUT “ ); wrefresh(w); std::pair< float, float > d = mm.getActiveDuty(); rc.rampDown( d.first, d.second ); sleep(5); break; } The rest of the main loop reads a character from the input -- if there is one -- and adjusts the speed and heading of the robot to reflect the user input. Finally, the current settings are shown to the user and the speed of each motor is set using RoboClaw::setMotorDuty(). int c = wgetch( w ); if( c > 0 ) { timeoutHandler.update(); const float incrSpeed = 0.5; const float incrHeading = 0.05; if( c == ‘0’ ) break; switch( c ) { case KEY _ LEFT: mvwprintw( w,1,1,”LEFT “ ); mm.adjustHeading( -1 * incrHeading ); break; case KEY _ RIGHT: mvwprintw( w,1,1,”RIGHT “ ); mm.adjustHeading( 1 * incrHeading ); break; case KEY _ UP: mvwprintw( w,1,1,”UP mm.adjustSpeed( “ ); 1 * incrSpeed ); break; case KEY _ DOWN: mvwprintw( w,1,1,”DOWN “ ); mm.adjustSpeed( -1 * incrSpeed ); break; default: mvwprintw( w,5,0,”. have char: %d”, c ); break; } } std::pair< float, float > d = mm.getActiveDuty(); mvwprintw( w,0,0,”speed: %+3.2f heading: %+1.1f d1:%+3f d2:%+3f”, mm.getSpeed(), mm.getHeading(), d.first, d.second ); rc.setMotorDuty( d.first, d.second ); usleep( 20 * 1000 ); } A duty cycle simply describes what percentage of time you want to run an electric motor. A duty cycle of 50 percent will run the motor about half the time. Note that the power to the motor might turn on and off many times extremely quickly, so you won’t notice that this is happening. The new helper class MantisMovement is responsible for maintaining the robot’s speed and heading and allowing the values to be updated. When you set the speed or heading, the MantisMovement updates internal variables to allow you to get the duty cycle for the left and right motors. The MantisMovement class knows nothing about the RoboClaw class; it is only interested in working out what the duty cycle (from -100% to +100%) should be in order to give the desired speed and heading. If MantisMovement returns a negative duty cycle, then you need to turn the motors in a reverse direction. In MantisMovement, the speed ranges between -100 and +100, and the heading ranges between -1 and +1. The adjustHeading updates a member variable and calls updateMotorDuty() to update what the duty cycle needs to be to give the desired movement. The updateMotorDuty() delegates to updateMotorDutyOnlyForwards(), which is shown below in simplified form. The duty cycle for the left and right motors starts out with the desired speed and is then modified to take the desired heading into account. As the heading ranges from -1 to +1, if we simply add 1 to the heading, then we get a range from 0 to 2. If we multiply the left duty cycle by a number from 0 to 2, then we either stop the motor completely or double the speed depending on whether we want to turn fully left or fully right. To find the correct duty cycle, we can reverse the value range to 2-(0 to 2) to get a range of 2 down to 0. Because there are multiple left and right wheels, each of which have quite a bit of grip on them, I found that letting any wheel stop during a turn was extremely bad. Robots with only two drive wheels might get away with holding a wheel stationary and pivoting on the spot, but this sort of turning doesn’t work well for the Mantis. So, the dampen factor was added to allow the range to be cut back. For example, a dampen value of 0.6 will allow the heading to generate a final motor speed between 40 percent and 160 percent of the original speed. void MantisMovement::adjustHeading( float v ) { heading += v; if( heading > 1 ) heading = 1; if( heading < -1 ) heading = -1; updateMotorDuty(); } void MantisMovement::updateMotorDutyOnlyForwards( float dampen ) { d1 = speed; d2 = speed; // heading ranges from -1 to 1. float headingRangeOffset = 1; float headingRangeDelta = 2; float h = heading * dampen; d1 = ( h + headingRangeOffset ) * d1; d2 = ( headingRangeDelta - (h + headingRangeOffset)) * d2; } The whole reason for the InputTimeoutHandler class to exist is to track whether user input has not been received for a given amount of time. The InputTimeoutHandler::update() method updates the internal timestamp to the current time. The diff() method returns the number of seconds since update() had been called. When a new keyboard event is received from the user, the update() is called. And, every time around the main loop, the diff() is used to check if no input has come in for too long. The diff() method uses timeval_subtract(), which is is adapted from the same function in the GNU libc manual. CONTROLLING THE ROBOT WITH A JOYSTICK With these tools, the robot can be controlled over WiFi using a keyboard to set the speed and control the direction. This is great to see that things are working as expected. Now I’ll show you how to use a PS3 joystick to control the robot over Bluetooth. The PS3 joystick is much easier to carry around than a keyboard and provides more natural adjustment of the speed and heading of the robot. No longer do you have to tap keys multiple times to steer the robot; just move the joystick a little more to the left or the right if you want to move more or less in each direction. Figure 8: The fully built and modified Mantis robot. The PS3 controller has four analog inputs, two as joysticks near the center of the controller and two analog buttons around the top left and top right of the controller. You can also get additions for the PS3 controller that give you a greater physical movement space for the same input range. This can be very useful when trying to control a robot with a controller that’s designed for video games. If you have a little more budget, a hobby radio control transmitter and receiver will give you longer range control than the PS3 controller (Figure 9). Figure 9: You can add a radio control transmitter and receiver for longer range control. If you add a Bluetooth dongle to the Raspberry Pi, you can set up a PS3 controller so that it gives events through the Linux kernel joystick API. The main setup step is writing the Bluetooth address of your Raspberry Pi to the PS3 controller. This is done by connecting the Bluetooth dongle to your Raspberry Pi and then connecting the PS3 controller to the Raspberry Pi using a mini USB cable. Then use the six-pair tool to write the MAC address of your local Bluetooth interface to the PS3 controller. Then, you can run the six-axis controller daemon (sixad) on the Raspberry Pi and press the “ps” button in the middle of the controller. It should indicate that it has connected as controller “1.” To test this out run the jstest program and you should see changes on the screen as you move the joystick around and press buttons. A joydrive command can then control the motors using input from the PS3 controller. This is much like the simpledrive command shown previously, which controlled the robot from the keyboard. The joystick is opened in non-blocking mode as shown below. int joyfd = open (“/dev/input/js0”, O _ RDONLY | O _ NONBLOCK); To read from the joystick, you use the struct js_event type. The js_event contains information about a single event, such as a button being pressed or where an axis of input is located. For example, if you press one of the input joysticks upwards then you will get events of type JS_EVENT_AXIS with a number of perhaps 3 (for that axis) and a value that ranges from 0 in the middle to +/-32767. The one trap for young players here is not maintaining state for the axis that you are using. For example, when the joystick is moved forward, it is possible that another button or axis changes state, too. If you want to track where the axis that you’re using for forward and backward is located at the moment, you have to cache the last value sent by the Linux joystick API for that axis. This is why the ev_forwardback and ev_leftright variables exist in the program. struct js _ event e; bzero( &e, sizeof(struct js _ event)); struct js _ event ev _ forwardback; bzero( &ev _ forwardback, sizeof(struct js _ event)); struct js _ event ev _ leftright; bzero( &ev _ leftright, sizeof(struct js _ event)); In the main loop, if a new joystick event can be read without blocking, we update the timeoutHandler and then inspect the new event that we read. If it is for the triangle button, then we assume the user is no longer interested in driving the robot. So, we stop it and exit the program. Movements on axis that are interesting are cached to local variables. struct js _ event ne; if( ::read (joyfd, &ne, sizeof(struct js _ event)) == sizeof(struct js _ event) ) { timeoutHandler.update(); e = ne; if( e.type == JS _ EVENT _ BUTTON ) { #define PS3 _ BUTTON _ TRIANGLE 12 if( e.number == PS3 _ BUTTON _ TRIANGLE ) { std::pair< float, float > d = mm.getActiveDuty(); rc.rampDown( d.first, d.second ); break; } } if( e.type == JS _ EVENT _ AXIS ) { switch( e.number ) { case 3: ev _ forwardback = ne; break; case 0: ev _ leftright = ne; break; } } } The gain of having a cached value for the axis that we are interested in is that we can update the robot speed and direction once every iteration, regardless of whether any changes are received from the joystick itself. There are many ways to do this update, I have found that treating the speed adjustment as an acceleration and the heading adjustment as a direct adjustment works fairly well. This means that you can hold the joystick forward to speed up the robot, then release the joystick, and the robot will continue to hold the current speed. If you move the joystick for axis control left, then the heading is directly modified to the current joystick value. This seems to work fairly well, as adjustments to how the robot is turning are made fairly quickly; whereas, you might like to have the robot keep moving without having to hold a joystick at any specific angle for a prolonged period. The main task is to convert the joystick value that the Linux kernel gave us from the range [-32767,+32767] to [-1,1] that the MantisMovement class expects. I found the axis that I was using for forward and backward was in reverse to what I expected, so I inverted the sign on that axis. const float incrSpeed = 1; const float incrHeading = 0.01; float v = ev _ forwardback.value; v /= 32767.0; v *= -1; mvwprintw( w,1,1,”FWD/BACK %f %d”, v, iter ); mm.adjustSpeed( incrSpeed * v ); v = ev _ leftright.value; v /= 32767.0; v *= 1.0; mvwprintw( w,1,1,”LEFT/RIGHT %f “, v ); mm.setHeading( v ); CONCLUSION The combination of a Mantis kit, RoboClaw motor controller, Raspberry Pi, battery, WiFi and Bluetooth dongles, and a PS3 controller give you a powerful robot base that can easily move outdoors. This is a great base platform to start playing with perception and semi-autonomous robot control. For improvement, you might want to add a feedback mechanism to the wheels of your Mantis so that you know how far you have traveled. Or, you could run a robotics platform, such as ROS, on top of an Ubuntu Linux installation on your Mantis. Maybe your Mantis robot will end up competing for fame and fortune in a NASA autonomous robot challenge. For longer range wireless control, you might like to use a dedicated transmitter and receiver pair designed for radiocontrolled hobbies. The range of these controllers is much greater, and they are much less likely to drop signal due to interference. These controllers emit a signal for multiple channels that can be read using an Arduino and turned into a serial stream over USB. The code I have given here is all open source and available on GitHub. Note that this is really a very minimal example of control and improvements to emergency stop conditions and battery voltage monitoring, and stop should really be added to the code. I want to thank ServoCity and ION Motion Control for supplying the Mantis 4WD Robot Kit and RoboClaw Motor Controller used in this tutorial. ServoCity also provided a Raspberry Pi Channel mount and RoboClaw mount to help complete the build quickly. Conclusion Thank you for your interest in The Linux Foundation Training. Now that you’ve gotten hands on with the Raspberry Pi, are you ready to learn more? Check out our full list of Linux Foundation Training courses or visit Linux.com/tutorials for more fun projects using Linux and open source. The Linux Foundation is creating the greatest shared technology investment in history by enabling open source collaboration across companies, developers, and users. We are the organization of choice to build ecosystems that accelerate open technology development and commercial adoption.
© Copyright 2024 ExpyDoc