Can it be true? That I hold here in my mortal hands, a splat of purest crud?

Today, a semi-successful experiment. I tried to make a small arc furnace using an arc welder, a graphite crucible and some inanimate carbon gouging rods. The goal was to melt aluminium successfully enough to do some casting. The idea behind using the arc welder is that it’s accessible and doesn’t require faffing around with fire, and getting the consumables brought in (gas, for example). The whole thing ought to be less messy and quicker to set up and tear down.

The furnace consists of a solid, 4kg sized graphite crucible (remarkably inexpensive) sitting in a badly welded, but very stable steel holder steel holder:

img_20170118_203057

An arc furnace. The white stuff on the inside is alumina fumes which settled on the side.

The idea was to strike an arc with the crucible and a copper clad carbon rod (a gouging electrode). It kinda worked, but the arc was pretty unreliable and surprisingly weedy even on the highest setting on the welder. I had much better luck striking the arc between two carbon rods and moving that around as a heat source.

img_20170118_203610

The rods are very much a consumable!

That kinda worked, and I was certainly able to get some melting (as you can see in the splat). Enough to prove the principle but not enough to actually do some casting. The summary is kind of:

  • Someone stole my flux (own brand lo-salt), so I got a lot of aluminium oxide for my troubles.
  • The welder doesn’t like the 16A breaker for the outdoor power socket. Works fine on the other 16A breaker in the basement but keeps tripping out.
  • Not enough insulation, a rather large crucible, repeated cutouts and cold weather meant I couldn’t retain enough heat to make a pour.

The thing to do now it appears is to make the furnace by hollowing out an alumina firebrick. They’re very porous and so excellent insulators (one video has the person picking up his brick with bare hands with a pool of molten aluminium in the central hole).

Nonetheless, it proves the principle. The 400 and 600A (one of each) crocodile clip style rod holders hold the carbon rods well. The rods work, strike an arc and provide aluminium melting heat.

 

Adventures in gluing

The thing I’m working on has some metal parts glued into a plastic case. The plastic is smooth (the mould is finished to the “Society of Plastics Engineers” 600 paper spec), and the metal is shiny chrome plated brass. I never considered either of those to be especially hard to glue, so I went for a pretty straightforward epoxy, Loctite 5 minute instant mix clear. It’s a decent enough go-to, much like any other random 5 minute clear epoxy. The short curing time is great for the impatient (me) and the clear finish is great because you can be a bit lax about the cleanup, which is especially important given the short curing time.

So, I splurged some on the metal part, shoved it in the hole and wiped off any egregious amount of excess with white spirit. A week later, I was fiddling with the part seeing how strong it was and was kind of surprised/distressed about how easily the joint broke. Like, really far too easily. And incidentally always the same way: the glue detaching from the plastic.

Then it got me thinking. I had a vague recollection that 5 minute epoxies kind of suck and come to think of it, so do clear ones. In a sort of ad-hoc way I think I’d come up with this:

Ed’s  rule of glue

Every feature added to glue makes it worse.

Fast curing? worse. Non, tinted transparent? That’ll cost you. Conductive? [sucks air through teeth]. It kind of makes sense, you can’t optimize everything at once.

That’s not to say you should never use that glue, it’s still perfectly fine for a lot of stuff, but slower curing and/or those ones that cure a nasty brown colour will almost certainly perform better. So, anyway, I tried  some polyurethane glue I had lying around and it seemed to be a bit better.

Time to experiment!

So,  which one to use? So first, the selection. There’s roughly an infinite number of glues out there, give or take a few. Some have wild and wacky properties, but even if you stick to the middle ground of generally gluing stuff to other stuff, there’s still a large selection.

So, I picked some somewhat arbitrary criteria and selected some glues that generally fitted:

  1. Specced to glue metal to plastic, bonus points for having ABS in the list.
  2. Available from local shops or next day delivery from RS
  3. Reasonable curing time to handling strength.
  4. Auto mixer if possible where applicable (better for large volumes).
  5. Not wildly expensive.
  6. Decent brands and available in the US (I’d normally be happy with RS pro stuff, but I need to be able to get it abroad easily).

