Teensy Load

Teensy Load is a project based on the Contextual Electronics Current Sink Or Swim course. The idea here is to develop a programmable load that can be used for for battery discharge experiments, tracing battery I/V curves, and so on. The Teensy Load extends the Current Sink Or Swim design by connecting to a Teensy microcontroller board to allow for programmatic setting of current and voltage levels and recording of the actual current and voltage levels provided by the device under test. Very simple firmware on the Teensy deals with the level setting and data collection, and a couple of Python GUI applications running on a PC talk to the Teensy over a USB serial connection to provide a nice interface for using the thing.

Current status: boards received and assembled. First software partially working. Debugging needed, then some work on calibration, then some more utility applications to write.


Click on any schematic image for a full-size version.

At the top level, there are some pin headers to connect the Teensy and a connector to attach the device under test. The idea is to power everything from the Teensy’s 3.3V supply. That can provide 250 mA, which seems like it ought to be enough, but I’m not sure how you might estimate accurate power requirements for a circuit like this. I started trying to do that, but realised I didn’t know what I was doing...

Top-level Teensy Load schematic

Following the approach in the Current Sink Or Swim course, there’s a current programming section, which in this case is driven by an I2C DAC to set the programming voltage that controls the current draw (with limits of 0 - 10A, set by a resistor divider between the DAC and the op amp input). As the FET used to draw current from the device under test, I’m going to use the Infineon BTS141, which has a pinout like a FET but has all sorts of protection features built in (overcurrent, thermal, etc.). Seems like a good part for someone who isn’t quite sure what they’re doing! There’s also an additional op amp unit used as a current level sense, with its output fed to one of the Teensy’s ADC inputs (they have a relatively low input impedance, hence the op amp as a buffer). That gives a way to monitor what current the device under test is really providing. (I’m using a TI TLV4333 quad op amp here, which seems quite jellybeanish, but ought to do the job.)

Teensy Load current control schematic

Finally, there’s a voltage limiting section, which sinks current from the FET gate if the total voltage across the device under test is too large. The voltage limit level is set by another DAC through a voltage divider to the input of an op amp used as a comparator, with the other comparator input coming from a voltage divider connected across the device under test. A final op amp buffers that voltage level for input to a Teensy ADC input for voltage monitoring. The way the voltage divider between the DAC and the op amp is set up limits the voltage range to 0 - 20V, but the idea is to control the maximum voltage setting depending on the current demanded to keep the total power dissipation in the FET below 20 W, which is what I think the heatsink I’m using will handle.

Teensy Load voltage control schematic

This is the first electronics design I’ve done where a substantial part of the design is stuff I’ve made up myself, so there are a few open questions about it all:

  1. Is this a reasonable approach to this kind of thing? Am I missing anything obvious? Have I done anything that’s just plain wrong? I think it’s mostly OK, and it’s good to be able to take the Contextual Electronics design ideas and extend them a little, rather than starting from a completely blank slate.

  2. Is there any way to get a reasonable estimate of the power requirements of something like this to work out whether driving it all from the Teensy 3.3 V supply is going to work? I’m guessing that the only way to do this is to do a detailed component-by-component power budget. That ought not to be too hard in this case, since there aren’t lots of modes of operation, but it would definitely be much harder for a more complex design. Are there tools to help? I don’t know yet.

  3. Should I add any extra protection components? For example, is it worth putting a Zener diode (with Zener voltage somewhere between 2.1 and 3.3 V) between the negative input of U102C and ground to protect the op amp input from excessive voltage from the device under test? I don’t know about this. Presumably I’ll find out when I have the thing on the bench!

  4. Is using a pair of DACs to set the current and maximum voltage levels overkill? Would it be simpler to use a couple of PWM outputs from the Teensy with low pass filters? Originally, I didn’t go that way because I didn’t know how to calibrate the resulting voltage levels, but a bit more thinking makes it obvious that they’re just linear in the PWM duty cycle. Still, I like the idea of using the DACs.

  5. Generally, are the component choices OK? The BTS141 seems solid, the DACs were chosen to have predictable zero output at power on reset, the op amps don’t seem to have very demanding requirements, and the heat sink was chosen to handle 20W of power dissipation in the FET.


