Posts Tagged ‘arduino’

rStep assembled and working

November 27th, 2010

I got the parts in from digikey today, and assembled a couple of the rStep boards.  Seems that sanguino uses the 644p and I ordered the 644.  Additionally, I’m clocking the 644 at 20Mhz while the sanguino expects 16Mhz.  I had to make a number of changes to make the 644 work with the arduino.  First, I had to modify the bootloader by adding an entry for the 644 @ 20Mhz, recompiled it, and uploaded it through the JTAG port.  Additionally, the boards.txt file had to be changed to reflect the 644 @ 20Mhz.  Now, it is compatible with the arduino IDE and I was able to compile a simple LED blinking application and upload it without problems.  A few more tests and I’ll be able to send out the beta boards to the developers for further testing.



Electronics, rStep , , , ,

CNC Success

November 14th, 2009


I was showing a friend my progress with the code, and he was complaining that the stepper motors were loud, and suggested I turn on fractional stepping. I switched to 1/16th steps, and he was right, the motors sounded much better. Additionally, the Z-axis magically started working! I was also impressed how well my code handled high stepping rates — well, more surprised that it worked without more surprises. So I’ve passed a big hurdle. I need to test the circle routine (pretty much the only piece of code I’ve not rewritten from the original code base), do some more tests, and try milling my first PCB!

Here’s a quick video demonstrating it moving in 3 axis at different rates, 1/16th step.

You can browse the latest version of the code here:

Electronics , , , ,

Stepper Motor Controller Update

November 13th, 2009

It’s a step forward, two steps back. I burnt out one of the channels running some preliminary tests, and I just got the replacement board in from Spent longer than I wanted trying to hook it up (note to self: don’t use such low gague wire). But I was still seeing more jitter in the clocking than I wanted. I tried a few different configurations, and finally came up with an approach that seems to work well, and exhibits a jitter equal to the resolution of the micros() call (4uS). In this approach, it computes the time when the next step happens, figures out which channel needs to step next, then waits for that time in a tight loop:

// start move
while (xaxis->delta_steps || yaxis->delta_steps || zaxis->delta_steps) {
        a = nextEvent();
        while (micros() < (starttime + a->nextEvent) ); //wait till next action is required
        if (can_move(a)) {
                _STEP_PORT |= a->direct_step_pin;
                //need to wait 1uS
                _STEP_PORT &= ~a->direct_step_pin;
        if (--a->delta_steps) {
                a->nextEvent += a->timePerStep;
        } else {
                a->nextEvent = 0xFFFFFFFF;

The latest version of the code is checked into SVN on google code.

So anyhow, I get everything working nicely only to find that the Z-axis controller is also fried — these guys are way too sensitive. Need to order yet another board.


Electronics , ,

Stepper Motor Controller Code Update

October 15th, 2009

Just a quick update, I’ve added support for limit switches in the firmware. Enable them by specifying the associated pin, and if it’s active high or active low.  The preferred method is active low otherwise you need to add your own pulldown resistor if it’s active high.

// specify min-max sense pins or 0 if not used
// specify if the pin is to to detect a switch closing when
// the signal is high using the syntax
// #define MIN_X 12 | ACTIVE_HIGH
// or to sense a low signal (preferred!!!)
// #define MIN_Y 13 | ACTIVE_LOW
// active low is preferred as it will cause the AVR to use it's internal pullups to
// avoid bounce on the line.  If you want active_high, then you must add external pulldowns
// to avoid false signals.
#define ACTIVE_HIGH _BV(7)
#define ACTIVE_LOW  _BV(6)
#define MIN_X 0
#define MAX_X 0
#define MIN_Y 0
#define MAX_Y 0
#define MIN_Z 0
#define MAX_Z 0

Electronics ,

Stepper Motor Controller Update

October 5th, 2009

I’ve recently posted about my new stepper motor controller. Well, I was unhappy with the implementation used in the RepRap project, and what started as a code cleanup has turned into a near full rewrite. I’m fairly happy with the code now and finished my preliminary testing. I based my original version of the re-written code turned out to be a variant of Bresenham’s algorithm (though I found this out after I had written the code). The algorythm would determine the axis which required the most travel, step that axis, then add the required travel from one of the other axis to an error term for that axis. When the error term was equal to or greater than one, it would step that axis and subtract one from the error term. This resulted in stepping synchronized with the major axis timebase. Looking at the output of the stepper motor driver, this pattern emerged.

steppring rates.jpg

Here the G-Code command was “G1 X3 Y2 Z1” — and indeed the ratio of steps is 3:2:1, but notice that the Y-steps are required to align with the X-Steps (master axis because it moves the furthest), but because 3 is not divisible by 2, it skips every third step. This motion is bad for the stepper motor, and it can cause all sorts of problems.

It is *extremely* important the steps be evenly spaced, unless you’ll be content with slow, unreliable operation. Jitter in the step pulse train will limit your top speed, as it *will* cause the stepper to stall. -Ray L.

So I spent some time thinking about it, and came to the conclusion that the Bresenham’s Algorithm only makes sense if you are dealing with a pixelated output (its main purpose is for fast rendering of lines on computer screens). I realized that I needed was a temporal based one, and came up with something. I still need to do a literature search to see if someone has come up with it yet (would be surprising if no one has) but this is basically what I came up with.

  1. Determine the number of steps per axis
  2. Determine the distance of travel for the command, and based on the feedrate, compute the duration of the command.
  3. Compute the time between steps (TBS) for each axis (duration / steps)
  4. Start the main loop.
    1. If the time elapsed is equal to 1/2 the TBS, then step that particular axis.
    2. Wait 1/2 TBS, then go to step 5.

I prototyped this in python, and came up with

maxtime = 100.0; #duration of motion in microseconds
steps = 41.0;  #number of y steps
timePERstep = maxtime/steps; #time per step
stepped = 0;
oldTimeIntoSlice = 0;
for time in range(0,int(maxtime)):
        timeIntoSlice = (time%timePERstep);
        if (timeIntoSlice < oldTimeIntoSlice):
                stepped = 0;
        oldTimeIntoSlice = timeIntoSlice
        if (timeIntoSlice >= 0.5*timePERstep) and (stepped == 0):
                        #print 'step'
                        stepped = 1;
                        y = y + 1;
        print '%d,%d' % (time,y)

Which generated this sort of a stepping profile. Notice that the steps are pretty evenly spread out..


After rewriting the arduino code, I tried the same test (with G1 X1 Y2 Z3 this time) and got much better results

temporal stepping.jpg

Notice how everything is nicely spread out. Looking at the timestamps, the maximum step jitter is about 150uS. The next step is to hook this up to some stepper motors and see what it does.

I’ve also released the code for the arduino here in case it might be of help to anyone. I’m thinking of making a daughter board for the arduino with the stepper controller ICs on it in order to simplify deployment for others — if there is interest.

Electronics , , , , ,

Arduino-Based Stepper Motor Controller

September 24th, 2009



Decided to drop my PCB and use some prebuilt modules from pololu. Doing the math, this turned out to be the cheapest option (3x$13 vs. $50 for the PCB plus another $30-$50 to populate). The pololu modules use Allegro’s A4983 intgrated h-bridge drivers rated at up to 2A – which amazes me given the size of the ICs. I’m a bit worried but I suspect that they’ve already been tested. I’m going to power it with a +/- 15V 3A supply I have, and use the g-code parser from the reprap project.

Electronics , , ,