That wasn’t in the (LMC555) datasheet :(

So I was making an one-off circuit to drive some things from an RPi and I needed a level shifter. Turns out that a CMOS 555 (on paper) looks like a pretty good bet if you need an ad-hoc solution with mild performance requirements. The TI LMC555 runs all the way down to 3V or so, and can source 100mA from the output. Being CMOS, the output goes more or less to the rails.

So far so good. The way to set it up is to power it off the high side, wire it in Schmitt trigger configuration (pin 6 to pin 2), and set the control voltage at 2/3 of the lower level. And that works just fine.

One problem, it seems that despite being specced to run off 3V, the current sourcing capability drops drastically under about 6V, to the point where at 5V it will only source about 12mA! That’s something of a pity because I needed those 100mA, or more than 12 at any rate, and annoyingly it doesn’t appear to be mentioned anywhere in the datasheet.


On the other hand, I’m glad I bought those jellybeans a while back. I replaced the 555 with a high side PNP switch (a now discontinued BC638 in a small TO92 from one of those Maplin grab bags)  who’s base is driven from a chunky STP55 (a giant TO220) since the latter switches adequate current at only 1V. The 2N7000 is kind of marginal for getting the high base current required to get a low saturated Vce when driven from  3.3V.

So, mission accomplished, but I’m still annoyed about the serious derating. I’ll make a graph when I figure out how to get my scope to act as a data logger.

EDIT: That was way easier than I thought. You can save traces via rather awkward interface to a USB stick in the front panel. So, I set up a 555 to output high into a 10 Ohm load and cranked the supply voltage by hand, measuring the supply and drop across the load. And here’s the result:

The LMC555 hist 100mA at 12V compared to 3 for the LM555

Graph of output pin current into a 10 Ohm load against supply voltage

Well, turns out the LMC555 has a rather high output resistance. The bipolar LM555 on the other hand is a bit of a beast and will give tons of current if you don’t mind the quite high (over a volt) drop at the output.


I’m low on parts and it’s time to restock. I’m after jellybean prototyping parts—generic ones without any surprising properties. The criteria are they are (a) reasonably cheap (b) available from RS, (c) through hole, (d) available in sensible quantities.


High power

STMicroelectronics STP55NF06L. Excellent logic level (50A at 3V, over 1A at 2V, something down to 1V), 55A/60V. (about 20p)

Low power

On Semi 2N7000. Logicish level, (50mA at 3V, not much below that), 200mA, 7p.

No outstanding low switching voltage small MOSFETS seem to exist as jellybean parts.


OK so everyone says the 741 is too old school and there are opamps better across the board. They’re also 24p which while cheap is actually more expensive than rather better amps. And there are way cheaper ones too.

Super generic

Taiwan Semiconductor TS358CD, 1MHz mostly because it’s 6p. Worse than the 741 in most ways, but 6p! For 2! That’s 3p each! Also, single supply down to 3V. Stretching the definition of jellybean a bit, since it’s so low end, but they’re still going to be fine for basic stuff and if they’re rubbish, well I didn’t lose much. Also did I mention they’re 6p?

Standard voltage

Texas Instruments TIL081, 3MHz, normal voltage range, FET input (33p). A drop-in replacement for a 741, slightly pricier, but better in every single spec. Similar to the LF411 recommended by H&H, not quite as good apparently, but about a tenth of the price.

RRIO, low voltage

Microchip MCP6002-I/P, 1MHz,   1.8V, 100uA single supply, FET? input (1pA) (20p)


Microchip MCP6291, 10MHz, 2.4V single supply,  1mA, RRIO, probably FET input (50pA) (35p).

Voltage Regulators

3.3v for things like bluetooth chips and other MCUs. 5V for obvious things and the 317 for everything else.

STMicroelectronics L78L33ACZ, 100mA (14p)

STMicroelectronics L7805CV-DG, 1.5A (9p)

Texas Instruments LM317KTC, 1.5A (15p)


I’ve never tried any of these particular variety of 555s before, but how bad can they be, eh? 🙂 Also yes, I know that an arduino/MCU can do a better job of a timer, but 555s do a bunch of stuff plus there’s always the “what weird things can I do with a 555” game.

Texas Instruments LMC555CN/NOPB, CMOS, 3MHz (74p, kinda expensive for a jellybean, CMOS and fast!)

Texas Instruments NE555P (22p – that’s more like it! Bog standard 555)


libble++: simple Bluetooth Low Energy on Linux.

Here’s the code on github!

I’ve been working on a Bluetooth Low Energy library for Linux. The emphasis is on modern C++ design, and simplicity of use. I started before BlueZ supported BLE in a meaningful manner, so this library uses bits and bobs from BlueZ, some linked from libbluetooth, and some extracted from the source code.

I don’t make use of any of the GATT (that’s the high level interface, which is implemented over the ATT protocol which itself is sent over bluetooth sockets) code within BlueZ, which is all implemented over DBus. I just construct the packets (that’s the code I pulled out of BlueZ) and send them over a bluetooth socket myself.

With the brief introduction out of the way, how about some code :).