The brands are mostly big, well known ones. 3M is always good. Loctite likewise seems fine. The other one, Araldite, I have a particular soft spot for. For years in the home gamer space it was pretty much synonymous with epoxy. My old DT teacher was a huge fan (rightly so) because you could fix all manner of sins with it. Countless projects were rescued with Araldite at my school.

And so, I came up with the following list:

  1. Loctite 5 minute instant mix. That’s the baseline, and my gut feeling says that other clear, fast setting epoxies won’t differ wildly.
  2. Araldite Standard. Bog-standard DIY shop glue. Slow setting (pot time of an hour, high strength in 24), dries kind of opaque yellowish.
  3. Araldite 2011. One of about a billion varieties. Similar to 2, but dries clear yellow. Allegedly slightly stronger on ABS. Also a pro glue, so comes in pro packaging which means you need one of those applicator guns and a clip on mixing nozzle for the auto mixer.
  4. Loctite 330. It’s an acrylic glue which I didn’t even know was a thing before today. You put glue on one surface an spray the activator on the other surface and put them together. Datasheet specifies 7387 or 7386 activator, but Loctite actually sell it packaged with 7388 of course. Fast cure time (30 mins to half strength) , and almost indefinite pot time, which is handy, since you don’t mix it with the activator. Not much by the way of instructions though.
  5. Araldite 2028. OK, I lied about not bothering with other fast curing clear epoxies. This one claims excellent performance on ABS, not so much in the datasheet which is not anywhere official I could find, but in this handy selection guide, which has a mysteriously chosen subset of the glues on offer. Also pro packaging with an auto-mixer.
  6. 3M ScotchWeld DP8005. Now I’ve heard about acrylic adhesives, I’m on a roll. Also RS had a relatively small selection of 3M and I felt things wouldn’t be complete without one. Claims to work well on ABS. Has an annoyingly short pot life (3 minutes and they’re not messing around).
  7. Everbuild gator glue. Bog standard polyurethane glue (basically the same as Gorilla
    Tasteful.

    I love the logo too!

    Glue). Generally considered OK for metal and plastic. Reasonable pot life and cure time. Single part, so no mixing needed. Also expands as it cures. This is not (as is popularly thought) useful for filling gaps since it expands as foam when the pockets of glue get too large. However, it does slightly splurge out so if you miss small areas, they get filled from the nearby ones. If you’re not familiar with British knock off brands, Everbuild is basically an adhesive company which makes cheaper versions of the well known stuff. So Gator glue/Gorilla glue, One Strike Filler/Pollyfilla, Stixall/No More Nails, etc etc. They also sell the delightfully named ASBO brand anti climb paint and anti graffiti painting. That makes me chuckle every time.

  8. Polycaprolacetone. I remember that sticking to everything really hard when I tried to use it. Applying it as an acetone based slurry, then reflowing it thermally after it’s dried. This is basically me messing around.

    crud

    White crud on the two snaps on the right hand side. No glue was applied there.

  9. Cyanoacrylate (generic brand). Another baseline, known to be strong and effective, but outgasses this white crud everywhere which is electrically insulating and has to be cleaned off.

Oh and the surface prep. Did I mention I forgot the surface prep before?

  1. Clean both surfaces with IPA (isopropyl alcohol).
  2. The full monty: clean with IPA, sand with 400 grit paper (3M as it happens), then clean again with IPA.
  3. As-is, with whatever crud and release agent is left on by the moulding processes.

And it’s arrived!

Swag! Lots of glue arrived

Swag!

Check out the swag, including a spiffy (and necessary) applicator gun, because as you can see, the pro packages don’t have full syringes. And 3 hours of cleaning, sanding, mixing, gluing and wiping off the excess, I present:

img_20161207_172650

That’s a lot of gluing and there’s more to come.

