Making Raspberry Pi Wifi connection more robust

While I am adding more and more nodes to my custom Raspberry Pi based home automation system (more on that in future posts), I've seen most nodes having a pretty stable wireless connection. The Pi in my garage that is controlling the motorized garage doors for example has an uptime of about 500 days now without any issues.


However, recently one of the Pi's connection became a bit flaky. The setup: A Raspberry Pi 2 Model B with an Edimax Wifi USB dongle. I am using these dongles for most of my Raspberry Pi devices, and had no issues.

When researching (and by that, I mean googling ;) ) I found a surprising number of topics where people report having issues with the Pi not reconnecting when a Wifi connection is dropped.

One solution I found involved rebooting the Pi when it notices that it has lost Internet connection. I find that a little bit drastic, but maybe something that can be done if all else fails. However, I also do not want to have all my Raspberry Pi devices in the house being stuck in a reboot loop, just because my ISP is having issues.

So instead, I was going for a solution that would involve detecting whether internal servers, such as the router, would be available and make the reset decision based on that. Furthermore, instead of rebooting the device, all I want is the Pi to reset the Wifi connection and try to connect again.

Based on a blog post by Thijs Bernolet, I ended up with this script:

Let me explain, what this does...

Line 3 tries to ping the address of my router (192.168.1.1, but you might want to choose a different target in your network) four times. If this succeeds, the return value of the ping command will be '0':

pi:pi /usr/bin $ ping -c4 192.168.1.1 PING 192.168.1.1 (192.168.1.1) 56(84) bytes of data. 64 bytes from 192.168.1.1: icmp_req=1 ttl=64 time=68.5 ms 64 bytes from 192.168.1.1: icmp_req=2 ttl=64 time=11.0 ms 64 bytes from 192.168.1.1: icmp_req=3 ttl=64 time=7.55 ms 64 bytes from 192.168.1.1: icmp_req=4 ttl=64 time=10.9 ms --- 192.168.1.1 ping statistics --- 4 packets transmitted, 4 received, 0% packet loss, time 3005ms rtt min/avg/max/mdev = 7.551/24.497/68.515/25.452 ms pi:pi /usr/bin $ echo $? 0
If it fails to ping the router, the return value will be '1':
$ ping -c4 192.168.1.222 PING 192.168.1.222 (192.168.1.222) 56(84) bytes of data. From 192.168.1.205 icmp_seq=1 Destination Host Unreachable From 192.168.1.205 icmp_seq=2 Destination Host Unreachable From 192.168.1.205 icmp_seq=3 Destination Host Unreachable From 192.168.1.205 icmp_seq=4 Destination Host Unreachable --- 192.168.1.222 ping statistics --- 4 packets transmitted, 0 received, +4 errors, 100% packet loss, time 3004ms pipe 3 pi:pi-cam-1 /usr/bin $ echo $? 1
In line 5 we check for that return value. If the value is 0, nothing happens. If the value is not, meaning the router was not reachable after four tries, the script will do do three things:
  • (Line 8) Log the date and time of the connection loss in a file. This is so that I can log in from time to time to check how many times this event actually occurred.
  • (Line 9+10) Shut down the wifi connection and wait a bit
  • (Line 11) bring the wifi connection back up.
What is left to do is run this script on a regular interval. You could do it by simply adding a loop around the code with a sufficient time-out. But if something goes wrong and the script exits, that's it.

A more straight-foward way to ensure the script is called regularly is to add it to the crontab:
$ crontab -e

Then add this line:
*/5 * * * * /usr/bin/sudo -H /usr/local/bin/checkwifi.sh >> /dev/null 2>&1

This will run the script as root using sudo every 5 minutes.

That's it! Make sure the log file (in my case located in /home/pi/restart_wifi_status.log) is writable by root and you're done. Hopefully your Raspberry Pis connection is more stable now.

Note: This above applies to any Linux based machine, and is not Raspberry Pi specific. So if you have some kind of server that is connected wirelessly and has trouble to stay connected, try the above.

Comments

Popular posts from this blog

Installing DD-WRT on the Linksys EA2700

Setting up Arduino IDE 1.0 and 1.6 for ATtiny and Manchester library

Backing up a NAS to CrashPlan using a Raspberry Pi