Motor position () or rotation() returns 0 after rotating for an angle

Hi, we have observed some unexpected results when using the inner encoder of motor to control the turning angle: the motor is connected to a gear which is connected to a long heavy arm. We setPosition(0) in the beginning and then spinToPosition(100). The motor does turn to the angle (which is roughly correct based on my calculation). However, position() returns 0. It appears the encoder loses the reading. However we don’t reset it.

We can’t figured out why. One possibility is the heavy load. When we use a much lighter arm, the code seems to return the right value. But this is quite scary. I wonder (1) whether load affects the encoder reading (2) if so, what the max safe load it is - can’t find any specs (3) any idea on how to solve this problem?

Many thanks!
Gavin

yep sounds like v5

No idea. I would try using an old encoder; they work.

Post your code, it’s most likely a simple programming mistake.

3 Likes

Thanks a lot for all the replies. Yes, this is V5. The code is very simple as follows. My problem is after running the code (raise, wait and lower), I always get “before lower_lift = 0” . The most weird thing is I sometimes get “after raise_lift =” something close to 200 but other times just 0.

The arm is quite long and heavy. But the motor has no difficulty of raising it up and down.

motor Lift = motor(PORT7, ratio36_1, false);
Lift.setPosition(0,degrees);

void raise_lift(bool bWait=true){
Lift.setStopping(hold);
Lift.setVelocity(100,percent);
Lift.spinToPosition(200, rotationUnits::deg, bWait);
Brain.Screen.print(“after raise_lift = %f”, Lift.position(degrees);
}

void lower_lift(bool bWait=true){
Brain.Screen.print(“before lower_lift = %f”, Lift.position(degrees);
Lift.setStopping(hold);
Lift.setVelocity(100,percent);
Lift.spinToPosition(200, rotationUnits::deg, bWait);
}

raise_lift(true);
wait(5, seconds);
lower_lift(true);

can you post the actual code you are using, lots of small errors in what you posted above so I assume it’s not exactly what you are using.

2 Likes

right , it is what I recalled from memory but not too different from the real code. Below is the real code:

void Lowheight(bool bWait=true){
char logmsg[256];
sprintf(logmsg, “before Lift Low = :%5.1f”, Lift.rotation(rotationUnits::deg));
log(logmsg, true);
Lift.setStopping(hold);
Lift.setVelocity(100,percent);
Lift.spinToPosition(low_height, rotationUnits::deg, bWait);
Lift.stop();
sprintf(logmsg, “after Lift Low = :%5.1f”, Lift.rotation(rotationUnits::deg));
log(logmsg, true);
}

void safe_ZeroHeight(){
char logmsg[256];
sprintf(logmsg, “before Lift reset = :%5.1f”, Lift.rotation(rotationUnits::deg));
log(logmsg, true);
Lift.setStopping(coast);
Lift.setVelocity(100,percent);
Lift.spinToPosition(0,degrees,false);
Lift.stop();
sprintf(logmsg, “after Lift reset = :%5.1f”, Lift.rotation(rotationUnits::deg));
log(logmsg, true);
}

I call Lift.setPosition(0,degrees); in pre_auton() which is executed before any of these 2 calls. My problem is in order to rotate the lift back to 0 the motor encoder needs to read the correct current position after Lowheight() is called. But as said earlier, I always get 0 "before Lift reset " and sometimes 0 "after Lift Low ".

the code is quite simple. did I use the wrong API?

many thanks!

unfortunately, context is everything. I can’t see when and how Lowheight and safe_ZeroHeight are called. This is also an issue.

Lift.spinToPosition(0,degrees,false);
Lift.stop();

you ask the lift to spinToPosition without blocking and then stop it, so it probably never moves.

3 Likes