When looking for a networking related problem to solve for my internetworking unversity course, I realized a major pain point for us specifically at our university— the WiFi sucks.
The thing is,
though, that there are three available wifi networks around campus, eduroam
, UMB-Guest
,
and Event-Guest
. They don’t usually suck at the same time, but all of them periodically become
very slow. This means that you, the user, have to take a break from whatever internet-dependent
work you’re doing for a second and manually switch to one of the other options.
ESP32s are pretty cheap and easy to use, and most importantly, they have a network card and can talk to PCs via USB. That means we can use the ESP32 as a second network card, totally dedicated to live-testing the WiFi throughput speed of available known networks!
This was not immediately obvious to me. Investigating solutions to this problem, I found this Python script on Reddit that automatically switches to the available known network with the strongest WiFi signal, all in the background using NetworkManager.
Problem solved, right? Well, not exactly. It only switches based on signal strength and physical data rate— not WiFi throughput1. Especially given the fact that many, many people are connected to these campus networks at any given time, WiFi signal strength alone is probably not a good indicator of the upload and download speeds you’ll get when you’re actually on the network.
The constraint here is that to measure a network’s internet throughput, you need to be actively connected to it, and use something like speedtest.net to see how fast your end-to-end data transfer rates are. Since laptops only have one network card and network cards can only connect to one network at a time, you can’t live test the internet speed of other networks without disconnecting from your current one.
Here’s where the ESP32 comes in! The laptop will send over the list of available known networks while running, and the ESP32 will keep a map of each available network and its current speed. It will keep switching between the available networks and re-testing them, updating the map until a new fastest is found— at which point it will send a message and alert the host PC. The host PC will then switch to the new fastest network, all without the user doing anything manually.
network diagram for this architecture, where “host device”=laptop and “external device”=esp32.
Once we had a clear plan for our solution, we spent a few hours hacking away at this thing until we eventually had a working version, which totalled in around 300 lines of C++/Arduino and Python. The main test case was to connect to one of my university WiFi networks and then turn on my hotspot, which is faster than any of the university networks, at least during the afternoon. Without fail, the esp32 would iterate through the available networks, see that my hotspot was the new fastest known network, tell the laptop to conenct to it, and it would connect automagically(tm).
Now, we have a prototype that will swap to the fastest available known WiFi based on the real live internet speed measurements :)
Although we have a working prototype, there is still a laundry list of things that we could add to this device including:
If you’re interested in trying it out or contributing, you can check out the project and give us a star on GitHub!
nmcli
provides the following info about wifi networks↩