HNTE Desk Hub: January 2014

Not that long ago, while shufling about on the floor plugging usb cables into the back of my computer, I thought to myself "I really should just buy a USB hub".
So I did.. I bought this one, a D-Link DUB-H7

Finished Right?


Not Quite Finished

Sure this USB hub works great and everything, it was just not useful enough. I could really use an ethernet switch sometimes. Or a DC power supply. I have been using an old PC power supply for years now and I could always use a few extra DC outputs. Or what about some digital outputs for playing around with, they always come in handy.
Or maybe a way of reading or logging data from different digital communications protocols, I hate writing communication software for new embedded hardware with no way of testing it.
Also wouldn't it be cool if I could see how much current my random projects were using without having to use my pesky multimeter.....
Alright time to break out the pencil and paper..

Now Were Talking

hub cad 01

After sketching up a few concepts I came up with something worth cadding up. Something to squeeze all of these ideas I was having into. Something that could sit proudly on my desk as if it was made to be there.. The Bloody Useful Desk, Box, Thing...

The Bloody Useful Desk, Box, Thing...

hub photo 01

The Hardware

What we have here is a bunch of laser cut acrylic pannels that fit together with box joint edges and fasten up with M4 bolts and t-slot nuts. The construction is quite simple, apart from a few (probably optional) pockets CNC'd in the front panel all of the parts can be laser or water cut from a single sheet of 6mm acrylic. I went for laser cut because I wanted a nice surface finish on the cut edges, water cutting is quite abrasive and leaves a dull sanded finish.
Another great thing about laser (or water) cutting is that you get all sorts of extra features and parts essentially for free, such as the power supply mounts and snap out spacers.

Cut Acrylic Panels

hub panels
PSU assm
fans assm

I got a bit carried away with my first design, I had drawn up a nice set of machined plates with routed features for easy assembly and helicoils inserted along the edges of the plates for fastening. I had hoped that despite the multiple setups required to NC it all, I would still be able to get it machined for a reasonable price in China.
After getting a couple of quotes I didn't like much, I decided I needed to be a bit cleverer with the design. What I ended up with is the laser cut plates you saw above. The slightly clever part I liked was the box joints and t-nuts at the edges, they are neat and the nickel plated fasteners look great with the black acrylic.

Box Joints

box joint

Everyone that sees this on my desk looks at it and says, "Right, cool, so what does it do?"
I still haven't really come up with a good answer to that, because it doesn't really do anything... But it has all sorts of handy outputs.

  • 2 x 24V, 12V, 5V and 3.3V, 50W DC outputs (4mm bananna plug)
  • 2 x 5V DC output (USB)
  • 5 x USB 2.0 hub
  • 4 x Ethernert Switch
  • 3 x Switched Mains Sockets
  • 32 x digital IO's (Arduino Mega)
  • 1 x UART, SPI and I2C Input
  • 24 x 4 Backlight LCD
    • Displays DC current usage
    • Displays recieved UART, SPI and I2C
  • Cooling Fans
  • Piezo Buzzer (because why not?)

Legend - Click to Embiggen

hub ios

The Electronics

So far I think it looks pretty good, but from here it starts to get a bit messy. I tried my best to keep the wiring neat inside, but every time I added a new feature it got a little messier. I guess it serves the purpose of keeping all the mess in one place which is something
Remember always be careful when playing with mains voltages, especially after reading my dodgy website!


hub inside

Block Diagram

block diagram

The block diagram / schematic above shows you what's inside the box. Nothing too ground breaking in there but I'll go through some of the electronics and software that I had fun with while building it.

Update: Tidy That Mess

I was unhappy with the mess of wires inside so I completely stripped it back and strarted again. The result is a much more manageable setup. Probably the biggest improvement was to grap a protoshield for the Arduino mega and wire everything up with some nice ribbon cables and IDC connectors.


new hub inside
new hub inside
new hub inside

Switching 12V loads with 5V logic using BJTs

There are plenty of different ways to switch 12V loads using the 5v logic from your microcontrollers, usually the first thing that comes to mind is a relay. At the time all I had was a bunch of transistors, for low current switching all you need are two resistors and two transistors. Make sure you calculate the resistor values specifically for the transistors you have selected, the wrong resistor values can cause the PNP transistor to operate in its active region which will cause it to overheat.
In my case I was switching 4 fans wired in series that draw 110mA each so I_load = 440mA, and Vbe is the base emitter voltage drop of the transistor which is usually about 0.7V.

base resistor equation
base resistor equation

Current Measurement

To measure the current drawn from the DC outputs on the front panel of my box I got myself a handfull of these ACS712 breakout boards from ebay. If you type in "ACS712 20A" into ebay search you shouldn't have any trouble finding them for about $2 each, these work a treat for measuring currents between +-20A.

current sensor

All you will need to do is plug these in series with your load that you want to measure (in my case the outputs on the front of my desk hub) and supply them with 5V. The output is zeroed at 2.5V and has a sensitivity of 100mV/A, so a reading on the output of 2.7V represents a 2A current measurement.
Now not that I was having any particular issues with noisy measurements, I did find it slightly annoying when the displayed measurements would jitter about. More importantly I was looking for an excuse to have a play with the numpy and scipy python packages, and designing a digital filter seemed like a good project to start with.