So now, I need some way to measure the force required to eject the metal bits from a case. Naturally, since I’m doing the whole thing at short notice and in rather a hurry,  I had to cobble together something with whatever was lying around or could buy locally. My solution is to go to a local DIY shop and enter a kind of trance until a solution based on the weird selection on offer presents itself. The result was this:

img_20161209_111453

After a few iterations, I settled on pushing down on a set of old kitchen scales held down with cable ties and string. The lever is 4x and the scales go to 5Kg, and the extra weights on the end are 2.5Kg at 5x. Maximum force it can apply is 32.5Kgf.

It’s basically a parallel action mechanism with a long lever. I balanced it to make it neutral and marked graduations on the lever so I can put a weight at a known position to apply a known force. You can’t see the M4 screw on the underside which is embedded into the pressing bit with some brass threaded inserts. I used some 5 minute epoxy (surprise!) to glue them in, but not a clear one and the horrendous brown colour made me think I should have tried it too. Though being nasty coloured and fast curing (hard to clean off) is not a great combo. The big M10 studding isn’t going into bare pine. The holes are lined with some sort of plastic tubing which felt a lot like HDPE. Naturally it was 15mm, and they only had 14 and 16mm drills, so a lot of sanding was involved (later I found just hacking off the outer layer with a Stanley knife was faster. Oh well). It’s also quite loose (inner diameter 11mm), which is good because I can’t drill straight apparently.

Oh, also, I glued on the main pillar upside-down first time (look: it’s not symmetric) at the other end with the Gator glue (scar is visible just by the pliers). I realised after about 20 minutes and that was enough that one of the end grain to long grain joints was already stronger than the wood. Even if I find doesn’t measure up here, I’ve become a fan of the speed of polyurethane glue and strength on end grain for woodworking

Oh and check out how straight the pillar is 8-). There’s nothing to keep it straight except for the square planed end. I’m excessively pleased about that.

RTFM, n00b.

So the spare DP8005 didn’t cure in a nice solid lump, at least in not in a few hours, and it’s meant to have a pot time of about 3 minutes. I think it was a mixing problem. I’m not 100% sure I got the right nozzles and since it’s a 10:1 mix, that really matters. So I mixed some by hand, too (strongly not recommended) and tried that. But since mixing is slow and it has a short pot time, I didn’t have a chance to glue up all variants. When it’s properly mixed, this stuff sets FAST.

The first results.

Thoughts so far during gluing:

  1. The Loctite 330 activator is this yellow gunk that has to be cleaned off. It’s pretty nasty and it’s more or less impossible to clean it off interestingly shaped surfaces.
  2. Scotchweld DP8005 is made by 3M and being 3M they’ve really put the effort into the packaging. It reseals really well by plugging up the holes (unlike the Araldite which has a simple cap), with a keyed cap, so you don’t mix the two sides. Also it’s gritty! That’s apparently to keep the surfaces apart by the minimum spacing. 3M think of everything.
  3. Cyanoacrylate is and always will be a pain in the neck.
  4. My lab now smells of glue and solvents. Niiiice.

Anyway, I left them curing for 36 hours in my lab. Then I spent I don’t know how long pressing snaps out of cases and writing down the results. And then some awk code to collate and prettyprint the results of course.

 

                        Surface prep||     IPA clean     |clean, sand, clean |       none        
Glue                                ||    ave     min    |    ave     min    |    ave     min    
------------------------------------++-------------------+-------------------+-------------------
Loctite instant mix 5 minuted epoxy ||    14.7    8.8    |    12.1    9.2    |     9.1    8.0    
Araldite standard                   ||*    7.9    5.6    |*   11.2   10.0    |*    4.8    4.0    
Araldite 2011                       ||*    6.5    4.8    |    11.5   11.2    |     5.4    5.2    
Loctite 330                         ||*   12.3    7.2    |*   16.3   14.4    |*   13.6   10.4    
Araldite 2028                       ||     7.1    5.6    |     6.9    6.4    |     5.9    5.2    
Scotchweld DP8005 badly mixed       ||*    4.4    3.6    |*    4.1    4.0    |*    4.5    4.4    
Scotchweld DP8005                   ||    22.1   20.0    |                   |    17.5   13.6    
Gator glue (no water)               ||*   11.7   11.2    |*    7.5    4.8    |*    9.7    8.8    
PCA                                 ||     3.2    2.8    |     5.1    3.6    |     3.0    2.0    
Cyanoacrylate                       ||    21.0   15.7    |    22.6   18.4    |    21.6   19.7    

