The goal of this little project is to demonstrate how easy it is to add hardware to PocketBeagle® and get it working. We do this by creating a simple Magic 8-Ball by adding the MPU 9DOF click and OLED C click to PocketBeagle®
Also, it can make all your executive decisions for you, so you don't have to! We used ours to help predict FIFA WorldCup team success!
Read more about the motivation behind the project on our blog and in this fun video:
The following figure shows the pin-out of the 2 headers of PocketBeagle®.
The default function of each pin is highlighted in dashed line. Click boards™ have a standardized MikroBUS™ pin-out (shown below).
BeagleBoard.org® PocketBeagle® (pictured below) headers conform to the MikroBUS™ standard and allow for two click boards™ to be interfaced with PocketBeagle® at a time (shown in the following figure). Although no guarantees are made with respect to compatibility, most click boards™ work with PocketBeagle® with a little bit of effort.
BeagleBoard.org® PocketBeagle® header pins with click board positions
Follow the below steps to display a picture on the OLED C click. This procedure assumes that an microSD card with a Linux image from Beagleboard.org: https://beagleboard.org/latest-images is installed on PocketBeagle®. Please see the PocketBeagle System Reference Manual for additional information on bringing up and connecting PocketBeagle®.
Install the 2 click boards into the 2 available positions on the PocketBeagle. The positions are important as we need to select the device tree overlays according to them. For this project, install the OLED C click board in position 1 and MPU 9DOF click on position 2. By installing the click boards this way, we select the interface with which the click boards interact with the PocketBeagle. The OLED C click uses the SPI0 interface and MPU 9DOF click uses the I2C2 interface. The 2 click boards installed on the PocektBeagle are shown below:
Note that the microUSB port will be underneath the OLED C Click.
Go to the PocketBeagle System Reference Manual and follow Section 3.3.1 (Getting Started) to quickly download and install the latest Linux image onto a microSD card. Please refer to the reference manual also for any additional information on the PocketBeagle®.
Use a microUSB to USB cable to connect PocketBeagle® to a computer/laptop. You should be able to bring up the Cloud9 IDE by entering the URL: http://192.168.7.2:3000/ide.html into the web browser. (use http://192.168.6.2:3000/ide.html for MAC o/s) Make sure you are using Chrome or Firefox. The IDE should look like the following figure:
Download the attachment, unzip it,and open the folder. You should see the following items:
The MPU-9DOF communicates on the I2C2 interface and has an I2C address of either 0x68 or 0x69. We need to check which one it is before downloading and including the appropriate device tree overlay. Use this command in order to do so:
If you see an I2C device, then the address is 0x68; drag and drop the following file in the 2-0068 folder intoCloud9. Otherwise, the address is 0x69, so drag and drop the file in the 2-0069 folder.
We also need the device tree overlay for the OLED, so drag and drop that into Cloud9.
Next copy these device tree overlay binary files (.dtbo) into /lib/firmware directory.
sudo cp PB-SPI0-OLEDC-CLICK.dtbo /lib/firmware/ sudo cp PB-I2C2-MPU-9DOF-CLICK.dtbo /lib/firmware/
Don't forget to enter the password for debian (temppwd) when you execute a command as root.
Edit /boot/uEnv.txt to invoke overlay on boot with this command
sudo nano /boot/uEnv.txt
Enter the names of overlay binary files(with total path) into uEnv.txt and un-comment the uboot_overlay_addr# variables that the overlay binary was assigned to
###Additional custom capes uboot_overlay_addr4=/lib/firmware/PB-SPI0-OLEDC-CLICK.dtbo uboot_overlay_addr5=/lib/firmware/PB-I2C2-MPU-9DOF-CLICK.dtbo #uboot_overlay_addr6=/lib/firmware/<file6>.dtbo #uboot_overlay_addr7=/lib/firmware/<file7>.dtbo
Save /boot/uEnv.txt (use ctrl+o) ENTER then exit (use ctrl+x) and then reboot
In order to download the additional software packages we need for this project, we first need to share our computer internet connection with the PocketBeagle®. Open up the control panel in Windows and navigate to the Network & Sharing Center (note that these steps will be different on MAC O/S and you should refer to BeagleBoard documentation for help with that):
Select the network connection where you connect to the Internet (in the case above, Wi-Fi). This window will pop up:
Select “Properties” and then click on the “Sharing” tab at the top of the new window that pops up:
Click to “Allow other network users to connect through this computer’s Internet connection,” and select the connection (in the case above, Ethernet 6) to the PocketBeagle®. Click OK.
Now, you have to manually change the IP address and its settings on the PocketBeagle® network device. Click on the appropriate network (Ethernet 6 in the example) and go to Properties:
Click on “Internet Protocol Version 4 (TCP/IPv4)” from the list and then click Properties. In the pop-up window, add the IP address of the gateway (192.168.7.1) and the other settings shown below:
Click OK. At this point, you should have noticed that the connection has closed between the PocketBeagle®and your computer due to the network connection resetting. Just reload the Cloud9 page.
Now, we need to tell the PocketBeagle® how to connect to the internet connection via the computer gateway (IP 192.168.7.1). Since we will have to reboot the device multiple times during this process, we should save time by setting it up to connect automatically. First, type the following command into the Cloud9 terminal to test the USB connection:
Ping is a debugging tool to test TCP/IP connections between devices. You should see an output on the screen, which is a response from your computer to say everything is ok. Press Ctrl+C to stop it.
Change to the “bin” directory below root and open a new script using the nano editor:
cd ~/bin nano network.sh
Add the following lines to this file and press Ctrl+X to leave it. The editor will prompt you to save the changes you have made, so make sure to select Y for yes:
#!/bin/bash /sbin/route add default gw 192.168.7.1 echo "nameserver 188.8.131.52" >> /etc/resolv.conf
This adds the computer gateway address to the PocketBeagle® IP address routing table and adds a name server to translate the IP addresses into names and vice versa. We also need to update the permissions so that this script is executable:
chmod 755 network.sh
Next, we will create a directory to store log files:
Now that we have this basic infrastructure, we can create our cron entry. First, we need to edit the"crontab" for root:
sudo crontab -e
(remember that the default password for PocketBeagle® is "temppwd").
This will prompt you to select an editor to add the cron entry; you can type 1 ENTER to open the nano editor. You should add the following line:
@reboot sleep 30 && sh/home/debian/bin/network.sh > /home/debian/bin/logs/cronlog 2>&1
This instructs cron that right after a reboot, it should first sleep for 30 seconds, and then execute our script. The output of the script and any error messages should be put into the file:"/bin/logs/cronlog". Now, reboot and check the connection:
sudo reboot ping google.com
(Don’t forget Ctrl+C to stop the output.)
This Python code for this project relies on the Linux Frame Buffer Image-viewer package (fbi).
sudo apt-get update sudo apt-get install fbi
- After boot up, you should see some text displayed on OLED C Click screen. If not, then there might be an issue with the device tree overlay.
- Make sure the screen does not time out (approx 3 mins). You should still see the letters on the screen. If the screen is blank, the screen has timed out. If this occurs, reboot.
- Now grab the “8_ball” folder and drop it into the Cloud9 IDE.
- Change current directory to 8_ball. If you followed step 8, you should see the directory in cloud9. Use cd to go into the directory.
- Change permission of display.sh file in this folder so it can be executed as part of the code
chmod +x display.sh
- Execute 8_ball.py
sudo python3 8_ball.py
Now is the time to ask the PocketBeagle® Magic 8-Ball some questions. Go ahead and give it a shake!
Now that we have a basic Magic 8 ball working using the code in "8_ball", we can update the code to add some additional functionality and auto-boot the program. The updated code and files for this part of the project are located in the "magic_8_ball" attachment. Drag and drop this folder into Cloud9.
In our first implementation, all answers (i.e. pictures) had an equal probability to be shown. However, we might want to adjust the probability, or weight, of a given image. To do this, we can implement a structure that groups an image with its weight:
images = [(10, "absolutely.jpg"), (10, "ask-again.jpg"), (10, "cannot-tell-now.jpg"), (10, "count-on-it.jpg"), (10, "go-for-it.jpg"), (10, "it-is-ok.jpg"), (10, "it-will-pass.jpg"), (10, "maybe.jpg"), (10, "no.jpg"), (10, "no-doubt.jpg"), (10, "not-now.jpg"), (10, "very-likely.jpg"), (10, "wait-for-it.jpg"), (10, "yes.jpg"), (10, "youre-hot.jpg")]
Now, we have an array of tuples that group the weight of the image with the image name. The probability for each image is: (weight of image) / (sum of all image weights). In the above, code snippet, we have given equal weight to all images (i.e. it is the same functionality as our previous implementation). However, it is now much easier to change the probability of a given image.
Try it yourself (Ctrl+X to save and exit):
At this point, we can adjust how we choose an image to account for the weight:
def choose_picture(): """Choose picture from images based on weights.""" total_weight = 0 # Compute total weight for (weight, image) in images: total_weight += weight # Choose random integer from total weight choice = random.randint(0, total_weight) # Choose picture based on the random integer above for (weight, image) in images: choice -= weight if (choice <= 0): return image # !!! Should never get here. Return bad value !!! return no_image # End def
As you can see from the code, we sum all the weights, choose a random number between 0 and the sum of all the weights, and then iterate through the images until we get to the image that was chosen.
This update to the code will make it far easier to change out the images that you can display as well as provide a way to selectively display images.
Now that we have an updated version of the Magic 8 Ball code, we want to automatically run this code on boot. To do this, we will use a service built into Linux call "cron". Cron can run scripts periodically or on boot and provides us with an easy way to have things run automatically. To make it easy to both run and debug any issues we might encounter when trying to automatically run our code, we should make sure we have a little infrastructure.
If you drag the zip file "magic_8_ball" into the /var/lib/cloud9 directory, you should see a "magic_8_ball" directory created. In that directory, we will create a directory to store log files:
Then we will should have a "run" script that encapsulates everything needed to have the program run. In this project, this has been provided in "run.sh". However, we do need to change the permissions so that it is executable:
chmod 755 magic_8_ball/run.sh
Now that we have this basic infrastructure, we can create our cron entry. First we need to edit the "crontab" for root:
sudo crontab -e
(remember that the default password for PocketBeagle® is "temppwd")
This should bring you to an editor such as "nano" which will allow you to add the cron entry. At the bottom of this file, you should add the following line:
@reboot sleep 15 && sh /var/lib/cloud9/magic_8_ball/run.sh > /var/lib/cloud9/magic_8_ball/logs/cronlog 2>&1
This instructs cron that right after a reboot, it should first sleep for 15 seconds (this is done to make sure that all the other components, like the IMU and display, are fully configured and ready) and then execute our run script. The output of the run script and any error messages should be put into the file: "/var/lib/cloud9/magic_8_ball/logs/cronlog". This will allow us to look at that file in case anything goes wrong during the execution of our code.
At this point, you are ready to reboot and watch your Magic 8 Ball start all on its own. Now you can run off a USB battery and take your Magic 8 Ball anywhere for all those times when you just need some help answering the tough questions.