This is the chapter web page to support the content in Chapter 8 of the book: Exploring BeagleBone – Tools and Techniques for Building with Embedded Linux. The summary introduction to the chapter is as follows:

This chapter describes bus communication in detail, explaining and comparing the different bus types that are available on the BeagleBone. It describes how you can configure them for use, and how you can communicate with and control I²C, SPI, and UART devices, using both Linux tools and custom developed C and C++ code. Practical examples are provided that use a low‐cost accelerometer, a serial shift register, and the Arduino microcontroller. After reading this chapter, you should have the skills necessary to interface the BeagleBone to almost all of its available bus types.

Learning Outcomes

  • After completing this chapter, you should be able to:
  • Describe the most commonly used buses or interfaces that are available on the BBB, and choose the correct bus to use for your application.
  • Configure the BBB to enable I²C, SPI, and UART capabilities.
  • Attach circuits to the BBB that interface to its I²C bus, and use the Linux I2C‐Tools to communicate with those circuits.
  • Build circuits that interface to the SPI bus using shift registers, and write C code that controls low‐level SPI communication.
  • Write C code that interfaces to, and C++ code that “wraps” the functionality of devices attached to the I²C and SPI buses.
  • Communicate between UART devices using both Linux tools and custom C code.
  • Build a basic distributed system that uses UART connections to the Arduino microcontroller to “outsource” workload.
  • Add logic‐level translation circuitry to your circuits in order to communicate between devices with different logic‐level voltages.

Digital Media Resources

Here the digital resources referred to in the chapter web page are provided. There are high-resolution versions of some of the important figures and links to videos, resources and websites that are described in the chapter.

P8 and P9 Headers

Figure 6-6 and Figure 6-7 from Chapter 6 are available for download as a high-resolution PNG raster format and a high-resolution PDF vector-mapped format using the following links:

  • BeagleBone P8 Header – [download label=”Download PDF”][/download](1.4MB), [download label=”PNG Format”][/download](0.4MB)
  • BeagleBone P9 Header – [download label=”Download PDF”][/download](1.9MB), [download label=”PNG Format”][/download](0.3MB)

These are high-resolution images that can be displayed and/or printed in color. The PDF version can be scaled to a format that suits your needs.

P8 Header

The P8 Header

BeagleBone Poster Icon Image

The P9 Header

Additional Content

SPI Analog to Digital Converter (ADC) Example

Here is the outline of an additional SPI example that I have written subsequent to the publication of the book. It is useful for a number of reasons:

  • It deals with writing and reading to/from an SPI device. The ADXL345 SPI example in the book focuses on reading/writing register values. While it is essentially the same thing, different class methods are required for this example.
  • This example is useful for communicating with SPI devices that have custom communication protocols.
  • The MCP3008 is a very low-cost device that is widely available (in PDIP form).
  • Chapter 6 describes how easy it is to damage the BeagleBone’s on-board Analog-to-Digital Converter (ADC) and therefore an external ADC might be preferable for some readers (e.g., the external ADC can easily be used with 3.3V levels). An external ADC also allows for the expansion of the total number of ADCs that are available on the BeagleBone.

For this example, the MCP3008 is used in a PDIP package (see the datasheet) – it is a low-cost, 8-channel 10-bit ADC with an SPI interface that can be powered at 3.3V. This particular IC can capture 75,000 samples per second when powered at 2.7V and 200,000 samples per second when powered at 5V – therefore the raw performance when powered at 3.3V  is somewhere within this range. However, it does not appear possible to achieve the upper level of performance under a regular Linux kernel with the configuration that is proposed. There are many similar SPI ADCs (and indeed DACs), including the MCP3004 that has four 10-bit input channels, the MCP3204 that has four 12-bit channels, and the MCP3208 that has eight 12-bit channels. The code that is presented in this section can be easily adapted to support any of these devices.

There is a BeagleBone ADC Cape available from CircuitCo that has a MCP3008 and can be used with this example code.

