BeagleBoneBlack 5.8GHz WiFi Reliability

After upgrading the operating system, providing more power via a powered USB Hub, and better understanding the startup scripts, I seem to have a reliable WiFi link from my BBB.

I still have occasional problems at boot time with the device not connecting to my WiFi network. I’ve got an FTDI USB-SerialTTL console cable that I can connect to the device and examine the status. Most of the time when I’ve not been able to reach the device over the network and I do this, running the lsusb command produces results showing nothing connected beyond the internal USB devices.

root@beaglebone:~# lsusb
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

If I disconnect the USB hub, remove and reapply it’s power, and reconnect the USB hub, sometimes it will cause the BBB to recognize the USB devices, but often it requires removing all power, disconnecting the hub, and reconnecting everything.

USB Power is the first issue in getting things to work. I only have the verbose reports from the lsusb command to go on for deciding how much power I need. The spec sheet for the BBB reports that it can only supply 500 mA on it’s USB port, and even then only if it’s powered by an external power adapter via the barrel jack. My WiFi adapter reports 450 mA. My camera reports 500mA. The hub in self powered operation reports 100mA. The power adapter that came with my hub reports it’s output as 2.1A, which would indicate that it should be able to provide the standard 500mA to each of it’s 4 ports if it’s running on external power.

root@beaglebone:~# lsusb ; lsusb --verbose | grep MaxPower
Bus 001 Device 002: ID 0409:005a NEC Corp. HighSpeed Hub
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
Bus 001 Device 003: ID 13b1:002f Linksys AE1000 v1 802.11n [Ralink RT3572]
Bus 001 Device 004: ID 046d:082d Logitech, Inc.
    MaxPower              100mA
    MaxPower                0mA
    MaxPower                0mA
    MaxPower              450mA
    MaxPower              500mA

I’m running a system that I started by flashing my eMMC with the 9/4/2013 image I downloaded from

The dmesg command reports the kernel as “Linux version 3.8.13 (koen@rrMBP) (gcc version 4.7.3 20130205 (prerelease) (Linaro GCC 4.7-2013.02-01) ) #1 SMP Wed Sep 4 09:09:32 CEST 2013”

I am running with a 32GB micro sd card installed, and partitioned into two volumes. In the root of the FAT volume I’ve got a uEnv.txt file that continues the boot process to the eMMC and it also issues the kernel command to disable the internal HDMI cape on the BBB. Since I’m only running this device over the network, I have decided it is more efficient to disable the HDMI entirely. I don’t think that the HDMI changes affect my WiFi, but I’ve not investigated it either.

root@beaglebone:~# fdisk -l /dev/mmcblk0 /dev/mmcblk1

Disk /dev/mmcblk0: 31.9 GB, 31914983424 bytes, 62333952 sectors
Units = sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disk label type: dos
Disk identifier: 0x00000000

        Device Boot      Start         End      Blocks   Id  System
/dev/mmcblk0p1            2048    41945087    20971520    c  W95 FAT32 (LBA)
/dev/mmcblk0p2        41945088    62333951    10194432   83  Linux

Disk /dev/mmcblk1: 1920 MB, 1920991232 bytes, 3751936 sectors
Units = sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disk label type: dos
Disk identifier: 0x00000000

        Device Boot      Start         End      Blocks   Id  System
/dev/mmcblk1p1   *          63      144584       72261    c  W95 FAT32 (LBA)
/dev/mmcblk1p2          144585     3743144     1799280   83  Linux

root@beaglebone:~# cat /media/BONEBOOT/uEnv.txt
optargs=quiet capemgr.disable_partno=BB-BONELT-HDMI,BB-BONELT-HDMIN

root@beaglebone:~# cat /etc/fstab
rootfs               /                    auto       defaults              1  1
proc                 /proc                proc       defaults              0  0
devpts               /dev/pts             devpts     mode=0620,gid=5       0  0
tmpfs                /tmp                 tmpfs      defaults              0  0
/dev/mmcblk0p2       /home                auto       defaults              0  2
/dev/mmcblk0p1       /media/BONEBOOT      auto       defaults              0  2
/dev/sda1            /media/PNY           auto       noauto                0  2
/dev/mmcblk1p1       /media/BEAGLEBONE    auto       ro                    0  2

