GoPro Viewfinder


The GoPro is quickly becoming my favorite camera to take hiking.  It is lightweight and unobtrusive, compared to even a small DSLR or compact.  The battery lasts long enough, and with a case on it it can be waterproof.  I actually carry a pair of them, one with a screen and a polarizing filter and an LCD for landscape photography, and one just for pointing and shooting with no filter or LCD.


One issue I have with the LCD is I can’t see it at all in the sun.  Its not particularly high brightness, resolution, or contrast, and if I can’t see it, it is just burning battery.  Not being able to see it also makes it impossible to properly adjust the polarizing filter, which means I end up with blurry, flat photos sometimes.

To resolve this problem, I printed a shroud to go around the back of the camera.  Friction and potentially rubber bands can be used to hold the camera in place.  A lens and an eyeshield make it comfortable to hold up to the eye and see what you are shooting.


It looks like it works so far.  I am excited to give it a test run in the real outdoors, although it may need a few more features before then- like something to hold in the camera, and eyelets for a strap.

Custom Service with SD110 the NRF51288

As a person who makes their living in the IOT world, I decided it would be handy to learn how to get data to and from the venerable NRF51288, which is certainly a contender for the best bluetooth SoC out there.  One annoying thing is that the wonderful Softdevice that Nordic provides does not have a particularly clear English translation, or good pictures in their documentation.  Here I will try to describe with pictures and arrows that my mechE brain is accustomed to, instead of with comments like “Attribute metadata for the User Description descriptor, or NULL for default”.  Hopefully after reading this, you will have a better feel for how to make a custom service, as well as what the more formal terms are for the different parts of the service in the softdevice API.

How to read this:

The 10,000 meter view will start with the softdevce and the GATT server, then at 1,000 meters, we will inspect bas.h to see what the minimum viable functions for a bluetooth service are.  At 100 meters we will look at the softdevice calls that add the information to the GATT server.  at 10 meters we will look at what gets passed to those calls- the real key to understanding how to add things.  At the very end, I will show you how I changed the bas example to report acceleration values.  This is by no means a definitive guide, but hopefully it will give you a jumping off point for adding services to your code.

10,000 Meters: GATT and the Softdevice


The thing we want to do is add a new service to our Generic Attribute Profile (GATT) server.  Adafruit does a wonderful job of explaining it here, with pictures.  Once you connect to a BTLE device over a Generic Access Profile (GAP), your bluetooth client, usually something like a phone or computer, can access the GATT server, usually something like a the NRF5.

A GATT server can have characteristics, as well as services.  Services are groupings of characteristics.  Services are distinguished by a 128-bit UUID.  Some of them are reserved for particular types of services, like a heart rate monitor, but we will deal with making sure we don’t use those later.  Two that are always included are the Generic Access Service and The Generic Attribute Service.

Characteristics live inside of services, and have characteristic values.  These characteristics can also have descriptors, which can tell you useful stuff like what the name of the characteristic is.  Characteristics are things that can be read and written to the server.  A client might read log data or a sensor value, and it might write a new state for the device or a device name.

The way that you access the GATT server on the NRF51288 (as well as the NRF52) is through the nordic softdevice (SD), which is a pre-compiled binary that you append to the beginning of your user application code.  It handles all the GATT and GAP stuff, and you need to tell it to do things like add services and characteristics using calls to the softdevice that are provided by nordic.

1000 Meters: What is in bas.h

typedef struct
} ble_bas_init_t;

typedef struct ble_bas_s
} ble_bas_t;

uint32_t ble_bas_init(ble_bas_t * p_bas, const ble_bas_init_t * p_bas_init);

void ble_bas_on_ble_evt(ble_bas_t * p_bas, ble_evt_t * p_ble_evt);

uint32_t ble_bas_battery_level_update(ble_bas_t * p_bas, uint8_t battery_level);

Taking a look at an abbreviated version of what is in bas.h will let us know what kinds of things a a bluetooth service might need to do, and what kind of stuff we should have to use the SDK as a template.  Here is a listing of the most important stuff in bas.h


ble_bas_init_t- this holds all the data for initializing the service

ble_bas_t – this holds all the data for actually running the service


ble_bas_init – this initializes the service, and inserts your vendor specific UUID, your service, and characteristics into the softdevice

ble_bas_on_ble_evt – this is called when the softdevice thinks something interesting has happened over BT that concerns the bas service.  For example, a client might write a new value to the server, or want to read a new value from the server.

ble_bas_battery_level_update – this actually updates the value of the characteristic with the new battery level.

So, all the stuff you need is in ble_bas_init_t and ble_bas_t, for the actual data about the services, and then you call ble_bas_init and it gets added to the softdevice.  After that ble_bas_battery_level update gets called every now and then, and if anything interesting happens bluetooth-wise to the service, ble_bas_on_ble_evt handles it.

100 Meters: Adding a Service and Characteristics

