Encoder resolution terminology: crowdsource edition

What encoder resolution measurement should FIRST software attempt to standardize on?
  • CPR (cycles per revolution)
  • CPR (counts per revolution)
  • PPR (pulses per revolution, 1 pulse = 1 count)
  • PPR (pulses per revolution, 1 pulse = 1 period)
  • EPR (edges per revolution, 1 edge = 1 count)
  • Something else (suggest in thread)

0 voters

So, as per usual, we’re seeing a lot of confusion about encoder resolution values. Part of the problem here is that no one seems to agree on a) what term should be used in the first place, and b) what that term actually means in practice.

In short, for a quadrature encoder, resolution can be stated in two separate numbers - the number of rising/falling edges per revolution, or the number of full periods per revolution (one-fourth the number of rising/falling edges). A quick google search will confirm that different resources use different acronyms for these two stats, and that each common acronym is used inconsistently by multiple common sources to mean one or the other. I’ve even seen a rare third instance of “PPR” referring to half the number of rising/falling edges.

When writing the characterization toolsuite, I attempted to change the terminology in an orthogonal direction to rectify this, by introducing “edges per revolution”, or “EPR” (which, as far as I know, isn’t used anywhere else). This appears to have done nothing but make everyone more confused, not in the least because now we have at least one popular motor on the market (the CTRE Falcon) that has a non-quadrature encoder, for which the term is technically inaccurate.

For want of any better ideas, I’m making this thread to crowdsource potential solutions (or, at least, ameliorations).


It may help to explain what the Falcon’s alternative to a quadrature encoder is. In my mind it’s a set of basically magnetic limit switches around the motor shaft, which would provide an output from several different channels but give a great idea where the shaft is. I’m pretty sure that’s not what happens though.

1 Like

whatever falcons call it


No standardization.

Preps people for the chaos of doing this in the real world.

Yes I’m jaded. Get off my lawn.

More useful answer: “Cycles per Revolution” is probably the relevant hardware-derived spec to use, and (IMO) what user-space code should deal with. The extra 4x/2x factor from edges is an artifact of how the software and electronics interprets that cycle, and therefor (IMO) lives inside that hardware only. As long as the user isn’t defining that encoding, keep it away from the user.

To me, “cycle” is unambiguous. If you look at the waveform of sensor output, one “cycle” would be the smallest non-repeating part of the pattern you can extract (and, is almost always defined pretty well in the datasheets).

Cycles per Rev still applies nicely even when the sensor hardware becomes magnetic in nature (and the electrical output is a sine wave of sorts).

But really really. Ya usually just gotta read the whole manual.


I voted for EPR. To my understanding EPR and CPR (counts per revolution) are the same number. I see CPR used more often but I think that is what is causing a lot of the confusion is nobody knows if you mean Cycles Per Revolution or Counts Per Revolution when you say CPR and the difference is everything. I don’t like Cycles per revolution as that doesn’t keep non quadrature encoders on the same playing field.

1 Like

I voted for CPR. It’ll be on every encoder data sheet, and the software can account for this. At this point, Falcon 500 and NEO series motors seem like enough of an edge case that it may be fine to add a special case for both of them, though as time goes on I suspect they’ll become standard as CIMs are phased out.

1 Like

Which one? This makes the point well.

I expect this to happen fairly quickly (if not already) for any team that is not extremely tight on money, which will more often be the teams worrying about encoders.

By your statement of “software can account for this” I will assume you mean “cycles per revolution” for CPR. Here are two of the most popular encoders in first. Neither mention CPR as cycles both mention it as counts, CUI calls your CPR PPR to make that even more confusing.
SRX Mag Encoder Section 1.4


Degrees, as a float. There should be a conversion factor that is fed in via the constructor, and derived classes can provide default constructors, so encoder X gets a constructor that provides the right conversion. This works for magnetic sensors too, is easy to understand and reason about, and puts the conversion factor in one reasonable place.

1 Like

Degrees between what though… neighboring edges (1/4 cycle), local maxima/minima (1/2 cycle), crest-to-crest (full cycle)? I thought about this too, but was stymied when I considered what the question was actually asking.

1 Like

Degrees in the sense of radians. In other words, just output things in degrees where 360° is one full rotation. The conversion factor you supply maps between edges, bits, cycles, whatever and degrees.

1 Like

I’m not entirely sure I understand the proposal. I at least agree that, at the end of the day, a nice class would calculate down to physical rotations and time, and user could should (as much as possible) be directly acting in terms of physical units.

WPI’s “distance per pulse” is fine as far as API’s go, I believe OP’s main gripe was… What exactly is this “pulse”? And, what nomenclature should be used to unambiguously indicate it across the board for all manufacturers?

Time comes in with velocity or acceleration. This is a bit off topic here, but I’d be tempted to just go with SI units on all of these (so consider radians, rather than degrees). There is also a difference between circular and linear motion. Degrees/radians is right for the former, meters (or inches or feet) is right for the latter. The units change for velocity or acceleration, of course.

There’s no way you can have a common sensor class for all the different types of sensors unless you do something like this – trying things to a feature of a particular kind of sensor means this particular detail is going to bleed up into all the classes that can use it.

1 Like

With respect, you’re missing the point. This thread is not about units of rotational or linear distance; it’s about ambiguity in the terminology around quadrature signals. Whichever your chosen unit of distance, you have to match it to a corresponding portion of the quadrature signal - but we have multiple choices for this portion, and for what we call that portion.


Sensors have a resolution. For a quadrature encoder, it’s 1/4 of the period of the light/dark lines – but the units for this resolution are still degrees/radians (or meters, for a linear encoder).

