This page lists some hardware posts, tools and projects I've created.

Feel free to adapt any of the open source designs here, bearing in mind that they come with absolutely no warranty, and should be treated as potentially dangerous given that I am not a chartered electrical engineer. Some of these circuits are capable of sourcing large voltages with enough current to kill. You've been warned! That being said, if you do find any of these designs useful, please drop me an email so I can get a warm fuzzy feeling!

In addition to the designs below, I designed most of the Razorbill Instruments RP100 high voltage power supply and amplifier for their line of stress and strain cells. It has many cool features, including USB control via some software. Buy one!

Standard resistors

Resistors, capacitors, inductors and zener diodes come in standard values. There's a lot of logic behind the choices of these values. More information, along with lookup tables of series and parallel combinations of standard resistors, is provided here.

Resistor types

There are various different types of resistor, each with different appropriate uses. See this post for more information.

High voltage polarity switcher


This circuit is designed to flip the polarity of its input, controlled via a signal between ±10 VDC. The input can have up to ±1000 VDC per conductor. When the control signal goes LOW, the first output pair is engaged and the input polarity is maintained. When the control signal goes HIGH (rising above 5 VDC), the second output pair is engaged and the input polarity is flipped at the output. The control signal can be generated by a CMOS compatible digital output.

Two pairs of reed relays map the input to output with opposing polarities. One pair of relays activates when the control signal is LOW (pair 1, polarity maintaining), and the other activates when it’s HIGH (pair 2, polarity switching). During switch-over, the circuit uses a delay circuit to "break before make", to avoid momentarily shorting the output terminals together. Components C17, C18, R8 and R9 are used to match the impedance and capacitance of any transmission lines connected at the outputs. Size C18 and C18 to match the transmission lines’ capacitance, and set R8 and R9 to their characteristic impedance. Components D3 and D4 are used to snub any residual transients due to impedance mismatch to ground.

The time constant of the RC filter determines the time it takes for the capacitor to discharge to 37% (1/e) of its peak voltage. As the logic gates are CMOS type, the threshold where a logic output of HIGH flips to LOW occurs at 40%, so the time constant essentially sets the switch delay. The delay must be longer than the switching time of the reed relays, which is around 1 ms. The suggested 3 kΩ resistor and 1 μF capacitor give a time constant of 3 ms.

The circuit requires a ±19 VDC power supply.

Contec digital input and output interfaces

Input interface

Output interface

These circuits map 32 electrically isolated, bipolar CMOS-compatible input or output channels to a Contec PIO-64/64L(PCI)H digital I/O card. The circuits are intended to be housed within GEO600 style cassettes, and the channels are intended to be routed to each enclosure’s front panel using 8 x D-sub 9 connectors each containing 4 digital input or output channels. Each channel may be used for independent applications without special grounding considerations.

The Contec card channels should be connected to the enclosure via a Contec PCB100WS distribution cable. Either the ‘CNA’ or ‘CNB’ D-sub 37 connectors on the PCB100WS may be used, but the HDRA-E100MA1 connector must be inserted into the PIO-64/64L(PCI)H card's ‘CNA’ (input) interface when using the input circuit, and the CNB (output) interface when using the output circuit.

The input circuit uses 4 of the digital I/O card’s input ports (out of a total of 8); each port provides 8 input channels to the circuit. The output circuit powers 4 of the digital I/O card’s output ports (out of a total of 8); each port provides 8 output channels to the circuit.

The ports in both circuits are recieved on the board via a 40-way IDC header, intended to connect via ribbon cable to a female D-sub 37 connector on the front panel. The channels are routed via optocouplers to 10-way IDC headers intended to connect via ribbon cables to D-sub 9 connectors on the front panel.

Channel switching time is approximately 1 ms, dominated by the IXYS CPC1017N optocouplers. A voltage greater than 3 VDC across each differential input is considered HIGH, whereas a voltage below 2 VDC is considered LOW.

The current through each digital output circuit should not exceed ±100 mA continuous ( ±350 mA peak).