Of these, ble_bas_init and ble_bas_battery_level_update are the most interesting functions, so we should look inside of them to see what is going on.  Here we will be focusing on sd_ble_XXXXXX calls, which actually add things to the Bluetooth Low Energy SoftDevice- hence sd_ble.  later we will go back and look at what we are actually feeding these functions.

ble_bas_init is a small function , but it also calls batter_level_char_add which we will need to take a look at- it is something we did not see in bas.h, but it adds the actual battery level characteristic to the service.  The big ble_sd calls here are:


this is just a macro to put the BLE_UUID_BATTERY_SERVICE information into a struct for later- if we want to make a custom service we will have to do it a different way, since our custon ble UUID needs to be added to the softdevice.


This adds our service.  There are some options here, but as long as you have this you will be able to see a service with the BLE_UUID_BATTERY_SERVICE if you look at your device with something like the nrf master control panel app.

inside of battery_level_char_add, a lot of other ble_sd calls happen- lets take a look!


this actually adds our characteristic.  This is pretty useful, since we want it added.


this actually adds the descriptor of the characteristic to the characteristic.

10 Meters: What goes into Softdevice BLE Calls

This is the real dive into the nonsense that is the NRF5 SDK.  I think that a flow chart/visual way of organizing this information is nice, although you have to zoom way in to read the text.  This is just another way of organizing the data, but instead of having to jump around a bunch of windows and files, I put it all in one place- like a cheat sheet.

These are meant to be read from the bottom up- look at the “what can you control” bar to see what you can change, the “where it comes from” bar to see how to actually make the change, and then the “where you can put it” bar shows where you need to put the variables in the sd_ble call.



This char has three layers explaining the arguments of the sd call.  The bottom layer is what you can change, the middle layer is how to generate the change, and the top layer is the actual argument and type that gets passed to sd_ble_gatts_service_add.

Here you can change the type of service between primary and secondary.  A secondary service is a service within a service, which seems fairly unusual.  You can also set the UUID of the service.  If you want to use a bluetooth SIG approved service, then you want to something like:



which is a macro that will fill the appropriate fields of ble_uuid with the info for a battery service UUID. NB, if you put weird characteristics inside of this service, the client may not be able to find the correct data, and you will not be compliant with the BTLE spec.

If you want to make your own custom service, you should do something like

sd_ble_uuid_vs_add(&acc_acce_uuid, &p_acc->uuid_type);
ble_uuid.type = p_acc->uuid_type;


This will make a new vendor specific (vs) UUID and then you manually stuff the values into ble_uuid before passing it to sd_ble_gatts_service_add.  When the function is called, the softdevice will write to the pointer for the service handle.  This is important for later on, when you may want to modify the service- for example, adding a characteristic.


Here you can change the service the characteristic is attached to, the characteristic metadata, and the structure that holds the characteristic value.  Just like sd_ble_gatts_service_add we also pass it a pointer to a handle that gets filled in by this function.  Unlike sd_ble_gatts_service_add there are about a million things that go in here, so each one will need its own diagram.

In the bas service example, we are adding a battery level characteristic to the service, so we should pass in the handle that was written by sd_ble_gatts_service_add.  We could pass in any service handle that was written by the softdevice, and it would add the service to that softdevice.


The characteristic metadata is how you control the properties of the characteristic, such as the read/write permissions and user description (a text description of the characteristic), but nothing to do with the value itself.  It has many many fields and some of those are actually other kinds of metadata structs.  The main groupings of structures are:

First, things that have to do with the properties of the characteristic, such as broadcast, indication, notification and read write permissions, writing with queued request and writing the characteristic user description, as well as the use of bluetooth assigned numbers to indicate the unit, exponent, and format, of the characteristic.  These are all about the actual characteristic and the value that it represents.  This is useful if you wanted to say that the value you are sending to the client is a uint16_t that represents micro-coulumbs for your battery measurement.

Second, the user description- this is really handy if you want to have a string associated with the value that you send that says “battery level”.  Here the important things are a pointer to a string buffer that holds the value, as well as the current length of the value, and the maximum length. Maximum length is important if the descriptor is re-written.  The last part of this grouping is the ble_gatts_attr_md_t, which controls how the description can be read and written.

The final grouping has to do with permissions around turning on and off notifications and indications, which live in the Server Characteristic Configuration Descriptor (SCCD) and Client Characteristic Configuration Descriptor (CCCD).  This post does a decent job of explaining it.


The last thing that goes into sd_ble_gatts_characterisitc_add is a structure that holds the characteristic value contains two main groupings.  The first is a pointer to a buffer that holds values of the characteristic, as well as information about the max length of the buffer, the size of each record in the buffer and the current offset.  The other grouping contains the metadata about r/w permissions.


This is the last softdevicecall, and mercifully it is pretty short.  Just like the other calls, you give it the handle of the characteristic it belongs to, as well as a pointer to store the handle for the descriptor.  The only real data you need to set up for it is a ble_gatts_attr_t which is the same as the one used in the sd_ble_gatts_characteristic_add call.