It took me two tries to get a board layout I was reasonably happy with. This is the first project that feels like “uncharted waters” where there are a few things where I’m really not sure what I’m doing.

Teensy Load PCB layout

I think that the critical bits of the design are OK: fat traces (with 2 oz. copper) for the high current loop (and the loop made physically as small as possible given the sizes of the components), power ratings for the sense resistor and FET should be OK (I think the heatsink might be overkill: the 3D render looks pretty ridiculous anyway...), and everything else pretty vanilla.

There is some “safety by design” using voltage dividers to make the full range of the DACs used for setting the current and voltage limits correspond to the maximum ranges of those things that I want. The only limit that needs to be managed in the Teensy firmware then is the overall power limit, done by capping the voltage limit to make sure the power limit isn’t exceeded.

OSH Park’s 2 oz. copper service for cheap boards is slower than their regular service, so now the long wait begins...

Assembly and testing

Assembly went pretty well. There were no obvious soldering problems. Even getting the big heatsink soldered down, and dealing with the thick 2 oz. copper traces I’d used for the main current loop didn’t cause much trouble.

Teensy Load assembly

Initial testing showed that the power supply from the Teensy was all fine, and that the DAC outputs were fine. Attaching a power supply and trying to use the thing for real though, showed that there was a problem with something somewhere. The current demand settings weren’t being respected and even with the current demand set to zero, the current drawn from the device under test would creep up until the power supply I was using cut out.

This took a while to figure out, since I started off by thinking it might be something to do with the opamps I was using. It turned out to be a much simpler problem than that though: the diode attached to the voltage limiting opamp was the wrong way round, so it was feeding current into the gate of the main current control FET instead of sinking it from the FET! No way was this thing going to work like that. In my defence, it turns out that the KiCad libraries have a whole set of “simulation only” components in them with different pin assignments to normal, and I’d somehow ended up using one of those instead of the proper diode symbol. Putting the diode round the right way made everything work better!

Later on when testing the calibration software I’d written, I discovered another problem that’s not going to be so easy to fix. It’s not preventing me from using the Teensy Load, but it will have to be fixed in Revision 2 (see “Revision 2 plans” below).


The Teensy is connected to a PC over a USB connection, appearing as a USB serial port on the PC. The user interface software PC and the firmware on the Teensy communicate using a simple ASCII protocol. All messages from the PC to the Teensy just give values for the Teensy ADC sample rate (setting this to zero stops sampling) and the current and voltage limits to use (as integer values in the range 0-1023 for the 10-bit DACs).

The firmware on the Teensy just loops waiting for commands from the PC (setting the current and voltage limits if it gets a command) and sampling the current and voltage values for the device under test at the requested sampling interval, writing the resulting values on the serial connection to the PC. There’s not a whole lot to it, since I decided to put most of the “interesting” bits of the software side of things on the PC.

One thing I did do, which makes life a bit easier, is to organise the firmware to make it easy to use it in a simulator mode, where the Teensy generates data itself without needing to be connected to the Teensy Load hardware. This makes developing the Python software to run on the PC much easier. All the main loop code is shared between the firmware for connecting to the hardware and the simulator, as is all the serial event handling for talking to the PC. The only part of the firmware that’s unique to the hardware side or the simulator side is the actual level setting and data sampling.


The idea is to have three separate applications, written in Python either as command line applications or using the Gtk UI toolkit and the Glade GUI builder to lay out the user interface. I’ve not used Gtk before (though I’ve done a lot of GUI programming using other toolkits), but at least with Python and Glade it’s quite a pleasant experience.