I am trying to watch the terminology but the question is kind of fuzzy here.

All linear/circular position sensors have a resolution, and an accuracy. The resolution is easy, traditional encoders are digital, analog sensors go through analog-to-digital conversion, and some sensors return a digital value. The number of events per rotation, or the number of bits over a full rotation provide the resolution. For accuracy, it’s a parameter of the sensor.

Most encoder interfaces I’ve seen count edges – so both counts and edges are the same. If you want to count either full or half periods, you lose resolution (unless you have fractional counts, but that’s only a semantic difference at that point).

1 Like

Lemme possibly rephrase the question, because I don’t agree with the statement:

There are multiple layers of conversion involved here:

  1. How to pick the “cycles” out of a periodic electrical signal
  2. How many periodic cycles are expected per revolution of the encoder
  3. How many revolutions of an encoder correspond to a particular motion in the end mechanism.

I’m purposefully ignoring the discussion of degrees/radians/revolutions/wrapped/continuous - The software answer is to make a class to do the conversions (ie just use Rotation2d).

The problem from OP, as I see it, is that 1 and 2 are frequently blurred together in datasheets and software API documentation. The survey is to eek out what the best way to unambiguously describe them is.

I’m still sticking to my metaphorical guns, even though it seems I’m going against the grain. For all sensors which communicate rotation via a frequency: Cycles (unabreviated!) is the way to go, as it’s the primary thing you can guarantee is tied back to electrical phenomenon.

Datasheets which can’t accurately and succinctly describe how rotation corresponds to electrical signals (IE, the sensor’s only job in life) for 2 should be declared “sucky” and shamed.

Similarly, software libraries which already internally know they are doing 1x, 2x, 4x, or whatever decoding (for 1) should not force the user to account for that factor in their code.

To be specific, I don’t believe this is easy at all. I base that on the fact that almost every year, I am drawing diagrams on a whiteboard to explain the concept to students. It’s never been a “copy/paste this number and look it magically works” thing.

1 Like

I remember having this conversation with someone a couple days ago.

The current standard of EPR for software makes it very clear that the software is doing 4x quadrature decoding and to give the highest precision number the encoder supports.

CPR and PPR in any sense is practically unusable. They can both be off by a factor of 4 very easily, a problem that was recently present in the characterization tool. Any team that looks at a datasheet and sees CPR could get anything under the sun. Not to mention, things like the NEO built in hall effect sensor doesn’t have a Cycles Per Revolution in the same way. It has an EPR of 42, with no option for a while number CPR.

EPR, defined as the maximum resolution of the encoder, is probably the only practical way to implement. Nothing in FRC uses anything less than 4x decoding.


Or you could be missing the point. Rather then try to come up with standardized terminology for which there is no standard, instead abstract it to a level where there is agreement. Instead of asking for edges or cycles and having to take into account several different methods of decoding for different motor controllers/wpilib instead ask the user for one rotation of the wheel, what does their encoder/decoder report.


This doesn’t work if they rotate it slightly more or less than a revolution - they’ll be off on their measurements.

1 Like

Correct, but the number used doesn’t have to be empirically measured. The empirical test confirms you’re within the right factor of ~2, but probably not much else.

I’m not 100% sure I understand. At least, in my view of the world, “Cycles per Revolution” wouldn’t have to be a whole number. As you mentioned it often is, but it’s really dependent on the underlying technology used to generate the electrical signal.

I might be splitting hairs here, but I think it’s an important hair to split. There’s still clarity needed to understand whether the encoder/decoder-reported-value will contain artifacts of a particular decoding strategy. I agree, the 99% use-case in FRC is 4x decoding, so perhaps that could be assumed in a roboRIO software API.

Yet, as clearly illustrated above, datasheets “out in the wild” don’t always make this assumption. So we’re right back to the same fact: you have to know how to interpret the datasheet to use the software API.

1 Like

I think the terminology is confusing this discussion, so I have to concede that it’s confusing. But we do have well defined and standardized terminology that greatly helps here, if used as defined – SI units. Resolution is also well-defined. I think where things go off the rails is trying to map quadrature encoders onto these terms. If I haven’t got this part right, then I apologize as I am off-topic or not answering the question or really contributing at all. Not trying to be dense or argumentative, good intent, …

With a quadrature encoder, there are two signals, 90° out-of-phase. This lets you work out direction, which is a big deal in many applications. So there isn’t just one signal at this level, which is one opportunity for creating confusion. Since both signals are digital, there at least are crisp edges here. If the problem is how to help students understand, that’s a discussion on a whole other level. If it’s to extract the information one-time for each sensor, we can do that here pretty easily. If we’re talking about sensors that don’t use this technique, that’s another factor – so I’ll drop that, at least here.

For quadrature encoders, the “cycle” is a bit like sin/cos – there are full periods of each of the two signals in one full period of the combined signal. But, the out-of-phase thing results in doubling the number of total edges and halving the overall period. You can count any of these things – full periods of the combined signal, full periods of one of the signals (this one is not commonly used for good reason – it’s kind of unnatural), or edges. The last of these is the resolution the sensor is capable of reporting. If you use one of the others, you are losing information/resolution, or you are forced to use fractions.

Vendors want to advertise the highest resolution they can, so there’s a tendency to emphasize edges, although they may not always use this exact term. However, since not everyone uses the same terminology/definitions, one has to read carefully (1x, 2x, and 4x are in fairly common use). The concept and mechanisms here are what they are, and resolution is clearly tied directly to the edges. So, distance/rotation per pulse is confusing because it’s too narrow – there are two signals, both pulsing. The combined signal “pulses” once per edge, if you want to try to put it in these terms.

1 Like