1 meter view- Custom Service

Lets make a new service- this will document the major changes from bas to a custom accelerometer service with three characteristics that represent x, y, and z accelerations.  For the sake of clarity, we will assume there are functions that do things like get the accelerometer data.  I will show code snippets in the post, but you can also see the whole project here, commit 705deb.

First off, we need to add a custom UUID to our service in ble_bas_init.

ble_uuid_t ble_uuid;
ble_uuid128_t acc_acce_uuid = {{0xAA, 0xCA, 0x55, 0xAC, ..., 0xEF}};

err_code = sd_ble_uuid_vs_add(&acc_acce_uuid, &p_acc->uuid_type);

ble_uuid.type = p_acc->uuid_type;


This adds our new made-up UUID to the softdevice, and then we pack the data into ble_uuid for later use in sd_ble_gatts_service_add.

Next up, we need to make some characteristics to belong to this service!  I will focus on only one characteristic here, because they are all acceleration data (just in different axes).

Compared to the battery level, we will want to make it a uint16_t instead of a uint8_t, give it a text description and add some nice units to our characteristic.

Lets start with making the value a uint16_t.  To change this in the GATT server, we will need to edit the ble_gatts_attr_t that represents the characteristic value that gets passed into sd_ble_gatts_characteristic_add.  In the code, that is called att_char_value.  To make the characteristic value a uint16_t instead of uint8_t, we need to do this:

attr_char_value.init_len  = sizeof(uint16_t);

attr_char_value.max_len = sizeof(uint16_t);


This will change the expected size of the record in the characteristic.  Now it is expected to be a uint16_t.  NB this only changes what the softdevice expects, so there are several other places in the code that will need to be changed to use the proper variable size.

Now for the text description.  This is handy, because your app might want to know what each characteristic represents, other than some crazy uuid.  This is pretty easy, since this information lives in the ble_gatts_char_md_t struct that we already passed to sd_ble_gatts_characteristic add.  We just have to change it by actually making a char buffer and passing the information about the user description size and max size into the struct, like this:

uint8_t user_desc[] = "ACCEL";

char_md.p_char_user_desc = user_desc;

char_md.char_user_desc_max_size = 5;

char_md.char_user_desk_size = 5;


We also have to give ble_gatts_add_descriptor an idea of the read/write permissions for the description.  We do this with a ble_gatts_attr_md_t

ble_gatts_attr_md_t user_desc_md;

memset(&user_desc_md, 0, sizeof(user_desc_md));



Although I could have set whatever permissions I wanted.

Finally, this all gets put into sd_ble_gatts_descriptor_add via the attr_char_value that holds all of the data.

Finally, lets add presentation format data.  We make a presentation format characteristic variable and put some values in it:

ble_gatts_char_pf_t accel_pf;

memset(&accel_pf, 0, sizeof(accel_pf));
accel_pf.format    = BLE_GATT_CPF_FORMAT_UINT16;
accel_pf.exponent  = 0;
accel_pf.unit      = 0x2713; //code for acceleration


then add it to the characteristic metadata:

char_md.p_char_pf = &accel_pf;


With this field filled in, it will automatically be added when the characteristic is added with sd_ble_gatts_add_characteristic.

0 Meters: Inspecting The GATT Server


To check to make sure the device is working properly, I used the nrf master control panel app to connect to and interrogate the GATT server.  As you can see, everything is working!

“Gravity” app for Misift Flash

After a long trip to CA, I am finally back at working on fun stuff.  First up is an app for the Misfit Flash that lights up the lowest LED on the board.  Source is here, but it is a bit hapazard and documentation is somewhat scarce.  So if you are going to build it make sure you have a few minutes.

The how:

This technique assumes that the board is not accelerating at much more than 1g in any direction- in other words, gravity has to be the dominant force.  It would not work very well if you were in a car speeding up, but it would work ok you were in a car with a constant velocity.

unit circ illus.png

To determine which way is down, I read the accelerometer and look at the X and Y components.  The Z does not have very much information for me, because tilting the board to the same angle in any direction will give you pretty much the same Z value.  The Z value would be good for something like a bubble level, but it is not useful here.  Another way to think about it is that a gravity vector straight down is being decomposed into ijk vectors that are fixed to the reference frame of the board.  We want to know in the ij plane which way is most “in line” with the gravity vector.  The X and Y axes of the accelerometer are collinear with the i and j unit vectors in this case.

The X and Y components form a vector that points in some direction on the face of the board (orange vector above).   Each LED lies along an imaginary circle with a radius of 64 units, although I show it as a unit circle above.  Each of these direction vectors is dotted with the XY vector, which gives a “score” of how much the XY vector is pointing in the direction of the LED.  The vector with the largest score has its LED illuminated.

Other Approaches and improvements:


There are simpler ways to do this with non-integer math and conditionals, but floating point math is apparently “expensive” on a M0.  The easy way to do it with floats would be to make a table of inverse tangents, and find the ratio between the X and Y components.  Then it would be simple to just look up which range you were within- for example the 2 o’clock LED here is between .25 and .66.  There would have to be special provisions if X were ever 0 to avoid a division by 0 error, but that would be pretty simple.

An easier optimization would be to get “hints” from the sign of the XY vector, if optimizing for speed.  right now, each 12 dot product operations and 12 conditionals are evaluated each time.  This could probably be cut down to 4 dot products and 6 conditionals if by looking at the quadrant of to do the dot products in first, depending on the value of the XY vector.  Given that the processor is only doing one thing, it does not seem like it is useful to implement.

Commandeering the Misfit Flash Board

setup w friend1

The flash acting as a thermometer.  Also pictured, FTDI friend and discovery board aka stlink programmer

In my last post about the Flash, I showed all the LEDs lighting up, but I really did not have the board mapped out or the toolchain set up yet.  I just went on mbed, and turned all of the outputs on and off, a condition pretty much guaranteed to blink some LEDs on the board.

I wanted to do something a little more involved with this board, so I took the time to reverse engineer the connections and figure out to talk to the sensors and I/O elements on the board. I have figured out the LEDs, the button, the internal temperature sensors, and the accelerometer.


This one was tedious, but not hard to figure out.  I knew all the LEDs would turn on, and that it was not likely to hurt anything if I had all the pins high.  All I had to do here was write a program that turned one pin on high at a time, until I had a map of pins to LEDs.  I was surprised to find out that the NRF was actually not sourcing the current to the LEDs- meaning that when the pin is low, the LED is on.


For about .5 seconds, the battery can source ~33mA

I am not 100% sure why they did this, but my theory is that they found out that you can sink slightly more than the advertised current into the chip, and that the driving output is pretty limited.  According to the datasheet for the energizer CR3032, it looks like it can provide 33mA for a few seconds before some serious voltage drooping sets in.  It also seems like trying to output more current might drop the output voltage more, while low side drive might guarantee a lower voltage (and therefore a bigger voltage drop, and more current across the LED).

flash button hold2

The current the original firmware drew when doing an LED animation

This is a recording of the current drawn from a 3v power source by the device using the original firmware, with the LEDs on.  You can see that they were very careful to use a lot of PWM (about 50% duty cycle) to keep the average current low, but the instantaneous current got as high as 30mA!

Once I figured out what went where, I made a nice little animation that turns on all the LEDS starting at 12 o’clock, and added them to a custom flashboard.h header so it would be easy to reference and compile everything.  I did this a few too many times and ended up killing my battery!  But I also found out ALL the LEDs can be on.



What a nice little dome switch

The button was also tedious, and I ended up not figuring it out on the first try.  My initial approach was to run my clock animation any time the button was pressed, pulling the button high, and waiting for it to go low.  Unfortunately, this did not work quite right, because the button was already pulled high by an external pullup.  This made it pretty tricky to find the button by looking for a response when the button was pressed.  Eventually I just looked for connections on the board, and then tested a few likely candidates for voltage drops when the button was pressed.  I also found what looks like a voltage divider, which may be used for measuring battery voltage (but I am not sure yet).



It is toasty in there!

The NRF51288 has an internal temperature sensor, which I decided would be fun to print out over the UART.  It seems ballpark reasonable, as it settled on about 42 or 43 C for my body temperate- but it may be generating a bit of heat on its own. It is a cool “free” addition to the board.



CS: 2 MISO: 5 MOSI: 4 CLK: 5

After a bit of poking at registers, I wrote a little SPI routine to talk to the accelerometer on board.  After I made sure I could read the WHO_AM_I register, it was easy to get the rest of it working.  Figuring out the pins for this was super easy, because they are labeled on the board- I just looked at where they went and I was right on the first try!  I even got CPOL and CPHA right.

Things I might make

Well, now that I have all this stuff working, its time to make this into something else and call it a day.  There are a few ideas I thought would be worth a try:

  1. Digital plumb bob- the bottom most LED would always light up as the device was rotated
  2. Digital marble- simulate a marble or a drop of water that “settles” at the lowest point
  3. Vibration logger- how often are doors opened?  when does the HVAC run? when are toilets flushed?
  4. Height sensor- detect free fall, and count how long before hitting the ground

The Kossel Science Project

About two months ago I had a hankering for a personal 3d printer- one that I could fix and break at home, instead of just fixing the ones at work.  Like many engineers, I was unable to decide on buying an off the shelf, already functional printer- no instead I decided to buy a delta printer- specifically the cheapest one I could find, the FolgerTech Kossel.  No, you cant have the link.  If you want to buy one too, you will have to figure out how yourself-  if you can’t do that, it is unlikely that you will finish the kit.  Read on to find out why.  See my summary at the end if you don’t want to read the long form post.

NB: at the time of posting this, the kit has been changed a little bit, but I expect the quality and service are about the same.