I have created a file /var/lib/connman/wifi.config that has two sections, one for each of the wifi networks that I regularly connect to. The first is my primary network, and it seems to be stable connecting. The second is a network I occasionally power up, but I’ve not spent much time testing it. The good thing is that the credentials are in one place, and it’s supposed to chose the first network in the list that is found.

root@beaglebone:~# cat /var/lib/connman/wifi.config
Type = wifi
Name = WimsWorld-5G
Security = wpa2-psk
Passphrase = MyPasswordInPlainText

Type = wifi
Name = WimsWorld-UAV
Security = wpa2-psk
Passphrase = MyPasswordInPlainText

I created /etc/udev/rules.d/70-wifi-powersave.rules following the information in , paying explicit attention to the fact that naming the file matters.

In this case, the name of the configuration file is important. Due to the introduction of persistent device names via 80-net-name-slot.rules in systemd v197, it is important that the network powersave rules are named lexicographically before 80-net-name-slot.rules, so that they are applied before the devices are named e.g. enp2s0.

root@beaglebone:~# cat /etc/udev/rules.d/70-wifi-powersave.rules
ACTION=="add", SUBSYSTEM=="net", KERNEL=="wlan*", RUN+="/usr/sbin/iw dev %k set power_save off"

The iw dev wlan0 set power_save off command disables a WiFi feature called power save mode. I believe it is part of the 802.11 standard, but support varies by driver and chipset. It gets negotiated between the client device and the access point on authentication. If it is enabled, the access point may buffer multiple small packets before sending them to the client and the client spends less time either transmitting or receiving. If I run the command ping -t from my windows machine with power_save off, the time is very stable at 1 to 2ms. If I get a connection with power_save on, the time varies greatly with most times reported over 100ms.

My home network has plenty of nearby networks to conflict with.

root@beaglebone:~# iw wlan0 scan | grep SSID | sort
        SSID: Aman-Guest
        SSID: Aman2.4G
        SSID: Aman5G
        SSID: Angela's Wi-Fi Network
        SSID: Battlestar Galactica
        SSID: Battlestar Galactica
        SSID: CenturyLink0705
        SSID: Cyberia
        SSID: Dagobah
        SSID: Derek's Wi-Fi Network
        SSID: HP-Print-60-LaserJet 100
        SSID: HSE-1305(a) .media
        SSID: Jaggernet
        SSID: Jaggernett
        SSID: Joergstrasse
        SSID: Joergstrasse5
        SSID: Joshernet
        SSID: MOTOROLA-06F23
        SSID: NCH1205
        SSID: NCH515
        SSID: NCH611
        SSID: NETGEAR84
        SSID: Paris
        SSID: PhishingNet
        SSID: Poop2 5GHz
        SSID: PoopTime
        SSID: SMC
        SSID: Se1301
        SSID: Seattle2GHz
        SSID: SusansWIFI
        SSID: WimsWorld
        SSID: WimsWorld-5G
        SSID: XVI
        SSID: bedford
        SSID: bedford
        SSID: go-seahawks
        SSID: goodtimes
        SSID: goodtimes-guest
        SSID: ladines
        SSID: maverick
        SSID: mridula_air
        SSID: shubaloo
        SSID: shubaloo-5g
        SSID: washington

One other change that I made was to disable the cpu-ondemand.timer service with the command:

systemctl disable cpu-ondemand.timer

I don’t know if that has affected my WiFi stability, but it has certainly made my overall system more stable. By default this service runs after the BBB has been running for ten minutes, and then puts the system clock into variable mode with the command cpufreq-set -g ondemand. I ran into problems with my machine changing it’s internal frequency on a regular basis. for my purposes, I chose to leave the CPU in it’s default state, running with the performance governor, which leaves it at 1000 MHz. run the command cpufreq-info to see what state the BBB is currently in, and what it’s possible to change it to.

