Sunday, December 15, 2013

DIY DAC for Beaglebone Black

I ordered the PCM5102 DAC chip long time ago, planning to follow the discussion in a forum to build a DAC for my BBB. Finally got a chance a few weeks ago as I was taking sick leave to stay at home :P. Here is the summary:


  • The chip I used is PCM5102. There are discussions in the forum that there might be timing issue on the I2S signal with BBB. But audio seems to be not affected.

  • The schematic shown in the discussion forum was with headphone amplifier. Since I already owned too many DIY headphone amplifiers, I only implemented the PCM5102 part. In fact, it is quite similar to the "Typical Application Circuits" shown in the datashet.

  • Only some minor variations on components, e.g. the power capacitors, as I used whatever I could find in my spare-parts box

  • Two LM3940 used to convert 5V to 3.3v for PCM5102, one to analog and one to the rest of the chip. Granted that LM3940 is not very good at ripple and noise handling, but it should be cleaner than the 3.3v on BBB.

  • Pin 11 of PCM5102 set as high so filter runs in low latency mode

  • The BBB connects to my home wifi network with a dongle (Ralink RT8070 chipset)


  • My Beaglebone Black is running Debian with 3.8.13-bone30 kernel

  • To support UPnP such that I can control the playlist etc from my phones, tablets, and other computers etc, gmediarenderer was compiled and installed

  • With normal UPnP setup, the controller needs to be connected to the renderer all the time so that it can send instructions to play one song after another. This is undesirable as I wanted to use mobile devices to setup a playlist and then disconnect. One solution is to add an OpenHome renderer. This way, the playlist and play controls (e.g. random and loop) can be set and stored centrally.

  • As I paid for the BubbleUPnp on my Android devices, I chose to install the BubbleUPnP Server as the OpenHome renderer on BBB. It is a Java application. As mentioned in my previous post, I have the Oracle JDK 8 Early Access ARM VM on my BBB.

  • The gmediarenderer and BubbleUPnP JVM take around 15% CPU while playing music. My NAS (acting as UPnp server to serve music files) transcodes FLAC to WAV

  • I did test FLAC files on the setup using ffmpeg. The performance is OK too.


  • Of my 2 BBBs, only one works with the DIY DAC. Dont know if it is a hardware defect or something else

  • Do not set the playback volume to 100% on BBB. Seems that the PCM5102 charge pump is not providing rail-to-rail voltage. Setting the volume to 100% will cause clipping

  • Using ffmpeg to play back audio at 44.1kHz will produce occasional distortion. Can be prevented by upsampling the music in ffmpeg to 48k, 88.2k etc. No such issue with gmediarenderer

Wednesday, December 4, 2013

Updating kernel of Beaglebone Black Debian

Notes to self. To update the kernel of Beaglebone Black Debian:

  • wget
  • sudo /bin/bash

PS. Using GPIO

Tuesday, November 19, 2013

PostgreSQL BuildFarm

One of my BeagleBone Black boards is currently running two PostgreSQL BuildFarm instances: one with gcc and one with clang.

A great way to show your support to open source software.

Saturday, September 14, 2013

Using the Power Button on Beaglebone Black for Shutdown

By default, when pressing the Power button on Beaglebone Black (BBB) for 8 seconds, the board will be powered off. However, this is not properly shutting down the OS.

Instead, I would like to use the power button to issue the shutdown command. After some research, found that the power button generates events that can be captured by monitoring /dev/input/event0.

Here is the script:



while true; do
  BTNVAL=`hexdump -e '8/2 "%x " "n"' -n 16 $BTN | grep ' 74 ' | awk '{print $7}'`
  if [ "$BTNVAL" = "1" ]
    echo "Power button pressed"
    /bin/sync; /bin/sync; /sbin/shutdown -h now
    exit 0
  sleep 1

The script reads the first 16 bytes and see if it contains 0x74, which is the code for power button. If so, it will execute the shutdown command. Otherwise, sleep for awhile and monitor again.

The script is add to /etc/rc.local in order to be executed after every reboot

/root/scripts/ > /dev/null 2>&1 &

Wednesday, September 4, 2013

DIY Constant Current Charger for AA / AAA NiMH Battery

Normally I use my MH-C9000 to recharge and condition my AA / AAA batteries. However, it wont charge some of my older batch batteries. Maybe the internal resistance is just too high.