* = Clean off excess glue with IPA

 

And… ehhhhhh.

It’s a bit mediocre.

Well OK. I’ve established that it’s really important to clean the parts before gluing. Sanding seems to help a bit, mostly, but to be honest I didn’t do a great job of it.

The 5 minute epoxy came out pretty strong comparatively and although it seems strong enough it’s not exactly decisive. The CA is strong (as expected), but has outgassing problems. The DP8005 is excellent if done properly, but I think it cures a bit fast to be useful for this application. The Loctite 330 is decent, but that spray is just too horrible for this application.

My ad-hoc experiments earlier had Gator Glue doing better relative to the Loctite epoxy. I think something might be wrong there.

And wow, Araldite, you kinda suck 😦 Is this the end of my fond childhood memories?

No, seriously, RTFM, n00b.

OK, so I forgot a bunch of stuff. I forgot to dampen one of the surfaces with the polyurethane glue (Gator Glue). That might explain the so-so results. Time to repeat the experiment. This time, I also switched to genuine Gorilla glue, not because I expect it to be better, but because the results are going to be used in the US and Gator glue isn’t available there.

Also, the lumps of left over araldite 2011 seemed kinda not fully cured even after 36 hours. I mean they’re sort of hard, but not really solid like I’d expect. The data sheet claims it cures at 10 degrees C (colder than the room I used) but rather sneakily, the strengths are not listed for low curing temperatures.

Double also, in the DP8005 datasheet, it mentions that you should discard the first bit out of the nozzle because it won’t be properly mixed. Not only did I not do that either, but it seems like a really good idea for the other auto mixers as well.

Round 2. Fight!

I’m only re-testing the ones which (a) didn’t seem to come out quite as expected (b) won’t cause massive wastage and (c)  don’t have other issues. So, I’m doing Araldite 2011 with a bake at 80 degrees C for an hour (far more than enough) and Gorilla glue with a water spray. I’m also going to be a bit more generous with the Araldite and apply it to both surfaces. I chose 80 based on a kind of gut feeling compromise: the datasheet listed curing times up to 100, but 80 still cured fast and the plastic starts to soften slightly at 85.

For surface prep I’m only doing the IPA clean since it works well, but not the sanding since it’s variable, hard to do and possibly too awkward to be good in production.

The only thing I am varying consistently is whether or not  to wipe off any excess with IPA.

aaand….

                        Surface prep||     IPA clean     
Glue                                ||    ave     min    
------------------------------------++-------------------
2011, both sides, bake              ||*   20.7   16.8    
2011, both sides, bake              ||    26.9   19.7    
Gorilla Glue, wipe after            ||*   19.9   17.6    
Gorilla Glue                        ||    17.2   15.6    
Scotchweld DP8005                   ||    22.1   20.0    

* = Clean off excess glue with IPA

Well, that’s a bit better.  The Araldite 2011 is the clear winner in strength terms. One measurement actually hit the maximum 32.5Kg the default setup of the press could reach and tore a chunk of the chrome plating off the underlying brass of the snaps . And the Gorilla Glue puts in a very respectable showing. Not quite as strong, but the worst cases are pretty similar. I’m pretty confident now that either of these will do in the final application with the correct surface prep.

winnar

TL;DR

 

 

 

Occasional ENOSYS with l2cap connect() on the RPi 3.

I’ve been working a lot with bluetooth and my library has recently been giving me occasional errors. The error is when calling connect() on an l2cap socket (this is the only bluetooth low energy socket and is packet oriented with retries) I occasionally and at random get ENOSYS.