Digital Filtering: Decimating Filter

The simplest form of digital filter is the decimating filter (Thanks Illogique for correcting my mistake). Most people are probably using this form of filter on their analogue inputs without a second though.
The decimating filter is as simple as taking the average of the last n (say 8) measurements. This filter is in essence a Finite Impule Response (FIR) filter, I won't pretend I know enough to start teaching you digital filtering theory so I'll let you google that if you want to know more than just how to use them.
A FIR filter takes the following general form, for a decimating filter all of the filter coefficients (b) just equal 1/n.

General FIR Filter

y_i = \sum_{i=0}^{n}a_ix_i

n = Filters order
y = Filtered output
x = Unfiltered input
b = Filter coefficients

Decimating Filter

y_i = \fract{1}{n}\sum_{i=0}^{n}x_i

Decimating Filter Frequency Response

average freq response

Decimating Filter Measured Output

average measured output

Decimating Filter c++ Implementation

Digital Filtering: More Advanced FIR Filters

The next step up is to generate a more advanced set of FIR coefficients using a window function. This is actually easier than it sounds using a simple python script. I'll go through the python code a lit later on, for now let's look at how the filter performs.
I have implemented a 20 pole FIR filter with a 100Hz cutoff frequency at a 1KHz Sample rate using a hamming window function.

20 Pole FIR Frequency Response

20p FIR response

20 Pole FIR Measured Output

20p FIR measured output

So You can see from the frequency response of the 20 pole FIR filter compared to the moving average that much less noise will creep past in the stop band. We also have lots more control now that we can define the cutoff frequency. The corner frequency is also called the half power or 3dB point, which makes sense when you look at the frequency response curve.

One thing that you will notice when playing with larger order filters is that the coefficients start to become quite small, to avoid using floating point numbers your best bet is to scale them up and then scale down your result. I have multiplied my filter coefficients calculated in python by 2^16 or 65536 then rounded them off to integers. After accumulating my 20 measurements I just bit shift the result by 16 which is the same as dividing by 65536.

FIR c++ Implementation

Digital Filtering: A Dash Of Recursion

The next step in my filter adventure was to rather un-scientiffically add some recursion, a filter that uses the past filtered results to generate the new filtered result is called an Infinite Inpulse Response (IIR) fiter. You can use python to go and design a nice set of butterworth filter coefficients, or you could digitise an RC filter using a bilinear transform.. Or you could just do what I did and hack the last FIR filter to include the last filtered result.

General IIR Filter

y_i = \sum_{i=0}^{n}b_ix_i- \sum_{i=0}^{n}a_ix_i

20 Pole IIR Hack Frequency Response

20p IIR response

20 Pole IIR Hack Measured Output

20p IIR measured output

My hacked IIR filter seems to produce a much smoother output than the moving average or the 20 pole FIR filter. There is a bit of time delay and it takes about 100ms to wind up at startup, this doesn't really bother me so I have stuck with this filter for now.
Instead of calculating new filter coefficients (a & b) for my IIR filter, I just add 25% of the last filtered result and add it to 75% of the last 20 unfiltered results... It was just an experiment but it seemed to work.
I did have a play with butterworth and RC filters but this is the filter I ended up sticking with so I'll leave more filter talk for another day.

IIR c++ Implementation

Digital Filtering: Python Script

I'm fairly new to Python, I have started using it as a Matlab replacement now that I can no longer get a student version of Matlab. I'm using the IPython notebook for my python scripts and I think it is growing on me.. Here is the script I wrote to calculate the filter response of my different filters.


The code for this thing got a little out of hand in the end so I won't go into too much detail here. I am using the Arduino Mega 2560, but I have developed the code in Atmel Studio 6 without any of the Arduino libraries.
To program your Mega in Atmel Studio 6 all you need to do is add an external tool via the Tools menu with the following command and arduments set. You will probably need to change the COM4 and the paths to avrdude.exe and avrdude.conf.

Command: C:\Program Files (x86)\arduino-1.0.5-r2\hardware\tools\avr\bin\avrdude.exe

Arguments: -C"C:\Program Files (x86)\arduino-1.0.5-r2\hardware\tools\avr\etc\avrdude.conf" -patmega2560 -cwiring -P\\.\COM4 -b115200 -D -Uflash:w:"$(ProjectDir)Debug\main.hex":i

External Tools Menu Screenshot

menu screenshot

You can get all of the code from the downloads section if you want to have a look, there are all sorts of AVR goodies in there. It is a bit of a living code at the moment, I will upload newer versions as it makes sense.
Downloads Link

Finished Product

This is one of those projects that will probably keep evolving over time, but for now it's finished. Here it is in all its useful glory helping me test out some lights for a new giant LED display I am working on.
Oh and a video of one of the not so useful functions.

Bloody Useful Indeed

testing photo