SparkMax NEO with DutyCycle Absolute Encoder - Hardware PID question

We’re trying to use NEO with SparkMAX and Absolute Encoder set as a DutyCycle encoder, in Swerve chassis as Angle motor,

For simplicity we set the PID range 0…360. So, when we try to tell the PID to go to an angle (say, 80.6), the motor continues rotating, and does not stop. So, I assume we’re not setting something right.

We would like to do all that in a code with motor reset rather than relying on the REV GUI.

So, here is the configuration we do:

// CANID = 3 at this point

    motorNEO = new CANSparkMax(CANID, MotorType.kBrushless);

    angleEncoder = motorNEO.getAbsoluteEncoder(Type.kDutyCycle);

    motorNEO.restoreFactoryDefaults();
    motorNEO.clearFaults();

    motorNEO.setInverted(true);

    angleEncoder.setInverted(true);

    pid = motorNEO.getPIDController();

   angleEncoder.setPositionConversionFactor(359.99);
    angleEncoder.setVelocityConversionFactor(359.99);

    motorNEO.setCANTimeout(0);

    motorNEO.enableVoltageCompensation(12.0);
    motorNEO.setSmartCurrentLimit(20.0);
    motorNEO.setOpenLoopRampRate(0.25);
    motorNEO.setClosedLoopRampRate(0.25);
    
    pid.setPositionPIDWrappingEnabled(true);
    pid.setPositionPIDWrappingMinInput(0);
    pid.setPositionPIDWrappingMaxInput(359.99);
    
    motorNEO.setPeriodicFramePeriod(PeriodicFrame.kStatus5, 20);

    // Configure PID values

    pid.setP(0.0016);
    pid.setI(0);
    pid.setD(0);
    pid.setFF(0);
    pid.setIZone(0);
    pid.setOutputRange(-0.5, 0.5);

    motorNEO.burnFlash();

Now to actually run PID, we do

    motorNEO.getPIDController().setReference(angle, ControlType.kPosition);

where angle is, say, 29.3

We’re new to PID with NEOs and external encoders. So, any suggestions would be greatly appreciated.

Also note that the

angleEncoder.getPosition()

does return the right value. So it seems at least the encoder object is working correctly

I’m not sure what swerve module you are using, but if you look at the Rev MAXSwerve Java template code, they use m_turningPIDController.setFeedbackDevice(m_turningEncoder) to specify the usage of the Absolute Encoder for the PID Controller instead of the default NEO internal encoder.

1 Like

This topic was automatically closed 365 days after the last reply. New replies are no longer allowed.