An LED may be attached to the board to indicate the presence of the +15 VDC rail.

High voltage amplifier


Note: this is not recommended to use as-is. A few updates to the design should be made to fix some design errors - see below.

This is a quad-channel, low noise, source/sink, high voltage amplifier for driving plate-capacitor electrostatic drives in the speed meter experiment. The design is based on previous incarnations evolved organically over the years by Andreas Weidner, Tobias Meier, and Tobias Eberle, all based at one point at the Max Planck Institute for Gravitational Wave Physics (Albert-Einstein-Institut) in Hannover, Germany.

The main changes I've made to previous designs are the support for multiple channels, the use of an integrated circuit with significantly lower quiescent current (leading to reduced heat sinking requirements), a digital interlock system and switchable 10dB dewhitening filters (used in order to prevent DAC quantisation noise from impacting on the output noise; see section 6.3.2 of my thesis).

The circuit includes a number of useful features:

  • 0 to ±375 V differential output amplified from a 0 to ±10 V input
  • Low output noise: around 30 µV/sqrt(Hz) between 10 Hz and 10 kHz on top of the ±375 V output rails
  • Output current limiting
  • Safety interlock which must be asserted active low by an external input in order for the device to output high voltages
  • Overtemperature protection via four independent temperature sensors
  • Two 10 dB, individually switchable dewhitening filters per channel, controlled by external input
  • Soft-start protection to limit inrush current on switch-on (and discharge current on switch-off)
  • Differential monitor channels to witness each output rail's signal
  • Indicator LEDs

You must provide the high voltage supply rails. Unless you have a suitable power supply already, one approach could be to use a circuit based on the 1980 Michael Meida regulator design using MOSFETs like this one from Pete Millett - though this requires significantly more care as you have to handle mains voltages.

There are improvements that could be made to the circuit to fix some mistakes and design choices, some of which are discussed below.

This was one of my earliest "big" electronics projects, and I made a few mistakes. The biggest one is the output monitor: as it is not buffered, the impedance of the ADC used to measure the monitor signal contributes to a voltage drop across the current limit resistor. The division ends up being more like 1/1000 instead of 1/100 if an ADC with input impedance of a few kΩ is used. This can be fixed by buffering the monitor output with a voltage follower op-amp circuit and the voltage drop across the current limit resistor can also be mitigated by using an active current limiter circuit instead of passive. It's also possible to rely on the PA95 chips' current limiter, which can be set with a resistor, but relying on a single failure point is not recommended. The passive current limit resistor included in this design is nice because it almost always fails safe.

Other mistakes:

  • The recommendation to use 0.1% resistors on the input is a bit pointless given the 1% resistors used in the next stages, and the digital switches that themselves have 25 Ω of on resistance. Gain errors created by resistor tolerance can be corrected with software calibration. Temperature driven changes in gain can be mitigated with appropriate choice of resistor material.
  • The overvoltage blocking diodes in the supplies of the MAX4659s are not necessary given the capacitors there, and furthermore the capacitors should connect directly to the supplies instead.
  • With no overtemperature signal at R110, there is a floating voltage which leads to an undefined state in the nearby switch and potentially degrade its life. A large resistor (e.g. 1 MΩ) should be added to ground here.
  • The MAX4659 is not available in the DIP package used on the board, so I used adapters for surface mounted packages. I'd suggest just making these surface mount, or finding a different IC.

Magnetometer board

Magnetometer board.

A 3D rendering of the magnetometer board with components.

This board lets undergraduates conducting the geomagnetic storm detection laboratory at the University of Glasgow observatory quickly understand and build a simple closed feedback loop with which to detect fluctuations in the Earth's magnetic field due to changes in solar activity.

Circuit files for v1 on GitHub

Ethernet environment sensor

This is an ethernet connected dust, temperature, humidity, pressure and light sensor.

Environment sensor board.

A 3D rendering of the environment sensor board, but without components (I upgraded to a new KiCad release which changed the 3D model names for the parts...)

