How do we test wireless for a classroom? The only way I have every been able to really test wireless has been to get a bunch of computers in a room and do some testing. It’s slow, time confusing and can’t be done while users are there. So, I decided to build something.
The idea of a Raspberry Pi Stack has always intrigued me, it’s the small nature of them that I like. Having a series of computers connected, to make a cluster, it’s always sounded awesome. A mini supercomputer that you can do cool things with… but for me I always struggled what I could do with them. Though about a year ago I had an idea… a Wifi Tester. And because of that the following idea was thought up!
The roots of this idea started to form almost five years ago, I was rolling out Ubiquiti Wireless at Central Coast Grammar School and I was frustrated that the only real way I could tell to test something was to take 15-20 devices into the room with me. You can see a photo here of my office at the time where I searched through our storeroom to gather 20 iPads and laptops, we had spare that I could use to test. I then had them doing a mix of YouTube and iPerf tests to generate load. While it may have worked, the issue with it was that the time taken to setup and test took too long, plus it required a bunch of cables to be run and I hate a messy office.
Want I wanted was a way to test the wireless without having to take a bunch of devices to a room. Even 2 years ago when we were getting ready for some online tests, the only way we could really do it was a borrow a class set of iPads, setup some long running 1080p videos and kick them off. I think we got around 30 going and saw no drop so we then moved to the next stage of testing… asking for an actual class to come into the room and then a year group of students. Either way if it failed with students in there it ruins perceived ability of the network.
So, I wanted an easier option. The idea came to me when I was setting up a Raspberry Pi 3 to use for a monitoring Pi monitor, I wondered if I could use a series of them to handle testing. And then what would happen if I plugged in a USB wireless card to a Pi. The issue was that even if I connected a bunch together how could I control them without taking a series of monitors and keyboards to handle them.
The final part of the puzzle came early this year when I came across a YouTube video about Ansible. Ansible is an open-source automation tool that can run on something as lite weight as a Raspberry Pi. This was the final part I needed to make it work, I could setup one of the Pi’s as the server to control the other Pi’s.
This was the diagram of how I could achieve a great wireless tester.
Then the final thing happened, I was thrown into an extended lockdown here in NSW. So, with some spare time due to the lockdown, I decided now was the time to see what I could build. Firstly, I came up with a test part lists.
4x Raspberry Pi 4
4x 32GB MicroSD cards
5x USB A to USB-C 15cm cables
5x Ethernet cables
16x USB Wifi 2.4/5GHz Wifi cards
1x Anker 65-Watt Charger
1x Ubiquiti UniFi USW Flex mini switch
1x Raspberry Pi Stack 4-part
1x 120cm Fan USB powered, late addition
When I picked my Raspberry Pi’s I decided on the Pi4 straight away since it was the current generation Pi, but I also went for the 8GB range as I wanted the extra grunt if needed. And if this failed, I figured having the more powerful ones meant they could have better uses for other projects than the 4GB ones.
When I picked my Raspberry Pi’s I decided on the Pi4 straight away since it was the current generation Pi, but I also went for the 8GB range as I wanted the extra grunt if needed. And if this failed, I figured having the more powerful ones meant they could have better uses for other projects than the 4GB ones.
One of the reasons I choice the USW Flex Mini switch from Ubiquiti was because it is USB-C powered, it meant the 4 Pi’s and the switch can all be run by the 6-port Anker 65-Watt charger. This meant that not just the 4 Pi’s and the USW. But also, the fan.
The Fan was a last-minute addition, I discovered that the Pi’s with USB Cards would generate some serious heat. They were generating around 70 degrees heat without the fan after a few hours. However, after adding the fan the average temp is around 30-35 degrees.
I then moved onto the software, each one was setup with Raspbian Lite, I didn’t need a GUI for this to work. I used the terminal for everything to be done. The setup was the same for each, with one Pi chosen as a Master to run Ansible and a website.
The setup process
Setup all Pi’s got;
Raspbian setup and configured for headless access. Each is accessed by SSH on one 172.16.0.95 through to 172.16.0.98. I then installed the following Wifi Card on each to enable the 4 USB Cards. I also had to do some custom changes to enable them to work with 802.11 WPA Enterprise networks since they are not out of the box allowed by Raspberry.
USB Wifi Card Drivers: https://github.com/fastoe/RTL8811CU_for_Raspbian
I then configured the wireless as below to get it to connect to our WPA Enterprise network.
To make it connect, I updated the /etc/wpa_supplicant/wpa_supplicant.conf file.
network={
ssid="CCGS"
priority=1
scan_ssid=1
mode=0
key_mgmt=WPA-EAP
eap=PEAP
identity="username"
password="password"
phase1="peaplabel=0"
phase2="auth=MSCHAPV2"
}
Under the user directory I then created a folder called scripts on each. The scripts folder is where you place the commands you want to run via Ansible on each Pi, you can see the scripts I have added later in this post.
On the main Pi I then added a DHCP server, this is a simple setup so that when you plug your device into the 5th USW port it gives that device a 192.168.1.X address. There is a point to this. With the setup I wanted to ensure that when an iPerf test was run it did not impact the wireless network at all.
The other setup to do on the main pain was to setup Ansible. Ansible setup was very straight forward and click HERE for the guide I followed to setup Ansible and enable ssh-key between them for easy running of tasks. In the user directory of the first Pi, I then created a folder called Ansible that houses the shell script for kicking off the script on each Pi.
At this point you have a Pi Stack setup that is being managed by Ansible, and now you need to organise the scripts for each Pi and the Ansible ones. In the scripts folder on each Pi, I have the following scripts, though they are modified slightly for each Pi. In the speed test links you need to mention the IP address of each Adaptor.
The reason they each have echo ” “ behind under each one to separate the results, you’ll see later.
The final thing I did was once the Pi’s, and their cards were connected. I went into my windows DHCP server and set static IPs for each card.
Host IP Addresses
#!/bin/bash
/usr/sbin/ifconfig eth0 | grep "inet " | awk '{print "Onboard eth0 Addr: " $2}'
/usr/sbin/ifconfig wlan0 | grep "inet " | awk '{print "Onboard wlan0 Addr: " $2}'
/usr/sbin/ifconfig wlan1 | grep "inet " | awk '{print "USB WiFi wlan1: " $2}'
/usr/sbin/ifconfig wlan2 | grep "inet " | awk '{print "USB WiFi wlan2: " $2}'
/usr/sbin/ifconfig wlan3 | grep "inet " | awk '{print "USB WiFi wlan3: " $2}'
/usr/sbin/ifconfig wlan4 | grep "inet " | awk '{print "USB WiFi wlan4: " $2}'
echo " "
Host Reboot
#!/bin/bash
sudo reboot
Host Shutdown
#!/bin/bash
sudo shutdown -h -t 10
Host Temperature Check
#!/bin/bash
vcgencmd measure_temp | awk '{print "Processor " $1}'
echo " "
The next three area from one of the Pi’s, while it is almost the same on each of course the -B IP is different as you need to bind it to a card. If there was a version of iPerf where I could -B to a interface name would be good. but unfortunately this is all I could get working.
Host Speedtest 10 Streams USB Adaptors
#!/bin/bash/
iperf -c 172.16.0.99 -B 172.16.64.240 -P 10 -i 1 | tail -n 1 | awk '{print "||", "Pi-1 Wifi Card 172.16.64.240","|", "Bandwidth", $4,$5, "|", "Speed:", $6,$7, "||"}'
iperf -c 172.16.0.99 -B 172.16.64.241 -P 10 -i 1 | tail -n 1 | awk '{print "||", "Pi-1 Wifi Card 172.16.64.241","|", "Bandwidth", $4,$5, "|", "Speed:", $6,$7, "||"}'
iperf -c 172.16.0.99 -B 172.16.64.242 -P 10 -i 1 | tail -n 1 | awk '{print "||", "Pi-1 Wifi Card 172.16.64.242","|", "Bandwidth", $4,$5, "|", "Speed:", $6,$7, "||"}'
iperf -c 172.16.0.99 -B 172.16.64.243 -P 10 -i 1 | tail -n 1 | awk '{print "||", "Pi-1 Wifi Card 172.16.64.243","|", "Bandwidth", $4,$5, "|", "Speed:", $6,$7, "||"}'
echo " "
Host Speedtest 10 Streams 2 Minutes USB Adaptors
#!/bin/bash/
iperf -c 172.16.0.99 -B 172.16.64.254 -P 10 -t 120 -i 1 | tail -n 1 | awk '{print "||", "Pi-1 Wifi Card 172.16.64.254","|", "Bandwidth", $4,$5, "|", "Speed:", $6,$7, "||"}'
iperf -c 172.16.0.99 -B 172.16.64.253 -P 10 -t 120 -i 1 | tail -n 1 | awk '{print "||", "Pi-1 Wifi Card 172.16.64.253","|", "Bandwidth", $4,$5, "|", "Speed:", $6,$7, "||"}'
iperf -c 172.16.0.99 -B 172.16.64.252 -P 10 -t 120 -i 1 | tail -n 1 | awk '{print "||", "Pi-1 Wifi Card 172.16.64.252","|", "Bandwidth", $4,$5, "|", "Speed:", $6,$7, "||"}'
iperf -c 172.16.0.99 -B 172.16.64.251 -P 10 -t 120 -i 1 | tail -n 1 | awk '{print "||", "Pi-1 Wifi Card 172.16.64.251","|", "Bandwidth", $4,$5, "|", "Speed:", $6,$7, "||"}'
echo " "
Host Speedtest 10 Streams 5 Minutes USB Adaptors
#!/bin/bash/
iperf -c 172.16.0.99 -B 172.16.64.254 -P 10 -t 300 -i 1 | tail -n 1 | awk '{print "||", "Pi-1 Wifi Card 172.16.64.254","|", "Bandwidth", $4,$5, "|", "Speed:", $6,$7, "||"}'
iperf -c 172.16.0.99 -B 172.16.64.253 -P 10 -t 300 -i 1 | tail -n 1 | awk '{print "||", "Pi-1 Wifi Card 172.16.64.253","|", "Bandwidth", $4,$5, "|", "Speed:", $6,$7, "||"}'
iperf -c 172.16.0.99 -B 172.16.64.252 -P 10 -t 300 -i 1 | tail -n 1 | awk '{print "||", "Pi-1 Wifi Card 172.16.64.252","|", "Bandwidth", $4,$5, "|", "Speed:", $6,$7, "||"}'
iperf -c 172.16.0.99 -B 172.16.64.251 -P 10 -t 300 -i 1 | tail -n 1 | awk '{print "||", "Pi-1 Wifi Card 172.16.64.251","|", "Bandwidth", $4,$5, "|", "Speed:", $6,$7, "||"}'
echo " "
On the main PI I then have in the ~/ansible I have several scripts saved that all use the same method to trigger the individual scripts across each Pi. Technically this part isn’t required, but to tie it to the python website it was easier to have it just show any shell scripts that are in that folder below.
The in the Ansible folder on the main Pi then has the following scripts added.
Check IP Addresses
#!/bin/bash
ansible Wifi_Stack_Hostname -a "sh /home/pi/scripts/host-ip-addr-all.sh"
Check IP Temperatures
#!/bin/bash
ansible Wifi_Stack_Hostname -a "sh /home/pi/scripts/host-temp-check.sh"
Reboot Stack
#!/bin/bash
ansible Wifi_Stack_Hostname -a "sh /home/pi/scripts/host-reboot.sh"
Shutdown Stack
This one does mean the stack is done until the power is unplugged and replugged.
#!/bin/bash
ansible Wifi_Stack_Hostname -a "sh /home/pi/scripts/host-shutdown.sh"
Speed Test 10 Streams 2 Minutes USB Antennas
#!/bin/bash
ansible Wifi_Stack_Hostname -a "sh /home/pi/scripts/host-speedtest-usb-10streams-2minutes-usb-wifi.sh"
echo " "
Speed Test 10 Streams 5 Minutes USB Antennas
#!/bin/bash
ansible Wifi_Stack_Hostname -a "sh /home/pi/scripts/host-speedtest-usb-10streams-5minutes-usb-wifi.sh"
echo " "
Speed Test 10 Streams USB Antennas
#!/bin/bash
ansible Wifi_Stack_Hostname -a "sh /home/pi/scripts/host-speedtest-usb-10streams-usb-wifi.sh"
Though at this point I still needed SSH into the Pi to run those commands, and while I have no issue running them the idea is to make this easy to use for anyone who wants to run a test. I knew what I wanted to do, I wanted a little website that was run on the site that allowed you to pick a script and see the results. Though I do not have the skills to do this, so in walked Stephen Webb, a very smart coder who in about ten minutes built me a python website that could run on the Pi.
The site is very simple in terms a drop down at the top, and results window and a small info window.
This site allows me to trigger the saved scripts and run them with the results appearing in the main window. Prefect for almost anyone to use. And to make it that slightly easy, a small ‘Help section’ was added on the site that pulls its data from a help.txt file on the Pi.
The dropdown list is populated by what is in the ~/ansible folder. If you create a new Ansible shell script to run another option is added.
The results window then shows you the output from the script into that viewing window for you. I can’t take Stephen Webb enough for his help here.
The last section, the info section is pulled from a text file ~/ansible/info.txt.
It is this reason I have also added a DHCP server to the main pi, you could take this to multiple networks, use the DHCP 192.168.0.x address to access the Pi’s and then connect them to whatever network you are testing. For my purposes they will also be connected to our school network, so I want to be changing the setting that often.
NOTE: You will see that each Pi’s IP listed below is 172.16.0.9x, this is because the Pi Stack is currently at work, and while typing this I am at home. If I hadn’t changed them from 192.168.0.x to my work network I wouldn’t have been able to access them remotely.
And then when you run a test you see results like this.
iPerf Server… how I did it and how can you
Since a lot of this testing happened during a lockdown, I did a lot of the work at home on a test network or two that I have. Because it was my test network, I couldn’t use any of my production servers since they didn’t have access to my test networks. So, I used a fifth Raspberry Pi connected via Ethernet to the test networks.
At CCGS on our network I span up an Ubuntu server on our ESX Cluster that has iPerf running as a server as a service. So, wherever we take the stack on the network it can always access the iPerf server when needed. The one part I feel is important is that your iPerf server needs to be cabled, you don’t want to be testing the wireless on both paths, your “clients” should be the only part using the wireless.
iPerf 2 vs iPerf 3
I stayed with iPerf 2 for my testing, this is because I could not figure out how to send multiple connections to an iPerf 3 server, and all the googling I could did pointed to the same answer. So, unless someone can show me how you change iPerf 3 to allow multiple connections on its server side… I’ll just sick with iPerf 2.
What does the future hold?
This did work, yes, the speed is not as high as I get when being tested on something with a bigger WiFi antenna, and you could add bigger antennas to them, but I don’t feel it is needed. The point of this is to see if your AP can handle multiple connections all trying to take big bandwidth at once. Even at their lower speed it shows that the AP can handle it, and most users are not trying to spend several hundred MB across the wireless at once. Most at the most need a few MB to handle their needs.
Impressed with this I decided to up stack. More gear has been brought and once it is done, I’ll do another post about it.
How it went?
For me the project was successful, I can act like multiple clients at once with a device that is small and compact, easy for 1 guy to take to a classroom and test. It is also easy to manage via Ansible and the python website.
I consider myself a jack of all trades and master of known, if any of the Wireless guru’s out there know a better iPerf settings I could use please let me know, I did some research on what the best command structure could be and feel I got close… but I am always up for learning more. Or even know a better CLI tool that can test your wireless connection better, please let me know.
Leave a Reply