Even with low capacity, these old batteries are good for mouse etc low power devices. So instead of throwing them away, they are charged with a slow constant current charger. Here is a simple design of such charger.

  • The design is powered by +5v. I usually use a phone charger or a computer USB port
  • The yellow LED has a +2v drop. With a 0.7v Base-Emitter voltage of BC337, that means there is 1.3v across R2
  • With R2 = 12 ohm, the charging current is around 1.3v / 12 ohm = 0.108A
  • With a 1000mAh battery, the charging rate is around 0.1C. Good for slow charging


  • Simple to make. I just used components I found in my DIY junk box. Resistors and transistors can be replaced by other parts. Just make sure you calculate the charging current correctly


  • No terminate logic. Batteries will be charged until removed. Make sure you don't overcharge your batteries
  • When the +5v power source is removed, the battery will be powering the LED. Adding a diode could solve the issue. But to keep it simple, I left that out and simply remove the batteries after charging

Thursday, June 13, 2013

Beaglebone Black, ANT+, and Garmin FR70

My BBB is running Debian. Your mileage may vary if your BBB is running the stock Ångström.

Just successfully extracted data from my Garmin FR70 to BBB via a Garmin ANT+ USB stick. The steps are quite simple once you figured what software you need.

Note that different version of Garmin products use different protocol to communicate. The program Garmin-Forerunner-610-Extractor supports the followings:

 - Garmin Forerunner 60
 - Garmin Forerunner 405CX
 - Garmin Forerunner 310XT
 - Garmin Forerunner 610
 - Garmin Forerunner 910XT
 - Garmin FR70
 - Garmin Swim

Basically you just follow the instructions on the page. To sync with your BBB the first time, remember to turn on the Pairing function on you device. On my FR70, it is under Settings > System > Computer > Pairing.

For other devices

If you are using other devices that are not supported by Garmin-Forerunner-610-Extractor, go check out garmin-ant-downloader (this can be installed via apt-get). If you are using garmin-ant-downloader, your may need to create the USB serial device manually on your BBB. After you plugged in the ANT+ USB stick, use the lsusb command to list the device:
debian@debian-armhf:~/garmin$ lsusb
Bus 001 Device 002: ID 058f:6254 Alcor Micro Corp. USB Hub
Bus 001 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub
Bus 001 Device 003: ID 154b:0062 PNY
Bus 001 Device 008: ID 0fcf:1008 Dynastream Innovations, Inc.

The last device is my ANT+ stick. The garmin-ant-downloader needs to access the stick via a serial device. By default, it is the /dev/ttyUSB0. If it is not created automatically, use the following command:
sudo modprobe usbserial vendor=0x0fcf product=0x1008

Where 0x0fcf and 0x1008 are the code from the lsusb command result. Use the values that correspond to the output of your stick.

Using Oracle JDK 8 for ARM Early Access VM in OpenJDK under BeagleBoneBlack

Note that Oracle 8 JDK official release for ARM is out.  There is no need to follow the steps below.  Also, if you want to install it via apt-get, you may refer to this link.

Following similar instructions for Raspberry Pi, here are the instructions on how to boost the Java performance on BeagleBone Black by using Oracle's JDK 8 Early Access HotSpot with OpenJDK.

Note that I am using Debian on my BBB

Install openjdk
/mnt/usb/debian/test$ sudo apt-get install openjdk-7-jdk

Optional. Download a benchmark program. Save it as and test the performance of the stock OpenJDK.
/mnt/usb/debian/test$ java -version
java version "1.7.0_03"
OpenJDK Runtime Environment (IcedTea7 2.1.7) (7u3-2.1.7-1)
OpenJDK Zero VM (build 22.0-b10, mixed mode)
/mnt/usb/debian/test$ javac
/mnt/usb/debian/test$ time java -XX:+TieredCompilation -XX:+AggressiveOpts fastaredux 25000000 > /dev/null 2>&1

real    1m40.294s
user    1m40.047s
sys     0m0.180s

Download the JDK 8 for ARM Early Access package from Oracle web site.

Following the instructions, extract the hotspot VM and add it to OpenJDK

