84

I'm using my pi to monitor my power meters. Data is transferred to PC by WiFi connection using Edimax EW-7811UN USB adapter. When the Wifi connection drops (switched off over night, or shaky connection), the USB adapter remains disabled.

Is there a way to restart the WiFi connection automatically without re-plugging the WiFi adapter?

andig
  • 1,087
  • 2
  • 11
  • 13

8 Answers8

75

(Only for RPi 1 and RPi 2, not RPi 3+. "does not work on dhcpcd based distros")

Well, there is a very simple solution:

  1. Go to /etc/ifplugd/action.d/ and rename the ifupdown file to ifupdown.original
  2. Then do: cp /etc/wpa_supplicant/ifupdown.sh ./ifupdown
  3. Finally: sudo reboot

That's all. Test this by turning off/on your AP; you should see that your Raspberry Pi properly reconnects.

Cray
  • 103
  • 3
AndaluZ
  • 866
  • 1
  • 8
  • 6
32

I prefer to disable most of the network auto configuration and connection management daemon stuff and deal with it myself. Here's a (bash) script that will keep the connection up as long as the network is there and you do not have a glitchy wifi driver or power issues; the idea is to ping the router every N seconds, and if that fails, re-connect:

#!/bin/bash    

# make sure we aren't running already
what=`basename $0`
for p in `ps h -o pid -C $what`; do
        if [ $p != $$ ]; then
                exit 0
        fi
done

# source configuration
. /etc/wifi.conf

exec 1> /dev/null
exec 2>> $log
echo $(date) > $log
# without check_interval set, we risk a 0 sleep = busy loop
if [ ! "$check_interval" ]; then
        echo "No check interval set!" >> $log
        exit 1
fi

startWifi () {
        dhclient -v -r
    # make really sure
        killall dhclient
        iwconfig $wlan essid $essid
        dhclient -v $wlan
}

ifconfig $eth down
ifconfig $wlan up
startWifi

while [ 1 ]; do
        ping -c 1 $router_ip & wait $!
        if [ $? != 0 ]; then
                echo $(date)" attempting restart..." >> $log
                startWifi
                sleep 1
        else sleep $check_interval
        fi
done

So, /etc/wifi.conf in this case might contain:

router_ip=192.168.0.1
log=/var/log/wifi.log
wlan=wlan0
eth=eth0
essid=someNetwork
check_interval=5

This all presumes an open unencrypted network (if otherwise, you will have to add the appropriate commands). I've used this approach on various linux machines, including the pi, and it works flawlessly; it will keep a system online indefinitely, even if it periodically goes to sleep (which the pi cannot anyway).

A decent check interval is 3-5 seconds; this activity will not significantly impact system resources at all.

You absolutely do need to disable the network auto-configuration first, . including ifplugd and other networking daemons, or this will interfere with your efforts:

How can I disable autoconfigured networking on Raspbian?

I in fact used apt-get remove ifplugd.

To start networking at boot (since I use the pi headless), I have this set to run on raspbian from /etc/rc.local:

wifi_mod=`lsmod | grep 8192cu`
if [ "$wifi_mod" ]; then
        echo "Starting wifi..."
        /usr/bin/nice -n -10 /usr/local/bin/wifi &
else
        echo "Starting ethernet..."
        /sbin/ifconfig eth0 up
        /sbin/dhclient eth0
fi

/usr/local/bin/wifi is the script. If you don't know what nice is for, read man nice.

The point of the if is that if my wifi dongle is plugged into the pi, the 8192cu module will be loaded by the kernel at this point -- so wifi should start. If not, then it's assumed that the ethernet is plugged in and should be used (if it is isn't, dhclient will just crap out and there is no network access).

For this to work you will probably have to

So, this gets a headless pi onto the network at boot and keeps it there. If you wanted a way to switch to eth while running without logging in, you could do something with udev rules for pulling the wifi dongle out.

goldilocks
  • 60,325
  • 17
  • 117
  • 234
22

I recently stumbled across a console application that sorts all the wireless configuration hell out. You can also use this tool to configure the LAN interface.

sudo apt-get install wicd-curses

It will install quite a few other packages and run its own daemon in the background but it sure makes configuring everything a whole lot easier. Run it with

sudo wicd-curses

enter image description here

