Code: Select all
long steps[3000][4];
long stepcount=0;
void ticky(int phase)
{
steps[stepcount][0] = phase;
steps[stepcount][1] = CurrentTick();
steps[stepcount][2] = MotorRotationCount(OUT_B);
steps[stepcount][3] = MotorPower(OUT_B);
stepcount++;
}
Code: Select all
void RotateMotorRURD2(byte output,
char pwr,
long angle,
bool UseSpeedControl = true,
bool BrakeAtEnd = true)
{
long l1, l2, l3;
char power = sign(angle);
angle = abs(angle);
power *= pwr;
if (angle > 720)
l1 = angle*0.10;
else
l1 = angle*0.20;
l3 = l1;
l2 = angle-(l1+l3);
byte om = OUT_MODE_MOTORON|OUT_MODE_BRAKE;
byte rm = OUT_REGMODE_IDLE;
if (UseSpeedControl) {
om += OUT_MODE_REGULATED;
rm = OUT_REGMODE_SPEED;
}
// we want to rotate a total of <angle> degrees
// we'll rampup from 0 power to specified power through 20% of the angle
// then run at the specified power for 60% of the angle
SetOutput(output, OutputModeField, om,
TachoLimitField, l1,
PowerField, power,
RegModeField, rm,
RunStateField, OUT_RUNSTATE_RAMPUP,
UpdateFlagsField, UF_UPDATE_MODE|UF_UPDATE_SPEED|UF_UPDATE_TACHO_LIMIT);
Yield(); // give firmware a chance to process this request to update motor state
// monitor runstate
while(MotorRunState(output) <> OUT_RUNSTATE_IDLE)
{ticky(1);
Wait(10);}
// as soon as it goes idle put the motor into the running state
SetOutput(output, OutputModeField, om,
TachoLimitField, l2,
PowerField, power,
RegModeField, rm,
RunStateField, OUT_RUNSTATE_RUNNING,
UpdateFlagsField, UF_UPDATE_MODE|UF_UPDATE_SPEED|UF_UPDATE_TACHO_LIMIT);
Yield(); // give firmware a chance to process this request to update motor state
// monitor runstate
while(MotorRunState(output) <> OUT_RUNSTATE_IDLE)
{ticky(2);
Wait(10);}
// as soon as the runstate goes idle we rampdown to zero power
SetOutput(output, OutputModeField, om,
TachoLimitField, l3,
PowerField, 0,
RegModeField, rm,
RunStateField, OUT_RUNSTATE_RAMPDOWN,
UpdateFlagsField, UF_UPDATE_MODE|UF_UPDATE_SPEED|UF_UPDATE_TACHO_LIMIT);
Yield(); // give firmware a chance to process this request to update motor state
// monitor runstate
while(MotorRunState(output) <> OUT_RUNSTATE_IDLE)
{ticky(3);
Wait(10);}
// now apply powered braking for a little while
SetOutput(output, OutputModeField, OUT_MODE_MOTORON+OUT_MODE_BRAKE+OUT_MODE_REGULATED,
TachoLimitField, 0,
PowerField, 0,
RegModeField, OUT_REGMODE_SPEED,
RunStateField, OUT_RUNSTATE_RUNNING,
UpdateFlagsField, UF_UPDATE_MODE|UF_UPDATE_SPEED|UF_UPDATE_TACHO_LIMIT);
Yield(); // give firmware a chance to process this request to update motor state
// Wait until the motor has stopped turning.
long rc = MotorRotationCount(output);
long oldrc = rc+1;
while (oldrc <> rc) {
oldrc = rc;
ticky(4);
Wait(100); // adjust this wait time to see what impact it has on accuracy.
rc = MotorRotationCount(output);
}
if (!BrakeAtEnd) {
// finally, go idle
SetOutput(output, OutputModeField, OUT_MODE_COAST+OUT_MODE_REGULATED,
TachoLimitField, 0,
PowerField, 0,
RegModeField, OUT_REGMODE_SPEED,
RunStateField, OUT_RUNSTATE_IDLE,
UpdateFlagsField, UF_UPDATE_MODE);
Yield(); // give firmware a chance to process this request to update motor state
}
ticky(5);
}
1) The ramp up phase shows the acceleration expected.
2) The speed during the constant run phase is about .7 deg/ms.
3) It continued .7 deg/ms in the ramp down phase, all the way to the end of the requested angle, at which point it slammed on the brakes.
Since the motor is running full blast at the end of the angle, it overshoots by about 40 degrees, then has to bounce a couple of times to get to the proper angle, which it does.
The "power" value wasn't all that interesting because it was -75 through phases 1 & 2, then 0 during phases 3-5.
(In case anyone wonders, I spent about 8 years as a performance analyst with IBM. )