StackExchange thread on how to successfully use the UART on the Raspberry Pi 3 (it’s not as simple as you might think)
Out with the Wand, In with the Pi
Electronics projects, like so many other things in life, don’t always work out the way we expect. This has definitely been the case with the C-BISCUIT demo bot, which has taken a few twists and turns on its way to becoming a functional system. Originally, we were using a Wandboard, but this was the point where we decided to replace it with a Raspberry Pi 3.
The dominant reason for this change was quite simple—the Wandboard had become an obstacle to our primary design goal, namely, transmitting live video from the robot to a computer via Wi-Fi. No one on the C-BISCUIT team knew exactly how to accomplish this after our initial attempt failed. It was one of those situations where we expected the third-party software environment to handle the details of the video transmission and, when it became clear that this was not exactly the case—well, let’s just say that the Wandboard quickly fell out of favor.
Fortunately, Patrick came up with the excellent idea of shelving the Wandboard and using a Raspberry Pi 3 instead. This also meant using the Raspberry Pi Camera instead of the WandCam, because of course we cannot expect a Wandboard camera to seamlessly interface to a Raspberry Pi (and seamless is what we want here—maybe there’s some way to make a WandCam talk to a Pi, but we’d much rather pay another $30 for a camera that just works).
Why the Pi?
The Raspberry Pi has more fully-developed software support than the Wandboard, and it gives us access to a larger pool of experience (from both AAC contributors and the wider RPi community). It is also smaller and less expensive than the Wandboard. It’s possible that the Pi is not powerful enough for some of the image processing tasks that we want C-BISCUIT to support, but we can worry about that later. For now, we just need the wireless video feed and some basic serial communication, and the RPi 3 can certainly provide that functionality.
And we certainly have no regrets about using the Pi Camera (version 2). This module does indeed interface effortlessly to the RPi, and it provides high resolution (8 megapixels) along with a variety of useful features (customizable output resolution and frame rate, image rotation, brightness and contrast adjustment, etc.).
So now you know why C-BISCUIT ended up with a Pi instead of a Wand; here is the updated block diagram:
Fortunately, the RPi can use the same 5 V supply and UART connections that were originally intended for the Wandboard, so we didn’t need to make any modifications to the Robot Control Board (RCB). Hooray!
Let’s take a look at how the robot is assembled, and then we’ll cover some details regarding the video and communication interfaces.
So the battery and RCB are on the upper level, and the RPi is down below. The camera is simply inserted into the dual-row header near the front edge of the RCB; I wrapped some electrical tape around the back row of pins so that they don’t short out anything on the back side of the camera PCB (the tape also ensures a snugger fit).
This arrangement wouldn’t be adequate for rough terrain, but it should be fine for initial testing and demonstration. Here are a few more assembly details:
Best RPi Video Software in the World
Well, OK, I only tried two techniques; the first one didn’t work and the second one did. But after the difficulties with the Wandboard and the convoluted failure produced by the first RPi attempt, it was extremely impressive to see how well the second solution performed. The software package is called the RPi Cam Web Interface, and you can read all about it here.
I’m going to skip the details because the extensive wiki has everything you need to know to get started. The overall process is as follows: Connect the RPi to your network, either through a cable or Wi-Fi. Install the software on the RPi and run it. Then you simply open up your favorite browser and connect to the video stream by typing "http://RPi_IP_address:port/subfolder" into the address bar (see the wiki for details). What you see is this:
The low-latency video appears in the browser window, and you can also capture images or video and modify camera settings:
This Is Not an Autonomous Robot... Yet
The robot won’t be very useful if all it can do is move around in circles or drive forward until it hits a wall. Thus, we need a convenient way to control its movement, and that is exactly what the following Python script provides:
ser = serial.Serial(
baudrate = 9600,
response = raw_input("Enter command: ")
if response == "forward":
elif response =="reverse":
elif response == "go":
elif response == "stop":
elif response == "s":
elif not response:
elif response == "rotate r":
elif response == "rotate l":
elif response == "low speed":
elif response == "high speed":
elif response == "very high speed":
ser.write("very high speed\r".encode())
elif response == "battery voltage?":
elif response == "disable battery protection":
ser.write("disable battery protection\r".encode())
elif response == "enable battery protection":
ser.write("enable battery protection\r".encode())
elif response == "exit":
The script itself is self-explanatory. It asks for input and then looks at the string entered by the user in order to determine which (if any) ASCII message should be transmitted over the UART. The EFM8 microcontroller on the RCB then receives the message and controls the motors accordingly.
But how do we use the script if we have no direct access to the RPi? That’s where SSH comes in. (Click here for more information on controlling a Raspberry Pi via SSH.) We already have the Wi-Fi network connection, so we simply SSH into the RPi and then run the script via the console.
One thing you might notice in the Python script is that there are three commands for stop. In addition to “stop,” we also have “s” and an empty string. This is an important feature because it ensures that you will be able to stop the robot quickly, even under pressure.
Let’s say that you get distracted for a minute and the next thing you know, your bot is about to tumble down a staircase, or run into a door at high speed, or knock over your favorite houseplant. You might not have time to type “stop,” and that’s why the script is designed to interpret “s” as “stop”—surely you have time to hit one letter and then the enter key.
But then there is the worst-case scenario: your robot is in serious danger and you panic. Maybe you can’t remember the stop command, or maybe you’re in such a rush that you hit the wrong key when you’re trying to send an “s” command. Well, you’re covered here too, because all you have to do to stop the robot is press the enter key! If you press nothing more than enter, the return string from the raw_input() function will be empty, and the script interprets an empty string as a stop command.
This screenshot gives you the sequence of commands for the robot movements shown in the video that follows:
The firmware is pretty straightforward. There is a simple UART interface for communication with the RPi, and the programmable counter array (PCA) is used to generate the PWM motor-drive signals. You can use the following link to download all the source and project files. The code uses descriptive identifiers and is thoroughly commented, so you shouldn’t have much trouble understanding the details.
One thing you will notice is additional files and code for USB communication. You can ignore this for now because USB functionality is not implemented in the demo-bot firmware.
We now have a fully functional C-BISCUIT demonstration robot, which means that this series of articles is complete. However, remember that C-BISCUIT is not a single robot but rather a platform for robotics projects. In other words, this demo bot is only the beginning!