The general unboxing experience was pretty awesome.  It is hard not to be excited when you get something like a 3d printer in the mail.  Smaller items were sealed in little bubble mailers with labels on them, while larger items like the rails and the extrusion were taped together with “kaptan tape”.  One extremely annoying and totally frustrating thing was that the screws were all mixed together.  It seems like it would have been easy to separate out the ~10 types of screws into different bags, and in fact, it seems like folgertech took all the separate parts and then mixed them together, making it worse for the person who has to assemble it.  Boo.


Fortunately, I had enough film canisters and petri dishes laying around to sort each fastener, bearing, and washer into a separate bin.  Hooray!


A note on the general quality of the kit seems appropriate here.  Most of the non-printed parts are of acceptable quality.  By this I mean that there were 1-2 defective screws, and after lubrication and cleaning, the linear bearings seemed ok.  Some of the parts were of totally unacceptable quality and will absolutely need to be replaced by the user.  I have a complete list later on of things that I had to buy, but the worst offenders of quality were:

-The hot end platform was completely useless, burned, and blobby.  They clearly did not use support and the cantilevered parts suffered because of it

-The end effector was similarly scorched.  It looks like a z axis/bed leveling problem

-Despite the massive 14 AWG (.064″) cables for running the high current DC to the heated bed, the AC power cord is maybe 30 AWG (.010″) stranded, and it heats up noticeably when turning on the printer.  I worried that when I ziptied it to the frame, I would pinch off the flow of electrons.  It is also not IEC color coded, which means right now, it is possible that my machine is grounded on the wrong side of the fuse.


Assembly was not difficult, aside from the poor print quality, shoddy instructions and missing pieces.

According to the kossel BOM, you need about 100 m8x3mm screws to complete the printer.  I was shipped 36.  After complaining, I was shipped another 36.  While I was impressed that they shipped me the screws, I was not impressed by the fact that I was still 28 screws short of the full 100.  Fortunately I had already ordered backup screws from McMaster Carr.  This took about four days, since it was over a weekend.  I could have easily built the printer over that time, but I was $4 short in screws.

The print quality of the components is also quite low.  The infill is decent, but it seems like their extruder had some difficulty keeping up.  As a result, the prints are extremely vulnerable to de-laminating.  This complication is compounded by the prints not being properly sized to fit the extrusion through them- this means that as you push in the extrusion, it is trying to tear apart the print.  Fortunately, I got mine together with only slight damage, which should allow me to print new brackets at a later date.

Print quality issues also caused some problems in holding nuts, which screws were supposed to thread into.  Coincidentally, all of the holes that should have been clearance holes actually being interference fits for the screws, so I could screw them in with no nuts.  A few of the parts (the end effector parts) I had to re print, as the parts I received were unusable.

Now that we have covered the problems with low quality and missing parts, we can talk about the instructions, which for the most part are usable.  They are not well lit, high quality, or in focus, but they are usable.  What was totally unusable was that the instructions conflict and were apparently not shot on the same model of machine.  There are extra stepper drivers, wires, and connectors that are not wired in the printer, but do show up in the pictures.  To add to that, the limit switches are shown wired in such a way that when the switch is not closed, it shorts 12V to what seems to be the arduino ground, which is not the greatest thing to do for many reasons.  As a note, this makes the arudino drop off the USB, so if you see that check your endstops.

Troubleshooting/Small Electrical Fires:

Of course, none of these problems prevented me from eventually building and testing the printer.  And then the real fun began! If I started a print with these lines:

M190 S105 ; wait for bed temperature to be reached
M104 S235 ; set temperature

This would result in the bed temp going up to 105, and then the hot end temp would go up to about 100, then crash.  Slowly, the bed temp would go down after that, until they were both at 25C (my room temperature).  It seemed like an electrical problem, so I checked the power out of the power supply, which was good.  Next, I checked the temperature of the board.  Surprisingly, they were very very hot.  At this point, the MSTBA connector started to make smells, smoke and melt, which led to me unplugging the printer.

The problem was that the polyfuses had blown, and some combination of the polyfuses heating, the FETs heating, and living under the heated bed had caused the plastic of the connector to heat up and short the 30A 12V supply.  In retrospect, it was probably that the board was mounted with metal screws (as per the instructions).  The RAMPS wiki page says “DON’T secure Arduino/RAMPS with conductive screws through both mounting holes. The screw may cut into the positive trace creating a HIGH current short.”.   Either way, this was not good, and totally the fault of the instructions that folgertech provided.  Using non-conductive nylon fasteners might be one way to fix this.

I disconnected all the electronics and moved the controller out from what was essentially a 110C oven.  I oriented the heat sinks and polyfuses facing up (as they should be) in open air, instead of in an oven.  With the connectors extended, the terminal block plug connector removed and with wires soldered in place, I powered the printer on and much to my surprise…it printed!

Print quality:

