RobotC - Bad programming habits

Stop your motors jittering

It seems like almost everyday we get a new question about motors that are jittering on the robot. The cause is setting the motor to multiple different values within the driver control infinite loop. Typical code may look like this.

#pragma config(Motor,  port1,           MotorA,        tmotorVex393_HBridge, openLoop)
//*!!Code automatically generated by 'ROBOTC' configuration wizard               !!*//

task main()
{
    while(1)
        {
        // Really bad code that causes motors to jitter
        if( vexRT Btn8U ] )
            motor MotorA ] = 127;
    
        if( vexRT Btn8D ] )
            motor MotorA ] = -127;
    
        motor MotorA ] = 0;
        
        wait1Msec(10);
        }
}

The motor is first set to +127, then set to -127, then set to 0. These all happen very quickly and it just depends on which value happens to get sent to the motor that determines what it does.

So we all know the fix, I left out all the “else” statements, it should look like this.

#pragma config(Motor,  port1,           MotorA,        tmotorVex393_HBridge, openLoop)
//*!!Code automatically generated by 'ROBOTC' configuration wizard               !!*//

task main()
{
    while(1)
        {
        // No jitter now
        if( vexRT Btn8U ] )
            motor MotorA ] = 127;
        else
        if( vexRT Btn8D ] )
            motor MotorA ] = -127;
        else
            motor MotorA ] = 0;
        
        wait1Msec(10);
        }
}

But what if we wanted to add some joystick control as well, typically this might start off as follows.

#pragma config(Motor,  port1,           MotorA,        tmotorVex393_HBridge, openLoop)
//*!!Code automatically generated by 'ROBOTC' configuration wizard               !!*//

task main()
{
    while(1)
        {
        // Button control
        if( vexRT Btn8U ] )
            motor MotorA ] = 127;
        else
        if( vexRT Btn8D ] )
            motor MotorA ] = -127;
        else
            motor MotorA ] = 0;
        
        // oops, jitter again
        if( abs(vexRT Ch2 ]) > 10 )
            motor MotorA ] = vexRT Ch2 ];
        else
            motor MotorA ] = 0;
        
        wait1Msec(10);
        }
}

But now we have jitter on the motor again. The problem, as before, is that we are using if-then-else statements to conditionally send values to the motor but keep overriding out previous decision. So we (well, the bad habit programmer) try and fix this by complicating the logic like this.

#pragma config(Motor,  port1,           MotorA,        tmotorVex393_HBridge, openLoop)
//*!!Code automatically generated by 'ROBOTC' configuration wizard               !!*//

task main()
{
    while(1)
        {
        // Button control
        if( vexRT Btn8U ] )
            motor MotorA ] = 127;
        else
        if( vexRT Btn8D ] )
            motor MotorA ] = -127;
        else
            {       
            // fixed again !
            if( abs(vexRT Ch2 ]) > 10 )
                motor MotorA ] = vexRT Ch2 ];
            else
                motor MotorA ] = 0;
            }
            
        wait1Msec(10);
        }
}

and so on, as we add presets, a partner joystick, whatever, it gets harder to stop those motors jittering.

There is a better way, use a variable, set the motor only once. A rewrite of the above may look as follows.

#pragma config(Motor,  port1,           MotorA,        tmotorVex393_HBridge, openLoop)
//*!!Code automatically generated by 'ROBOTC' configuration wizard               !!*//

task main()
{
    int     MotorA_Value;

    while(1)
        {
        // Clear to start with
        MotorA_Value = 0;
        
        // Button control
        if( vexRT Btn8U ] )
            MotorA_Value = 127;

        if( vexRT Btn8D ] )
            MotorA_Value = -127;

        // Joystick control
        if( abs(vexRT Ch2 ]) > 10 )
            MotorA_Value = vexRT Ch2 ];
        
        // Finally - send to the motor here
        motor MotorA ] = MotorA_Value;

        wait1Msec(10);
        }
}

There is still priority to the control, joystick will override button 8D and that will override button 8U, but what the priority is can be determined by the order of the statements. The final value of the variable is only sent to the motor once, it is impossible for there to be any motor jitter (the code may not work but that’s another story).

1 Like