Given a NEO/NEO550 motor
Is it possible to use the Spark Max’s relative encoder and also plug in a REV through bore encoder used as either Absolute or Relative(Incremental) and get date from each at the same time through the Spark Max
Given a NEO/NEO550 motor
Is it possible to use the Spark Max’s relative encoder and also plug in a REV through bore encoder used as either Absolute or Relative(Incremental) and get date from each at the same time through the Spark Max
Yes, this is possible by using the getEncoder()
method in the CANSparkMax
class in combination with getAbsoluteEncoder()
, getAlternateEncoder()
, or getAnalog()
You’d want to plug in your through bore using either one of these for absolute mode:
or one of these for relative mode:
For more information see the revlib docs on CANSparkMax:
https://codedocs.revrobotics.com/java/com/revrobotics/cansparkmax
It does not look like it is possible currently to use all three (NEO Relative Encode, Through Bore Relative Encoder, and Through Bore Absolute Encoder). You would have to pick two (where you only get both Through Bore inputs using a Brushed Motor, not a NEO).
The reason for this is that to use both relative encoders you need to use the Alternate Encoder Mode on the Spark MAX, which repurposes the Absolute/PWM Pin which the Through Bore Absolute Input would use for the Relative Encoder Quadrature input.
I don’t know what your current use case is, but personally I would opt for the use of the NEO Relative Encoder and Through Bore Absolute Encoder, and just handle converting the relative encoder counts/position to that of the Through Bore’s position in software by calculating the gear ratio between the two. This would also give you access to the Limit Switches if you need them, and wouldn’t have the ~20RPM speed limit the use of the Alternate Encoder Mode would impose using a Through Bore Encoder’s relative output.
Yet Another option would be to use an analog absolute sensor for your absolute value input like a poteniometer (in case of only needing a few rotations) or an MA3 encoder (in the case of continuous rotation). You’d still lose the use of limit switches, but you could have the NEO Relative Encoder, Through Bore Relative Encoder, and Analog Absolute Encoder/Sensor. Of course this would add complexity with more sensors.
Basically using a through bore to control an elevator. Would like to use it directly, but allow the user to switch the relative if it came disconnected. Use the Through bore in absolute the primary. If it starts acting funny switch to the relative mid match.
Switching between using the through bore absolute input and NEO relative Encoder should be perfectly doable as you should be able to use both simultaneously using the Absolute Encoder Adapter that FritzG linked above.
Here are a few recommendations from my own experiences for such an implementation (assuming Java/C++ Command Based).
Include a Limit Switch at, at least, the bottom of your elevator Motion. Really you should try to have one that will trigger at the top of your motion too to stop over-extension, but the reason I specify one at the bottom in particular is that it makes a very convenient way to zero your relative encoder if your absolute encoder is out of commission in the event of some kind of position drift. You can create a Button
object in your code that reads the state of the SparkMAX’s Limit Switch and use that to schedule a ‘zero encoder’ command when it is triggered.
Abstract the encoders interfaces. In the elevator subsystem, I would have two Encoder Methods, one for each the absolute and relative encoders, that handles converting the encoder values to make them the same unit. That way any higher level code (Commands) do not need to actually care about which encoder they are reading.
Handle switching at the Subsystem Level. Have a boolean variable and generic “get position” method in the subsystem that returns one of the two encoder methods from the above recommendation based on the value of the boolean variable (false = absolute encoder, true = relative encoder or visa-versa). Then you simply need some kind of trigger/button and Command that changes that boolean variable’s value to switch between your two encoder inputs without having to complicate your other commands or their triggers/buttons. Everything is handled at the subsystem level and everything above it doesn’t have to care about where the value came from.
Good Luck, and feel free to ask for more info/details if needed.
Hey thanks. This was basically what we planned on doing in the future, except using limit switches. We were going to use manual control for that, but limit switches sound good too.
Is there a way to determine if the through bore absolute encoder loses connection. So let’s say I can still see the SparkMax, but lose connection to the through bore. Is there a way to do this with kError codes
I am not aware of any sort of error code that would be thrown, though it may exist, that would likely require either physical testing or deep diving into the documentation/API to figure out.
I know one way you could do it is having some code that monitors both inputs, if the relative encoder value is changing, but the absolute encoder’s is not, or isn’t changing as expected (depending on if the input floats at weird values or not, would likely take physical testing to see what the behavior is), that could indicate an issue. Fine tune that health check, put it in a method returning a boolean health status, tie that to a Button, and have it handle automatic switch-over (though make sure you have an override)
Our team used both absolute and relative encoders on our robot’s wrist and Arm this year, and our logic was basically that if the built in encoder dies we’re in trouble anyway (since it’s required for the motor to run properly) so we just sync the builtin to the absolute value on initialization
Something you might run into when trying to use the absolute functionality of a through bore encoder with an elevator is that the through bore only is absolute on one rotation. This basically means that it’ll tell you what angle it’s currently rotated to, but not how many times it has previously been rotated. Most elevator designs that I’m familiar with require several rotations of the output pulley in order to extend fully, so this might be something you need to think through.
If I forgot to buy this, can I connect it to sparkmax and take motor encoder away? I want to use it for PID, but not sure if this way work.
Can you provide more details? Is the thing you forgot to buy one of the encoder adapter boards mentioned here? Are you hoping to run a PID off of a through bore encoder without one of those boards?
Yeh, I am not sure if I can run a PID only with through bore encoder instead of motor encoder.