Here’s a complete program which scans for BLE devices:

#include <blepp/lescan.h>

int main()
   BLEPP::log_level = BLEPP::LogLevels::Info;
   BLEPP::HCIScanner scanner;
   while (1) {
    std::vector<BLEPP::AdvertisingResponse> ads = scanner.get_advertisements();

Is that about the shortest scanning example you’ve ever seen? 😎 I cheated very slightly by bumping up the log level. Otherwise it’d sit there scanning and generating no output whatsoever, which would not be all that much use.

I’ve also not commented this because I think it’s reasonably self evident. There are only two active lines, creating a scanner object and getting the scan results. I also bump up the logging level so it shows scan results without having to print stuff from the ads struct. Not that that is hard, but since more or less everything is optional information, it’s mildly tedious.

With that little hook out of the way, the library follows a socket-and-function design, much like XLib if you happen to know that. In other words, there’s a socket which all the functions use and which is created for you. If you have a simple interaction with BLE to write, you can just use the functions and never worry further. If you have a slightly more complex interaction, for example if you don’t want to block, then you can get the socket and select(), poll(), epoll() or use any other of your favourite system calls.

So as a result, there’s no framework. It’s just a library. It won’t steal your main loop or make it hard to integrate with any other I/O system you happen to have kicking around.

Interacting with a bluetooth device beyond scanning is a bit more complicated, because devices with interaction are a bit more complicated. It’s more or less the same model, except it uses callbacks (set via std::functions), because various bits of information can arrive asynchronously.

Here’s a complete example which shows how to connect to a temperature monitor and log the readings it gives. I’ve highlighted the non-trivial lines so you can see how much code and how much boilerplace there is (not much!):

#include <iostream>
#include <iomanip>
#include <blepp/blestatemachine.h>
#include <blepp/float.h>  //BLE uses the obscure IEEE11073 decimal exponent floating point values
#include <unistd.h>
#include <chrono>
using namespace std;
using namespace chrono;
using namespace BLEPP;

int main(int argc, char **argv)
	if(argc != 2)
		cerr << "Please supply address.\n";
		cerr << "Usage:\n";
		cerr << "prog <addres>";

	log_level = Error;

	//This class does all of the GATT interactions for you.
	//It's a callback based interface, so you need to provide 
	//callbacks to make it do anything useful. Don't worry: this is
	//a library, not a "framework", so it won't steal your main loop.
	//In other examples, I show you how to get and use the file descriptor, so 
	//you will only make calls into BLEGATTStateMachine when there's data
	//to process.
	BLEGATTStateMachine gatt;

	//This function will be called when a push notification arrives from the device.
	//Not much sanity/error checking here, just for clarity.
	//Basically, extract the float and log it along with the time.
	std::function<void(const PDUNotificationOrIndication&)> notify_cb = [&](const PDUNotificationOrIndication& n)
		auto ms_since_epoch = duration_cast<milliseconds>(system_clock::now().time_since_epoch());
		float temp = bluetooth_float_to_IEEE754(n.value().first+1);

		cout << setprecision(15) << ms_since_epoch.count()/1000. << " " << setprecision(5) << temp << endl;
	//This is called when a complete scan of the device is done, giving
	//all services and characteristics. This one simply searches for the 
	//standardised "temperature" characteristic (aggressively cheating and not
	//bothering to check if the service is correct) and sets up the device to 
	//send us notifications.
	//This will simply sit there happily connected in blissful ignorance if there's
	//no temperature characteristic.
	std::function<void()> found_services_and_characteristics_cb = [&gatt, &notify_cb](){
		for(auto& service: gatt.primary_services)
			for(auto& characteristic: service.characteristics)
				if(characteristic.uuid == UUID("2a1c"))
					characteristic.cb_notify_or_indicate = notify_cb;
					characteristic.set_notify_and_indicate(true, false);
	//This is the simplest way of using a bluetooth device. If you call this 
	//helper function, it will put everything in place to do a complete scan for
	//services and characteristics when you connect. If you want to save a small amount
	//of time on a connect and avoid the complete scan (you are allowed to cache this 
	//information in certain cases), then you can provide your own callbacks.

	//I think this one is reasonably clear?
	gatt.cb_disconnected = [](BLEGATTStateMachine::Disconnect d)
		cerr << "Disconnect for reason " << BLEGATTStateMachine::get_disconnect_string(d) << endl;
	//This is how to use the blocking interface. It is very simple. You provide the main 
	//loop and just hammer on the state machine struct. 


OK so there are come caveats.

Mostly, it’s not finished. I wrote the library to support the work I’m currently doing, and so I’ve not needed to do anything like everything that the BLE protocol supports. BLE also has a lot of features I doubt anyone’s seen in the wild. I don’t like implementing code I can’t use and test, so I’ve not got any interface to features I don’t currently use.

It’ll likely grow over time and get more features, but if there’s something you’d like in there, let me know. It might be easy for me to put in, or I can give pointers to help you write the necessary code.

A long overdue rewrite of my Autoconf tutorial

In 2003, I learned Autoconf in order to write a configure script for libCVD. There were not many good resources for those getting started so I wrote a tutorial.  The tutorial was rather dated and contained some bad practices and missed things I should have covered properly. I also made the mistake of documenting just Autoconf on its own without doing a more in depth treatment of how it integrates with Make. In hindsight that was a mistake. Technically Autoconf is entirely independent of Make. In practice you’re almost always going to use them as a pair and without showing them together it’s hard to convey how to get Autoconf to control Make properly.

I also didn’t have any complete, working examples. Now I have 13.

The new version is now hosted on github:

and on my website here as well:

louder, Louder, LOUDER! (or: more dead bugging)

Sometimes someone makes a chip to do just what you want.

I’ve recently been needing to generate beeps from a BLE113 module (it’s a CC2541) which runs off a CR2032 coin cell at a nominal 3V, but more like 2 to 2.5 in practice. The speaker of choice is a surface mount piezo sounder which are small (9mm square) and unlike the discs don’t require mounting on a sounding board to get sound out. I’ve not idea if those Murata ones are the best, but it’s a respectable brand and those are the first I found that seemed to meet the spec.

They’re not especially loud, only 65dB at 1.5V pk-pk. The microcontroller I’m using has 4 useful channels on timer 1 for this application, and of course the outputs are totem pole outputs. So, driving it with two PWM channels in opposition is driving it with an H bridge which gives the full 2-3V pk-pk swing (depending on the battery voltage).

That makes it little louder, but not an awful lot. The datasheet says that the sounders can be driven at up to 12V pk-pk without damage. The datasheet however merely notes that it is “probable” that increasing the voltage will increase the volume, which is a bit unhelpful, though it has a graph for one (not the one I want) showing an increase with voltage exactly as you’d expect.The question then is how to generate a higher voltage for the buzzer. I had lots of ideas:

    Boost / switched capacitor converter and another H bridge (impractical–too many components)A miniature transformer (none quite small enough or with the right turns ratio)A miniature autotransformer (closer, but still the same problem)Something cunning with an inductor—some sort of ad-hoc boost thing which generates spikes rather than a square wave. Idea not really fully formed.

None of them are really any good. They’re either require impractically large number of components, components that either don’t exist (or I can’t find) or are vague and ill formed and I don’t have the parts to test the idea and anyway I’d probably end up busting up the chip with voltage spikes.

Fortunately it appears that someone thought of this already. It turns out the PAM8904 already does exactly this. It’s a switched capacitor converter with an H bridge, that takes a digital signal in, precisely for the application of driving piezo sounders from low power microcontrollers. Which is nice.

Except I’m not very trusting, and I’ve no idea if it’s worth the effort. I don’t want to order a circuit board and then fiddle around hand soldering QFNs (I’ve seen it done, I’d rather use a stencil) for a one off test. Like so many chips, it’s QFN only now. So the obvious thing to do is to buy one and deadbug it.

I figured I’d try the nice fine hookup wire I’ve got. The colours make it a bit easier to follow which wire is which. Next time, I’d try the same soldering job with enamelled wire. It’s harder to strip and tin, but the insulation doesn’t get in the way. The key to getting the soldering to work in the end was to tape down the wires with masking tape (3M blue tape) as I went along. Even with that it’s two steps forward, one back as you accidentally desolder wires when trying to attach new ones. Here it is!


(OK, not as good as this, or this, or this—hey that socket is a really nice idea!)

Spot the schoolboy error? I remembered to check continuity between neighbouring pins, but I forgot to pot it or otherwise protect the wires and so some of them fell off when I tried to change the boost voltage selection. And then another 4 wires fell off when I was taking it out. The connection area is tiny and the solder work is frankly not that good, so the joints are amazingly fragile. It’s what I should have done first time, doubly so because the bits of stiff wire for the breadboard really get in the way.


Well, it seems to operate correctly, but I think I’d do it differently next time. A chip socket or veroboard with .1″ header soldered in is a much better choice than flying wires. Potting makes it as robust, but you have to pot it before you know it works.

It’s always a bit hard to tell volume because ears have a logarithmic response and at 4kHz the sound is quite directional. Nonetheless it’s noticeably louder. Yay 🙂



Good job, TI, I half mean that

I was a little surprised today when trying to debug a board when one of the output voltages was 4.8 V. The main reason for the surprise is that the power supply is specced at 3.3V. And I didn’t make the supply, Texas Instruments did. In fact it’s one of these.


Checking the manual reveals that TI do indeed claim that it’s supposed to output 3.3V. Time to find the regulator! There’s no continuity between USB power and the output so it’s not a short. Poking around on likely looking chips quickly reveals that the regulator is OUCH THAT SUCKER IS BOILING HOT! this one:


And has the markings in very small “PHUI”. I got a far as googling “PHUI v” before it autocompleted to “PHUI voltage regulator”, so I guessed I was on the right track :). Not very further down the track the TI TPS730 datasheet crops up showing it’s a TPS73033, which is a 3.3V LDO regulator rated to 200mA. And did I mention it’s baking? It seems to be fried in a rather unfortunate mode (and just for good measure, the NR pin which ought to be at 1.22V is at 0.14). Also, it turns out that the entire circuit diagram was in the manual, so there was no need for that bit of minor sleuthing.

So why good job TI? Well, the other, much more important chips, such as the micro controller I’m programming are rated to 3.9V absolute maximum and it didn’t die with 4.8V across it. I’m pretty pleased about that, because I can imagine going round a cycle frying many chips before finding out the power supply was defective. :shudder: :(.

Well anyway, it’s fried and I can’t use it. I mean technically I’ve successfully programmed the chip and not fried anything as far as I know, but there’s another as yet untested chip on the board rated to only 4.8V absolute maximum. I can’t trust it, so I can’t use it and so as far as I care it’s broken.

And that means I’m free! This guy has a great philosophy which is that if something is broken then there’s no risk of breaking it so you may as well try to fix it. Fortunately, I have some old boards which I’m not currently using which have ST Microelectronics L78L33 SO-8 voltage regulators on them. They’re not LDO so getting 3.3V from 5V is a bit dubious and actually is not quite within spec, but whatever, both my chip and the one in the programmer (a CC2511) work all the way down to 2V, so I reckon that is won’t matter. Also, it’s only rated for 100mA, not 200mA like the original, but both the chips are low power wireless ones so I doubt the current will go too high even when it’s programming. And besides that won’t be for long.

Time to dead bug it! And pot it in hot melt!


And it works! 😎

The LED perhaps to the surprise of no one is dimmer than before and the output voltage is 3.2V which is in fact well within spec for the 7833.


The best of both worlds

I currently run Ubuntu LTS (14.04 at the moment) on my work laptop and Arch on my home laptop. I like the stability of Ubuntu, and very much like that I  can run security updates without breaking anything. However, the old versions of programs are annoying in some cases. I love running Arch because I always have the latest versions. This bit me today since the version of gerbv I was running was too old to support the high resolution drill placements in Eagle 7 and so my gerbers looked bad.

Give me Archbuntu!

First, get and run it in (say) /other_OS to make /other_OS/ARCH_x64. You now have a bootstrapped arch installation. You can chroot into it and it looks arch-like but won’t work properly.

The main reason is that none of the special files are there. Essentially you want everything to mirror your main OS, except for the the OS itself. This can be done with bind mounts. Add the following to /etc/fstab and run mount -a

/proc          /other_OS/ARCH_x64/proc          none defaults,bind 0 0
/sys           /other_OS/ARCH_x64/sys           none defaults,bind 0 0
/dev           /other_OS/ARCH_x64/dev           none defaults,bind 0 0
/tmp           /other_OS/ARCH_x64/tmp           none defaults,bind 0 0
/home          /other_OS/ARCH_x64/home          none defaults,bind 0 0
/etc/passwd    /other_OS/ARCH_x64/etc/passwd    none defaults,bind 0 0
/etc/shadow    /other_OS/ARCH_x64/etc/shadow    none defaults,bind 0 0
/etc/group     /other_OS/ARCH_x64/etc/group     none defaults,bind 0 0
/etc/sudoers   /other_OS/ARCH_x64/etc/sudoers   none defaults,bind 0 0
/etc/sudoers.d /other_OS/ARCH_x64/etc/sudoers.d none defaults,bind 0 0

Now you can chroot into /other_OS/ARCH_x64 and run pacman. Note that /tmp is shared partly to avoid duplication, but also because that’s where the X11 socket it. Without it, you’ll need to use xhost to allow chroot’d programs to connect. And the password related files are duplicated to so sudo still works.

While you can sudo, chroot, then su – to yourself then run programs, that’s a little inconvenient. chroot is root only for security reasons, but since the chroot image is legitimate, we can chroot into that safely as anyone. The following code essentially chroots into /other_OS/ARCH_x64, drops root and then executes its arguments.

#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <errno.h>

int main(int argc, char** argv)
	int r = chroot("/other_OS/ARCH_x64/");

	if(argc == 1)
		return 0;
	if(r == -1)
		fprintf(stderr, "Error chrooting: %s\n", strerror(errno));
		return 1;
	r = setuid(getuid());

	if(r == -1)
		fprintf(stderr, "Error dropping root: %s\n", strerror(errno));
		return 1;

	r = setgid(getgid());

	if(r == -1)
		fprintf(stderr, "Error dropping root: %s\n", strerror(errno));
		return 1;

	execvp(argv[1], argv+1);

	fprintf(stderr, "Error: %s\n", strerror(errno));

Compiling this as ae (think arch exec) and putting it in the path allows you to do “ae gerbv” instead of “gerbv” to get the Arch version, for example. Note that unlike the commandline version, the chroot function doesn’t alter the CWD, so it all works just fine.

Now I have the best of both worlds!