My machine seems to be stable right now, as can be shown by nothing being added to the dmesg log since the initial boot, 19 and a half hours ago.

root@beaglebone:~# dmesg | tail -32 ; uptime
[    9.360135] usb0: eth_open
[    9.360359] IPv6: ADDRCONF(NETDEV_UP): usb0: link is not ready
[   10.281944] gs_open: ttyGS0 (dcaccc00,dcaa8600)
[   10.282105] gs_close: ttyGS0 (dcaccc00,dcaa8600) ...
[   10.282119] gs_close: ttyGS0 (dcaccc00,dcaa8600) done!
[   10.283944] gs_open: ttyGS0 (dcaccc00,dcd1f980)
[   11.637465] usb0: stop stats: rx/tx 0/0, errs 0/0
[   11.742846] ip_tables: (C) 2000-2006 Netfilter Core Team
[   12.058808] net eth0: initializing cpsw version 1.12 (0)
[   12.070772] net eth0: phy found : id is : 0x7c0f1
[   12.070810] libphy: PHY 4a101000.mdio:01 not found
[   12.075883] net eth0: phy 4a101000.mdio:01 not found on slave 1
[   12.133068] IPv6: ADDRCONF(NETDEV_UP): eth0: link is not ready
[   12.694713] IPv6: ADDRCONF(NETDEV_UP): wlan0: link is not ready
[   18.301568] wlan0: authenticate with 20:4e:7f:85:ce:5b
[   18.327171] wlan0: send auth to 20:4e:7f:85:ce:5b (try 1/3)
[   18.327734] wlan0: authenticated
[   18.336184] wlan0: associate with 20:4e:7f:85:ce:5b (try 1/3)
[   18.337359] wlan0: RX AssocResp from 20:4e:7f:85:ce:5b (capab=0x411 status=0 aid=2)
[   18.342420] wlan0: associated
[   18.342545] IPv6: ADDRCONF(NETDEV_CHANGE): wlan0: link becomes ready
[   18.342777] cfg80211: Calling CRDA for country: US
[   18.342940] cfg80211: Regulatory domain changed to country: US
[   18.342951] cfg80211:   (start_freq - end_freq @ bandwidth), (max_antenna_gain, max_eirp)
[   18.342962] cfg80211:   (2402000 KHz - 2472000 KHz @ 40000 KHz), (300 mBi, 2700 mBm)
[   18.342973] cfg80211:   (5170000 KHz - 5250000 KHz @ 40000 KHz), (300 mBi, 1700 mBm)
[   18.342983] cfg80211:   (5250000 KHz - 5330000 KHz @ 40000 KHz), (300 mBi, 2000 mBm)
[   18.342993] cfg80211:   (5490000 KHz - 5600000 KHz @ 40000 KHz), (300 mBi, 2000 mBm)
[   18.343003] cfg80211:   (5650000 KHz - 5710000 KHz @ 40000 KHz), (300 mBi, 2000 mBm)
[   18.343013] cfg80211:   (5735000 KHz - 5835000 KHz @ 40000 KHz), (300 mBi, 3000 mBm)
[   18.343022] cfg80211:   (57240000 KHz - 63720000 KHz @ 2160000 KHz), (N/A, 4000 mBm)
[   18.418237] wlan0: Limiting TX power to 23 (23 - 0) dBm as advertised by 20:4e:7f:85:ce:5b
 16:34:09 up 19:35,  1 user,  load average: 0.03, 0.07, 0.05

Webcam on BeagleBoardBlack using OpenCV

I’ve been working with my BBB and Logitech C920 webcam trying to stream video at low latency for some time and have not yet managed to get the latency under 2 seconds.

As a side project I wanted to use the BBB to create a time lapse video, capturing a picture a second, and then later stitching all of the pictures into a video using ffmpeg.

I’m using OpenCV for the first time. I’m really only using it for the capture/save and to draw some text and lines onto the image, which probably makes OpenCV significant overkill.

My C++ code for the process is:

#include <iostream> // for standard I/O
#include <string>   // for strings
#include <iomanip>  // for controlling float print precision
#include <sstream>  // string to number conversion
#include <unistd.h> // for sleep
using namespace std;
using namespace cv;

std::string timeToISO8601(const time_t & TheTime)
	std::ostringstream ISOTime;
	struct tm * UTC = gmtime(&TheTime);
	ISOTime << UTC->tm_year+1900 << "-";
	ISOTime << UTC->tm_mon+1 << "-";
	ISOTime << UTC->tm_mday << "T";
	ISOTime << UTC->tm_hour << ":";
	ISOTime << UTC->tm_min << ":";
	ISOTime << UTC->tm_sec;
	ISOTime << "Z";
std::string getTimeISO8601(void)
	time_t timer;

int main()
    VideoCapture capture(-1);	// Using -1 tells OpenCV to grab whatever camera is available.
	    std::cout << "Failed to connect to the camera." << std::endl;
    //capture.set(CAP_PROP_FRAME_WIDTH,2304);	// This should be possible for still images, but not for 30fps video.

	for (int OutputFolderNum = 100;	OutputFolderNum < 1000; OutputFolderNum++)
		for (int OutputImageNum = 1; OutputImageNum < 10000; OutputImageNum++)
			Mat C920Image;
		    capture >> C920Image;
				std::ostringstream OutputFilename;
				OutputFilename << "/media/BONEBOOT/DCIM/";
				OutputFilename << OutputFolderNum;
				OutputFilename << "WIMBO/img_";
				OutputFilename << OutputImageNum;
				OutputFilename << ".jpg";

				line(C920Image, Point(0, C920Image.rows/2), Point(C920Image.cols, C920Image.rows/2), Scalar(255, 255, 255, 32)); // Horizontal line at center
				line(C920Image, Point(C920Image.cols/2, 0), Point(C920Image.cols/2, C920Image.rows), Scalar(255, 255, 255, 32)); // Vertical line at center

				circle(C920Image, Point(C920Image.cols/2, C920Image.rows/2), 240, Scalar(255, 255, 255, 32)); // Circles based at center
				putText(C920Image, "10", Point((C920Image.cols/2 + 240), (C920Image.rows/2)), FONT_HERSHEY_SIMPLEX, 1.0, Scalar(0, 0, 255));
				circle(C920Image, Point(C920Image.cols/2, C920Image.rows/2), 495, Scalar(255, 255, 255, 32)); // Circles based at center
				putText(C920Image, "20", Point((C920Image.cols/2 + 495), (C920Image.rows/2)), FONT_HERSHEY_SIMPLEX, 1.0, Scalar(0, 0, 255));
				circle(C920Image, Point(C920Image.cols/2, C920Image.rows/2), 785, Scalar(255, 255, 255, 32)); // Circles based at center
				putText(C920Image, "30", Point((C920Image.cols/2 + 785), (C920Image.rows/2)), FONT_HERSHEY_SIMPLEX, 1.0, Scalar(0, 0, 255));
				circle(C920Image, Point(C920Image.cols/2, C920Image.rows/2), 1141, Scalar(255, 255, 255, 32)); // Circles based at center
				putText(C920Image, "40", Point((C920Image.cols/2 + 1141), (C920Image.rows/2)), FONT_HERSHEY_SIMPLEX, 1.0, Scalar(0, 0, 255));

				string DateTimeText = " " + getTimeISO8601();
				int baseline=0;
				Size textSize = getTextSize(DateTimeText, FONT_HERSHEY_SIMPLEX, 1, 1, &baseline);
				putText(C920Image, DateTimeText, Point((C920Image.cols - textSize.width), (C920Image.rows - baseline)), FONT_HERSHEY_SIMPLEX, 1.0, Scalar(0, 0, 255));
				imwrite(OutputFilename.str(), C920Image);
				std::cout << DateTimeText << " Wrote File : " << OutputFilename.str() << std::endl;
			std::cout << getTimeISO8601() << "\r" << std::flush;
    return 0;

I compile it on the BBB with the command:

g++ -O2 `pkg-config --cflags --libs opencv` TimeLapse.cpp -o TimeLapse

