joystick problem

I can run my robot by using joystick.I try to use buttons to run specified function( i plan to move left motor for 0.2 second when i press 8R) and found it was working but Ch2 was not function anymore(i.e. i move Ch2 but the robot didn’t move anymore)), can anyone tell me what’s wrong, thanks.
task main()
{
while(1==1)
{
motor[left]=vexRT[Ch2];
motor[right]=vexRT[Ch3];

if(vexRT[Btn6U]==1)
{
motor[port5]=63;
}
else if(vexRT[Btn6D]==1)
{
motor[port5]=-63;
}
else
{
motor[port5]=0;
}

if(vexRT[Btn8R]==1)
{
motor[port1]=32;
motor[port10]=32;
wait1Msec(200);
}
else if(vexRT[Btn7L]==1)
{
motor[port1]=-32;
motor[port10]=-32;
wait1Msec(200);
}
else
{
motor[port1]=0;
motor[port10]=0;
}

}
}

This is one of those things that, unfortunately, seems simpler than it really is.

What’s happening is that when you use 8R or 7L, the code gets ‘stuck’ in the


wait1Msec(200);

statements, making the robot unresponsive for 0.2 seconds.

The easiest way to get around this would probably be with tasks, but I would personally prefer to avoid tasks for a situation like this. (If you’re interested in tasks, someone will probably post about them here eventually)

This would be my solution:

task main(){
  
  //Create variables to represent the time 200ms after pressing the buttons
  //Initial value of 0 because nSysTime will never be less than 0 (see if statements below)
  long motion8REndTime = 0;
  long motion7LEndTime = 0;
  
  while(1==1){
    
    motor[left]=vexRT[Ch2];
    motor[right]=vexRT[Ch3];
    
    if(vexRT[Btn6U]==1){
      motor[port5]=63;
    }
    else if(vexRT[Btn6D]==1){
      motor[port5]=-63;
    }
    else {
      motor[port5]=0;
    }
  
    if(vexRT[Btn8R]==1){
      motion8REndTime = nSysTime + 200; //200ms after the current time
    }
    else if(vexRT[Btn7L]==1){
      motion7LEndTime = nSysTime + 200; //200ms after the current time
    }
    
    if(nSysTime < motion8REndTime){ //if 200ms haven't yet elapsed since pressing 8R
      motor[port1]=32;
      motor[port10]=32;
    }
    else if(nSysTime < motion7LEndTime){ //if 200ms haven't yet elapsed since pressing 7L
      motor[port1]=-32;
      motor[port10]=-32;
    }
    else {
      motor[port1]=0;
      motor[port10]=0;
    }
    
  }
}

Notice I didn’t use any


wait

statements inside the primary execution loop (a.k.a. the


while(1==1){}

loop inside


task main(){}

).

Dear Barin,

Thanks for your reply, i try it on my robot and
task main()
{
long motion8REndTime=0;
long motion7LEndTime=0;

while(1==1)
{
motor[left]=vexRT[Ch2];
motor[right]=vexRT[Ch3];

if(vexRT[Btn6U]==1)
{
motor[port5]=63;
}
else if(vexRT[Btn6D]==1)
{
motor[port5]=-63;
}
else
{
motor[port5]=0;
}

if(vexRT[Btn8R]==1)
{
motion8REndTime=nSysTime + 200;
}
else if(vexRT[Btn7L]==1)
{
motion7LEndTime=nSysTime + 200;
}
if(nSysTime < motion8REndTime){
motor[port1]=32;
motor[port10]=32;}

else if(nSysTime < motion7LEndTime){
motor[port1]=32;
motor[port10]=32;}

else {
motor[port1]=0;
motor[port10]=0;}

}
}
After compiled, 2 messages shown:
Warning:Comparison between ‘signed’ and ‘unsigned’ operands.
Warning:Comparison between ‘signed’ and ‘unsigned’ operands.

And the claw operated normally, but the left and right motors are not working at all.

Could you post your complete code, including


#pragma

statements? I think the issue might be there. Also please use the



 tag to post code next time.

Dear Barin,

Thanks for your reply, here are the pragma:

#pragma config(Motor, port1, left, tmotorVex393_HBridge, openLoop)
#pragma config(Motor, port5, claw, tmotorVex393_MC29, openLoop)
#pragma config(Motor, port6, arm, tmotorVex393_MC29, openLoop, reversed)
#pragma config(Motor, port10, right, tmotorVex393_HBridge, openLoop, reversed)
//!!Code automatically generated by ‘ROBOTC’ configuration wizard !!//

i mended the code as follow and the robot is partly working:

unsigned long motion8REndTime=0;
unsigned long motion7LEndTime=0;
unsigned long tmp;
tmp = nSysTime; // i have changed all nSysTime as tmp

No more warning came out and
6U and 6D are working, 8R was working, 7L failed and robot can only go forward but not backward.

The full version:
#pragma config(Motor, port1, left, tmotorVex393_HBridge, openLoop)
#pragma config(Motor, port5, claw, tmotorVex393_MC29, openLoop)
#pragma config(Motor, port6, arm, tmotorVex393_MC29, openLoop, reversed)
#pragma config(Motor, port10, right, tmotorVex393_HBridge, openLoop, reversed)
//!!Code automatically generated by ‘ROBOTC’ configuration wizard !!//

