My Raspberry Pi 3 Wi-Fi isn’t very reliable even after disabling power management my RPI still manages to lose connection to my Wi-Fi router and i don’t have any keyboard or screen connected to it and its not advisable to do hard reset i.e unplug the power as it may corrupt your SD card. I’m going to cover writing a short script that Auto Reconnect WiFi on Raspberry Pi to a Wi-Fi network. The script will run as cron job at around 5 minutes interval to check if the Pi has network connectivity and if it is offline, restart the wireless interface to bring it back online.
There are a few ways to determine if the Raspberry Pi has Wi-Fi network connectivity. I’ll be using ping to determine Wi-Fi connection status.
Auto Reconnecting Wi-Fi Script
First we need to determine if the Raspberry Pi is connected to the Wi-Fi network. To do this, we can ping a our Wi-Fi router if you want to test internet connectivity you can use google DNS IP address 8.8.8.8 instead but we only want to check connection to our Wi-Fi router. If Raspberry Pi receives a ping response from the Wi-Fi router then we have network connectivity. If the we don’t get any response then we’ll turn wlan0 off and back on.
Copy and paste following script and save it (check_wifi.sh) i have all my cron schedules scripts saved under /var/www/cron you can save it to anywhere you like.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 |
#!/bin/bash #================================================================= # Script Variables Settings clear wlan='wlan0' gateway='192.168.99.1' alias ifup='/sbin/ifup' alias ifdown='/sbin/ifdown' alias ifconfig='/sbin/ifconfig' #================================================================= echo " _____ _ _ _ " echo " | __ \ (_) | | | | " echo " | |__) | _ | |__| | ___ _ __ ___ ___ " echo " | ___/ | | | __ | / _ \ | |_ \_ \ / _ \ " echo " | | | | | | | | | (_) | | | | | | | | __/" echo " |_| |_| |_| |_| \___/ |_| |_| |_| \___|" echo " " echo " S M A R T H E A T I N G C O N T R O L " echo "*************************************************************************" echo "* PiHome is Raspberry Pi based Central Heating Control systems. It runs *" echo "* from web interface and it comes with ABSOLUTELY NO WARRANTY, to the *" echo "* extent permitted by applicable law. I take no responsibility for any *" echo "* loss or damage to you or your property. *" echo "* DO NOT MAKE ANY CHANGES TO YOUR HEATING SYSTEM UNTIL UNLESS YOU KNOW *" echo "* WHAT YOU ARE DOING *" echo "*************************************************************************" echo echo " Have Fun - PiHome" date echo " - Auto Reconnect Wi-Fi Status for $wlan Script Started "; echo # Only send two pings, sending output to /dev/null as we don't want to fill logs on our sd card. # If you want to force ping from your wlan0 you can connect next line and uncomment second line ping -c2 ${gateway} > /dev/null # ping to gateway from Wi-Fi or from Ethernet # ping -I ${wlan} -c2 ${gateway} > /dev/null # only ping through Wi-Fi # If the return code from ping ($?) is not 0 (meaning there was an error) if [ $? != 0 ] then # Restart the wireless interface ifdown --force wlan0 ifup wlan0 sleep 5 ifup wlan0 fi ping -I ${wlan} -c2 ${gateway} > /dev/null date echo echo " - Auto Reconnect Wi-Fi Status for $wlan Script Ended "; |
Make your script executable by running following command
1 |
chmod +x /var/www/cron/check_wifi.sh |
Test Auto Reconnecting Wi-Fi Script
First run following command to test there are not errors in your script.
1 |
sh /var/www/cron/check_wifi.sh |
After successful execution of Auto Reconnecting Wi-Fi script you should get output as below.
Lets add Auto Reconnecting Wi-Fi script to cron schedule so this script runs every five minutes. run crontab -e command and add following line to your crontab, make sure you add >/dev/null 2>&1 otherwise you will end up burning your SD card with unnecessary logs.
1 2 3 |
crontab -e */5 * * * * sh /var/www/cron/check_wifi.sh >/dev/null 2>&1 |
Lets do more testing taking down wlan0 and let script to restart Wi-Fi.
Note: running following command will immediately disconnect your shell session. and you have to wait for cron job to start your Wi-Fi it shouldn’t take more then 5 minutes.
1 |
ifdown --force wlan0 |
After waiting for cron job to run auto reconnecting Wi-Fi script you can try to ssh to your raspberry pi. Assuming everything worked as it should your raspberry pi should reconnect to Wi-Fi. You can adjust time of script to what ever you value you like.
21 comments
Short and effective, great work thanks 🙂
your wifi check (Auto Reconnect WiFi ) script with power management settings worked great
good work, keep it up
Hi this is great work, i couldn’t solve this puzzle myself, my rpi disconnect wifi connection at random interval to my home wifi but your script helped to keep raspberry pi connected to wifi specially this script to check wifi connection.
Now I m wondering if there is an easy way to detect configured wifi availability and if none of configured wifi available then RPI act as wifi access point so I can connect to it but as soon as wifi become available it connect to wifi but only fall back to wifi access point when no wifi is available. I have read lots of tutorials on how to setup rpi as access point may be you can help setup raspberry pi act as access point when no wifi is available.
Hi Garey, glade this post helped you, i had similar issue with raspberry pi wifi setup each time i want to change my wifi password i have to go back and change password in pi first then change password of my wifi router. i m working on on script to make pi as access point when no wifi is available but there are some dependencies i.e. not all wifi dongle are support to act as wifi access point but its work in progress and i’ll update here once i have something working….
When i run “ifdown –force wlan0” i get this “ifdown: unknown interface wlan0”
Does anyone know what is wrong?
@Athanasios
do you have wifi configured? your WiFi connected? it might be wlan1 interface try this and me know.
Admin
Hello,
I’ve got a problem with your script or especially with cron executing the script. If I test the script manually everything works fine. But crontab can’t do the auto reconnect. I’ve made only two changes: The file has a different name and the location is different to yours (/usr/local/bin/network_status.sh)
Do you’ve got any idea why it isn’t working?
@Asker,
can you try to add following line to your crontab, and mke sure you are logged in as root so all cron jobs run as root. this line will create log and save it to /usr/local/bin/reboot_wifi.log once you have log file you can share here to get some suggestions.
*/5 * * * * sh /usr/local/bin/network_status.sh >> /usr/local/bin/reboot_wifi.log 2>&1
It’s a long log file but here are the first trials 🙂
‘unknown’: I need something more specific.
Sun 25 Mar 18:40:02 CEST 2018
– Auto Reconnect Wi-Fi Status for wlan0 Script Started
connect: Network is unreachable
ifdown: waiting for lock on /run/network/ifstate.wlan0
ifup: waiting for lock on /run/network/ifstate.wlan0
ifup: interface wlan0 already configured
ifup: waiting for lock on /run/network/ifstate.wlan0
ifup: interface wlan0 already configured
ping: Warning: source address might be selected on device other than wlan0.
Sun 25 Mar 18:40:46 CEST 2018
– Auto Reconnect Wi-Fi Status for wlan0 Script Ended
‘unknown’: I need something more specific.
Sun 25 Mar 18:45:02 CEST 2018
– Auto Reconnect Wi-Fi Status for wlan0 Script Started
connect: Network is unreachable
ifup: waiting for lock on /run/network/ifstate.wlan0
ifup: interface wlan0 already configured
ping: Warning: source address might be selected on device other than wlan0.
Sun 25 Mar 18:45:51 CEST 2018
– Auto Reconnect Wi-Fi Status for wlan0 Script Ended
‘unknown’: I need something more specific.
Sun 25 Mar 18:50:02 CEST 2018
– Auto Reconnect Wi-Fi Status for wlan0 Script Started
connect: Network is unreachable
ifdown: waiting for lock on /run/network/ifstate.wlan0
ifup: waiting for lock on /run/network/ifstate.wlan0
ifup: interface wlan0 already configured
ifup: interface wlan0 already configured
ping: Warning: source address might be selected on device other than wlan0.
Sun 25 Mar 18:50:46 CEST 2018
did you change gateway=’192.168.99.1′ variable to your router ip address?
Yes like I said bevor. If I run the test “sudo ifdown –force wlan0” everything is working fine..
can you try to run your script while you are logged in
sh /usr/local/bin/network_status.sh
and what you see there ?
Also Yes!
Sun 25 Mar 20:57:29 CEST 2018
– Auto Reconnect Wi-Fi Status for wlan0 Script Started
Sun 25 Mar 20:57:31 CEST 2018
– Auto Reconnect Wi-Fi Status for wlan0 Script Ended
can you try this code, this should ping your gateway,
#!/bin/bash
#=================================================================
# Script Variables Settings
clear
wlan='wlan0'
gateway='192.168.99.1'
alias ifup='/sbin/ifup'
alias ifdown='/sbin/ifdown'
alias ifconfig='/sbin/ifconfig'
#=================================================================
date
echo "Auto Reconnect Wi-Fi Status for $wlan Script Started ";
echo
ping -c2 ${gateway}
if [ $? != 0 ]
then
ifdown --force wlan0
ifup wlan0
sleep 5
ifup wlan0
fi
ping -I ${wlan} -c2 ${gateway}
date
echo
echo "Auto Reconnect Wi-Fi Status for $wlan Script Ended ";
Sun 25 Mar 22:03:53 CEST 2018
Auto Reconnect Wi-Fi Status for wlan0 Script Started
PING 10.0.0.138 (10.0.0.138) 56(84) bytes of data.
64 bytes from 10.0.0.138: icmp_seq=1 ttl=64 time=8.08 ms
64 bytes from 10.0.0.138: icmp_seq=2 ttl=64 time=7.59 ms
— 10.0.0.138 ping statistics —
2 packets transmitted, 2 received, 0% packet loss, time 1001ms
rtt min/avg/max/mdev = 7.591/7.837/8.083/0.246 ms
PING 10.0.0.138 (10.0.0.138) from 10.0.0.12 wlan0: 56(84) bytes of data.
64 bytes from 10.0.0.138: icmp_seq=1 ttl=64 time=3.72 ms
64 bytes from 10.0.0.138: icmp_seq=2 ttl=64 time=6.04 ms
— 10.0.0.138 ping statistics —
2 packets transmitted, 2 received, 0% packet loss, time 1001ms
rtt min/avg/max/mdev = 3.720/4.882/6.044/1.162 ms
Sun 25 Mar 22:03:55 CEST 2018
Auto Reconnect Wi-Fi Status for wlan0 Script Ended
@Asker
now clear log file and let it run in cron and compare the output, i just trying to get picture why its not working.
Admin
‘unknown’: I need something more specific.
Mon 26 Mar 15:00:01 CEST 2018
Auto Reconnect Wi-Fi Status for wlan0 Script Started
connect: Network is unreachable
ifup: waiting for lock on /run/network/ifstate.wlan0
ifup: waiting for lock on /run/network/ifstate.wlan0
ifup: interface wlan0 already configured
ping: Warning: source address might be selected on device other than wlan0.
PING 10.0.0.138 (10.0.0.138) from 0.0.0.0 wlan0: 56(84) bytes of data.
— 10.0.0.138 ping statistics —
2 packets transmitted, 0 received, 100% packet loss, time 1038ms
Mon 26 Mar 15:00:46 CEST 2018
Auto Reconnect Wi-Fi Status for wlan0 Script Ended
‘unknown’: I need something more specific.
Mon 26 Mar 15:05:01 CEST 2018
Auto Reconnect Wi-Fi Status for wlan0 Script Started
connect: Network is unreachable
ifdown: waiting for lock on /run/network/ifstate.wlan0
ifup: waiting for lock on /run/network/ifstate.wlan0
ifup: interface wlan0 already configured
ifup: waiting for lock on /run/network/ifstate.wlan0
ifup: interface wlan0 already configured
ping: Warning: source address might be selected on device other than wlan0.
PING 10.0.0.138 (10.0.0.138) from 0.0.0.0 wlan0: 56(84) bytes of data.
— 10.0.0.138 ping statistics —
2 packets transmitted, 0 received, 100% packet loss, time 1039ms
Mon 26 Mar 15:05:51 CEST 2018
Auto Reconnect Wi-Fi Status for wlan0 Script Ended
…
So you have also no idea where the problem lies?
i tried to replicate your issue but so far can i m unsuccessful, can you try following script i have this running for very long time and never had issue, and can you create cron tab while logged in as root, ame make sure you have change the settings to allow root login as per OS (Raspbian Jessie) Installation and WiFi Configuration
echo "*************************************************************************"
date
##################################################################
# Settings
# Where and what you want to call the Lockfile
lockfile='/var/www/cron/reboot_wifi.pid'
# Which Interface do you want to check/fix
wlan='wlan0'
gateway='192.168.99.1'
alias ifup='/sbin/ifup'
alias ifdown='/sbin/ifdown'
alias ifconfig='/sbin/ifconfig'
##################################################################
echo
echo "Starting WiFi check for $wlan"
echo
# Check to see if there is a lock file
if [ -e $lockfile ]; then
# A lockfile exists... Lets check to see if it is still valid
pid=
cat $lockfile
# if kill -0 &>1 > /dev/null $pid; then
if kill -0 &>1 $pid; then
# Still Valid... lets let it be...
echo "Process still running, Lockfile valid"
exit 1
else
# Old Lockfile, Remove it
echo "Old lockfile, Removing Lockfile"
rm $lockfile
fi
fi
# If we get here, set a lock file using our current PID#
echo "Setting Lockfile"
echo $$ > $lockfile
# We can perform check
echo "Performing Network check for $wlan"
# Only send two pings, sending output to /dev/null
#ping -c2 ${gateway} #> /dev/null
ping -c2 ${gateway}
# If the return code from ping ($?) is not 0 (meaning there was an error)
if [ $? != 0 ]
then
# Restart the wireless interface
ifdown --force wlan0
sleep 5
ifup wlan0
fi
#ping -I ${wlan} -c2 ${gateway} > /dev/null
ping -I ${wlan} -c2 ${gateway}
# Check is complete, Remove Lock file and exit
#echo "process is complete, removing lockfile"
rm $lockfile
echo "Reboot WiFi Script Ended"
date
exit 0
Thank you for sharing.
I did this to get the gateway address:
gateway=$(ip route get 8.8.8.8 | grep via | cut -d ‘ ‘ -f 3)
@Matheus,
doesnt work for me but running command in shell gives gateway ip
ip route get 8.8.8.8 | grep via | cut -d ' ' -f 3