Encoders randomly Zeroing

We are using a CTR MagEncoder on a wrist that is sticking out of a four bar we use. Recently we have been having issues with this Encoder deciding to zero itself and then our wrist moving down more because the position is different. We do have a forward limit switch that once it rezeroes that wrist, but we have eliminated the idea of the limit switch being clicked somehow, and have replaced both that limit switch and the encoder multiple times to no better results. I have talked to other people from FIM States, and a few other teams have had the same issue but haven’t been able to figure this out either. If any more information is needed to help me with this situatuon, pease just let me know.

What is the encoder plugged into?

The encoder is ran through a ribbon cable directly to the Talon.

Intermittent power issues to the Talon can be a cause: See this thread/replay.

We’ve also had this issue with bad encoder cables that were hand-crimped. Our plan next year is to only use premade COTS cables to avoid this.

1 Like

Thank you. We had Mike from CTR both in our pit, and one of our mentors is a engineer for CTR, and they were at a loss of words, its something that bizarre. We just wanted to reach out to see if anyone else may have had this issue, for further info, we had the limit switch report to the dashboard and when it randomly “zeros” it prints that the limit switch was triggered, even though it wasnt. We have tried to use 5 different limit switches. We replaced the encoder slice at FiM Marysville and had no issues for about 15-20 matches, and then it came back. We have also replaced encoder cable multiple times, encoder itself with new solder joints on the back for the limit switch, and the talon. The only thing we did not do is change the Talon at FiM states, so just to rule it out we will most likely due this at worlds.

1 Like

Does the MagEncoder return to reading the correct value? In other words, does it give you a zero value, and then return to a non-zero value, or is the encoder constantly reading zero?

I have seen cases where a different encoder (not the CTR MagEncoder) plugged into the Talon would read zero, and then return back to the correct value. Maybe there is some CAN error condition causing this.

We resorted to filtering out all zero values, so the only way you could read a zero is if the (external) limit switch was activated. That will not help you if the encoder is actually resetting rather than just giving the occasional zero value.

We had the same issue we had this year (FYI it was with an AMT-103V wired directly to the roborio, not its respective Talon) and had so much trouble solving it that we could not use the PID elevator code that we wrote and had working with a few days left in build season.

What we found was the issue was a signal/code problem out of our control (likely from the roborio) that caused the begin.vi to be called again, which zeroed the encoder. We rewrote the robotmain.vi from scratch with exactly the same code and got it back working. Identical code and identical electrical should not be a solution, but it was.

We also had an issue at our first competition where the camera would work in the pits but not on the field. This issue, WITHOUT ANY CODE CHANGES, spiraled into a problem where wheels randomly moved without joystick input, the camera refused to work at all, the elevator moved without user input, and many other problems. We even had to miss a match because of this and were immobile in others.

Without changing anything electrically, rewriting the entire code from scratch during the playoffs that we missed fixed all of our problems. The weird thing was that the rewritten code was 100% identical to the previous code.

Seeing that everything you tried with replacing the encoder/limit switch did not work, I would think that the root of the problem is at the Roborio (which is linked to the talons and their logic through CAN bus), with the problem likely being lost packets or something of that sort because from what I am reading, it sounds like your robot is calling earlier use of the code (possibly begin.vi, or some joystick/code input from a previous match). An example of the earlier code being called is in that match on Houston Einstein 2018 where 2655 faced 254, and 2655 did the 3-cube auto on the wrong side due to data packet loss. Link here

I would recommend rewriting the code from scratch, without ANY copy/pasting, and making sure the new code is 100% identical to the old code. Also, reset driver station between matches, it works wonders for solving packet loss, which I am about 80% sure (I say 80% because with this type of gremlin, you can’t be too sure) is of the same realm as your problem since you say the robot with new encoder worked for 15-20 and then the issue returned without any other variable changing.

Yes, we graphed the Target Position for the wrist encoder and it would all of a sudden reset its position to 0, then try to go to the target position which was ~2100 causing it to shoot around and us having to force it backwards to hit the limit switch in order for functionality again.

We had a similar issue this year with our lift. We were using one of these from FIRSTChoice on the bottom of our lift. The symptom was that our positions were unreliable, and the encoder seemed to be ‘slipping’, with the values being off when we came down (not returning to near zero again at the bottom), despite the magnet of the Mag encoder being glued in very well. We changed 3 encoders, but had the same issue on our practice robot and comp robot.

At Seven Rivers late on Thursday we noticed that the encoder position was being reset to zero as the lift went up (we have code to re-zero every time we hit the bottom switch). We swapped out that limit switch for one of the regular small Honeywell microswitches, and have not had a problem since.

We tried the new switch this year since we broke a number on last years lift. With better PID control etc. this year, we have not broken a microswitch since the change. But I was surprised at the bounce in the original switch we used, either due to the internal switching mechanism (which would really surprise me), or due to it being a high(er) current switch.

At least is was good to finally isolate the problem, and I’m glad it’s not the encoders themselves.

We also saw issues with the encoder position reset on the Talon taking some time before the reset actually occured. We NEVER call the encoder reset. Instead, we track an offset and use that so that you can avoid…

 encoder.reset();
 System.out.println(encoder.get());  // this prints a non-zero value

There is a delay between calling the reset, and the reset actually taking place in the remote TalonSRX device.

