8 9 Keychain Giveaway

2 years ago @npcmusic brought us the wonderful Here Right Now under his newsroom project, 8 9.

1 year ago he topped himself with Geocity Skylines complete with this amazing commercial.

And despite the inherent uncertainty that 2020 has brought us the highly anticipated The Third Album.

To celebrate, I’m going to be giving away 89 of these 8 9 keychains I printed.


To get your keychain use the form below to send me your info and I’ll get the keychain made and sent. You can alternatively email the info to This email address is being protected from spambots. You need JavaScript enabled to view it.

Want more than one? If you buy any of the 8 9 Albums, you can get up to 10 keychains! I'll also be entertaining the idea of design tweaks or different colors for people who have bought an album (no promises). Just e-mail me you're receipt and request.

STLs coming soon!

HeatSync Ulitmaker2 Underextrusion

I had seen on the HeatSync Slack that we were having some issues with the 3D printers. The next time I stopped at at Heat Sync, I saw the Ultimaker 2 just had a note:

Underextruding :(

So the next week I made a date with the UM2 to see what was going on. First thing was first: test print. As a first test for just about any FFF printer I like to slice the following gcode

  • 20mm Cube
  • Vase Mode*
  • 1 base layer
  • 0 top layers
  • ~.2 layer height
*A.K.A. Corkscrew mode A.K.A. single perimeter A.K.A. spiraled contour mode

I like this kind of print since it's fast, and you can get a lot of information from it. In this case I wanted to see how bad the underextrusion was, and with the first print I got this:


First thing's first, check the basics. PLA was loaded, settings on the printer matched. Cooling fans were working correctly and running unload/reload showed that the extruder itself was (probably) working fine. But once the filament hit the hotend the extruder started having a hard time pushing, which meant that there was be a problem with the extruder or that there was a jam in the hotend. As the latter was far more likely, I started with some basic operations to try to unclog the hotend.

Just incase the printer had been loaded with ABS or another material that needs a higher temp, I heated up the extruder to 265 and extruded several hundred millimeters or plastic. When that didn't help much, I tried Ultimaker's Atomic Method (which is more or less a manual cold-pull). While this did pull out a bunch of dirt, The printer was still having extrusion problems.


At this point if I had a new nozzle I would have tried that - but if there are any spares, I don't know where they are. So I took apart the hotend

  • Remove the 4 phillips screws connecting the fan shroud to the toolhead
  • Remove the 4 hand screws to disconnect the heatsink/hotend from the toolhead
  • Remove the 2 M2.5 bolts from the top plate that connects to the heatsink
  • Remove the phillips screw what goes through the hotend into the bottom heatsink plate
  • Unscrew the heater block from the coupler on the other side of the heatsink plate

Note: The heater cartridge and RTD are held in with friction and hope, so they may pop out on you.

Once I had the hotend free I used the hot air rework gun to heat the inside of the nozzle. A mix of cold pulls, tiny picks, a tiny drill and some percussive maintenance left me with a clean(er) nozzle.

I reassembled the hotend and re-ran my cube. Finally, there was a vast improvement over the original. There was still one spot that had some small underextrusion, but I saw a similar spot on the second print at the same spot, which makes me think there could be an overflow in the firmare or the extrusion just needs some fine tuning (rather than continued nozzle jamming). Though we should still get some new hotends to be safe.


The other problem with the print was that the first layer was awful. I'm guessing that when I reassembled the toolhead, I inadvertently changed the height.

Running the UM2's bed adjustment (on the LCD menu, Maintenance -> Build Plate) was very easy. At first I decided not to mess with the set screws, but after my first print showed up lopsided I went through the whole thing and was pretty happy with the results - for my final print I did the same cube, except wider (100mm in X/Y) and about twice height (40mm in Z).


So I'll leave it to run overday with a "real" test print. Hopefully it stays working for me to see what's going on with my nemesis The Choocher.

HeatSync CooCheer Printer Repairs

A couple of weeks ago I was at Heat Sync labs during open hours and a couple of guys were having problems with the CooCheer printer. I hadn’t printed with it before but I decided to take a look.


The main issues at the time were

  1. The coocheer has no way to load/unload filament from the LCD
  2. Connecting to the printer from my laptop would crash my laptop
  3. The wire connecting the control board to the bed’s heater pad was disconnected / melted.

Obviously #3 is a big problem, and had to be solved first. I’ve seen this kind of melting before on pluggable terminal blocks. Usually the problem is that the stranded wire is only contacting on a couple of strands, which can lead to the strands heating up and slowly melting the connector. Oxidation on the strands can also cause a similar problem. Sometimes however, the connector is just not rated correctly so too much power goes through and melts the connector. .

Just adding a ferrule to the wires and putting on a new connector would likely fix this problem, but I had am external MOSFET board meant for powering a bed heater, so I decided to get that hooked up.


-12 gauge silicon wire
Note - 14 gauge would probable have been a better pick as it met the power requirements and wold work better with the terminals I had.

-8-10 stud size Insulated Spade Terminals

-BIQU btmos v2
Note - there are newer models out there, this is just the one I had one hand.

-Misc ferrules and an extra pluggable terminal block found at Heat Sync



Here’s a simplified block diagram of the wiring. The 12v supply had empty terminals so I decided to wire directly from there instead of trying to piggyback of the 12v input on the main boards to help balance the power lines.

Ideally I would gotten the 5v control signal directly from the board, or reprogrammed an empty pin and controlled the BTMOS from that. Getting the control signal before the board’s built in MOSFET would involve an ugly solder job, and extra pins on the ANET board are in short supply. So while this might change in the future, I’ve decided to control the BTMOS directly from the FET output on the control board. There will be hardly any power draw, so the port melting again is not a concern.

Luckily the BTMOS accepts 12v in, so wiring directly to the FET output was not a problem. The BTMOS does not have markings for polarity on the input because it doesn’t matter, as there’s board compensates if the polarity is ‘wrong’.

The Coocher’s HBP has six wires coming off of it - 2 are form thermistor and the other 4 are for power. I haven’t yet checked if this is because it has two separate circuits or if the extra wires are just for balancing the power of one circuit on two sets of wire. Either way, I connected both positives together onto the positive output of the BTMOS and both negatives to the negative output on the BTMOS.

Following Jasper’s advice (and my own experience) I decided to put connectors on all the stranded-wire connections on the printer.


    2 x 24v lines (board side) 2 x Hotend lines(controller side)

Spade/fork terminals

  • 3 x AC input lines
  • 2 x 24v lines (power supply side)
  • 2 x Build Platform Heater (controller side)

Fixing What I Broke


During my various fixes I managed to crack one of the acrylic pieces holding the Z-Motor. Luckily there was some scrap acrylic in the lab and I cut a replacement part on the laser CNC. I used a part from this project and converted the STL to a DXF so I could cut it on the laser. Hopefully no one minds the new clear look.


After setting everything else I set the starting height and the bed level by eye. It’s not the best way to do it, but it’s good enough for a first print. I’d like to take another pass at leveling the bed and setting the starting height, possibly using some calibration prints. I’m a little spoiled with my M3-ID’s touch probe and built in calibration prints, but I might be able to adapt something for the Coocheer.



I had to leave before the first print was done, but the first layer was…ok. It was at least good enough that the first several layers looked good. I’ll post an update when I retrieve the first print.

To do

Firmware Update

I need to do some research on what version of firmware the board might have (an “M115” just responds “ANET anet3d.com”). But I’d like to load some new firmware onto the board, if only to add more options to the LCD (like load/unload filament)

control board

I originally intended to replace the electronics on the printer. I have a RAMBo I can donate to the project, or a board with some nice TMC drivers would be great. However all of these options mean some significant changes to the machine. None are directly compatible with the A8’s LCD (at least without re-wiring ) and some boards have some drastically different configuration methods. So for now I’m going to leave the stock board on there.


I love Octoprint. Organizing, starting and monitoring prints is so much easier, and the plugin system makes it really easy to add notifications/ triggers and other cool features. I’m going to get a Pi 2 or 3 and then get Octoprint running in the near future.


This machine needs some documentation for Heat Sync users, so after I hunt down any existing docs, I’ll get to work on that.

I really prefer to set starting height with a firmware offset as opposed to a physical screw offset like in the Coocheer. The screw is vulnerable to vibration / changing the starting height. This will need several changes though (physical, software, firmware) or just a new Z-home indicator like a probe.

I really like the Nextion LCD so that octoprint can be controlled without needing to login from a computer.

Overall the machine could probably use a tune-up in terms of rods and belts, but that’s for another day.

Misc - Computer Shutdown

Earlier I mentioned that my computer would reboot after plugging into the A8’s board over USB. It turns out I had an old driver on my Mac for the CH340. I updated the driver and now I can communicate with the printer.


Some notes on my Life as a Lifer

Arm Link Updates

We recently updated the RobotGeek Snapper Arm with a new gripper, so I've been off in documentation land, getting everything happy for the new change. This inevitable led me to doing some work on the Arm Link Software. I have a love hate relationship with my little arm link program, but it works, so why not?


So first up didn't actually have a whole lot to do with the software, but the Snapper firmware. Andrew wrote all of the IK code for the Snapper, but never implemented Cylindrical or Backhoe modes. Backhoe mode is obviously pretty easy - just map the arm link packets to the servo joints. Cylindrical wasn't bad either, as Andrew had done all the IK work (the code is very similar to the code for the Cartesian X/Y/Z IK, only you ignore the X axis). The pain was going through the code and making it ready for multiple modes. A tedious hour later, I had everything working smoothly.

On the Arm Link side, it didn't take much to get things working. I had disabled cylindrical and backhoe mode on the snapper, so I quickly re-enabled them and added in all of the limits.

Of course an update like this turns into a black hole of updates. I had to update the ArmLink reference page for the new features, commands, and limits. Then I had to add the cylindrical IK engine into the main joystick IK software. And while I was at it I added the backhoe to joystick (which had previously been its own sketch). And then I updated that documentation. It never ends.

We make binary executables available for ArmLink, so making updates can be a little bit of a pain. It's nothing herculean, but to get java embedded with the app I need to build it on each target platform (once on Mac, once on Linux, once on Windows). So I try to wrap up multiple updates in one release when possible. So I decided to move onto a couple of things I've wanted to fix/change in the software.

Too Many Updates!

There are two ways to send positional updates to the arms - you can hit the Update button to send the current values, or you can check the Auto Update box. If you check the box, the positions will automatically be sent to the arm. If you lower the transition time (the delta) then you can get the arm to react in real time with your sliders and knobs. This feature works, but I found out that under certain positions that you could start to have problems. I'll go into more details in a later post, but with our Arm Link packet, if you send the same packet multiple times, and the packet has too many '0xff'/255 bytes, it is possible to read the last half of one packet and the first half of the next as a 'valid' packet. This can lead to some bad situations like arms repeatedly pounding the table. I'm still ruminating on ways to fix this on the packet side, but I decided that an easy fix on the software side would be to only send positional packets if a position was actually going to change. So every loop I check the current values against the last values - if there's a change, I send a packet. If not, I go on with my life. Either way I store the packets away to check against next time. This has fixed most my problems, though I'm still investigating an issue where two many '0xff' can freeze the arm temporarily.

Reading Registers and More

Finally I got to add something fun that I've wanted to add for a while. For the InterbotiX arms that use DYNAMIXEL I've gotten a couple of questions about accessing the servos directly. Basically each DYNAMIXEL serveo is a smart servo with a micro controller on board. There's all sorts of data that you can poll the servo for like position, temperature torque, and more. You can also set parameters like compliance on AX servos and PID settings on MX servos. But to get at any of this you need to work at the firmware/arbotix level. After another request for the feature last week I finally decided to implement the future.

On the firmware side I added two new instructions in the inputContro.h file. The first will get data from the servo / register that you request from (instruction 0x81). The second instruction(0x82) will set data to a servo/register that you set. To pass the data I'm just using the packets normally reserved for X/Y/Z/Wrist for the parameters Id/RegisterNumber/Length/value.

So before I started integration into ArmLink, I wanted to do some testing. The easiest way would probably have been to fire up Cool Term and write out the packets to send to the arm, but I'm a masochist so I started ANOTHER project- Arm Link Barebones. Arm Link started as a basic demo both Interface wise and code wise. And while the code is readable, it jumps through a ton of hoops, so there's a lot to wade through if you're a developer and you just want the minimum example to get going. So Arm Link Barebones is just that, a really basic example of how to control the arm. There's no GUI, just some functions to talk to the arm over serial. Eventually I'll wrap it up in a nice library, but it's a decent stop gap.

Really starting Arm Link Barebones wasn't a big deal, I just ripped up a copy of Arm Link proper. So another hour later I had Arm Link Barebones sending commands to the arm. A few more functions added and there I was blinking servo LEDs and reading firmware versions from my computer. Huzzah!

When I started working on the get/set registers I didn't even plan to integrate it into Arm Link, but I took it that far, so I went just a little further. Really the biggest pain was integrating everything into the GUI. It's kinda cramped as is, and I really didn't want to re-arrange the whole gui. But after some 'creative' moving I finally got all of my fields in. I'm at home right now, and I did a lot of testing by putting some Arm firmware on a spare Geekduino, but I need to actually test it on a real arm. So keep your fingers crossed, hopefully I'll have a release tommorow.

Now keep in mind that I really want to move the Arm Link software over to a chrome app. I think for a demo that chrome apps have everything I need, are cross platform, and super easy to update/do gui stuff. Maybe next time

Custom Error Messages in Arduino


`The Setup: our Arm Link Firmware supports 3 different arms. A one line #define

//#define PINCHER
//#define REACTOR
//#define WIDOWX

Just uncomment the line for your arm and you're good to go, the firmware takes care of all the work for picking the arm.

The Problem: If you try to compile the code you get a slew of unhelpful errors, starting with ...

In file included from InputControl.h:4,
                 from InterbotixArmLinkSerial.ino:72:
Kinematics.h: In function 'uint8_t doArmIK(boolean, int, int, int, int)':
Kinematics.h:101: error: 'WristLength' was not declared in this scope
Kinematics.h:102: error: 'BaseHeight' was not declared in this scope
Kinematics.h:106: error: 'ShoulderLength' was not declared in this scope
Kinematics.h:106: error: 'ElbowLength' was not declared in this scope
Kinematics.h:143: error: 'BASE_N' was not declared in this scope
Kinematics.h:143: error: 'BASE_MIN' was not declared in this scope
Kinematics.h:143: error: 'BASE_MAX' was not declared in this scope

and going on for several dozen lines. Now if you've read the Setup guide then you should know that you have to uncomment a line for your arm. But what if you didn't? Or what if you forgot? How can we make this a better user experience?

A while back I did some searching for 'Custom Arduino Errors' and the like, but I never found much. But last month while looking at the Razor AHRS Firmware I found exactly what I needed

// Check if hardware version code is defined
  // Generate compile error

You see, the Razor AHRS Firmware supports a bunch of different hardware, so at the very top of the file you need to define which hardware you're using (sounds familiar, eh?). So the little block above throws an error and stops the user if the hardware wan't defined. And it's a totally custom message, so you can explicitly tell the user what the problem is. Since this code lets you throw custom errors based on pre-processor defines. So now the Arm Link code looks like

#define PINCHER 1
#define REACTOR 2
#define WIDOWX 3

//uncomment one of the following lines depending on which arm you want to use

#if !defined(ARMTYPE) 
   #error YOU HAVE TO SELECT THE ARM YOU ARE USING! Uncomment the correct line above for your arm

Later in the code we can check the type of the arm (see GlobalArm.h)


  #define ARMID       1
  #define CNT_SERVOS  5 //(sizeof(pgm_axdIDs)/sizeof(pgm_axdIDs[0]))

It is worth noting that the firmware should probably be doing a check against the servos that it sees and not engaging unless it sees all the servos. Though this would cause a whole different issue - code running on the robot but no good way to tell the user that servo discovery has found a problem. But that's a quest for next time I guess.

Get A Grip

IMG_5626.jpg IMG_5627.jpg

With one of our crew out, I've been working double duty all week, so I don't have all too much to report on this week. One of the things that came up is the need for something a little more robust then the RobotGeek Gripper for our RobotGeek line. The InterbotiX line has the Parallel Gripper, and we actually made some prototypes that use that gripper with RobotGeek servos a while back, but it never really went anywhere. Upon revisiting the project with our slightly newer, slightly stronger servos, we found that it actually works out pretty well. We made a jig for drilling the extra holes needed, and made some new prototypes. Matt came up with some clever ways to mount everything and the gripper seems to do pretty well.

I toyed around a little with the 3D printer over the week, intent on making some new gripper fingers. I started of by printing the original finger file, which turned out decently. I think opening up the rails would make it move smoother, but I also had a sanded-down bottom plate it could attach to, so I forged ahead. I tried a couple of other designs.


A parallel gripper works by connecting the servo motor horn to two swings arms. The swing arms then connect to two finger pieces. The finger pieces are on a plate with parallel rails. As the servo rotate, the swings arms bring the finger plates in or push them out. This means that the maximum movement of the fingers is defined by the servo rotation and the swing arm length. So by changing the size and shape of the fingers, you can change the size of the object you can grip. But since the overall distance the arms move doesn't change, this means that you can only grip objects in a range. So If I can normally grip objects between 0 and 25mm, and I modify my fingers to be 25mm apart, I can only grip things from 25mm to 50mm. Anything below 25mm wide and I won't be able to grab them. For some tasks, this works out.

Matt is experimenting with cutting/modding the existing fingers and has had some luck. He also had the idea to mount 3D attachments to the cut-down fingers, so I printed out some fingers designed for a soda can. I didn't put much thought into the design, so it's kinda ugly. Because the gripper has such a small travel, I don't think this gripper will really work - you'd have to be super accurate or you'd be more likely to spill the can before you could pick it up


Still, there are a lot of grippers you could design that would be actually useful. We've got a couple secret designs in the work. Hopefully next week I'll be able to share some more as well as some improvements to our other 'bots.


Crazy Quadruped


This isn't the First Time I've tried to get a RobotGeek Crawler going. I toyed with the idea of a MK-II style crawler, and later a MK-I style quad (because of the lack of 45 degree brackets for RobotGeek). At one point I passed it off to Wade who tried some head-crab like machinations

None of that really went anywhere though. But last week I was thinking about what I could do to make a simple 2-degrees of freedom(dof) quadruped. So that means each leg would get 2 servos, so a total of 8 servos. On your standard Arduino/ ATMEGA 328 you get 6 hardware PWM channels - so you can control up to 6 servos. There are lots of ways to do PWM in software like KurrtE's ServoEX Library, though it will take up some processing power. Still, being able to control 8 servos with no additional hardware is great for keeping the cost down.

I started off with a really simple design shown in the first picture. The body plates Kevin cut me for other experiments. Basically it's the body plates for the PhantomX Quad with the centimeter grid pattern and servo slots for RobotGeek Servos. The coxa to femur is just a dual hinge bracket. The femur extensions are actually plates from the RobotGeek Snapper Arm. Part of me wants to do some alternative designs (swap the coxa/femur ), but that makes mounting harder, so I'll probably stick with the current design.


It was the weekend, so rather than wait for Kevin to cut me some plates, I fired up the 3d Printer and made some plates for the femur extensions / feet. Just a simple taper, a little reminiscent of the MK-I feet. I'm still considering some other options (flipping the femur servo, making the extensions longer, etc) but it's a start.


So the million dollar questions is - Does it walk?. Well, no, not yet. I've got it moving around and doing some motions, but nothing too fun. I'm doing a lot of reading in Inverse Kinematics, and I've got a super simple solver for a 2dof leg to make it move to a position in xyz space. Now I'm trying to figure out exactly how I turn that into consistent movement on the crawler. I'm going to start with rotating the body and the move onto walking. I've been walking through the NUKE generated code that we use for the 3 dof crawlers, which has been useful - I just have a ways to go.

So if I'm still working on this next week, maybe I'll have it shambling around. I'm also thinking about a couple different walker type robots that might be fun, but I want to see where this one goes.