Grayhill Encoders on Talon SRX CAN with Java CB

SO we are trying to use encoders for the first time.

Current setup is a Grayhill on each side of our drive train, wire with 5 pin connector(leaving 4th pin empty) to the talon SRX encoder breakout board. I then use a 10 pin ribbon cable to the Talon SRX connector.

Using the web dashboard, i can see the encoder value. If i manually spin and refresh, i can see the value has changed… so i am assuming that the mechanical and wiring portion is good for now.

We are using Java Command Based… I have a few questions… All our code was “borrow” from an other team online and since we are new to java, i am not that good in totally getting it ! lol but we are trying hard!

Question #1
I have the following in my RobotMap class…

 encoderRight = new Encoder(0, 1, true, Encoder.EncodingType.k4X);
    encoderRight.setPIDSourceType(PIDSourceType.kDisplacement);
    encoderRight.setDistancePerPulse(1.0 / tinch);
    encoderRight.reset();
    
    encoderLeft = new Encoder(2, 3, false, Encoder.EncodingType.k4X);
    encoderLeft.setPIDSourceType(PIDSourceType.kDisplacement);
    encoderLeft.setDistancePerPulse(1.0 / tinch);
    encoderLeft.reset();

While i understand the team that create that code is using the DIO input on Roborio (that will be the 0, 1 & 2,3 right?), what should i put in there if i am using the CAN breakout board…?

Question #2
I am trying to display value on my Smardashboard… Every time i add this code, it makes my teleop crash… Basically enable for a few seconds, then disable itself…

	public void teleopPeriodic() {
		Scheduler.getInstance().run();
		SmartDashboard.putNumber("encoder value right", (RobotMap.encoderRight.get()));
        SmartDashboard.putNumber("encoder value left",  (RobotMap.encoderLeft.get()));

	}

Thank you!!!

You’ll need to use the Talon SRX API instead of the Encoder class. Check the Talon SRX Software Reference Manual for details.

Your second problem may be fixed by your first, but I’ve never encountered that behavior. Does an error get printed to your driver station log?

Thanks for your reply…

I am a newbie and very inexperienced with Java. I know enough to be in trouble, but very limited knowledge…

I am looking at the CTR manual and i am not sure what to look for at this point.

just very frustrated with lack of documentation for new folks… There is a huge learning curve between trying stuff and actually applying it and on top of it, try to teach our students what we learn as we learn it…

Looking at the manual does not help much as i am not sure how to translate that i want the encoder value on the smartdashboard and what the manual says…

So when you have encoders plugged into the Talon SRX, and when you use the Talon SRX to do your PID control (as you should be), you don’t use the Encoder class at all. That class is for encoders plugged into the RoboRIO’s digital inputs, so it’s not for what you are doing.

The Talon SRX software reference manual (linked above) is a very large book and it can be difficult to just instantly find the solution you need, but it does have good examples of this code.

Here is the Java API for the CANTalon class, which is the class you will be using to do all of your code work for this. Trust me, once you get started, it is much easier and better to be doing your PID this way than it is to do your PID using WPILib’s classes.

You can definitely get the encoder value from the Talon SRX and put it onto SmartDashboard if that’s what you want to do - we do the same thing using our shooter encoder.

Example code:


CANTalon someTalon = new CANTalon(/* talon id */);
someTalon.setFeedbackDevice(CANTalon.FeedbackDevice.QuadEncoder);
someTalon.configEncoderCodesPerRev(/* eg, for a Grayhill 63R256, this would be 256 */);
// if applying positive voltage to the motor causes it to spin in a direction the encoder counts as negative, do this to make sensor and motor match
someTalon.reverseSensor(true);

Then to read the encoder:


double revolutions = someTalon.getPosition();

Or set up a PID loop


// setup
someTalon.configNominalOutputVoltage(+0.0f, -0.0f);
someTalon.configPeakOutputVoltage(+12.0f, -12.0f);
someTalon.setProfile(0);
someTalon.setF( ... );
someTalon.setP( ... );
someTalon.setI( ... );
someTalon.setD( ... );

// enable PID
someTalon.changeControlMode(CANTalon.TalonControlMode.Position);
someTalon.set(/* your setpoint, in revolutions */);

// disable PID
someTalon.changeControlMode(CANTalon.TalonControlMode.PercentVbus);
someTalon.set(0);

Thank you so much guys !!! think i am on the right track…

So here is my DriveTrain Subsystem… I realized that the talon definition should be in RobotMap but for some reason, we ended up defining weach talon in each Subsystem instead… hopefully whne the pressure is off, we will review and change as needed.

public class DriveTrain_Subsystem extends Subsystem{
	
	/* talons for arcade drive */
	CANTalon _frontLeftMotor = new CANTalon(4); 		/* device IDs here (1 of 2) */
	CANTalon _rearLeftMotor = new CANTalon(5);
	CANTalon _frontRightMotor = new CANTalon(1);
	CANTalon _rearRightMotor = new CANTalon(2);

	/* extra talons for six motor drives */
	public RobotDrive MainDrive = new RobotDrive(_frontLeftMotor, _rearLeftMotor, _frontRightMotor, _rearRightMotor);
	
    // Put methods for controlling this subsystem
    // here. Call these from Commands.

    public void initDefaultCommand() {
    	setDefaultCommand(new ArcadeDrive_Command());
    }
    
    public void TeleopDrive(Joystick Driver){ 
    	MainDrive.arcadeDrive(Driver.getY(),Driver.getX());   	
    }

	public void getLeftDistance() {
    	_frontLeftMotor.setFeedbackDevice(CANTalon.FeedbackDevice.QuadEncoder);
    	_frontLeftMotor.configEncoderCodesPerRev(64);
    }
	
	public void getRightDistance() {
    	_frontRightMotor.setFeedbackDevice(CANTalon.FeedbackDevice.QuadEncoder);
    	_frontRightMotor.configEncoderCodesPerRev(64);    	
	}
		
    public void Stop(){
    	MainDrive.drive(0,0);
    }
}

Now trying to display this value… in my Robot.java class I added this method but cannot get rid of the error…

public void teleopPeriodic() {
		Scheduler.getInstance().run();
		SmartDashboard.putNumber("encoder value right", (DriveTrain_Subsystem.getLeftDistance());
        SmartDashboard.putNumber("encoder value left",  (DriveTrain_Subsystem.getRightDistance());

Thanks for your help…

Does the Smardashboard automatically suppose to open when you open the driver station? I have Java selected int he drop down…

The code currently included in GetLeftDistance and GetRightDistance should be run at init, not on the function call.

I would suggest setting the talons without encoders on each side to Follower mode, having them follow the talons with encoders. This means the onboard PID on one talon will also drive the other, when you get to that point. That also means changing your RobotDrive to only take two speed controllers as arguments.

use CANTalon.getEncPosition() to get the encoder position. Check the API for details.

Are you saying the robotInit in Robot.java?

Allrighty… Thanks everyone for the help… I finally got it to work…