Logitech C920 Angle of View

I realized today that the Logitech C920 webcam produces images covering a different field of vision (FOV) for the same width based on the height. I was expecting the horizontal field to be the same for a given width but it was not.

Using the command ffmpeg -f video4linux2 -list_formats all -i /dev/video0 to retrieve the sizes of video available lists the same set of sizes for h264 and mjpeg. 640×480 160×90 160×120 176×144 320×180 320×240 352×288 432×240 640×360 800×448 800×600 864×480 960×720 1024×576 1280×720 1600×896 1920×1080. In Raw/yuyv422 mode two additional sizes are available. 2304×1296 2304×1536.

I pointed my webcam at the building out my window, giving myself a rough grid pattern to look at and ran it through all of the h.264 sizes, and manually counted the horizontal and vertical blocks visible. 

I expected 640×480 and 640×360 to be the same horizontal FOV but have different vertical FOV. What actually happened in the FOV was that they displayed the same vertical FOV but different horizontal FOV.

I ran through all of the h264 resolutions, and the vertical FOV appeared to shrink slightly when I requested resolutions below 200, but otherwise stayed the same. 

Selecting 2304×1536 produced a slightly larger vertical FOV with the same horizontal FOV as 1920×1080. 2304×1296 seemed to produce the same FOV in both directions as 1920×1080.  Both of these resolutions run at lower frame rates and only in raw mode. I was testing them using ffmpeg transcoding and sending to my windows desktop with the command: ffmpeg -re -f v4l2 -video_size 2304×1536 -framerate 2 -input_format yuyv422 -i /dev/video0 -f mpegts udp://192.168.0.10:8090

The C920 advertises a Diagonal FOV of 78°, but I didn’t find official meaning of that.  I found a nice bit of information at http://therandomlab.blogspot.com/2013/03/logitech-c920-and-c910-fields-of-view.html that describes it as explicitly as being when the camera is running in 16×9 mode. 

I will probably get around to writing a program to more accurately produce the results.  Here’s my manual table:

Resolution Width Height Blocks Floors Width/Height Ratio MegaPixels
160×90  160 90 9 8 1.777778 0.01
160×120  160 120 7 8 1.333333 0.01
176×144  176 144 7 9 1.222222 0.02
320×180  320 180 9 8 1.777778 0.05
320×240  320 240 7 9 1.333333 0.07
352×288  352 288 7 9 1.222222 0.1
432×240  432 240 10 9 1.8 0.1
640×360  640 360 10 9 1.777778 0.23
640×480  640 480 7 9 1.333333 0.3
800×448  800 448 10 9 1.785714 0.35
800×600  800 600 7 9 1.333333 0.48
864×480  864 480 10 9 1.8 0.41
960×720  960 720 7 9 1.333333 0.69
1024×576  1024 576 10 9 1.777778 0.58
1280×720  1280 720 10 9 1.777778 0.92
1600×896  1600 896 10 9 1.785714 1.43
1920×1080 1920 1080 10 9 1.777778 2.07
2304×1296 2304 1296     1.777778 2.98
2304×1536 2304 1536     1.5 3.53
  16 9     1.777778
  4 3     1.333333

 

Advertisements

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 http://circuitco.com/support/index.php?title=Updating_The_Software#Procedure

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
mmcdev=1
bootpart=1:2
mmcroot=/dev/mmcblk1p2
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
[service_WimsWorld-5G]
Type = wifi
Name = WimsWorld-5G
Security = wpa2-psk
Passphrase = MyPasswordInPlainText

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

I created /etc/udev/rules.d/70-wifi-powersave.rules following the information in https://wiki.archlinux.org/index.php/Power_saving#Network_interfaces , 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 192.168.0.17 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

Interesting BeagleBoneBlack Power Solution

I’ve been working on a project that I want to make portable that requires powering both the BBB and a USB hub, so that enough power is supplied to the required USB peripherals. While looking for other items in Fry’s recently I came across a USB Barrel Jack Adapter. http://www.frys.com/product/7726838 At only $3 for a part with reasonable strain relief I was quite happy to give it a try.

BBB Powered by USB Hub

Barrel Jack draws power from hub to power the BeagleBone

Items plugged into my USB Hub:

  • Linksys AE1000 802.11n WiFi Adapter connected to my 5.8GHz network
  • Barrel Jack Adapter providing Power to BeagleBoneBlack
  • Logitech C920 WebCam

Because of the orientation of the ports on my hub and the fact that the AE1000 is wider than most USB devices I’m not able to plug four devices into this hub. The BBB starts and runs consistently when I apply power to the USB hub in this situation. This is a good situation for me because it appears that I just need to properly power the 2Amp/5Volts required by the hub, and it can provide enough juice for the BBB to operate.