If you get a message saying no networks detected press P (must be capital so use [SHIFT]p) and type in wlan0 in the wireless interface field and press F10 to save.

  1. R to refresh the list.
  2. Use the cursors on the keyboard to navigate up and down the list
  3. Press right to configure the wireless connection
  4. Press down a few times and check "Automatically connect to this network"
  5. Press down a few times again and type in your password in the key field
  6. Press F10 to save

enter image description here

You might have to press C to connect to the access point. If you were wired that will most likely kill the LAN interface and bring up wireless.

It is also manages the connection so it will reconnect to any configured wireless access points if it drops out for whatever reason.

I tested plugging out the WiFi adapter and plugging it back in. It takes about 60~90 seconds but it will connect back to WiFi (I think the LAN must be unplugged though)

Hope it helps!

Piotr Kula
  • 17,336
  • 6
  • 66
  • 105
14

This can be solved with no extra scripts.

In /etc/network/interfaces put:

allow-hotplug wlan0 iface wlan0 inet manual wpa-roam /etc/wpa_supplicant/wpa_supplicant.conf iface default inet dhcp

The roaming allows the interface to self-heal.

David Sainty
  • 249
  • 2
  • 3
1

netcfg

Try netcfg. Without further details about which distribution you are using, I can't provide many more details, but it should do what you want.

Alex Chamberlain
  • 15,638
  • 15
  • 69
  • 113
1

Another solution, as extracted from this one.
First configure your wifi settings: sudo vi /etc/wpa_supplicant/wpa_supplicant.conf adding a section like this:

network={
   ssid="MyNetworkName"
   psk="MyPaz0rdz"
   key_mgmt=WPA-PSK
}

Then your network settings with sudo vi /etc/dhcpcd.conf:

interface wlan0
inform 192.168.1.200 # the static ip for the wifi card
static routers=192.168.1.254 # your router's ip
static domain_name_servers=192.168.1.254 # your dns, usually=your router

Then create this script file somewhere, for example in /home/pi/reconnect.sh and give it +x permission to be executable.

#!/bin/bash
router=`ip route | awk '/default/ {print $3}'`
/bin/ping -q -c1 $router > /dev/null

if [ $? -eq  0 ]
then
  true
  # echo "Network OK"
else
  echo "Network down, fixing..."
  # ifdown --force wlan0
  # sleep 5
  /bin/kill -9 `pidof wpa_supplicant`
  /sbin/ifup --force wlan0
  /sbin/ip route add default via $router dev wlan0
  /bin/mount -a
  echo "wlan0 reconnected at `date`"
fi

Then login as root with sudo su and edit root's crontab with crontab -e.
At the end of this file add this line:

*/10 * * * * /home/pi/reconnect.sh

That means: "execute that script every 10 minutes (as root)" - note without the */ at the start it would be "execute at 10 minutes past the hour, every hour".

Now, if you have a connection then the script will exit and nothing will happen. If you can't ping your router then the script will try to reconnect to it using wpa_supplicant.

Notice that everything that is echoed from a cron script (in this case only when disconnected) will be emailed to root. So if you have configured your mail aliases and postscript then you will receive an email whenever your pi's wifi connection went down and then succefully back again thanks to the script.

nickcrabtree
  • 438
  • 4
  • 15
Leonardo
  • 119
  • 4
1

This worked for me, using Raspian Jessie on 30.March.2017:

http://alexba.in/blog/2015/01/14/automatically-reconnecting-wifi-on-a-raspberrypi/

0

Somehow the rest of the answers were still not satisfactory. There still doesn't seem to be a standard functionality (for such a basic function) which just works, or works with few extra settings, which also works in RPi 3 and up.

Then there are some scripts which either make things too complicated or need hardcoding addresses, or rely on custom assumptions. For example, what does it help to try pinging default route or 8.8.8.8, if the Wifi maybe is local-only? What if it doesn't set a default route at all? What if the default route is set on eth0 and is always available and wifi is used for other purposes? The question is "how to reconnect WiFi".

This is all you need:

#!/bin/bash

SSID=$(/sbin/iwgetid --raw)

if [ -z "$SSID" ] then ifconfig wlan0 down sleep 30 ifconfig wlan0 up fi

Just put that on auto-repeat/cron as root and you're set. This solution is from https://gist.github.com/carry0987/372b9fefdd8041d0374f4e08fbf052b1 which has more details as well.

PS in case there is an obscure OS or RPi version, try using "ip link set wlan0 down / ip link set wlan0 up" instead of ifconfig ....

Cray
  • 103
  • 3