I made this board mainly to learn about networking on the physical layer, using ethernet. Ethernet connections aren't trivial, especially high speed ones. They are inherently high frequency connections, and as such aren't (and often can't be) connected straight through using bare copper to the device on the other side. Instead, they are connected via inductors and capacitors which block and pass signals with certain frequencies.

As communication has grown faster, it's no longer practical to process packets on microcontrollers. Instead, the first few layers of the network stack are provided by a so-called PHY, or physical layer chip, connected to or including on-board "magnetics", or the transformer that separates the device circuit from the ethernet connection - usually in an RJ45 socket. Modern microprocessors usually now include the physical layer hardware on-die, and as such don't require much in the way of controlled impedance tracks and transmission lines. For simplicity (or, perhaps, fun), I chose to use a popular Wiznet W5500 stand-alone PHY to which I could send SPI commands from any microcontroller. This prevented the need to bother with learning a new microprocessor API for talking to an on-board device, or using a vastly overpowered processor that can run e.g. embedded Linux.

Environment sensor PCB.

Environment sensor PCB. KiCad can look really awesome sometimes. Red and green tracks are on the top and bottom, respectively. The USB connector is top left, RJ45 is top right, the PHY is three-quarters of the way up on the left and the main microcontroller is on the middle right. The BME280 environment sensor is on the middle of the other side of the board. The dust sensor plugs in to the bottom left socket.

I chose an Atmel/Microchip ATmega32U4 for the main microcontroller, which I have prior experience with. It has enough memory to hold a large networking library and has the nice advantage of a USB controller on-board so that you can easily talk to it and power it from a standard cable.

For the network stack, I took the convenience of using Wiznet's ioLibrary which deals with the nuances of DNS and DHCP for you in order to send payloads over the network.

The dust sensor is the Shinyei PPD42NS PM2.5 sensor, available on eBay. There is also a reverse engineering of the (very simple) schematic available from Tracy Allen. This shows that it is feasible to provide a different voltage on one of the pins to get more sensitive readings of smaller particles, which I implemented.

Environment sensor enclosure.

The simple enclosure I made for the circuit. There are two gaps on one side to allow air flow through the dust sensor. A resistor in the dust sensor creates convection through a channel where particles scatter incident light from an LED onto a photodetector.

Two LEDs are on also present to allow indication of networking and hardware status.

The light sensor is a standard light dependent resistor read by the microcontroller. The other environment readings are made by the tiny Bosch BME280. In hindsight, this was a bad choice as its self-heating is quite high and it must be placed far from the hot parts of the circuit. Since I didn't really care much for energy efficiency (since it was anyway to be wired to an ethernet cable), the circuit produces somewhere in the region of 0.5 W of heat which significantly alters the accuracy of the sensor - not helped by my enclosure (below) - giving readings up to 12°C higher than they should be! This also affects the humidity readings, of course, rendering this aspect of the circuit a bit useless. If I were to redesign this circuit I would put the sensor far from the rest of the board, and in separate air and with isolated copper. You live and learn.

Environment sensor enclosure, inside view.

Inside the enclosure. I took the unconventional step of putting the circuit on the lid of the enclosure, and drilling a hole underneath where the temperature/humidity/pressure and light sensors are. The idea was to keep the sensors away from the microcontrollers and dust sensor, which all produce lots of heat, but this didn't really work as the temperature and humidity readings were still wildly inaccurate.

I wouldn't build this again without making modifications due to the sensor inaccuracy. However, the dust readings are reasonably accurate as far as I can tell, and the light sensor can tell if the room light is on or off, which is about as much as I wanted. I have this hooked up in my office to periodically send my server the settings, just in case long term data there is ever useful. The main benefit this circuit has given me is the experience of making it work!

Hardware files on GitHub

Firmware on GitHub


Bill of materials

Wireless energy sensors

...when I finish testing them.

Op-amp noise and parameter tester

...when I can be bothered to write about it.

Networked coil drivers using Arduinos

...when I can be bothered to write about it.