Inline Bandswidth Meter

As a geek, I like to know my bandwidth usage when I'm gaming/streaming/bored (okay, all the time!). I wanted a device that would sit between my router and cable modem and provide upload / download rates (Mbps) in real time. I wanted to create a standalone device that could be plugged into any 10/100Base-T network and work without any user configuration or complicated installation.

TL;DR Quicklinks

Passive Network Tap
MAC + PHY chip
Serial Peripheral Interface (SPI)
Plotting with Python
LED Matrix
Laser Cut Case
Demo Video

I also wanted my device to not interrupt normal network operations. For example, if the device lost power or its software crashed, the network should continue to functional as usual. For this, I decided that a passive network tap was the best solution. There are a few concerns with passive taps, such as extra noise/loading on the line and incompatibility with gigabit connections. As most home connections are well under 100Mbps (except maybe FIOS?), gigabit compatibility isn't a big deal. To mitigate noise/loading issues, cables/board traces are kept as short as possible.

Passive Network Tap

I created a prototype passive network tap out of female RJ-45 push down sockets. Under normal conditions, data is transmitted on TX and recieved on RX, however when sniffing traffic on a line, the listening device must treat each direction as seperate receive channels. To handle two RX channels, two NICs are required.

10/100Base-T Passive Network Tap

I ran into Mike Ossman at a GNU Radio conference and received one of his Throwing Star LAN Tap. He uses them as business cards, how cool is that? If I ever get around to populating the board, it will certainly clean up my protyping efforts a bit.

MAC + PHY chip

The bandwidth meter operates at the ethernet frame level, counting bytes transmitted and received (including headers). As such, I looked for a MAC + PHY chip with a large receive buffer and the ability to handle raw ethernet frames. I first looked at the WIZnet module, but found it's raw ethernet support lacking. The interface could only store one raw ethernet frame at a time and block any incoming packets until the first frame is read. For this application, the blocked packets would lead to an incorrect byte count and defeat the purpose of the meter.

I ultimately selected the ENC624J600 chip. Unlike the WIZnet module, the ENC624J600 does not have a built in TCP/IP stack, but had a much better raw ethernet interface. I ordered a single Olimex breakout module from Mouser to get going. I planned on making a PCB with two ENC624J600 chips and some flavor of Atmel to keep track of the packet count and drive the display.

I realized at the last second that the ENC624J600 was a 3.3v device, so I added a few level shifters to my order.

The SPI IO pins on the ENC624J600 are 5v tolerant and the Atmega128 recognized ~3.3v as high, so the level shifters weren't needed.

Olimex ENC624J600 module

Serial Peripheral Interface (SPI)

I originally planned to use the parallel interface, but I decided to test the module with the SPI interface first, to ensure it was functional. I had to do some research on SPI and was delighted to see how similar it is to JTAG (in fact I believe JTAG is a subset of SPI). These are a few links that proved helpful.

The ENC624J600 datasheet provided configuration information for the interface:

"The SPI port on ENC424J600/624J600 devices operates as a slave port only. The host controller must be configured as an SPI master that generates the Serial Clock (SCK) signal. This implementation supports SPI Mode 0,0, which requires: SCK is Idle at a logic low state, Data is clocked in on rising clock edges and changes on falling clock edges"

I initially hooked up the SPI interface to an Arduino Uno in an attempt to verify the module worked correctly.

ENC624J600 -> Level Shifter -> Arduino Uno

After many painstaking hours of debugging with the Arduino Uno, I switched to an Atmega128 in the form of the BDMicro Maveric IIB from a previous project. The JTAG debugger proved quite valuable in the finding several coding mistakes (not to mention the fact that I confused CS and SPISel for about two days).

Mavric IIB -> ENC624J600 w/ JTAG debugger

After I completed the initial tests with the SPI interface, I began searching for a microprocessor with a parallel interface with sufficient data rates for my needs. I found the PIC24F to be a suitable candidate and began laying out a pcb to interface with ENC624J600 breakout board I purchased.

PCB v1.0 back from fab

PCB v1.1 back from fab

PCB v1.2 back from fab

In-line bandwidth meter v1.1 mockup

Plotting with Python

With v1.1 populated, I was able to interface with the MAC+PHY chip via the parallel interface and begin sending download rate data over the serial port. I wrote a Python program to plot the data, and compared it with the bandwidth graphs provided by DD-WRT on the router. To my delight, the plots track pretty closely.

Python plot of live data from in-line bandwidth meter vs DD-WRT plotPython + in-line bandwidth meter vs. DD-WRT

Having verified the functionality of version 1.1, I will begin working on version 1.2 which will incorporate the MAC and PHY chip as well as the passive tap into the main PCB. Until then, behold the working prototype below.

LED Matrix

Following a suggestion from the folks at Hack A Day, I purchased a couple of 8x8 LED matrices. The LEDs are controlled by a MAX7219 chip with a SPI interface. In the video below you can see the results. I chained two matrices together to form a 8 x 16 grid. The vertical direction represents the download rate for a one seconds. The scale is roughly adjusted such that a full vertical bar corresponds to the maximum download rate on my network. I plan on getting another set of LED matrices of a different color to display the upload rates.

Laser Cut Case

I designed a front plate and back plate and had them laser cut out of 3mm clear acrylic. I didn't have any standoffs on hand, so I made some out of cut down pens and zip ties.

Demo Video