That means “Function not implemented” or “System call not implemented”. Very strange. Even stranger is that it was not on connect(), but on return getsockopt. This is an async call, so connect() returns either EINPROGRESS (if all is well) or another error. Connection errors (i.e ETIMEOUT, EREFUSED, or if you’re unlucky EIO or ENOMEM) are then collected when you come back later and pick them up with getsockopt.

My first thought was my program had bugs (of the form of pointer related memory errors) and I was somehow corrupting my system calls. Strace revealed that actually my system calls were precisely as expected and identical and so it wasn’t (maybe) my fault.

I then came across https://www.raspberrypi.org/forums/viewtopic.php?f=63&t=145144&p=962612, which seemed to imply that this was a problem on the RPi 3, and not entirely unique to me. I was beginning to really suspect that it wasn’t my fault and something else was causing it. I then started (unfairly as it transpires) cursing the kernel devs responsible in my head because that should never happen: either the syscall is implemented or it is not. There’s no dynamic behaviour there.

Anyway it’s clearly a problem with bluetooth, so it was time to break out btmon, a bluez tool which gets copies of all HCI packets, parses them and pretty prints them. And I was getting this:

 HCI Event: LE Meta Event (0x3e) plen 12                                                                                                                                                   [hci0] 461.313621
      LE Read Remote Used Features (0x04)
        Status: Connection Failed to be Established (0x3e)
        Handle: 64
        Features: 0x1f 0x00 0x00 0x00 0x00 0x00 0x00 0x00
          LE Encryption
          Connection Parameter Request Procedure
          Extended Reject Indication
          Slave-initiated Features Exchange
          LE Ping

It had me going a while because you’ll see that the error code (0x3e ) is by irritating coincidence the same number as the code indicating it’s a BLE related event. To cut a rather long and winding story short, I eventually ended up digging into the kernel sources to find where bluetooth errors got translated into system call errors. And I found this:

http://lxr.free-electrons.com/source/net/bluetooth/lib.c#L45

The rather handily named “bt_to_errno()” function. Now 0x3e was missing from the list. Checking with the bluetooth 4 spec, we eventually find in table 1.1 in  Volume 4, Part D, Section 1.1 the list of error codes. And it corresponds to “Connection Failed to be Established”. There’s no real explanation and this code seems to mean “something went wrong”.

As I mentioned, that was missing from bt_to_errno(), I’m guessing because it’s rare in the wild, and possibly no hardware until recently actually ever returned the code. I’m generally in  favour of the idea of never writing code to handle a condition you’ve never seen, since it’s awfully hard to test.

And flipping to the end you can see that if a code arrives and no code has been written to handle it, the function returns ENOSYS. And you know that’s kind of sensible. The list of errors is not very rich, and there isn’t really anything more suitable.

Of course now we know this happens and seems to correspond to a sporadic error from the hardware, I think the correct choice is to return EAGAIN, which is more or less “try again: it might work, fail again or fail with a new error”. I’ll see if the kernel bluetooth people agree.

Edit: they don’t: EAGAIN and EINPROGRESS are the same error code! Time to figure out a better code.

 

 

 

 

 

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.

Jellybeans

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.

MOSFETS

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.

OP-AMPS

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)

Fastish

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)

555s

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>";
		exit(1);
	}

	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.
	gatt.setup_standard_scan(found_services_and_characteristics_cb);

	//I think this one is reasonably clear?
	gatt.cb_disconnected = [](BLEGATTStateMachine::Disconnect d)
	{
		cerr << "Disconnect for reason " << BLEGATTStateMachine::get_disconnect_string(d) << endl;
		exit(1);
	};
	
	//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. 
	gatt.connect_blocking(argv[1]);
	for(;;)
		gatt.read_and_process_next();

}

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:

https://github.com/edrosten/autoconf_tutorial

and on my website here as well:

http://www.edwardrosten.com/code/autoconf/