# Slew Rate modification

My team and I were researching about preventing our PTC fuse from tripping, and stumbled upon @jpearman 's work of art. Of course, most of you have probably seen it before:

``````#define MOTOR_NUM               ((int) kNumbOfTotalMotors)
#define MOTOR_MAX_VALUE         127
#define MOTOR_MIN_VALUE         (-127)
#define MOTOR_DEFAULT_SLEW_RATE 10      // Default will cause 375mS from full fwd to rev
#define MOTOR_FAST_SLEW_RATE    256     // essentially off
#define MOTOR_TASK_DELAY        15      // task 1/frequency in mS (about 66Hz)
#define MOTOR_DEADBAND          10

// Array to hold requested speed for the motors
int motorReq MOTOR_NUM ];

// Array to hold "slew rate" for the motors, the maximum change every time the task
// runs checking current mootor speed.
int motorSlew MOTOR_NUM ];

task MotorSlewRateTask()
{
int motorIndex;
int motorTmp;

// Initialize stuff
for(motorIndex=0;motorIndex<MOTOR_NUM;motorIndex++)
{
motorReq[motorIndex] = 0;
motorSlew[motorIndex] = MOTOR_DEFAULT_SLEW_RATE;
}

// run task until stopped
while( true )
{
// run loop for every motor
for( motorIndex=0; motorIndex<MOTOR_NUM; motorIndex++)
{
// So we don't keep accessing the internal storage
motorTmp = motor motorIndex ];

// Do we need to change the motor value ?
if( motorTmp != motorReq[motorIndex] )
{
// increasing motor value
if( motorReq[motorIndex] > motorTmp )
{
motorTmp += motorSlew[motorIndex];
// limit
if( motorTmp > motorReq[motorIndex] )
motorTmp = motorReq[motorIndex];
}

// decreasing motor value
if( motorReq[motorIndex] < motorTmp )
{
motorTmp -= motorSlew[motorIndex];
// limit
if( motorTmp < motorReq[motorIndex] )
motorTmp = motorReq[motorIndex];
}

// finally set motor
motor[motorIndex] = motorTmp;
}
}

// Wait approx the speed of motor update over the spi bus
wait1Msec( MOTOR_TASK_DELAY );
}
}
``````

When we added this into our code, we saw a huge improvement on our lift. Now, we just have two more questions, is there any variable we can play around with, and kind of ‘tune’ to our specific application that is in the definition block, because it does still stall a little (although less often). Also, is there a way that we can write this code so that it only applies to our one lift motor, instead of everything?
Thanks

For that task to provide slew control, you must have driver control code relate to the motorReq array. Instead of

``````
motor[liftMotor1] = vexRT[Ch1];

``````

you would write

``````
motorReq[liftMotor1] = vexRT[Ch1];

``````

. Using motorReq in place of motor adds slew. Using motor alone results in no slew.

I am doubtful it would make much of a difference, but you could try and reduce MOTOR_DEFAULT_SLEW_RATE and see if it improves your performance. The smaller you make that constant, the longer it will take to arrive at full speed – making the response to driver input seem sluggish.

@Doug Moyers I see what you mean with your motorReq statement. The main problem is that since this is a task, it may interfere with other tasks running at the same time, and with the same motors that are being used. We were wondering if there was a way so instead of saying something like motor[index], it would say motor[specific motor]
Also, thank you for your suggestion about the MOTOR_DEFAULT_SLEW_RATE, I’ll try to get back to that ASAP.

Yes you can adjust a specific motor. Just set the variable motorSlew[the_motor_I_want]; Just do it once you have initialized the slew rate in starting the task.

You can also measure the current to see the effects. Don’t worry about the actual amps, you want to see the difference in new slew rate values. Look at the height of the spikes. Measure it very quickly at 1-5ms intervals.

https://vexforum.com/t/estimating-motor-current-part-3/22231/1

@Team80_Giraffes Do you mean something like this?

``````
if (vexRT[Btn6U]==1)
{
startTask(MotorSlewRateTask);
motorReq[conelift] = 127;
motorSlew[conelift] = 127;
wait1Msec(20);

}
else if (vexRT[Btn6D]==1)
{
startTask(MotorSlewRateTask);
motorReq[conelift] = -127;
motorSlew[conelift] = -127;
wait1Msec(20);
}
else
{
startTask(MotorSlewRateTask);
motorReq[conelift] = 0;
motorSlew[conelift] = 0;
wait1Msec(20);
}
``````

The task should be started at the beginning of user control. You want to start it once and let it run.

motorSlew should be the absolute value of the step size so a step size of 0 will never go anywhere. Step size of 127 is basically ignoring the slew rate.

``````task usercontrol()
{
startTask(MotorSlewRateTask);
motorSlew[conelift] = 50;  // or something reasonably big, but not too big

if (vexRT[Btn6U]==1)
{
motorReq[conelift] = 127;

}
else if (vexRT[Btn6D]==1)
{
motorReq[conelift] = -127;
}
else
{
motorReq[conelift] = 0;
}
wait1Msec(20);

// and the rest of the user control task
``````