In the Talon initialization is the only place we do a reset (at robotinit).

    talonSRX.configSelectedFeedbackSensor(FeedbackDevice.QuadEncoder, 0,  0);
    talonSRX.setSelectedSensorPosition(0, 0, 0);

and from there we have 2 routines to get the position and the rate

@Override
public int get() {
    // Get the raw counts
    return super.get(talonSRX.getSelectedSensorPosition(0));
}

@Override
public double getRate() {
    // Get the raw rate
    return super.getRate(talonSRX.getSelectedSensorVelocity(0));
}

If we want to zero the sensor, we have a super class that adjusts for offset and inversion. Using this idea, the encoder reset is always instantaneous. Here is the code…

package com.torontocodingcollective.sensors.encoder;

/**
 * TEncoder class used as the base for all TEncoders
 * <p>
 * The encoder interface is not consistent for PWM and CAN encoders, and this
 * interface is used to unify the calling interfaces
 * <p>
 * Known implementations: {@link TCanEncoder}, {@link TDioQuadEncoder},
 * {@link TDioCounterEncoder}
 */
public abstract class TEncoder {

    boolean isInverted = false;
    int     offset     = 0;

    /**
     * TEncoder default constructor
     * <p>
     * Sets the encoder as not inverted
     */
    protected TEncoder() {
        this(false);
    }

    protected TEncoder(boolean isInverted) {
        this.isInverted = isInverted;
    }

    /**
     * Get the distance of this encoder
     * 
     * @return distance in encoder counts
     */
    public abstract int get();

    /**
     * Invert the raw distance if required
     * 
     * @param rawDistance
     * @return int inverted distance
     */
    protected int get(int rawDistance) {

        if (isInverted) {
            rawDistance = -rawDistance;
        }

        return rawDistance + offset;
    }

    /**
     * Get the rate (speed) of this encoder
     * 
     * @return speed in encoder counts/second
     */
    public abstract double getRate();

    /**
     * Invert the raw rate if required
     * 
     * @param rawRate
     * @return double raw rate inverted if required
     */
    protected double getRate(double rawRate) {

        if (isInverted) {
            return -rawRate;
        }

        return rawRate;
    }

    /**
     * Returns whether the current speed controller is 
     * inverted
     * @return {@code true} if inverted, {@code false} otherwise
     */
    public boolean isInverted() {
        return this.isInverted;
    }

    /**
     * Reset the encoder counts for this encoder
     */
    public void reset() {
        // set the offset for this encoder in order to
        // get the distance to zero
        // clear the previous offset
        offset = 0;

        // set the offset to the current encoder counts
        // in order to zero the output.
        offset = -get();
    }

    /**
     * Set the encoder counts to a known value
     * 
     * @param encoderCount
     *            to set the encoder to
     */
    public void set(int encoderCount) {
        offset = 0;
        offset = -get() + encoderCount;

    }

    /**
     * Set the encoder inversion
     * <p>
     * A call to setInverted also resets the encoder if the inversion changes
     * 
     * @param isInverted
     *            {@code true} if the output should be inverted {@code false}
     *            otherwise
     */
    public void setInverted(boolean isInverted) {

        if (this.isInverted != isInverted) {
            this.isInverted = isInverted;
            reset();
        }
    }

}

Also going along with what i originally said, we also get a FWD Limit Switch Sticky Fault coming fron that Talon. This has been indicating to us that there is a problem with that limit switch been clicked somehow. We thought maybe it was being bounced around enough to be somehow getting tricked into getting clicked, but we flicked the switch and tried that with no result, so it doesn’t seem like the limit switch is failing mechanically, we are thinking maybe some noise is causing this.

Our team had issues with encoders on our lifts (for climbing) and came up with this troubleshooting guide. Use the Phoenix Tuner to graph or print out the encoder counts as this rules out most code issues.

  1. Check that you are receiving a value from the encoder and that it is updating when the motor is running (move the motor and see if the encoder value updates to something other than zero).

  2. If the encoder value is not updating, replace the encoder wire.

  3. After replacing the encoder wire, test the encoder to make sure encoder value is updating.

  4. If the value is updating, HOORAY, problem solved! if not, check the encoder light (present on VersaPlanetary encoders). If on skip to step 6.

  5. If the encoder light is off, make sure the wire is plugged in all the way to both Talon and encoder. If the light is still off, replace encoder and retest for updating values.

  6. If the encoder light is on and you have replaced the wire, but are still not getting values, replace the Talon with one you KNOW WORKS and go back to step one to verify that everything works.

As a final step, check to make sure your code is reading the correct encoder value and using that value the correct way.

We had the same issue with the SRX Mag Encoder zeroing. We didn’t have a limit switch attached, so we know that is not the problem. Most of the time, the encoder value updates 100% correctly. Sometimes though, the encoder value randomly goes to zero. The encoder light stayed green while it zeroed.

Yes this is the same that has happened to us. We have a practice robot that is the exact same code and all, the only thing different is how it is wired. We run the wire down the arm, and we were thinking there was a short but we then ran external wires with the same problem. The practice bot has no problems. So what we are planning on doing is, before we left states we took the RIO off of the comp bot, so we are going to see if the RIO is calling the onStart function periodically, to eliminate the RIO software flaw completely.

2 Likes