Skip navigation


Attached to this blog post is the handout which was used in the element14 booth at Maker Faire Detroit 2013:

Sponsored by Element14


Presented by Jason Kridner with Drew Fustini, David Hamblin, Justin Triplett (i3 Detroit volunteer) and Mark Miles

(i3 Detroit volunteer)


BeagleBone BlackBeagleBone Black is a $45, 1GHz computer that ships with a Linux distribution on its on-board 2GB flash and has extensive I/O capabilities. We’ll be focusing on how you can wire up sensors and actuators using an included JavaScript library and IDE.


It has four lessons which utilize Bonescript on the BeagleBone Black:


  1. Blink an LED
  2. Use button to set LED
  3. Use potentiometer to control LED brightness
  4. Read temperature using a TMP36 temperature sensor


Here's a quick video of what the workshop in our element14 booth looked like:



Photo gallery of our booth:

BeagleBone Black Workshop in element14 Booth at Maker Faire Detroit 2013



Bill of Materials (BOM) for the workshop with Newark element14 SKUs:


SKU: 65W6016


Qty: 1


SKU: 53W6187

Desc: Adafruit 702: PROTO PLATE, BEAGLE BONE & BEAGLE BONE BLACKAdafruit 702: PROTO PLATE, BEAGLE BONE & BEAGLE BONE BLACK [does not come with breadboard]

Qty: 1


SKU: 53W6131

Desc: Adafruit 64: Half-size breadboardAdafruit 64: Half-size breadboard

Qty: 1


SKU: 38K0357

Desc: MULTICOMP - MCF 0.25W 270R - RESISTOR, CARBON FILM, 270 OHM, 250mW, 5%MULTICOMP - MCF 0.25W 270R - RESISTOR, CARBON FILM, 270 OHM, 250mW, 5%

Qty: 3 [should match qty for Red LED since this is the current limiting resistor]


SKU: 09J9321

Desc: Lumex LED, RED, T-1 3/4 (5MM), 250MCD, 660NM (it is diffused)Lumex LED, RED, T-1 3/4 (5MM), 250MCD, 660NM (it is diffused)

Qty: 3


SKU: 66W7458

Desc: Adafruit 1119 - Tactile Switch Buttons (12mm square, 6mm tall) x 10 packAdafruit 1119 - Tactile Switch Buttons (12mm square, 6mm tall) x 10 pack

Qty: 1


SKU: 38K0327


Qty: 10 [should match number of buttons since used as pull-up resistors for the buttons]


SKU: 19M9015


Qty: 2 [recommend 2 in case one is broken due to wiring it incorrectly and shorting it out ]


SKU: 53W5879

Desc: Adafruit 356: Breadboard trim potentiometerAdafruit 356: Breadboard trim potentiometer

Qty: 1


SKU: 53W6160

Desc: Adafruit 674: Beagle Bone - Sticker!Adafruit 674: Beagle Bone - Sticker!

Qty: 1






UPDATE: Here's the page on for the workshop with interactive bonescript demo and video tutorial:


We'll be adding more video tutorials overtime that we shot (4 total).

I have attached slides from Jason Kridner's Physical Computing with JavaScript presentation at Sketching in Hardware 2013 (

These were rendered from the mfg bundle, and may be useful for documenting any changes/wiring as people start to customize their boards.








Following my last update, we decided to use TinyG to do motion control for our Pick-n-Place machine.  The BeagleBone Black needs to send the appropriate g-code over the serial port to tell the TinyG what movements to make.  One of our team members, Ed Bennett, had the idea of using the mouse to control the PnP machine while we continue to develop it.  For now, we need "exercise" the X-Y gantry to see how well it works before mounting Ed's vacuum nozzle head which has Z-axis and alpha-axis (rotation).


Porting PyQt demo