In addition to eight independent single-ended inputs, the MCP3008 (and most of the extended family) support pseudo-differential input pairs. For example, CH0 can be used as IN+ and CH1 can be used as IN- and the difference between the two inputs can be determined. In this mode, the IN+ input can range from IN- (a zero value digital output) to the sum of Vref plus IN- (a digital output of 1023).

 Figure 8.A1 The BeagleBone SPI ADC circuit

Figure 8.A1 illustrates how you can connect the SPI ADC to the BeagleBone Black using the pin configuration that is described in Table 8.A1 below. The Vref pin in Figure 8.A1 does not have to be set at 3.3V, however it is a useful initial range. For further information on the input characteristics study the datasheet.

Table 8.A1 Table of pin inputs/outputs for the 16-pin MCP3008.

IC PinsPin TitleDescription
Pins 1-8CH0-CH7The eight ADC inputs
Pin 9DGNDDigital ground – connected to the internal digital ground. Can be connected to the BBB GND.
Pin 10CS/SHDNChip Select/Shutdown. Used to initiate communication with the device when pulled low. When pulled high it “ends the conversation” and puts the device in standby. Must be pulled high between conversions.
Pin 11DINUsed to transfer data that is used configure the converter (e.g., chose which ADC input to use and whether to use single-ended or differential inputs)
Pin 12DOUTThe SPI serial data output provides the results of the analog to digital conversion. The data bit changes on the falling edge of the clock.
Pin 13CLKThe SPI clock can be used to clock out the bits. Ideally a minimum clock rate of 10KHz should be maintained to avoid introducing linearity errors.
Pin 14AGNDAnalog ground – connected to the internal analog circuit GND.
Pin 15VREFReference voltage input
Pin 16VDDVoltage Supply (2.7V to 5.5V). Can be connected directly to the BBB 3.3V supply rail.

Table 8.A2 Configuration of the operation mode for the MCP3008.

Single-Ended Configuration (Single/Diff = 1)Differential Configuration (Single/Diff = 0)
Control Bit SelectionsControl Bit Selections
CH0000IN+=CH0 IN-=CH1000
CH1001IN+=CH1 IN-=CH0001
CH2010IN+=CH2 IN-=CH3010
CH3011IN+=CH3 IN-=CH2011
CH4100IN+=CH4 IN-=CH5100
CH5101IN+=CH5 IN-=CH4101
CH6110IN+=CH6 IN-=CH7110
CH7111IN+=CH7 IN-=CH6111

The source code example below uses the SPI class that is described in Chapter 8. This example uses a Single-Ended Configuration, therefore Single/Diff=1 and the left-hand side of Table 8.A2 is used. As also described in the table, to sample from Channel CH0, the D2, D1, and D0 values must be set to 0. Therefore, the bit pattern to be sent to the ADC input in this case is 1000. In the code example provided below, these bits are set as the most-significant bits of send[1]. The last bit in send[0] is 1, which acts as the start bit to inform the device that a sample is being requested. The full code example is in the directory /chp08/spi/adc_example/

This example can be executed and will give the output as follows:

This will give the output on the Logic Analyzer as in Figure 8.A2 below. In this figure you can see that the values which are sent to the SPI ADC are 0x01 followed by 0x80 (and a blank value of 0x00) on the MOSI line (orange). The SPI ADC responds on the MISO line (green) with the value 0xF9 and 0xEB. These values are 0xF9 = 249 decimal and 0xEB = 235 decimal in the code example output above. This data needs to be parsed to extract the actual ADC response value. This is achieved by taking the last two bits of the first byte (0xF9 = 0b11111001) and all eight bits of the second byte (0xEB = 0b11101011) in order to create the binary value 0b0111101011, which is 491 decimal (as outputted by the code example above).

Figure 8.A2 The Logic Analyzer output for the code example above (note: the colors align with the connection wires in Figure 8.A1)

Adapting this Example for the 12-bit MCP3204/08

