Introduction: Best USB WiFi Adapter and Setup for Raspberry Pi
Get the most bandwidth from your wifi adapter. I wrote this instructable because I bought an RT5370 USB WiFi Adapter that was advertised as conforming to 802.11n, but struggled to run at 1Mbps.
Image: iperf3 results with a microwave running (red) and two LTE mobile phones making a call (blue).
Introduction
Using iperf3, an RT5370 and a Raspberry Pi 2 Model B, I measured a peak bandwidth of 1.69Mbps. However, the usual maximum bandwidth was 768Kbps, and bandwidth often dipped into sub-kilobit speeds. This was very frustrating.
I gathered about 100 web ideas on how to improve WiFi bandwidth. I combined duplicate ideas and was left with about 30 unique improvements, and then over a four week span ran multiple measurements on each.
Almost all of the ideas have no statistically significant effect on WiFi bandwidth. The ones that matter are (in order of most important):
- Good Raspberry Pi power adapter
- Have AP on clear channel
- Proper settings on Wireless Access Point
- Don't run the microwave
- Good USB WiFi Adapter
- all others are in wpa_supplicant.conf or /etc/network/interfaces
The goals of this instructable are:
- measure, measure, measure
- select best adapter based on measurements
- provide best performing setup for selected adapter
I expect this to be a "living" instructable in that more adapters will be added and measured.
Step 1: Gather Parts
For this instructable, I am using:
- Raspberry Pi 2 Model B running Raspbian
- Smart Phone with WiFi Analyzer App
- U-verse 2-Wire Gateway
- Linksys WAP300N Wireless Access Point
Notes:
- Text enclosed in spades, such as, ♣replace-this♣, should be replaced with an actual value. Of course, remove the spades.
- Measurements are included throughout and in an Appendix.
Step 2: Setup Wireless Access Point
Image: a screen shot of the app WiFi Analyzer running on a smart phone.
WiFi Analyzer
Ensure your wireless access point (AP) has minimal interference from your neighbors.
- Load Wi-Fi analyzer app on a smart phone.
- Ensure your Wi-Fi channel is not the same as your neighbor’s.
- By default, most ISPs set up their users on channel 1.
- If possible put your AP on a channel different from your neighbors'.
- Use an odd numbered channel.
Setup Wireless Access Point
Ensure your AP is setup correctly. My ISP provider's gateway has a built-in 802.11b/g AP and I pay for an 18Mbps connection. I disabled the gateway's AP, and added an 802.11n AP to my network. The 802.11n AP has the following setup:
- 2.4 GHz (5GHz disabled)
- Network Mode = Mixed
- Network Name (SSID) = :
- Channel width = Auto (20MHz or 40MHz)
- Channel = 1
- SSID Broadcast = enabled
- Security Mode = WPA2 (don't use WEP - it is less secure)
2.4GHz works best with Raspberry Pi.
Step 3: It's All About the Power
Image:power adapter and Raspberry Pi pins
Power Adapter
A high quality power adapter is fundamental to a properly functioning RPi.
I have 5 power adapters, which were included in Raspberry Pi starter kits. 2 of the 5 adapters provide consistent 5V. The others do not.
Any device added to the Raspberry Pi uses power. So, a USB device, or an HDMI monitor can push the Raspberry Pi into sub-optimal performance.
According to http://nordicgroup.us/rpi/power/:
“Raspberry Pi starts operating erratically below 4.75V”
[You must have a power supply that outputs] “2.4A at 5.2V (12 watts). The extra 0.2V mitigates the effect of the voltage drops in the cable and on the Raspberry Pi board.”
According to http://elinux.org/RPi_Hardware, to measure voltage:
- Using a multimeter set to 20 volts DC (or 20v =)
- Measure voltage from Pin# 02 DC Power 5V to Pin# 06 Ground
- Voltage should be between 4.75 and 5.25 volts.
Recommended power adapter and cable:
- 5.2V 2.1A USB Power Adapter from Amazon $5.99
- Micro USB to USB cable 3ft from Amazon $4.69
Measurements:
- Transfer Bandwidth for adapter providing correct voltage
- 12.2 Mbps
- Transfer Bandwidth for adapter providing 4.75V or less:
- 7.66 Mbps
Step 4: Choose Adapter
Image: iperf3 for 1000 intervals on each of the adapters. The x-axis is Mbps and the y-axis is the count of the measurements in that bandwidth.
Choose Adapter
A device can be advertised as 802.11n, but not be able to achieve 11n bandwidth rates on the Raspberry Pi. Listing the transmit rate of the device is misleading. Instead measure actual bandwidth.
There are multiple aspects of a Wi-Fi chipset that negatively impact bandwidth.
Realtek pioneered soft modems; driving the cost of Ethernet down, while offloading processing from the Ethernet chipset to the host processor. On a PC or MacBook, where the CPU often sits idle, this is a great feature and saves money. However, on a Raspberry Pi, offloading processing to the ARM negatively impacts WiFi bandwidth and application performance.
Most of my applications don't require high WiFi bandwidth. Some applications that do require high WiFi bandwidth are Media Server, NAS, and Raspberry Pi-based PC.
Some general rules:
- The adapter must be natively supported in current version of Raspbian.
- Check if anyone has gotten the adapter to work, or if it is known to have issues.
- Start by looking at this link: http://elinux.org/RPi_USB_Wi-Fi_Adapters.
- The adapter must be supported by Raspberry Pi model being used (Raspberry Pi 2 Model B)
- Measure performance
I will measure more adapters as I acquire them. In order of best performance (best bandwidth is on top):
- Panda 300Mbps Wireless N USB Adapter
- Edimax EW-7811Un 150Mbps 11n Wi-Fi USB Adapter
- Wi-Pi Raspberry Pi 802.11n Wireless Adapter
- TP-LINK TL-WN725N Wireless N Nano USB Adapter 150Mbps
- RT5370
The Panda device is the size of a thumb drive and probably does not offload as much processing to the CPU as the smaller dongles do.
Step 5: Minimum Setup
Image: results of running iperf3 for 100 intervals with minimum setup (blue), and then again with the recommended setup (red). The x-axis is Mbps and the y-axis is the count of the measurements in that bandwidth.
The difference between a minimum setup and my recommended setup is not significant. I choose to have a setup, which is a bit more complex than the minimum, but the measurements don't support this choice (see image).
As long as you don't have power issues, your gateway supports dhcp, your adapter has driver support in raspbian, then this is the minimum setup to get wifi to work:
/etc/network/interfaces
If you have a wpa_supplicant.conf file rename it.
Run the command:
$ sudo nano /etc/network/interfaces
and edit to contain only :
auto wlan0 allow-hotplug wlan0 iface wlan0 inet dhcp wpa-ssid "♣your-ssid♣" wpa-psk "♣your-pass-phrase<♣"
CTRL-o to write file
ENTER to confirm write
CTRL-x to exit nano editor
Step 6: /etc/network/interfaces
Image: results of running iperf3 for 100 intervals with "iface eth0 inet dhcp" (blue), and then again with "# iface eth0 inet dhcp" (red). The x-axis is Mbps and the y-axis is the count of the measurements in that bandwidth.
/etc/network/interfaces
Each parameter in the /etc/network/interfaces file was measured.
This file must be correct or wifi won't work.
login into raspberry pi and run the command:
$ sudo nano /etc/network/interfaces
Edit the file to be:
# interfaces(5) file used by ifup(8) and ifdown(8) # Please note that this file is written to be used with dhcpd # For static IP, consult /etc/dhcpcd.conf and 'man dhcpcd.conf' # Include files from /etc/network/interfaces.d: # source-directory /etc/network/interfaces.d # Commented parameters were used in measurements # All comments can be removed # Replace spades (♣) and text enclosed in ♣replace-this♣ with actual value # loopback interface # loopback is used for tools to talk to themselves on the RPi auto lo iface lo inet loopback # ethernet interface # leave ethernet interface - may be needed for cable connection in the future iface eth0 inet dhcp # Wireless adapter # Use only one group of settings at a time - either RT5370 or WiPi # RT5370 settings: auto wlan0 allow-hotplug wlan0 iface wlan0 inet dhcp # Use wpa-ssid and wpa-psk OR wpa_supplicant, but not both # wpa-ssid "♣your-ssid♣" # wpa-psk "♣your-pass-phrase♣" # Use wpa-conf instead of wpa-roam # Using wpa-roam without correct wpa_roam.conf causes issues # For example, on reboot wpa-roam can default to IPv6 and wifi stops wpa-conf /etc/wpa_supplicant/wpa_supplicant.conf # # Turning power management off reduces dropped packets wireless-power off # WiPi settings: # auto wlan0 # iface wlan0 inet dhcp # wpa-ssid "♣your-ssid♣" # wpa-psk "♣your-pass-phrase♣" # default interface # iface default inet dhcp
CTRL-o to write file
ENTER to confirm write
CTRL-x to exit nano editor
Step 7: /etc/wpa_supplicant/wpa_supplicant.conf
Image: results of running iperf3 for 100 intervals with a pre-generated key and instead using a pass phrase. The x-axis is Mbps and the y-axis is the count of the measurements in that bandwidth.
Pre-generated Key
Create a pre-generated PSK key. Login to Raspberry Pi and run the command:
$ wpa_passphrase ♣your-ssid♣ ♣your-pass-phrase♣
output:
network={ ssid="♣your-ssid♣" psk=♣your-pre-generated-key♣ }
/etc/wpa_supplicant/wpa_supplicant.conf
Each parameter in the /etc/network/interfaces file was measured.
The wpa_supplicant.conf file must be correct or wifi won't work.
Login into raspberry pi and run the command:
$ sudo nano /etc/wpa_supplicant/wpa_supplicant.conf
Edit the file to look like this:
ctrl_interface=DIR=/var/run/wpa_supplicant GROUP=netdev update_config=1 network={ ssid="♣your-ssid♣" # use a pre-generated key psk=♣your-pre-generated-key♣ # if creating a standard image for many projects, then use pass phrase # instead of generated key # a generated key depends on the Raspberry Pi's MAC # psk="♣your-pass-phrase♣" # specify for clarity key_mgmt=wpa_psk proto=rsn # CCMP is the correct encryption to use for WPA-PSK # The Wi-Fi Alliance requires 802.11n transmissions use WPA2 and CCMP pairwise=CCMP group=CCMP }
CTRL-o to write file
ENTER to confirm write
CTRL-x to exit nano editor
Step 8: Testwifi.sh
Image: shows drop in transfer rate when a microwave oven runs.
testwifi.sh
On my first Raspberry Pi project, the pi would intermittently lose connectivity and not recover. At the time, I was unaware of the importance of the power adapter. I wrote this script to restore wifi, if anything goes wrong.
Login to the Raspberry Pi and run the following command:
$ sudo nano /usr/local/bin/testwifi.sh
Edit the file to look like this:
!/bin/bash # Router IP address TESTIP=♣u-verse-gateway-ip-address♣ counter=0 while true; do # ping the router ping -c1 ${TESTIP} > /dev/null if [ $? != 0 ] then # try a couple of times before restarting, pings can get lost if [ "$counter -lt 3 ] then counter=$((counter+1)) logger "testwifi.sh: WiFi seems down, sleeping" sleep 2 else logger "testwifi.sh: WiFi seems down, restarting" sudo /sbin/ifdown --force wlan0 sleep 10 sudo /sbin/ifup wlan0 exit 0 fi else logger "testwifi.sh: WiFi seems fine" exit 0 fi done exit 0
CTRL-o to write file
ENTER to confirm write
CTRL-x to exit nano editor
Make the file executable:
$ sudo chmod ug+x /usr/local/bin/testwifi.sh
or
$ sudo chmod 0755 /usr/local/bin/testwifi.sh
Create a crontab entry to periodically run the script:
$ sudo crontab –e<br>
and make it look like:
# run every 2 minutes: */2 * * * * /usr/local/bin/testwifi.sh >> /var/log/syslog
CTRL- to write file
ENTER to confirm write
CTRL-x to exit nano editor
Your Done !
Step 9: Appendix Measurements
Image: shows with and without wpa_supplicant.conf
Measurements
The basic measurement approach is:
- repeat and refine until the measurements are accurate and easily reported
- reflash the micro SD card to NOOBS
- apply setup changes to get Raspberry Pi to a known good state
- run iperf3 as a server on a laptop
- repeat the following steps for each measurement:
- reboot the (Raspberry Pi) RPi
- with no change run iperf3 as a client on the RPi
- make one change and reboot the RPi
- run iperf3 as a client on the RPi
- remove the change
- copy and paste the iperf3 results into Excel
- graph the results w/ and w/o the change in Excel
During the measurements, I reflashed the microSD card five times.
Most measurements have 100 intervals. Some measurements have 1000. A larger number of intervals is required when more accurate data is required. For example, when comparing Adapters.
Analysis includes calculating average, min, max and standard deviation, plus significance using a 2 sigma test. All iperf3 results are converted to Mbps (M bits / second)
Measurement results are rounded to fit in 1Mbps bins and counted. Rounding removes some accuracy, but makes graphing the results easier to interpret.
Both results (with and without change) are graphed: y-axis = count and x-axis = Mbps.
Step 10: Appendix Iperf3
Image: shows bandwidth between two MacBook Pros running iperf3 through a wireless access point.
iperf3
iperf3 is a command line speed test tool for measuring bandwidth.
Measure bandwidth between two laptops (PCs or MacBooks). This measurement establishes a baseline for highest achievable bandwidth on your network. Using an iperf3 server external to your network can introduce differences in measurements, which are outside of your control.
All other measurements are made between a laptop and a Raspberry Pi. This approach isolates changes on the Raspberry Pi showing impact on bandwidth.
Expect bandwidth between a Raspberry Pi and a PC to be less than between two PCs.
Install iperf3:
Open a terminal window.
Download and install iperf3 on two laptop/desktop. (I use a MacBook Pro, but it works on PCs as well)
http://macappstore.org/iperf3/
Find the MacBook's IP address, which will act as iperf3 server
$ ifconfig | grep "inet 192.168" inet 192.168.1.76
ssh and login into the Raspberry Pi
$ ssh pi@♣raspberry-pi-ip-address♣
Install iperf3 on Raspberry Pi
$ sudo apt-get install iperf3
Using perf3 for measurements:
To make a measurement run iperf3 from Raspberry Pi to MacBook
Open a terminal window and start an iperf3 server running:
$ iperf3 -s
Open a second terminal window, login into the Raspberry Pi and run:
$ iperf3 -c 192.168.1.76 -R -b 0 -i1 -t 100
Options explained ($ man iperf3):
-R runs perf in reverse mode
-b n=0 sets the bandwidth to unlimited, otherwise n=bandwidth - not required
-i1 pause n seconds between bandwidth reports - not required
-t 100 sets the number of intervals to 100
Step 11: Appendix CCMP
Image: with and without CCMP
CCMP is the standard encryption protocol used with WPA2 standard, which is more secure than the WEP protocol and TKIP protocol of WPA. There isn’t really a choice here. Use CCMP.
$ sudo nano /etc/wpa_supplicant/wpa_supplicant.conf network={ ssid=♣your-ssid♣ psk=♣your-pre-generated-key♣ # only have one of measurement 1, 2 or 3 # measurement 1 # pairwise=CCMP # group=CCMP # measurement 2 # pairwise=CCMP # group=CCMP # measurement 3 pairwise=CCMP TKIP group=CCMP TKIP }
Step 12: Appendix Key_mgmt and Proto
Image: with and and without key_mgmt and proto
Measure with and without key_mgmt and proto.
$ sudo nano /etc/wpa_supplicant/wpa_supplicant.conf network={ wpa-ssid="♣your-ssid♣" wpa-psk="♣your-generated-psk♣" # Only include measurement 1 or 2, but no both # Measurement 1 # key_mgmt=WPA-PSK # proto=RSN # Measurement 2 key_mgmt=WPA-PSK proto=RSN pairwise=CCMP group=CCMP }
Step 13: Appendix Loopback Interface
Image: with and without loopback interface
Measure with and without loopback interface.
Loopback is used by various applications on the Raspberry Pi to talk to itself. So, I won’t make this change.
$ sudo nano /etc/network/interfaces
# Measurement 1 auto lo iface lo inet loopback # Measurement 2 # auto lo # iface lo inet loopback
Step 14: Appendix Default Interface
Image: with and without default interface
Measure with and without default interface.
$ sudo nano /etc/network/interfaces
# Measurement 1 iface default inet dhcp # Measurement 2 # iface default inet dhcp
Step 15: Appendix With and Without GUI
Image: with and without GUI
Measure with and without GUI. Removing the GUI frees about 2GB on the micro SD card.
To remove the GUI:
$ sudo apt-get --purge remove 'x11-*' $ sudo apt-get --purge auto remove $ sudo reboot
$ sudo raspi-config
Advanced Options
memory_split:
Raspberry Pi’s RAM is limited. RAM is shared between a central processing unit (CPU) and a graphics processing unit (GPU). Raspbian Wheezy gives 64MB of RAM to the GPU. Removing the GUI frees this RAM up for applications running on the CPU. Running raspi-config afterwards should show 0MB allocated to the GPU.
Once set in raspi-config, this command will show memory allocated to GPU:
$ cat /boot/config.txt gpu_mem=0