I’ve got a bug in that I don’t automatically create the directory structure that I’m saving files into. That’s in the to-do list.

I had been interested in the angle of view on the C920 and found it defined on the Logitech support site that the “Diagonal Field of View (FOV) for the Logitech C920 is 78°”. Unfortunately I was not able to understand if that varied based on the resolution being used. I’m currently using the resolution of 1920×1080, but for stills the camera can capture up to 2304×1536.

I did the geometry math to figure out that 10° off center would be a radius of 240, 20° off center would be a radius of 495, and 30° off center would be a radius of 785. Remembering SOHCAHTOA as Some Old Hags Can’t Always Hide Their Old Age from 9th grade math class came in useful. Using 1920×1080 and 78°angle, my diagonal radius (opposite) works out at 1101 and angle of 39° for tangent, allowing me to calculate my eye height of 1360 = (1101/Tan(39°)). Once I had my eye height I could calculate the radius of circles at any angle by Radius = Tan(Angle) * EyeHeight.

I wanted the circles and angles of vision for my streaming video application and decided that seeing them drawn on the images created here would be helpful, along with both the horizontal and vertical center lines.

The thing I’m not happy with is that the application seems to be running between 30% and 60% of the CPU load on the BBB. When I stream video from the C920 using the native H.264 output the C920 can produce, I was only using about 3% of the BBB CPU. I’ve commented out my drawing code, and verified that the CPU load is primarily related to acquiring the image from the capture device and saving it out to a jpeg file. The lines and text drawing produce minimal incremental CPU. I want to keep the CPU load as low as possible because I’m powering this device from a battery and want it to have as long a runtime as possible.

I believe that the OpenCV library is opening the capture device in a movie streaming mode, and it’s using more CPU interpreting the stream as it’s coming in than the method I was using for streaming to a file. I’ve not yet figured out if there’s a way to define what mode OpenCV acquires the image from the camera.

I was trying to draw the lines and circles with some alpha transparency, but it seems that my underlying image is not the right number of channels and so the lines are being drawn fully opaque.

When the capture opens, it outputs several instances of the same error “VIDIOC_QUERYMENU: Invalid argument” that I’ve not figured out what they mean, or stopped procucing.

I am working on a 32GB flash card, partitioned into two 16GB filesystems. The first is Fat32, has a simple uEnv.txt file in the root allowing the BBB onboard flash to be used, and following the Design rules for Camera File systems standard for the image naming. It allows me to take out the card put it in a PC and it’s recognized just like a normal camera memory card.

Contents of uEnv.txt:


The camera seems to be focusing on the building across the street instead of West Seattle.

View from 1200 Western Ave, 13th Floor Elevator Room

1200 Western Ave, 13th Floor Elevator Room

New FFMPEG install on BeagleBone Black

There was a 1.0 release of FFMPEG that came out in December of 2012. It moved the bar forward significantly in working with video formats. The Angstrom distribution is still including a 0.8 version which doesn’t even have direct support for h264.

My solution was to use “git” to download the latest code image for both ffmpeg and libx264, and build the libraries. The interesting complications I had were removing the old libraries from the machine, because they caused ffmpeg not to build correctly. Because I do not plan on using thwe machine interactively, I don’t care that I had to remove gimp. I don’t know what the other dependencies I removed may be related to.

I repeatedly issued the command “opkg remove –force-removal-of-dependent-packages libav” until no packages were removed.

I setup a usb drive partition, and a second user. As the second user on that drive partition I issued the following commands.

git clone git://
git clone git://
cd x264/
./configure --enable-static --enable-shared
date ; make ; date

I switched to the root user, changed to the x264/ directory and

make install

back to the second user

cd ../ffmpeg/
./configure --enable-gpl --enable-libx26
date ; make ; date

and as root

make install

I had a problem because the default installation for libx264 puts the libraries in /usr/local/lib. I had to add that line to the file /etc/ before running ffmpeg.

root@beaglebone:/usr/local/lib# ffmpeg -?
ffmpeg: error while loading shared libraries: cannot open shared object file: No such file or directory