/mnt/usb/debian/test$ tar --extract --verbose --file=jdk-8-ea-b36e-linux-arm-hflt-29_nov_2012.tar.gz jdk1.8.0/jre/lib/arm/client
/mnt/usb/debian/test$ sudo mv jdk1.8.0/jre/lib/arm/client /usr/lib/jvm/java-7-openjdk-armhf/jre/lib/arm/oracle
/mnt/usb/debian/test$ sudo chown -R root:root /usr/lib/jvm/java-7-openjdk-armhf/jre/lib/arm/oracle

Make the HotSpot VM as our default VM. Edit the file /etc/java-7-openjdk/jvm-armhf.cfg and add -oracle KNOWN as the first parameter. (or, as stated in the instructions, use the sed command to add it to the first line of the file)
-oracle KNOWN
-server KNOWN
-client IGNORE
-hotspot ERROR
-classic WARN
-native ERROR
-green ERROR
-zero ALIASED_TO -server
-cacao KNOWN
-zero ERROR
-shark ERROR
-jamvm KNOWN

Note the last line of the output. Now it changed to use HotSpot VM
/mnt/usb/debian/test$ java -version
java version "1.7.0_03"
OpenJDK Runtime Environment (IcedTea7 2.1.7) (7u3-2.1.7-1)
Java HotSpot(TM) Client VM (build 25.0-b04, mixed mode)

Result of running the same benchmark. The performance almost tripled.
/mnt/usb/debian/test$ time java -XX:+TieredCompilation -XX:+AggressiveOpts fastaredux 25000000 > /dev/null 2>&1

real    0m35.102s
user    0m34.906s
sys     0m0.166s

Note that using the -server option on the HotSpot VM seems to slow down the performance though.

Using the -server option will actually switch back to use the default OpenJDK Zero VM
$ java -server -version
java version "1.7.0_03"
OpenJDK Runtime Environment (IcedTea7 2.1.7) (7u3-2.1.7-1)
OpenJDK Zero VM (build 22.0-b10, mixed mode)
$ java -version
java version "1.7.0_03"
OpenJDK Runtime Environment (IcedTea7 2.1.7) (7u3-2.1.7-1)
Java HotSpot(TM) Client VM (build 25.0-b04, mixed mode)

You can also alias -server option to use HotSpot VM:
-oracle KNOWN
-server ALIASED_TO -oracle
#-server KNOWN
-client IGNORE
-hotspot ERROR
-classic WARN
-native ERROR
-green ERROR
-zero ALIASED_TO -server
-cacao ERROR
-zero ERROR
-shark ERROR
-jamvm KNOWN

PS. Here is the before vs after result on my Raspberry Pi.

pi@raspberrypi ~/test $ time java -XX:+TieredCompilation -XX:+AggressiveOpts fastaredux 25000000 > /dev/null 2>&1

real    8m4.807s
user    7m56.410s
sys     0m1.880s

pi@raspberrypi ~/test $ time java -XX:+TieredCompilation -XX:+AggressiveOpts fastaredux 25000000 > /dev/null 2>&1

real    0m44.109s
user    0m43.160s
sys     0m0.320s

Wednesday, June 12, 2013

OpenCV facial recognition with BeagleBone Black

After flashing my BBB with Debian, I proceed to install OpenCV and the required Python packages. Using the sample code from here, I could get the facial and eye recognition demo running in a few minutes!

A few points to note:

  • I am running Debian Wheezy on my BBB with the image flashed to eMMC. It is a headless setup. Connect to it from my Windows PC using putty and Xming
  • BBB seems to be having problem when the webcam resolution is too high. The sample code ran OK when the witdth and height set as 320x240 or 352x288
  • For the facial recognition sample, some external XML files are required. You may get them from the OpenCV source code package. Just modify the sample code to point to the correct directory

Monday, June 10, 2013


I think I will give up Ångström and flash Debian Wheezy onto the eMMC of my BeagleBond Black directly...

Sunday, June 9, 2013

Upgrading Ångström on Beaglebone Black

Got my BBB a few weeks ago. My first attempt to update and upgrade the stock Ångström failed. I knew that the in memory /tmp is not big enough for "opkg upgrade" to store the downloaded packages. So I added the "-t" switch to write the temp files to another directory.

However, even the BBB eMMC is not big enough. The upgrade failed and probably corrupted the base. Needed to re-flash the eMMC.

Notes to self: Plug in a USB stick and use it as temp storage for "opkg upgrade" next time!!