Ed developed a PyQt demo for mouse control of PnP gantry on his Linux laptop.  Bonnie King and I then worked on getting Ed's program working on the BBB.  It turned out to be an issue that the code seems to use Qt3 classes.  It worked on Bonnie's Fedora laptop with Qt3 installed.  However, neither Angstrom, Debian 7 ( or Ubuntu 13 ( had Qt3 available in their repos.


We ended up rewriting the program for Qt4 based on various PyQt for Qt4 examples (using Debian 7 as it was last distro we tried when still search for Qt3):


The code is messy right now, but it will writes g-code to the serial port (via PySerial) per mouse movement.  At first I thought there was a problem, as it was really slow, but I realized after awhile it was because I running it remotely via X.  I put my 4.3" LCD touchscreen cape on the BBB and installed LXDE desktop env into Debian on the BBB.  It then drew at a normal speed no problem - d'oh   I could also draw using my finger on the touchscreen.  The photo attached looks crude as I was drawing points with a large pen at that point before going to drawing lines with a finer pen.




Software Setup:

Here is the process I followed to setup my BeagleBone Black to run the demo:


1) Download Debian 7.0 image from and burn to microSD:


2) Boot off microSD card and then copy to eMMC (so microSD card won't be needed anymore at bootup; based on instructions)


a) Boot off of Debian SD card by holding down the boot button

b) copy the image file to the BBB from your computer (for example, filename debian-wheezy-7.0.0-armhf-3.8.13-bone20.img.xz).

c) the .img.xz can be directly applied to the Bone’s internal eMMC while booted from the external microSD card:


xz -cd debian-wheezy-7.0.0-armhf-3.8.13-bone20.img.xz > /dev/mmcblk1


d) power down and remove the microSD card

e) power on the BBB and you'll now enjoy a nice photo of Tux on the bootscreen



3) Install required packages:

sudo apt-get update

sudo apt-get install lxde git python-sip python-qt4 python-setuptools python-pip python-serial minicom


4) Clone my bbqt GitHub repo:

debian@debian-armhf:~$ git clone

Cloning into 'bbqt'...

remote: Counting objects: 31, done.

remote: Compressing objects: 100% (19/19), done.

remote: Total 31 (delta 12), reused 30 (delta 11)

Receiving objects: 100% (31/31), 10.01 KiB, done.

Resolving deltas: 100% (12/12), done.


5) Connect TinyG mini-USB port to the BBB's USB 2.0 host port & verify serial port exists

debian@debian-armhf:~$ ls /dev/ttyUSB0

#it could potentially be ttyUSB1, ttyUSB2, so check those if ttyUSB0 not present


6) Run script in the bbqt repo (edit the path for serial port if not /dev/ttyUSB0)

debian@debian-armhf:~/bbqt$ sudo python ./



Live Testing:

Here's a video of the gantry running under mouse control.  We taped a marker to the head and used a pizza box to simulate the PCB to determine if the machine's X & Y were calibrated properly:



Here's a still photo from the process:

13 - 6.jpg