task main()
{
unsigned long motion8REndTime=0;
unsigned long motion7LEndTime=0;
unsigned long tmp;
tmp = nSysTime;

while(1==1)
{
motor[left]=vexRT[Ch2];
motor[right]=vexRT[Ch3];

if(vexRT[Btn6U]==1)
{
motor[port5]=63;
}
else if(vexRT[Btn6D]==1)
{
motor[port5]=-63;
}
else
{
motor[port5]=0;
}

if(vexRT[Btn8R]==1)
{
motion8REndTime=tmp+200;
}
else if(vexRT[Btn7L]==1)
{
motion7LEndTime=tmp+200;
}
if(tmp < motion8REndTime){ //last time warning here, now gone
motor[port1]=32;
motor[port10]=32;}

else if(tmp < motion7LEndTime){ //last time warning here, now gone
motor[port1]=32;
motor[port10]=32;}

else {
motor[port1]=0;
motor[port10]=0;}

}
}

The


#pragma

statements are important to this situation as they provide crucial information I did not know before. See my notes below.

#pragma config(Motor, port1, left, tmotorVex393_HBridge, openLoop)
#pragma config(Motor, port5, claw, tmotorVex393_MC29, openLoop)
#pragma config(Motor, port6, arm, tmotorVex393_MC29, openLoop, reversed)
#pragma config(Motor, port10, right, tmotorVex393_HBridge, openLoop, reversed)
//*!!Code automatically generated by 'ROBOTC' configuration wizard !!*//

task main(){
  unsigned long motion8REndTime=0;
  unsigned long motion7LEndTime=0;
  //See note 2

  while(1==1){
    //See note 3

    if(vexRT[Btn6U]==1){
      motor[claw]=63; //See note 1
    }
    else if(vexRT[Btn6D]==1){
      motor[claw]=-63; //See note 1
    }
    else {
      motor[claw]=0; //See note 1
    }

    if(vexRT[Btn8R]==1){
      motion8REndTime=nSysTime+200; //See note 2
    }
    else if(vexRT[Btn7L]==1){
      motion7LEndTime=nSysTime+200; //See note 2
    }

    if(nSysTime < motion8REndTime){ //See note 2
      motor[left]=32; //See note 1
      motor[right]=32; //See note 1
    }
    else if(nSysTime < motion7LEndTime){ //See note 2
      motor[left]=-32; //See notes 1 and 4
      motor[right]=-32; //See notes 1 and 4
    }
    else {
      motor[left]=vexRT[Ch2]; //See note 3
      motor[right]=vexRT[Ch3]; //See note 3
    }
  }
}

Notes:

  1. I replaced all instances of

motor[port ]

with the names of the motors from your


#pragma

statements. This is good practice in general, but I also assumed originally that


motor[port1]

and


motor[port10]

were not the same as


motor[left]

and


motor[right]

. My previous code didn’t work because the motors were actually the same, so they were commanded to go at 2 different speeds each in a single execution of the


while(1==1){}

loop.
2. The


tmp

variable you created could have worked, but it would have to be synchronized with


nSysTime

every time the


while(1==1){}

loop executed, so


tmp = nSysTime;

would need to be inside the loop, not outside. In any case, that process is an inefficient and unnecessary waste of resources. The warnings could also have been safely ignored, but changing


motion8REndTime

and


motion7LEndTime

to


unsigned

got rid of the warnings anyway.
3. My solution to the problem described in note 1 is to relocate


motor[left]=vexRT[Ch2]; motor[right]=vexRT[Ch3];

to the


else {}

as you can see in the code. This way, during the 200ms after pressing 7L or 8R, the left and right motors go at ±32, while going at the joystick-dictated speeds at other times.
4. I assume this was a typo and you wanted these to be


-32

as you posted originally, not


32

as you posted in your latest 2 posts. If this was not an error, feel free to change them back.

Dear, Barin,

Thanks, it works perfectly.

I’d like to show you a way to simplify a portion of your code. I only found out about it in my second year of coding, so it’s not as obvious as it seems.

Your code:


    if(vexRT[Btn6U]==1){
      motor[claw]=63;
    }
    else if(vexRT[Btn6D]==1){
      motor[claw]=-63;
    }
    else {
      motor[claw]=0;
    }

Can be simplified to:


motor[claw] = 63 * (vexRT[Btn6U] - vexRT[Btn6D]);

This is because


Btn6U - Btn6D

will equal

  • 1 if Btn6U is pressed and Btn6D is not pressed,
  • -1 if Btn6U is not pressed and Btn6D is pressed,
  • 0 if Btn6U is pressed and Btn6D is pressed,
  • 0 if Btn6U is not pressed and Btn6D is not pressed.

So if only the up button is pressed, the claw will be


63 * 1

, if only the down button is pressed, the claw will be


63 * -1

, and if either both buttons are pressed, or neither is pressed, the claw will be


63 * 0

.

I actually quite like that method; it’s one I’ve never encountered/thought about myself. It isn’t very intuitive at first glance, though, so I’m not sure I’d use/suggest it in all cases.

Once a student understands the


if / else

statements I like to share the ternary version. Its still readable, a little more versatile and, like @DarkMatterMatt code, it fits on one line.


motor[claw] = vexRT(Btn6U) ? 63 : vexRT(Btn6D) ? -63 : 0;