Disclaimer

To begin, I should say that this isn't the most interesting article. Although it's real in the sense that I've given some thought to the content, I'm publishing this to get a feel for the process rather than because I think other's will find it useful or because I think it describes a finished project.

My ADSL connection

At home I have an ADSL Internet connection, which works perfectly well most of the time. However, sometimes, the connection dies and the modem reconnects automatically. Occasionally, perhaps once or twice a month, the connection dies and the modem doesn't reconnect. I tried replacing the ADSL modem without success, so presumably there's a problem at the exchange or with the line. However, trying to get that fixed sounds like a lot of effort given the sporadic nature of the problem. After all, power-cycling the modem fixes the problem.

On the other hand, it's pretty irritating to reset things manually, especially if I'm not at home when the connection dies. Inspired by a recent tutorial at OSCON1, I realized that it would be sensible to automate the process. Essentially it's simple: if the link has hung then just cycle the power to the modem.

Detecting a hung connection

A simple Perl program is enough to test the link. Rather than checking that the link is alive directly, we'll just try to fetch the Google homepage. After all, people sometimes say that if something's not on Google then it might as well not exist. We're going to assume that if we can't reach Google then the link might as well not exist.

use strict;
use warnings;

use LWP::Simple qw(get);

reset_modem()
 unless link_is_up();

sub link_is_up
  {
    my $t0 = time;
    while(time - $t0 < 180)
      {
        my $page = get("http://www.google.com");
        return 1
          if $page && $page =~ /google/i;
        sleep 1;
      }

    return;
  }

sub reset_modem
  {
     print "Please reset the modem!\n";
  }

Obviously we'll shortly replace the reset_modem() subroutine with something which talks to the hardware.

The PIC Mini Web

Cycling the power is easy, the only tricky part is that the modem is some distance away from the computers. One could run extra cables, but there's a perfectly good network in place which ought to be able to carry an extra bit of data: though to do this one would need a network enabled microcontroller. Happily Microchip2 make it relatively easy to connect a PIC microcontroller3 to ethernet, and a company called Olimex4 sell a PIC Mini Web5 with all the necessary components on it for about 25 pounds (US $50). You can see a picture of the Mini Web below. To get an idea of the scale, the large box-like connector on the left is an ethernet socket.

The board has three significant components:

Obviously we need some extra hardware, but this is easy: a relay to switch the power to the modem, and transistor to drive the relay from the Mini Web. Happily the ADSL modem has a 12 volt external power supply, so we're only switching low voltages, and we can steal some current to supply the Olimex board to boot. 12 volts is rather too much for the Olimex board, so we drop the voltage down to 5V with a 7805. The final touch is an LED which comes on when the power to the modem is switched off: we don't need anything in the other leg of the switch because the modem itself is a veritable Christmas tree of light when it's powered up. Here's the circuit diagram:

When RST goes high, the transistor turns on, so current flows through the relay coil. In turn that causes the switch to move, turning on the LED and turning off the modem.

Mini Web software

The Mini Web comes pre-programmed with Olimex's software, which is derived from the standard library provided by Microchip. When I did this project version 3 of the the library was all the rage, but now it's been superseded by version 4. So, I won't talk much about it here beyond brief notes:

The software is written in C, and so needs a compiler. For Window's users Microchip provide a free demo/student edition of their commercial compiler, but this is crippled: after 60 days some of the code size optimizations are disable and the full application no longer fits in the PIC's memory. Happily a simple HTTP over TCP server does still seem to fit, but extraneous stuff e.g. UDP and FTP support need to be removed.

For this particular project it's highly desirable that we can make the PIC pulse the relevant output line rather than sending one command to turn the modem off and another to reset it. Actually it's essential because the communication between the PC running the software and the Mini Web actually goes through the ADSL modem's internal hub.

Some sort of interrupt driven solution is probably the 'right' way to handle a long (~ seconds) delay, but I took the quick-and-dirty approach and just executed a delay loop. The Mini Web might well be unresponsive during the delay, but the modem's dead and so nobody can talk to it anyway.

One minor consequence of the interrupted network is that the Mini Web's reply to the GET request is never seen by the Perl program. Thus, the reset_modem() subroutine looks like this:

sub reset_modem
  {
    # Set an alarm here because when we reboot the modem
    # we won't see the HTTP reply!
    local $SIG{ALRM} = sub { print "Bing!\n" };
    alarm 30;  # long enough for the modem to reboot

    get("http://192.168.1.100/1?3=0");
  }

Programming the Mini Web

Having generated a new application file, it needs to be programmed into the Mini Web. I used Microchip's PICkit 27, an inexpensive programmer which connects to the PC over USB. It comes with Windows software, but you can also drive it from Linux or MacOS. You'll need to make a cable to connect the mini-ICSP connector on the Mini Web to the 0.1" header on the PICkit2, or you could buy one from SparkFun8 at least I think that should work.

Conclusions

This isn't really a finished project, and it's easy to see ways to improve it:

On the other hand, for all its problems the software does actually do a useful job! Perhaps the right message to take away from this, is that devices like the Mini Web make it easy to use Ethernet as a control network.