Close

Developing: Testing test patterns

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/27/2017 at 22:120 Comments

I am developing for the Ultratronics v1.0 which is a Arduino Due.

This is done in Visual Studio 2015 and a tool: VisualMicro.

Developing the code is not easy because I have been slamming into a wall for a few days before I started to realize that the compiler may not produce correct code for what I wanted.

It seems that inside classes the C++ does not like "MyClass* myClass=new MyClass()" on the Arduino Due. Dynamic memory allocation seems not to function nicely. Something that would have worked correctly on a Windows C++.

It forced me to a redesign. Less dynamic assigned memory and more static compile time determined memory.

But I have results:

Hooking up the logic analyzer shows the clear test pattern.Each puls is a stepper motor step command.

Zoomed in

Zooming even more in you clearly short pulses that are a bit higher than 2µS.

The code that generates the puls is below. I use one bit per motor to drive the simultaneously. Then a silly loop with a "nop" in it that generates a pulse with that is a bit higher than the required 2µS

void MotorCommand::StepMotorPulseDelay2Micros() {
    // Code blow should be about 2 µS on a 84 Mhz Arduino Due
    for (auto i = 0; i < 36; ++i) {
        asm("nop \n");
    }
}
void MotorCommand::SendMotorStepCommand(byte step_command) {
	// Make the signal high
	SendMotorStepHighCommand(step_command);
	StepMotorPulseDelay2Micros();

	// Make the signal low
	SendMotorStepLowCommand(step_command);
	StepMotorPulseDelay2Micros();
}

void MotorCommand::SendMotorStepHighCommand(byte step_command) {
    byte level = step_command;

    level = step_command & MOTOR_BIT_Z;
    if (level != 0) REG_PIOD_SODR = PIO_PD0;        // Z_AXIS_STEP set to high, bit 7

    level = step_command & MOTOR_BIT_Y;
    if (level != 0) REG_PIOB_SODR = PIO_PB26;        // Y_AXIS_STEP set to high, bit 6

    level = step_command & MOTOR_BIT_X;
    if (level != 0) REG_PIOC_SODR = PIO_PC3;        // X_AXIS_STEP set to high, bit 5

    level = step_command & MOTOR_BIT_E3;
    if (level != 0) REG_PIOC_SODR = PIO_PC7;        // E3_AXIS_STEP set to high; bit 4

    level = step_command & MOTOR_BIT_E2;
    if (level != 0) REG_PIOA_SODR = PIO_PA19;        // E2_AXIS_STEP set to high, bit 3

    level = step_command & MOTOR_BIT_E1;
    if (level != 0) REG_PIOC_SODR = PIO_PC19;        // E1_AXIS_STEP set to high, bit 2

    level = step_command & MOTOR_BIT_E0;
    if (level != 0) REG_PIOC_SODR = PIO_PC16;        // E0_AXIS_STEP set to high, bit 1
}

void MotorCommand::SendMotorStepLowCommand(byte step_command) {
    REG_PIOD_CODR = PIO_PD0;                        // Z_AXIS_STEP set to low
    REG_PIOB_CODR = PIO_PB26;                       // Y_AXIS_STEP set to Low    
    REG_PIOC_CODR = PIO_PC3;                        // X_AXIS_STEP set to Low
    REG_PIOC_CODR = PIO_PC7;                        // E3_AXIS_STEP set to low
    REG_PIOA_CODR = PIO_PA19;                       // E2_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
    return;
}

The idea is to have pre-calculated motor bits ready in memory that can, be read at a fast rate and executed by a timer. The time above is at 32Khz, which means that a 200 Steps motor, at 32 microso-steps has about 5 revolutions per second.

This may seem fast but the Thor robot has geared steps with a 5:1 ration and then we have another gear X:1 slowing it even more. I image think about having to have only 16 or maybe even 1 micro step per motor.


Next step direction and enable control.


Discussions