I have several headless Raspberry Pis around my house, and some of the Raspberry Pis use WiFi to connect to the home network. The WiFi connections are pretty stable most of the time, but I sometimes notice that my Pis get disconnected from WiFi and never reconnect to the home network. Usually, I can solve this problem by either turning off and on the WiFi antenna via command prompt on the affected Pi (which requires hooking up a keyboard, mouse, and a monitor) or simply rebooting the system by disconnecting and reconnecting the power supply. Although these two solutions solved the problem, I wanted to manage the problem by setting up an automated solution to the WiFi connection problem.
How can I have the Pi disconnect and reconnect the WiFi antenna whenever there is a WiFi problem? Using a prewritten bash script and cronjob, I was able to have my Raspberry Pi (1) auto-check whether there was a WiFi problem, and (2) reconnect to the WiFi network by disconnecting and reconnecting the WiFi antenna.
Creating the bash script
First, I created a bash script on my home directory by using GNU nano. I named the bash script “WiFichecker.sh”.
cd && nano WiFichecker.sh
The cd
command changes the current working directory to the user’s home directory. &&
or AND operator allows me to run consecutive commands, where the subsequent command (nano WiFichecker.sh
would run only if the previous command (cd
) ran successfully. Finally, nano WiFichecker.sh
opens up nano (our text editor) with a bash script file named “WiFichecker.sh” ready to be saved.
Once nano is open, we can write the following commands in sequence on each line.
ping -c4 google.com > /dev/null
To determine whether we have a WiFi connection, we simply use the ping
command to check whether our Raspberry Pi can connect to one of Google’s servers. Parameter -c4
indicates that we want to ping Google four times in case the first few pings do not work. The >
operator redirects any output of ping -c4 google.com
to a specified destination right of the operator. The > /dev/null
ensures that all of the output of the ping command gets thrown away. (/dev/null
can be seen as a black hole in Linux)
For the next block of code, it makes sense to see it as a whole in multiple lines.
if [ $? != 0 ]
then
sudo ip link set wlan0 down
sleep 15
sudo ip link set wlan0 up
sleep 15
sudo dhcpcd
else
echo "nothing wrong"
fi
When we run the previous ping -c4 google.com > /dev/null
command, there is an exit status left in memory, where we can access the value of the exit status by looking at the variable $?
. The $?
variable will usually give a value of “0” if the previous command was successful and a value other than “1” if there were any issues. If our ping command did not encounter any errors (i.e., the device was able to ping and get a response from Google’s servers), then the value of $?
would be “0”. However, if there were issues with our ping command (e.g., the device could not ping Google’s servers or Google’s servers did not respond back with our ping request), then the value of $?
would not be “0”.
Thus, we can set a conditional statement in bash, where we can write a set of commands only we encounter a problem with our ping command (value of $?
is not 0). When we have ping issues, we can write a series of commands to (1) shut off the WiFi device, (2) wait 15 seconds, (3) turn on the WiFi device, (4) wait 15 seconds, and (5) reconfigure the network interface to ensure that we can reconnect to the network.
sudo ip link set wlan0 down
This command turns off our WiFi device (wlan0
) via superuser privileges.
sleep 15
This command makes our device wait for 15 seconds until moving on to the next command.
sudo ip link set wlan0 up
This command turns back on our WiFi device via superuser privileges.
sleep 15
Just like the previous sleep
command, our device will wait for 15 seconds until moving on to the next command.
sudo dhcpcd
Assuming we are reconnected to our WiFi network, we can use the dhcpcd
command via superuser privileges to reconfigure the network interface (e.g., determining which IP address to use for the network) to ensure that we can interface with the network.
That’s it! These following sets of commands, whenever we do not have access to Google’s servers, should successfully reset our WiFi network interface to reconnect to our designated network.
The command echo "nothing wrong"
is nested inside our conditional statement when we have successfully been able to ping google. I intentionally left this echo
statement for logging purposes.
Our script as a whole is the following:
ping -c4 google.com > /dev/null
if [ $? != 0 ]
then
sudo ip link set wlan0 down
sleep 15
sudo ip link set wlan0 up
sleep 15
sudo dhcpcd
else
echo "nothing wrong"
fi
We can press the “Control” key and “O” together to save the bash script, and we can press the “Control” key and “X” together to exit nano.
Scheduling the WiFi checkup
Now that we have our script, we can use a cronjob entry to run our script at regular intervals. Because we have some commands that require superuser privileges, we need to run cronjob via superuser privileges. To run our script via cronjob with superuser privilege, we can open crontab via superuser privileges.
sudo crontab -e
If this is your first time running crontab via superuser privileges, crontab may ask which text editor to use to edit the cron table. I pick nano because I am most familiar with this text editor. Once the crontab is open, we can add the following command at the end of the text file.
*/5 * * * * sudo bash /home/[username]/WiFichecker.sh
The first five columns proceeding our command denotes time variables, where we can adjust to run the script to our liking. I want to run the script every five minutes, so I write */5 * * * *
to indicate that the script should run every 5 minutes, of every hour, of every day, of every month, and of every weekday. Feel free to adjust this parameter to your liking.
Next, sudo bash /home/[username]/WiFichecker.sh
essentially executes our bash script (located at our home directory) via superuser privileges.
Afterward, we can save our cron table (“Control” key and “O” on nano) and exit the text editor (“Control” key and “X on nano).
Finally, we can either restart the Raspberry Pi (sudo reboot
) or restart the cron service (sudo service cron restart
) to apply the changes to our cron table.
No more disconnected Raspberry Pis
After implementing the WiFi checker and reconnection script, my Raspberry Pi never had a network disconnection issue. I hope this guide ensures that your headless Raspberry Pis always have a stable WiFi connection!