The three applications are:


This ia a real-time “meter” view of the current and voltage values from the device under test. The user interface allows you to set the current draw and voltage limit, and there are some facilities for setting sample rates and display smoothing, and for saving data to files (along with comments, which I often find useful when doing a series of experiments).

This currently mostly works. I’ve also written a calibration tool for the device called tl-cal, and discovered a problem with the circuit design while testing that (see “Revision 2 plans” below).

Here’s a video of my first test run of tl-meter with the Teensy Load hardware running the hardware firmware:


This is a command line script to automatically trace out I/V curves for batteries and power supplies–you set up some ranges of load currents you want to look at, and the software samples enough data to make a useful I/V curve.

Here’s an example plot produced from tl-iv for a breadboard power supply that I use. This takes input from an unregulated 5V “wall wart” supply and provides a 3.3V regulated supply. On the following plot I show results collected for both the 5V and 3.3V supplies.

Breadboard power supply results from tl-iv

It took a couple of minutes to collect the data for each case. You can set the current demand values to use, some values for sampling statistics, a maximum voltage limit, and a minimum voltage limit to use for stopping the data collection if you demand too much current from the device under test and the supply voltage drops out (you can see that happening for the 3.3V supply here).

Making tl-iv and the (so far unwritten) tl-discharge application command line applications is a lot easier than writing a GUI application. You just give some command line options and off it goes. The data from the Teensy Load is saved to files, and plotting the data is done separately. I find it to be more convenient than a GUI, in fact!


This will be a utility to record discharge curves over time–set the current draw and voltage limits, and the software regularly samples the current and voltage supplied by the device under test, stopping when the voltage falls below a given limit, and generating voltage and current versus time data files.

Status: not even started! I think this will end up being a command line tool as well.

Revision 2 plans

While I was testing the tl-cal calibration program, I discovered something really weird that I didn’t understand at all. The voltage values being set by the DACs looked reasonable, and the voltages produced at the inputs of the current setting opamp looked okay (that’s just a voltage divider, so it ought to work!). In contrast, the voltage at the input of the voltage limiting opamp didn’t make any sense at all. There’s a 60kΩ : 39kΩ voltage divider there, so with a DAC output voltage of 3.3V, you’d expect to get (60+39)/39 × 3.3V = 2V at the opamp input. But it wasn’t that at all! I was measuring 1.3V there. I did more measurements and concluded that the opamp input was sinking a significant amount of current, pulling the voltage I expected to see there way down.

I didn’t understand why this was happening, so went for help to the Contextual Electronics forum. There, someone pointed out a graph in the datasheet for the opamp I’m using that made everything clear. The voltage limiting opamp is set up as a comparator, i.e. it has no feedback path and the inputs can differ by a non-zero voltage. The TLVx333 opamps that I’m using don’t like that (the relevant graph is Figure 17 in the datasheet). They’re chopper-stabilised opamps, and this graph showed how the ESD input protection on the opamp can start sinking quite a bit of current if the inputs are pushed too far apart in voltage (explanation in Section 8.3.5 of the datasheet). So that part of the circuit doesn’t really work at all.

I don’t remember exactly why I chose this opamp, but I certainly didn’t take on board the fact that it was special, and I didn’t know anything about chopper-stabilised opamps before this!

Fixing this seems like something for Teensy Load Rev. 2, and I have a few other things that need to be done as well. The main points I want to address in the redesign are:

  1. Use a true comparator instead of a TLVx333 for the voltage limiting comparison.

  2. Improve the PCB layout for physical stability (it’s a bit wobbly and falls over more or less every time I touch it!). I might redo the thermal calculations to see if I can get away with a smaller heatsink, since I’m using one that’s comically out of proportion to the PCB.

  3. Deal with biasing for opamps to avoid operating close to ground. This is something else that came up in a discussion on the Contextual Electronics forum starting here