We learned we needed to adjust the size of the canvas in Qt and also scale the mouse coordinates to the dimensions of our machine (about 10" travel on both the X & Y).  Luckily, I was able to use the LCD4 cape directly to edit the (tiny) Python code:


Ed B (right) and Dan D (left) decided it would be better if we tried to draw a square exactly:

13 - 2.jpg

We wrote exact g-code for a square instead of using the mouse and it worked well:

13 - 1.jpg

We were very proud to see our little PnP bot's artistic taste move from abstract to realism

13 - 2 (1).jpg


Coming Soon...

Our next big task is a mechanical one: mounting Ed's Z-axis + alpha-axis head onto the PnP gantry. 


In my next post, I'll describe the process Ed went through in design the Z-axis and alpha-axis and how he machined the parts in the device




Vote for us here!


So we took this:




And ended up with this:


One Tired Paul


With Paul looking a bit perplexed at controlling the arms with the BeagleBone Black, the tracking actually works!



The above video is the OpenCV code tracking the direction of the ball and predicting where it will go so that the motors controlling the arms can react.



The above video shows the arms moving in reaction to the location of the ball; it acknowledges the location of the ball and tries to identify which player is best to 'chase' it, so that's why it seems a bit erratic at times.


It took a few weeks tracing through the technical reference manuals for the PRU along with misinformation on the internet to understand the pinmux and produce a table which actually made sense. Along with actually being able to share a document properly via Google Docs, hopefully this is now published and the file is available : PRU PinMUX Tables for reference.


This helped Paul along to do the code; which is on github: Paul's Python binding for PRUSS code for loading the PRU assembly and Paul's BeagleBone Football Code (PRU/Python/OpenCV) for ball tracking (OpenCV) and motor control.


The motor control was effectively working as a shield with a custom pinmux table hacked together (we didn't bother using the dtc -@ to have a proper shield configuration and just hacked apart the default dtc because that worked) so here's the Circuit Design for Motor Control where the BeagleBone Black plugged into, which may not have the values stated at present along with the 12-20v Charge Pump for part of the Motor Control. The Playstation Eye (not Eyetoy) was used as the camera for the ball tracking.


Beautiful BeagleBone Motor Shield!


On the left, hiding underneath is the BeagleBone Black, then connecting to the motor driver circuitry just for ease of use/soldering, which's then connected to the table for the motor movement.


There's also a plan for the goal scoring to be tracked by the BeagleBone Black, we installed infra-red sensors into the goals and proto-typed it with a Minimus32 modified with an Arduino bootloader for ease of use; this was going to be passed off onto the PRU but I didn't have (enough) time.



Imgur Album

Angus's Flickr


Previous blog posts:


Edit for More Information:


I had glossed over a lot of the detail above, but quite a bit of work went into doing this project, mainly because we weren't 100% clued up on how to use the BeagleBone Black best.


So for this build we didn't use the default Angstrum (sp?) linux on the BeagleBone but went with a distro we were familiar with, Debian. This was mainly because we intended on using SimpleCV as opposed to OpenCV because we thought it was a package that had been used before and were familiar with. Turns out it was actually OpenCV we'd used but we decided to stick with Debian anyway.


The custom build of Debian which was modified for the ARM processor didn't have an up to date device tree compiler (PinMUX file creator effectively,  dts/dtc/etc) until a few weeks into the project, so we didn't focus on using the proper method for modifying the PinMUX settings and just looked at disabling the shields that are created by default. This's mainly for the HDMI, etc.


This tied in with finding out how the PRU actually worked; there was a lot of good examples on element14 and Hipster Circuits about how to interact with it but many were confused about how exactly to set the pins as input or output and not many good examples for the actual assembly code for using the PRU. After reading through the technical manuals for the chip on the BeagleBone Black, which mainly was the original version 'c' of the main ARM chips documentation we found the assembly commands and discovered about the registers, such that r30 is mainly hard wired/coded as output only and r31 as input. However these still had to be reflected in the PinMUX so the correct hex values had to be put in place, again discovered by further reading and hopefully the google doc I created will clear things up for people.


Though we've now learnt that you can pass kernel parameters to disable the shields, we hadn't found this information at the time and so rebuilt the kernel to have them all disabled by default. Paul Brook also found that there was a limitation in using OpenCV with an external USB Webcam, a problem I think with handling images from the Webcam, that could potentially be fixed in the kernel.


The cogs and braces for holding the poles and the motors to interface with them were laser cut at the Hackspace, this's a laser cutter that's on loan from NottingHack. Other parts were either sourced from our current stores or from our own pocket when visiting the Farnell trade counter and gleefully heckling the staff with some polite banter. Jon Stockill put the majority of it together and wired it up, along with the wood cutting for the desk and attachment to the table itself.


For the motor control the mechanism utilised endstops so that it didn't try to ram the table repeatedly or shoot off, we had to create a driver board for the motors because the nature of them and with them being 12v required a bit of adaptation to use them effectively. Basically this is an area I'm not entirely familiar with as Paul and Jon handled it so they can answer it better. We had devices attached to them so we could check how far they had moved/their location because we wanted the BeagleBone to be able to adjust the 'person' on the rod to where the ball was, etc.


With the ball tracking we discovered that it was best using two white LED strips above the table to help to illuminate it, while we 'blacked out' any unwanted white marks on the table and used an orange ball for high(er) contrast.


There really is a lot of code that went into this; so make sure to visit the github links above and check them out!

Before I write about the Pick-n-Place (PnP) project at Pumping Station: One (Chicago's hackerspace), I thought those of you that might be Dr. Who fans would appreciate what we put on the roof of our building):




PnP motion control idea #1 - LinuxCNC:

Our first idea was to leverage existing open source CNC software called LinuxCNC (formerly EMC2).  Old PCs with parallel ports can be used to build a CNC controller with LinuxCNC.  We like this low cost approach to CNC and felt makes sense to replace a builky PC with a single board computer like the BeagleBone BlackBeagleBone Black





We discovered there was already a pre-built SD card image for the original BeagleBone.  However, it utilized the Linux 3.2 kernel whereas the BeagleBone Black (BBB) currently requires the 3.8 kernel.


I did some research which I documented in this thread: BeagleBone LinuxCNC blog.  I then discovered one of the developers is a Community member, Michael Haberler, and he explained the current effort to port LinuxCNC to the BeagleBone Black and 3.8 kernel.  He also pointed out the BeagleBone LinuxCNC which had a relevant post:


BeagleBone Black, Linux 3.8, and Device Tree


Our team decided we didn't have the skills to help with the neceessary Linux kernel modifications.  There wasn't much we could do until the LinuxCNC developers had some more time, so we decided to look at other solutions.  As I'm writing this now, I see that their work has progressed where they can use the BeBoPr 3D printer cape with the BBB:


Using a BeBoPr with a BeagleBone Black



PnP motion control idea #2 - Replicape PRU & Python code:

After the launch of the BBB, I kept seeing great tutorials by Elias Bakken on his Hipster Circuits website.  I discovered he'd previously designed a 3D printer cape for the original BeagleBone called the Replicape:



Elias uses the BeagleBone PRU to handle steppper motor acceleration and send step and direction signals to TI DRV8825 stepper motor driver ICsTI DRV8825 stepper motor driver ICs:




Elias also wrote a great library to allow him to control the PRU from Python in Linux on the Bone:


PyPRUSS – A simple PRU python binding for BeagleBone


I reviewed his code for the Replicape to see how we could adapt it for our use case.  However, in the end, we decided that unless we are actually using the Replicape itself that we'd be better off sticking with the TinyG controller.  Elias has been working on a new version which is BBB-compatible:


Replicape Revision A2 ready for review



PnP motion control idea #3 - Use TinyG and write Qt app:

Meanwhile, the PS1 member who designed the PnP gantry, Ed Bennett, had tuned the TinyG controller for the motors in the gantry.  This improved the performance and made us realize it would be counterproductive to PnP project to replace the TinyG with out own solution.  Even though the BBB wouldn't create the stepper motor signals, it could still play a critical role in generating the gcode that is sent to the TinyG.  The TinyG would connect to the BBB's USB host port and allow for simple serial communication.


To exercise the gantry, Ed then had the idea to write a Qt app in Python using PyQt that would generate gcode based on the movement of the mouse and print gcode to the USB serial port for TinyG to interpret:

13 - 11.jpg

I've since gone through the process of getting it to run on the BBB which required rewriting it for Qt4.  I'll write more about that and the features we plan to add to our Qt app in the future.  I'll also talk about the design process and machining Ed has been doing for the vacuum nozzle (which will pick up and place the parts).




Introduction - why would you want to extend I/O over USB?

The Beaglebone Black's PRU allows very high speed I/O capabilities with guaranteed timing while Linux applications continue to run. As useful as this is, occasionally there may be a need to use FTDI's USB-interfacing UART/FIFO ICs to extend capabilities further. There are a number of benefits to this:


* It increases the number of I/O pins available

* It increases the number of serial interfaces

* Provides interfacing to traditional peripherals that require *CS, *RD, *WR signals and an 8-bit data bus

* High speed parallel data transfer (60MHz) in a FIFO mode

* Portability so that applications can run on any device with a USB port


In theory the notes here should work just fine for other processor boards too, e.g. RPI, but clearly having a good USB capability (and the processing power to handle high-speed parallel data transfer is important - and the BBB is the ideal platform).

Some example applications could also be listed, but it's clear the possibilities are vast. Another benefit is that it is possible to easily enable a USB interface on custom hardware, by simply adding a FTDI chip to the project. It's only fair to mention that there are alternative, possibly lower cost methods too. People have successfully shoe-horned small USB stacks into small PIC and AVR microcontrollers that do not possess a native USB interface. Atmel offer ATmega devices that already contain USB capability, at very little cost.

Other manufacturers like Silabs, Exar and Cypress produce devices with similar capabilities to FTDI devices too.

Is it easy?

It turned out to be surprisingly easy - almost no soldering if a pre-built board is used, and very little coding. For creating a custom board (e.g. with your own peripherals on it), FTDI devices don't need a lot of additional circuitry.

There are quite a few similar-sounding part codes, but the FT2232H (PDF datasheet) has been on the interest list for quite a while - working with the BBB provided the opportunity to finally experiment with it. For clarity, it is the FT2232H range, available in a QFP package as part code FT2232HL-R.


Connecting up the FT2232H to the BBB

Like most of FTDI's chips, it doesn't take a lot of circuitry to assemble, however in this case I just used a pre-built board available from Seeed Studio for a quick prototyping exercise.


Connecting this to a BBB is trivial - just plug in the USB connector and it will power up from the 5V offered by the BBB's USB host port. For experimentation, I tried the so-called bitbang mode, which provides 16 pins of I/O in two banks of 8. Of more interest will be the FIFO modes for high-speed data transfer at up to 60MHz.


When plugged in, lsusb reveals the following:

root@beaglebone:~# lsusb
Bus 001 Device 003: ID 0403:6010 Future Technology Devices International, Ltd FT2232C Dual USB-UART/FIFO IC
Bus 001 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub
Bus 002 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub


Note the 0403:6010 - this is the vendor and product ID respectively, in hex (needed later). The board doesn't come with any connector, so SIL headers need to be soldered. The reverse of the board shows the pin naming, and the circuit diagram is here.


The bitbang mode is brought out to the ADBUS[7..0] and BDBUS[7..0] pins. For input testing, I just pulled various pins high and low (i.e. to 3.3V and 0V) through a 1k resistor (in case a pin was accidentally still an output) and for output testing a multimeter was used (an LED and resistor would be fine too).

Software introduction

Generally, hi speed I/O may require kernel drivers; in the case of the FT2232H this is no different, but it is already part of Linux images. Some code and libraries are required as part of the application. This is explained in the diagram below.


The application software will be the area of interest, where the data is received and transmitted and any processing with the end data is handled. To connect to the kernel driver, a couple of libraries of code need to be linked in to the application code; these are libftdi (open source library for many FTDI ICs) and libusbx which provides a consistent API regardless of if the OS is Linux or Windows.

Building the software

This was quite simple; three downloads are required:

libftdi (download here) - I used version 1-1.0

libconfuse (download here) - version 2.7 - this is used for parsing text files for configuration purposes

libusbx (download link) - version 1.0.16

Create a folder off your home directory (e.g. called 'development') and create a folder called usb inside it.

The three downloads were extracted in the usb folder.

Installing libconfuse 2.7:

make install

(installs in /usr/local/include,lib and share)


For libusbx 1.0.16:

./configure --disable-udev
make install

(installs in /usr/local/libusb-1.0 and /usr/local/lib)


For libftdi 1-1.0, the makefiles are intended to be built with cmake, which I didn't have installed (and is a little unfamiliar to me) - however it is possible to build the code from the command line easily, there are not a lot of commands.

In the folder where libftdi was extracted, traverse to the 'src' folder. Then copy to ftdi_versio_i.h and replace the variables marked with '@' with a custom value. In other words, modify the following lines so that this is how they appear, and then save the file.


const char FTDI_VERSION_STRING[] = "1-1.0";
const char FTDI_SNAPSHOT_VERSION[] = "0";

In the same src folder, compile like this:

gcc -c ftdi.c -I/usr/local/include/libusb-1.0
gcc -c ftdi_stream.c -I/usr/local/include/libusb-1.0
ar rs libftdi.a ftdi.o ftdi_stream.o
cp libftdi.a /usr/local/lib/.
cp ftdi.h /usr/local/include/.

Now the code in ftdi_eeprom can be compiled (path is development/usb/libftdi1-1.0/ftdi_eeprom). It requires a file ftdi_eeprom_version.h to be created in a similar manner as before.


Type these commands to compile it:

gcc main.c -I/usr/local/include/libusb-1.0  -I/usr/local/include -I. -L/usr/local/lib -lftdi -lusb-1.0 -lconfuse -o ftdi_eeprom
cp ftdi_eeprom /usr/bin

Then example code files can be compiled as shown here for instance (path is development/usb/libftdi1-1.0/examples):

gcc simple.c -I/usr/local/include/libusb-1.0  -I/usr/local/include -L/usr/local/lib -lftdi -lusb-1.0 -o ftdi_simple
cp ftdi_simple /usr/bin

There is an another example program in the same folder, called bitbang_ft2232.c but it needs a small change; replace where it says 0x6001 (product ID) with 0x6010 in two places, and then compile:

gcc bitbang_ft2232.c -I/usr/local/include/libusb-1.0  -I/usr/local/include -L/usr/local/lib -lftdi -lusb-1.0 -o bitbang

When the bitbang program is run, it will just slowly toggle some pins (bits 0 and 1) on the two ports.

As an experiment, the code was modified to toggle pins with no delay for thousands of times; a speed of about 20,000 writes per second is possible, allowing for 10kHz square-waves (this was not measured on a scope, so it is just a guideline). Bitbanging in this manner will not have real-time accuracy like the PRU. (The FIFO mode that the FT2232H is capable of will be far better than bitbanging too, but needs to still be tested. However, bitbanging is still suitable for some purposes). Note: See comments section below. Accuracy is extremely poor with the bitbang way; an alternative method using buffers is available on the FTDI and that method should be investigated.

A quick program was created to test inputs in bitbanging mode too, and it reads input values at a similar speed. The program is attached (very untidy for now - it's late in the evening! but it works). The program reads the AD[7..0] pins repeatedly, and displays the 8-bit value in hex on the screen. Run it, and it will display lots of 0xff on the screen (the inputs appear to float high) and pulling low (1k resistor to 0V) on any of the input pins will make the text change.

To compile the code:

gcc bbtest.c -I/usr/local/include/libusb-1.0  -I/usr/local/include -L/usr/local/lib -lftdi -lusb-1.0 -o bbtest


Summary / Next Steps

To a large extent the PRU capability has rendered this almost redundant, but it's good to know that it is easy to interface high-speed data in several ways with the BBB now. The FTDI device is easy to use because a ready-built board is available, but equally it is easy to include the IC on a PCB where a USB interface is not currently available. Experimenting with the FIFO modes will be interesting.


Part 2: FIFO mode

A "synchronous FIFO" mode is available on the FT2232H, which is supposed to allow far higher rate I/O. In order to enable this, an EEPROM needs to be programmed. There is a ftdi_eeprom program that was compiled earlier (see above), however it did not work. The alternative is to just download a Windows executable called FT_PROG and use that.

Download FT_PROG from here  (PDF help file is here).

Run FT_PROG, click on the magnifying glass icon ("scan and parse") to read the board EEPROM. It will display as lots of FFFF, since it is a blank part.


On the left side device tree, expand to FT EEPROM->Hardware Specific->Port A->Hardware, and change the property from RS232 UART to 245 FIFO, which is needed for the FIFO modes to function. Repeat for Port B.

Then, go to File->Save as Template (e.g. my245fifotemplate.xml).

Select the Device:0 on the device tree, right click, and select 'Program device'. It should be virtually instantaneous, and the Device Output will show some new values instead of FFFF.

You could confirm all is well by restarting the FT_PROG application and clicking the scan icon again, and viewing the EEPROM contents.


Once this is done, unplug the FT2232H from the Windows maching and plug it back into the BBB. There is code in the examples folder called stream_test.c, and it is compiled in a similar manner as the other examples:

gcc stream_test.c -I/usr/local/include/libusb-1.0  -I/usr/local/include -L/usr/local/lib -lftdi -lusb-1.0 -o ftdi_stream_test
cp ftdi_stream_test /usr/bin

The program can be run by typing:

ftdi_stream_test -n dump.bin

It will capture data at a very high speed and dump to a file (unformatted raw bytes), whenever the *WR pin (pin 27 on the FT2232H-R chip, or P3_17 (ACBUS3) on the ready-built board is pulled low.

The '-n' suppresses error messages when bytes are skipped.

It appears that bytes are guaranteed to skip, and I'm guessing this is because there is a delay writing to the filesystem. With a very short *WR pulse (of the order of tens of nsec) the number of bytes written to file appear to be close to the expected value (assuming that the FT2232H is trying to capture at 60MHz). At any longer pulse, bytes are skipped. For further investigation!


BBB - Building a DAC

Posted by shabaz Top Member Jul 6, 2013

Part 2 to this post, which implements the prototype, can be found by clicking here.


Part 3 implements a complete design in an enclosure for a Sonos-like solution.


See Creating an Internet Radio for a complete project by the EAGLE team including board layouts



The BBB has an on-board I2S interface, which makes interfacing an external DAC easy. The I2S interface is connected from the AM3359 processor to the HDMI chip (TDA19988) but it is not required for HDMI to be used in order to make use of the I2S interface. The I2S interface is brought out to some pins on port P9 (see here for details). It was encouraging that Technoshaman and Donald Miller had some success with the interface, so I wanted to try it out and I got some time today.


Since the interface is capable of 24-bit/192kHz audio, it was worthwhile picking a nice DAC. A good but not over-the-top device seemed to be the Texas Instrument's PCM5101 which is nice because it has reasonable specs and also provides a built-in charge pump so that it can function from a single supply. A headphone amp was connected, and this was ON Semi's NCP2811A. The combination of PCM5101 (actually my prototype used PCM5101A which can also function from 1.8V, but this was not needed)  and NCP2811A was chosen so that the entire circuit could operate from the BBB supply if desired, even if it was from a Li-Ion battery that was powering the BBB, and for low noise and distortion. The only problem is that the PCM5101 has quite a high output (clearly a good thing!) but the audio amp minimum recommended gain is 1 and it cannot meet the required output voltage, and it means that it will distort at high volume. So, at a lower volume (and lower SNR) it will be fine, and I prefer this particular amp because of the very low distortion. The ON semi datasheet was sparse though.


This is the DAC prototype:


This is the whole thing connected up:


This is the rear of the board - a bit messier! It was built on a SMD to DIP adapter board with some copper tape for supply rails:


This is the audio amp - not a lot to it, since it is so integrated.



I made a recording, but excuse the quality. The audio is from a small 64 ohm speaker picked up by a simple camera in-built microphone so it sounds bad, but connecting to headphones is a different story - it sounds as good as an ipod (although this is subjective - I don't have a way to measure). Another thing I still need to check is that originally I thought the data was read on the falling edge of the bitclock on the BBB, but I2S specifies the opposite. Maybe I made a mistake in my initial observations (I have not had a chance to re-check), or maybe it changed in a build. But the circuit as shown here works for me.


This is running on an not-recent Angstrom downloaded build (maybe a few weeks old image), and I still hear some very slight audio issues - it sounds like perhaps a break for a few tens of milliseconds occasionally, only if you're listening closely. I really hope it is resolved in a build soon (or maybe it is due to ffmpeg - perhaps avconv gives better results).

EDIT: I've since been using mplayer (command line is mplayer -ao alsa -volume 4 AmyWinehouse-BackToBlack.mp3  and either I'm not noticing any audio issues or they have disappeared). I've concluded it sounds at least as capable as my old ipod touch, maybe better).


I played audio using the command line:

ffmpeg -i AmyWinehouse-YouKnowImNoGood.mp3 -f alsa "default:CARD=Black" -re -vol 150

and it reported the stream as:

Stream #0.0: Audio: pcm_s16le, 44100 Hz, stereo, s16, 1411 kb/s




This is the circuit. All the 3.3V supplies were connected together for the prototype (I wouldn't do that for real, although it sounded very good in my limited tests). The amplifier V+ can be connected to 3.3V or the 5V supply (or the Li-Ion battery directly).

Note 16th Jan 2014: See the comments section below for more detail; the SCK pin on the PCM5101A was disconnected from 0V and instead connected to the BBB P9 pin 25. This will provide the lowest jitter by disabling the DAC's internal PLL. A sample capture of the audio quality (captured from the headphone output of the NCP2811A, just to give an approximate idea of what it sounds like from headphones) is attached to the post below, in the zip file More info on it in the comments section below.




I've also tried a FLAC file, but I'm hitting some limitation with ffmpeg it seems, and it picks a 16-bit format when it ought to be 24-bit. Meanwhile, avconv I couldn't get to work for MP3 or FLAC (it reported 'av_interleaved_write_frame(): Resource temporarily unavailable'). If anyone knows, any tips on how to play FLAC at 24-bit would be gratefully appreciated.



root@beaglebone:~# ffmpeg -i Taxman_2009_Digital_Remaster.flac -f alsa "default:CARD=Black" -re -vol 5

ffmpeg version v0.8.4, Copyright (c) 2000-2012 the Libav developers

  built on May 20 2013 13:00:42 with gcc 4.7.3 20130205 (prerelease)

This program is not developed anymore and is only provided for compatibility. Use avconv instead (see Changelog for the list of incompatible changes).

[flac @ 0x2da80] max_analyze_duration reached

Input #0, flac, from 'Taxman_2009_Digital_Remaster.flac':


    ORIGREFERENCE   : 6C05C9F79EE74052A7991B9669B98533

    ORIGDATE        : 2009:09:14

    ORIGTIME        : 11:57:01

    TIMEREFERENCE   : 5292000

    CODINGHISTORY   : A=PCM,F=44100,W=24,M=stereo,T=SADiE5


    TITLE           : Taxman

    track           : 1

    ARTIST          : The Beatles

    ALBUM           : Revolver (24 BIT Remastered)

    DATE            : 2009

  Duration: 00:02:37.85, bitrate: 1892 kb/s

    Stream #0.0: Audio: flac, 44100 Hz, 2 channels, s32

Incompatible sample format 's32' for codec 'pcm_s16le', auto-selecting format 's16'

Output #0, alsa, to 'default:CARD=Black':


    ORIGREFERENCE   : 6C05C9F79EE74052A7991B9669B98533

    ORIGDATE        : 2009:09:14

    ORIGTIME        : 11:57:01

    TIMEREFERENCE   : 5292000

    CODINGHISTORY   : A=PCM,F=44100,W=24,M=stereo,T=SADiE5


    TITLE           : Taxman

    track           : 1

    ARTIST          : The Beatles

    ALBUM           : Revolver (24 BIT Remastered)

    DATE            : 2009

    encoder         : Lavf53.21.0

    Stream #0.0: Audio: pcm_s16le, 44100 Hz, 2 channels, s16, 1411 kb/s

Stream mapping:

  Stream #0.0 -> #0.0


One of my good friends and I were at the local climbing gym staring at a moon board, when we (and by we, I mean he) had a great idea.  What if the climbing holds were lit up by LEDs to indicate which ones were fair game? This would eliminate the need to memorize where the hold was and what it looked like.  This way when you were climbing, and holding onto the wall with everything that you had, you didn’t need to fumble around for where to go next. It would be very obvious because it would be lit up.


The more we started talking about this the more that we thought about making clear holds, and lighting up the entire hold.  (As opposed to putting a light above/below the hold.)  Even better, you could climb at night, so that the holds would jump out at you.  Then it would be impossible to “mistakenly” grab the wrong hold.


When I got home, I found out that someone had already patented the idea of illuminated rock climbing holds, which is good news because that means that it could one day be a reality.



So, I set about to build a way to use the BeagleBone to light up a sequence of LEDs to show the route to go up the wall.  To do this, I followed this great tutorial on how to use a 74HC595 shift register.  The tutorial was written for the arduino, but the circuit diagrams are easily transferrable – all that changes is what GPIO ports to connect to.


The code is a bit different though.  I was unable to find an analogous function for shiftOut, which seemed to be the heart of the program.  After a couple of attempts to write my own, I decided to just hard code the routes into the program and include an easy, medium and hard route.  Here are what the three routes look like:


IMG_5444 (849x1280).jpgIMG_5445 (597x1280).jpgIMG_5446 (606x1280).jpg


Here’s a quick video of the step up:


To choose between the routes, there is a switch statement:


loop = function() {

digitalWrite(latchPin, LOW);


route = 1;




case 1:



case 2:



case 3:





digitalWrite(latchPin, HIGH);



At some point I’m hoping to improve it and have an up/down selector and a small multi-segment LED to display which route you’ve selected.  The full code is attached, in case you were wondering how it was done.


Final Thoughts

I was pretty excited to use the cloud9 IDE it looked really nice and seemed like it was going to make programming a breeze.  Unfortunately, that was not the case.  I ran into two problems.


First, I could only get the program to run once through the debugger.  After that the BeagleBone seemed to be unresponsive.  In order to get it to run again, I had to restart the BeagleBone.  Not sure what the problem was, but this made it very difficult to debug.  I quickly scrapped this method and ended up just writing the code in cloud9 and running the program through PuTTY.  Not ideal, but it was certainly better than restarting every time.


Second, the cloud9’s inability to properly flag errors was annoying.  It seemed to claim that every line was in error, but it would run just fine. For someone who doesn’t know javascript very well, this made it pretty difficult to try to figure out whether there was a problem in the code or not.  I also had problems figuring out what commands were built into bonescript.


Overall, not the smoothest project, but it seemed to work in the end.