I ran the make commands surrounded by the date commands so that I’d be able to get an estimate on time required. With the BeagleBone running at 1GHz, libx264 gets built in slightly less than 10 minutes and FFMPEG takes 1 hour and 40 minutes.

I was left with an ffmpeg that I wanted to use for my video streaming project.

ffmpeg version N-54212-g034b31d Copyright (c) 2000-2013 the FFmpeg developers
  built on Jun 27 2013 04:05:20 with gcc 4.7.3 (Linaro GCC 4.7-2013.02-01) 20130205 (prerelease)
  configuration: --enable-gpl --enable-libx264
  libavutil      52. 37.101 / 52. 37.101
  libavcodec     55. 17.100 / 55. 17.100
  libavformat    55. 10.100 / 55. 10.100
  libavdevice    55.  2.100 / 55.  2.100
  libavfilter     3. 77.101 /  3. 77.101
  libswscale      2.  3.100 /  2.  3.100
  libswresample   0. 17.102 /  0. 17.102
  libpostproc    52.  3.100 / 52.  3.100
Hyper fast Audio and Video encoder
usage: ffmpeg [options] [[infile options] -i infile]... {[outfile options] outfile}...

Use -h to get full help or, even better, run 'man ffmpeg'

BeagleBoneBlack WiFi configuration problems

I got a BeagleBone Black last week. It seems to be a nice system, with a 1GHz ARM7 processor, ethernet, USB, HDMI and plenty of expansion possibilities, all for $45.

It’s shipping configuration runs the Angstrom Linux distribution. I’ve worked with Angstrom in the past on a Beagleboard used for an embedded application. It seems that the newer Angstrom is using ConnMan 1.4 as the network manager. The version that’s available at the ConnMan site, 1.7, has a command line configuration tool, while the version included in the distribution does not.

I’ve not been able to figure out how to enable wireless networking. Plugging in an ethernet cable just works. Plugging in the USB WiFi adapter gives me a wlan0 device, and the MAC matches that printed on the device.

I’m not able to issue the command “ifup wlan0” without an error. It looks like the connman settings file should enable WiFi by default.

root@beaglebone:~# ifup wlan0
ifup: can't open '/etc/network/interfaces': No such file or directory
root@beaglebone:~# ifconfig wlan0 up
ifconfig: SIOCSIFFLAGS: No such file or directory
root@beaglebone:~# lsusb
Bus 001 Device 002: ID 04b4:6560 Cypress Semiconductor Corp. CY7C65640 USB-2.0 "TetraHub"
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
Bus 001 Device 003: ID 13b1:002f Linksys AE1000 v1 802.11n [Ralink RT3572]
root@beaglebone:~# ls -alFR /var/lib/connman/
total 16
drwxr-xr-x  3 root root 4096 Jan  1  2000 ./
drwxr-xr-x 17 root root 4096 Jan  1  2000 ../
drwx------  2 root root 4096 Jan  1  2000 ethernet_c8a030a62b80_cable/
-rw-------  1 root root   68 Jan  1  2000 settings

total 16
drwx------ 2 root root 4096 Jan  1  2000 ./
drwxr-xr-x 3 root root 4096 Jan  1  2000 ../
-rw------- 1 root root 4096 Jan  1  2000 data
-rw------- 1 root root  186 Jan  1  2000 settings
root@beaglebone:~# cat /var/lib/connman/settings 



I went so far as to connect to an HDMI monitor with keyboard and mouse and was able to see the graphical connection manager. I tried both with and without having the ethernet cable plugged in, but was not able to click on the “Enable” button on the wireless networks dialog.


I believe that I need to do something with wpa_supplicant to get the password properly accepted on my machine, but I’m more interested in getting the wireless up and running than worrying about getting the security set.

I included the lsusb command in my code listing before because it lists the WiFi device that I’m using. I’m powering the device by a standalone power supply, not via USB, so I believe that I should have enough power to run the wifi. This connection has it connected via an external hub, but I’ve had the same results when connected directly to the board.