Considering that the printer is held together with zip ties and given the generally low quality feel that I had as I put it together, my expectations for this printer were low.  However, I have to say that it has performed admirably so far.  It is extremely quick, and with a 1″ calibration cube (printed in the center) I measured that it was within about .005″ (that’s 120 microns for you metric people).  This is without bed leveling,  or really properly tensioned belts or anything, so I am pretty pleased.

NB: after further prints this turned out to be a fluke, the Z of this print was pretty far off.


Count this as more of a box of parts, some of which you may be able to put into a usable printer.  The cost of the kit is about $350, but expect to need to spend another $50-100 on parts that you didn’t expect to need, but that you will need (and that will slow down your build).

Putting GoPros in Milling Machines


Too far away from the light, and the action!

…Because why not?  A lot of people have done it, but what I really wanted was a way to clamp my gopro to the table of the machine- that way I could watch the part form up close, or even choose my angle.  I decided the way to do this was to use the T nuts from the hold down sets we have in the shop. A T nut and a flange nut hold a 1/2″-13 stud to the bed, and then the gopro mount threads onto the top of the stud.


Since it was easier to just throw it on the bridgeport and make it the “right shape”, I decided to avoid the CNC.  After the fact, I modeled it in onshape, and made a drawing to try out their drawing tool.  While I like their modeling tool, the drawing tool seems like it could use some work- it was really slow for some unknown reason, and I really miss the smart dimension tool from solidworks.


Here is the finished mount on the table of the bridgeport.  I hope I get to try it out sometime soon!  Maybe it will capture some cool footage, or maybe it will get thrown back in the scrap bin.  Who knows?


Here is the drawing in case anyone wants to make one.

Gauging Kossel Z Accuracy


The gauge, with its value lasered on

Once I had conductive probing on my Kossel, I thought it would make sense to take stock of the Z accuracy of the machine.  To do this, I wanted to compare two Z heights, but I did not want to measure off of the bed, in case it was scratched or locally not very flat.  So I turned a small piece of scrap aluminum to two diameters, and two lengths.  The top flat is 3.98 mm above the other flat, as measured with a rather cheap micrometer

To test the accuracy of Z height, which should be the “easiest” thing for a kossel to exceed at, I put the gauge under the head at x0 y0 and probed it in Z with my M430 command, which lets me know if the head is touching a grounded part of the machine or not.  Since the conductive gauge is on a conductive build plate, I can tell if I am touching it or not.


After doing a few tests, it seemed like the .01 mm movement had too much hysteresis to be trusted, meaning that my resolution was .1 mm (.0039″).  After several trials, the average value difference between contact on the top and bottom was 4.03 mm, which is pretty dead on- which impressed me.

Kossel Adjustable Bed + Conductive Probing

The bed probing in action!

My Kossel, which I have jokingly named “Screw Loose”, left a lot to be desired when I built it.  One of the major problems I had was print adhesion- or lack thereof.  Even with a heated build plate and kapton, the printer had trouble with peeling and plain not sticking to the bed. I learned what the problem was with a simple test- I went to z0 x0 y0 and moved the head around.  On one side of the bed, the head touched the plate.  On the other side, it moved away from the plate.

After some searching (circa late 2015), I discovered that there were no RAMPS compatible firmwares that had bed tilt compensation for the Kossel, even though .  I am not sure why,  and I think since then this has been rectified in a fork of the marlin firmware.

Instead of trying to have the printer compensate based on readings, I decided to take the mechanical approach of actually making the bed flat to the plane of motion of the head.  The first thing that had to be changed was how the bed was mounted to the frame of the printer- as it was designed, it just bolted straight on with no adjustment, which was a bad decision because it almost guarantees that the build surface will be at an angle.

Bed adjuster, with thumb screws above and below the bed.

Bed adjuster, with thumb screws above and below the bed.

Making the bed adjustable was actually pretty easy.  I put a long, steel 4-40 screw through the original mounting points, and fixed it to the frame with a nut, creating a “stud”.  Using what I had on hand, I made some thumbscrews by laser cutting acrylic and putting it around hex nuts.  This let me easily adjust the bed up and down at the three points it attaches to the frame.

The next step was to set up conductive probing.  I know people have gotten good results with the servo+microswitch, but I after using a renishaw probing system I just cant deal with how floppy it looks, nevermind the extra wire routing.  Conductive probing is actually really easy- I made the mistake of thinking I would have to write some software and started writing my own M code commands, but its actually a hardware solution.

I have no desire to add more wires to this rat nest.

I have no desire to add more wires to this rat nest.

The way bed probing is normally done on the kossel is with a switch mounted on a servo, which is mounted to the print head.  This gets wired to an endstop header on the RAMPS board.  Each endstop has three pins- ground, 5v, and signal.  In order to set up conductive bed leveling, all I had to do was run a wire from the bed to ground, and add a pull up to D18, the pin connected to the “signal” of the endstop header I used.  The code in question is here:

float z_probe() {
feedrate = homing_feedrate[X_AXIS];

enable_endstops(true);                      //Turn endstops ON!
float start_z = current_position[Z_AXIS];
long start_steps = st_get_position(Z_AXIS);

feedrate = homing_feedrate[Z_AXIS]/7;   //Make the speed slow
destination[Z_AXIS] = -20;              //plan to crash into the bed on purpose
st_synchronize();                       //Actually execute crash move
endstops_hit_on_purpose();              //We crashed into the bed on purpose

Before trying this, it is critical to make sure that the bed and head are clean, and that when they touch you actually trigger the endstop.  If the endstop is not triggered, the printer will do its best to drive the print head through the bed, which will leave a dent- I know this from experience.  It’s always a good idea to implement a command like my M430 command in marlin_main.cpp to make sure it is working before running g29 (bed probing).

    case 430: //M430

This snippet lets you know that everything is working by manually moving the head into contact with the bed, and checking to see if D18 changes from high to low.  It it does not change, the the endstop is not being detected and the printer will try to destroy itself- which is bad.

Once everything is working, G29 should probe the bed, and the head should gently “kiss” the bed in a few locations and spit out a map like this:

21:40:47.704 : 0.000 0.000 -0.400 -0.438 -0.400 0.000 0.000
21:40:53.881 : 0.000 -0.337 -0.400 -0.375 -0.387 -0.438 0.000
21:41:02.489 : -0.375 -0.475 -0.400 -0.375 -0.388 -0.400 -0.413
21:41:11.061 : -0.350 -0.413 -0.338 -0.363 -0.400 -0.388 -0.375
21:41:19.624 : -0.312 -0.475 -0.400 -0.388 -0.388 -0.488 -0.388
21:41:25.760 : 0.000 -0.438 -0.375 -0.350 -0.400 -0.313 0.000
21:41:29.438 : 0.000 0.000 -0.350 -0.363 -0.313 0.000 0.000

After some adjusting, it should be possible to get all the numbers really close- as you can see in this printout.  The diameter of the “grid” for these points was ~100mm, and all the points are within about .13 mm, or about .005″, which is pretty good.  NB that there are zeroes in all the corners- with stock firmware, you will have bogus numbers there.  It is easy to change that to setting them to zero, as seen here (note to self: use git in future):

// For unprobed positions just set to zero
if (abs(y) >= 3) {
bed_level[1][y+3] = 0;
bed_level[5][y+3] = 0;
if (abs(y) >=2) {
bed_level[0][y+3] = 0;
bed_level[6][y+3] = 0;

After this, I easily made some decent prints, since it all the layers were even, and the print head never crashed into the plastic!  I highly recommend leveling the bed of your kossel if you have one.

Re-Flashing the Misfit Flash


After a thorough electrical and mechanical investigation of the Flash device, I decided I would do a little more poking around to see if I could download the firmware from the device. In the end I was not successful (although there is hope), but I did manage to put my own firmware on the device quite easily.


I took a multimeter to the tag-connect header to see which pins when where.  It doesen’t look like the normal SWD or JTAG 10 pin connector, but I did find power, ground, SWDIO/RST, and SWDCLK.  For reference, on the drawing above, the single hole of the tag connect is at the top.


I connected a few wires to the programming pins, and then wired those pins to an STLink programmer from one of the STM discovery boards.  Using OpenOCD, I first tried to download the firmware from the chip with dump image- but it came back all zeros (not shown)!  This is because the NRF51822 has a read-protection feature to prevent people from gaining access to your code.  This is configured through the second register in the UICR, RBPCONF.  The UICR starts at 0x10001000, so I started there and read a few registers.  RBPCONF was 0xffff0000, which means that all of the program memory is protected.

after erase

The values in the UICR can only be cleared if the entire program memory is erased, so that’s exactly what I did- nrf51 mass_erase.  With the memory wiped, reading the RBPCONF resulted in 0xFFFFFFFF, the default value of read back protection for code region 0 and all code regions being disabled.


Once it was erased, I checked that I could write to the chip by putting a simple blinking LED program on the chip.  All the program does is sleep and toggle all of the IO pins, but it was enough to show me that everthing was working.  Later on, I can use this program to test what pin goes to what LED, if I want to make a cool blinky display or something.

After talking to my coworker about this, I learned that there is a way to dump the firmware even with the memory protection on.  Since I was already on the prowl to find a non-destroyed flash to reprogram as a cool display, I might go ahead and buy one and see if I can get the firmware out of it after all.

Misfit Flash Teardown


Misfit Flash Teardown!

I was at an REI garage sale and found a Misfit Flash for 10 bucks.  I always loved the Misfit deadfront displays, so I picked it up figuring it would be fun to take apart, especially since I work at a company that specializes in connected devices.  I was surprised when I got home and realized that there is a big difference between the ultra-cool shine, and the much more economical flash.  I still learned a lot and I am glad I got to dive into some hardware that did not already have several big teardowns.


mec layout

Battery, PCB and ring, and bottom

The engineering in the flash is as minimalist as its design.  The almost featureless puck sits about 6mm high and is about 25mm across.  Most of the space is taken up by a battery, which is installed by popping the bottom cover off.


The bottom cover is held in by an annular snap, which is sealed against water by an o-ring that runs around its perimeter.  The snap is molded with two external actions, as you can see from the flash in the groove.  The material is almost without a doubt ABS.


Under the battery cover is the battery, which is attached to the PCB.  To prevent the PCB from falling out, a ring of plastic is heat staked to the “top” plastic which retains the PCB.  This is super obvious in the rightmost photo, where you can see that the case was accidentally melted by the heat stake tool.


I used a razor knife (x-acto #11) to sneak under the ring and cut out the heat stakes.  This let me pop the PCB out after I removed the ring.  The ring is a really small part, but it is important for holding in the PCB, locating the battery and protecting the battery clips!

This leaves the flash at a grand total of three molded parts- but one is a little more complicated than the others.  This is the “face” of the device, which is a translucent, soft-touch plastic (santoprene maybe?) overmolded on a thin piece of ABS.  This outer layer allows the fairly bright LEDS to shine through tiny holes in the ABS, creating a crisp dot on the face of the device.  In the left photo you can see thin walls of the darker soft-touch material in the light wells.  This is was caused by clearance between the ABS insert and the tool that held it.


The overmolding was done carefully to minimize the impact it had on the cosmetic outer surface.  It looks like this edge was used for injecting the plastic, and it was carefully trimmed away later.  The rest of the edge is totally smooth.



Orange: accelerometer, light green: Crystals, dark green: NRF51822 AA model, dark red: RF antenna and balancing network

Compared to something like a phone, there is not a lot going on, but that is not to say that it is not complicated.  On the east side of the board, you can see the RF block and antenna.  To the north, you see a couple of crystals.  The west side is dominated by a QFN which is likely an accelerometer.  Right in the middle, there is a button, and on the south end of the board there is a happy little sputnik.


On the back side of the board, there is a battery holder, a tag-connect 10 pin header, and a nice silkscreen that says it was designed in San Fransisco, along with the initials AR and GR- maybe the initials of the people who did the layout.  When in use, most of this is covered by a big sticker, but I love seeing cool little details like this.

In any battery operated product, less is more.  The flash uses a CR2032 coin cell, which boasts a lofty 225 mAh at 3 volts.  The best AA you can buy in stores- the energizer L91- has about six times as much energy, although comparing batteries is like trying to compare apples to bread- they both have calories but they are processed in very different ways.

To achieve its quoted 6 month lifespan, this means that it has a whopping 15 joules per diem to spend.  That’s insanely low- to put it in perspective, that’s the same amount of energy as it takes to lift a bag of about 7 apples from the floor to the top of the fridge.  Another way to put it would be 1/30,000 th of the kcalories  in an apple.  Anyway, the device has to be designed very carefully to use such a small amount of power.

The most radical part of the power saving strategy is to actually have no voltage regulator.  Many devices have started to use very efficient switching power converters to regulate power, allowing all devices to operate at the voltage they are most efficient at.  However, these converters come with three major costs- money, board space, and quiescent current (power consumed when the converter is idle).  The designers of this board decided to eschew converters, and just choose parts with a wide voltage range, from 1.8V-3V+.


The accelerometer is most likely the LIS2DH from ST Micro.  Adafruit and Sparkfun both mentioned it on their teardowns of the shine, and the package is the same.  The pinout is also identical to what I saw labeled on the board (see photo) in terms of an SPI connection between the microcontroller and the chip.  NB that SPI has a power savings over I2C in terms of not needing pull up resistors.

leds on

The choice to use red leds on the flash is not because it looks cool or sinister, but because much like the the other major components, red LEDs will still work at low voltages.  While or blue LEDs require almost 4V to work, while a nice green led would be in the range of 2.2V.  Red leds have the lowest voltage drop of any color of led, at around 1.7 volts, although they are quite a bit dimmer at low voltages.  This means they will operate down to about the voltage level that the accelerometer does.

At the heart of the device is the beloved NRF51822.  This is a frontrunner in terms of low power bluetooth, with plenty of development kits and even cheap pre-certified modules.  This SoC combines a 32 bit Arm Cortex-M0 with a power sipping 2.4Ghz transceiver.  This is the brain of the device.  Around it, there are a couple of crystals, one at 16 Mhz and one at 32 Mhz.  These allow the chip to sleep at low power for long periods of time.  Also in the constellation of parts surrounding the NRF is an antenna balancing network, and a trace antenna.

Final Thoughts


The Misfit Flash is a neat thing.  I mean that in the fullest sense of the word- it is tidy.  Everything is neatly connected, and everything has a purpose, and the effect is a simple and attractive object.  I never used it for fitness tracking, but I did have a lot of fun just playing with it and watching the LEDS blink.  People who are designing connected hardware would do well to study this exercise in minimalism.