To adapt this code for the 12-bit MCP3204/08 (see the datasheet) you need to make a few modifications to the source code. The circuit has the exact same wiring configuration as in Figure 8.A1 and uses a very similar structure. The significant difference in the configuration relates to Figure 6-1 in both datasheets. Since there are an additional 2 bits required for a MCP320x data transaction, the Start Bit and Data Channel selection bits are shifted left by two bits. Therefore, to complete a request for a single-ended sample from Channel 0 you must send the value 00000110 00xxxxxx xxxxxxxx = 0x060000. Therefore, send[0] = 0b00000110, and send[1] = send[2] =0. The response is now the 8-bits of receive[2] and the four LSBs of receive[1]. Therefore, the combineValues() function should be called as follows:

which results in a 12-bit return value, so the result should be presented as “out of 4096”.


Gnuplot is a very useful command-line-driven function and plotting program that can be easily installed on the BeagleBone. It can be configured to display on-screen custom plots, or to save the output plot to a file. To install gnuplot on the BeagleBone you can use the following command:

Make sure that you install gnuplot-x11 if you are planning to display the output on screen. In the following example I am using a VNC connection to the BeagleBone — such a configuration is described in detail in the book at the beginning of Chapter 11. You can see that I use ssh -XC on my Linux desktop machine to connect to the BeagleBone for this very reason.

Once gnuplot is installed, you can test it using the following steps:

This should result in the on-screen display of a plot of sin(x) as in Figure 8.A3 below.

Figure 8.A3 Testing the gnuplot program

Gnuplot can also be used to output a print-ready or raster version of the plot in a file. In the following code segment the function is plotted to a PostScript file and to a PNG file. The PostScript file is subsequently converted to a PDF file using the ps2pdf tool so that it is more generally viewable, while remaining in a vector-mapped format.

For your information, the outputted files are available here for you to view: test.png (5.41KB), test.pdf (3.78KB).

In the next section gnuplot is used to display the output from the ADC circuit that is used to sample a signal for a number of samples (200 and 20,000). To use gnuplot to plot your own data, you can simply pass the name of a file to gnuplot that contains a single data sample on each new line — this is demonstrated in the example in the next sectionFor more information on gnuplot, please see:

SPI ADC with Multiple Samples

A version of the SPI ADC example is also available in the same directory that can be used to test the SPI ADC sampling performance with multiple samples for different frequencies of input signal.

A sine wave is applied to the ADC input using the Analog Discovery Waveform Generator in order to test the quality of the analog data capture. The 200 samples that are captured using the test application are plotted in Figure 8.A4 for different input sine wave signal frequencies of 50Hz, 500Hz, 1KHz, 2KHz, and 5KHz (moving left to right — click each image for a larger view).


Figure 8.A4 (a)-(f) The ADCmulti application output displaying 200 samples from an input signal that varies from 50Hz to 5KHz.

A PDF version of the output at 500Hz is available in the file: plot.pdf. The circuit set up works surprisingly well up until the 2KHz sine wave is applied as the input. There are modest levels of jitter — however, that would not be the case for a longer sample duration at high frequencies, as the ADCmulti program is heavy on BeagleBone CPU resources.

This discussion also brings up an interesting point! The use of the BeagleBone frequency utilities is described in Chapter 5 (Page 153) and it is important to note that the CPU frequency of the BeagleBone has an impact on the performance of this application. For example, if the application is modified to take 20,000 samples and executed you will get a plot like this: Plot for On-Demand Governor (Also see Figure 8.A5 on the left-hand side). You can clearly see that there is a change in the observed frequency (after approximately 5,000 samples) — this is because the on-demand governor switches the BeagleBone CPU frequency to 1000MHz when the CPU is busy for an extended period.

Figure 8.A5 (a) The ADCmulti application running with an “on demand” governor and (b) with a “performance” governor.

You can resolve this problem by setting the governor and re-capturing the data as follows:

The PDF plot of the output is now consistent and appears like this: Plot for Performance Governor (See Figure 8.A5 on the right-hand side).

If required, you can set the governor back to “on demand” using:

BeagleBone Bus Videos

An I²C Tutorial Video

In this video I discuss the I²C bus and how we can connect and program devices attached to the bus using C/C++. I explain the use of i2c-tools on embedded Linux and then show how we can interface to a digital accelerometer (Bosch BMA180) or any other I²C device. Finally, I show how we can use sysfs to build a C++ class that wraps the functionality of the digital accelerometer.

Arduino Videos

An Introduction to the Arduino

This is a short introduction to the Arduino platform.

An Arduino on a Breadboard

This tutorial shows you how to build an Arduino on a breadboard. It describes the use of 16MHz and 20Mhz crystals for driving the Arduino and compares their use to the use of a resonator. A simple circuit is created that blinks an LED for 1000ms and 100ms. The Arduino is programmed on the breadboard using an Arduino shield’s Reset, TX and RX pins.

LCD Display Introduction

This short video looks at the different options available for connecting an LCD character display to an Arduino. It uses a wide set of displays: The nuelectronics display shield, 20×4, 20×2,16×2 and 8×2 display modules. It shows the code that you need to create an example display and describes the use of the POT in the display. The modules used are the nuelectronics display shield, JHD 204, WH1602, CM200200 and a YJ 802A.

Arduino Application – A Reaction Timer

In this video I combine three previous videos and write some code to create an Arduino based Reaction Timer. The entire circuit is built on a breadboard using an ATmega328P on its own, which is combined with a Newhaven Display LCD Module that has an RGB backlight. I work through the code in some detail and explain how to write the code for the reaction timer. At the end of the video I provide links to the previous videos that show how to build the three individual circuits: Breadboard PSU, Arduino on a Breadboard and Arduino LCD Tutorial.

8×8 LED Dot Matrix Display Tutorial

In this video a 2 Colour (red/green) 8×8 LED Dot Matrix Display circuit is developed that uses three 74HC595 ICs to drive the rows/columns and a darlington transistor array (UDN2981A) to source the current. An Arduino is used to provide the serial data and the source code is presented to show how this was achieved. The display is a common anode display and the experiment spends time examining the current constraints, explaining why we require transistor arrays to source or sink current.

Source Code

All of the source code that is described in this book is available in a public GitHub repository: Derek Molloy Exploring BeagleBone repository.

You can clone this repository on a Linux desktop computer or your BeagleBone using the command:

The code for this chapter can be accessed in the chp08 folder of the cloned repository. The formatted code is provided here for your convenience.

Some High-Resolution Figures from this Chapter

Here are high-resolution images of some of the more complex figures in this chapter, which may help you in wiring the circuits. Please note that you can close this pop-up window by pressing the Escape key.

External Resources

Important Documents

External Web Sites

The ADXL345 Datasheet

The BeagleBone Black System Reference Manual (SRM)

  • The I²C Manual, Jean‐Marc Irazabal and Steve Blozis, Philips Semiconductors, TecForum at DesignCon 2003 in San Jose, CA, on January 27, 2003, at
  • The Linux I²C Subsystem , at
  • Serial Programming Guide for POSIX Operating Systems, 5th ed., Michael R. Sweet, 1994‐99, at
  • Serial Programming HOWTO, Gary Frerking, Revision 1.01, at


  • Page 277 7-bit addressing goes from 0x00 to 0x7F (not 0x00 to 0x80)
  • Page 298 the file handle fd should be of type int, rather than type unsigned int. This prevents the test to see that the file opened correctly (<0) from working correctly.
  • Page 311 (loc 8869) there is a typo in the command to load the UART4 virtual cape at the top of the page. The command should read “sudo sh -c …” instead of “sudo su -c”
  • Page 311 (loc 8891) there is a typo in the call to the minicom command. It should read “$ minicom -b 9600 -o -D /dev/ttyO4″ rather than 9200.
  • Page 317 (loc 9017) there is a typo in the third bullet point that describes the termios structure. The cflag_t should be tcflag_t, just like the other entries. The structure is used correctly elsewhere.