Sunday, February 10, 2013

Prototype 5-Axis CNC Board

Since I'm working on some CNC firmware, I thought I needed a test platform.  I didn't want to rip-apart the CNC so I decided to build a new 5-axis board using the new Pololu stepper drivers. These are nice little cheap boards and their advantage over the ubiquitous A4988 drivers is that they don't need cooling up to 1.5A per phase.  This makes things way easier, since those tiny little heatsinks for the A4988 chips are scattered all over my apartment, double-sided tape all linted up so they won't stick, just waiting to be stepped on.  They hurt even more than stepping on a Lego block, little buggers.

Anyway, I figured I should just go to five axes, which would allow me to control the 3D printer eventually (1X, 1Y, 2Z, 1E).  So I built a protoboard test board:

I laid out the board and soldered it up.  It was pretty easy except for having to drill a few extra holes in the power-rails to get the spacing I wanted.  After electrically testing everything I decided not to blow all 5 drivers simultaneously on a meticulously copied wiring error, opting instead for only two.

The MCU controlling the whole mess is an Arduino Uno.  I have the step pins on PortD and the direction pins on PortB, which allows fast bitwise operations to be used for stepping.  While picking up the stuff for the prototype board I also bought a proto-screw-shield, wanting a more resilient mounting option for the Uno:

I have the early version of my CNC firmware loaded onto the Arduino.  After firing up the serial terminal, I had the thing running!

Not super crazy, but still rewarding nonetheless.

CNC Firmware running on Arduino Uno

In an earlier post I described some prototype CNC firmware that I had gotten running on the Teensy3.0.  The Teensy3.0 is a 32-bit ARM board and is pretty nice, but I wanted to see if the code would also run on an Arduino Uno.  This is a much more restrictive platform; only 2k of ram and 32k of program space.  However, after a bit of porting of the hardware layer, it compiles and seem to run no problem.  Here's a screen-capture from a (brief) session, the pulse-ticks stuff is debugging the motion control module.

Note that this is running the full GCode interpreter, with spec-compliant command sorting and an 8-move lookahead buffer.  The step timer is running off a 2KHz Timer1 interrupt.  I'm hoping to increase this to 8+ KHz, at least on other platforms, which should make smoother motion control possible, but at the moment I'm just happy that my ANSI C + POSIX code that I've developed on on a 64bit quad core machine with 16Gb ram ports easily to an 8bit system with 2k or ram and only interrupts after changing less than 50 hardware-specific lines of code.

I've written the code this way for just this reason; by keeping all the hardware specific stuff isolated in a hardware abstraction layer I'm hoping to make a code base that stands the test of time, from small embedded platforms to boards like the Raspberry Pi, to full-blown PCs.  So far so good, it's running on an 8bit AVR, a 32 bit embedded ARM and a full X86_64 PC.