Close

A solution: More efficient stepper motor control

A project log for Building the Thor robot

Building a 6-axis robot based on the Thor robot. When size DOES matter!

olaf-baeyensOlaf Baeyens 05/13/2017 at 22:421 Comment

Using this method we lose about 5µS per stepper motor we want to control.

digitalWrite(X_AXIS_STEP, level);
As sampled by the logic analyzer below.

Each stepper motor gets a pulse 2µS later than the previous one accumulating a delay.

This puts our robot in a wait state that could have been used for productively instead.


But we found a way to control the Due processor directly.
The documentation was a bit confusing and information is hard to find but this is the key.

    REG_PIOC_SODR = PIO_PC3;		// X_AXIS_STEP set to high
    digitalWrite(E0_AXIS_STEP, 0);      // Delay 2 micro seconds
    REG_PIOC_CODR = PIO_PC3;            // X_AXIS_STEP set to Low

We use direct port mapping and write the bit directly to the PIO.

And for 7 stepper motors we end up with something below. We lose 0.2 µS instead of

The code that was executes is seen below.
However it does not explain why we have differences in ending of the pulses. The smaller pulse is only 1.76 µS which may be a bit too short.

void MotorExecutionBlock::SendMotorStepCommand(byte step_command) {
	REG_PIOC_SODR = PIO_PC3;		    // X_AXIS_STEP set to high
	REG_PIOB_SODR = PIO_PB26;		    // Y_AXIS_STEP set to high
	REG_PIOD_SODR = PIO_PD0;		    // Z_AXIS_STEP set to high
	REG_PIOC_SODR = PIO_PC16;		    // E0_AXIS_STEP set to high
        REG_PIOC_SODR = PIO_PC19;		    // E1_AXIS_STEP set to high
	REG_PIOA_SODR = PIO_PA19;		    // E2_AXIS_STEP set to high
	REG_PIOC_SODR = PIO_PC7;		    // E3_AXIS_STEP set to high

	// Delay 2 micro seconds
	digitalWrite(E0_AXIS_STEP, 0);

	REG_PIOC_CODR = PIO_PC3;		    // X_AXIS_STEP set to Low
	REG_PIOB_CODR = PIO_PB26;		    // Y_AXIS_STEP set to Low	
	REG_PIOD_CODR = PIO_PD0;		    // Z_AXIS_STEP set to low
	REG_PIOC_CODR = PIO_PC16;		    // E0_AXIS_STEP set to low
	REG_PIOC_CODR = PIO_PC19;		    // E1_AXIS_STEP set to low
	REG_PIOA_CODR = PIO_PA19;		    // E2_AXIS_STEP set to low
	REG_PIOC_CODR = PIO_PC7;		    // E3_AXIS_STEP set to low
}

We can optimize even more because some bits are mapped to the same PIO (e.g. 4 bits to PIOC), gaining 4x40=160 ns.

The only question is: Does the power supply and motherboard handle 7 simultaneous steps easily?

Discussions

Naturobotic wrote 02/15/2018 at 14:00 point

You are killing it!
Great work

  Are you sure? yes | no