FRC Sensors Explained: Encoders, Gyros, Beam Breaks, and Limit Switches
A practical FRC guide to encoders (quadrature, absolute, CANcoder, through-bore), gyros (NavX2, Pigeon 2.0), limit switches, beam breaks, and current sensing.
- to read
- 17 min
- words
- 3,449
- sections
- 8
to read
words
sections
Your motors can spin a mechanism, but without sensors your robot is blind. It has no idea whether the arm is at 30 degrees or 90, whether the elevator has hit the top, whether a game piece is actually in the intake, or which way it's pointing on the field. Sensors are how the roboRIO closes the loop between "what the code commanded" and "what physically happened." Get them right and your autonomous routines repeat to the millimeter; get them wrong and you spend competition debugging phantom behavior.
This guide is a practical tour of the sensors FRC robots actually use — encoders, gyros/IMUs, limit switches, beam-break and proximity sensors, and current sensing — how each one works, how it wires into the control system, and how to pick the right one for a given mechanism. Every number here is pulled from a primary source (REV, CTR Electronics, Kauai Labs, and WPILib docs) so you can trust it on your bill of materials.
The big picture: what a sensor gives you
A sensor converts a physical quantity — angle, distance, presence, current — into an electrical signal the roboRIO can read. In FRC, those signals arrive over four broad channels:
- Digital IO (DIO): on/off or pulse-train signals on the roboRIO's DIO ports. Limit switches, beam breaks, and quadrature/PWM encoders live here.
- Analog input: a continuous 0–5V voltage the roboRIO reads on its analog channels. Potentiometers and some distance sensors use this.
- CAN bus: smart sensors that stream position, velocity, and status as data packets. CANcoder and Pigeon 2.0 are CAN devices. See our CAN bus guide for how the network is built.
- Motor-controller integrated: sensors baked into the motor (like the encoder inside a Kraken or Falcon) that report through the controller.
Picking a sensor is really picking one of these paths, then matching the resolution and robustness to the job.
Encoders: measuring rotation and distance
An encoder measures how far and how fast a shaft has rotated. Because almost everything on a robot is rotational — wheels, arm pivots, elevator drums — encoders are the workhorse sensor of FRC. There are two fundamentally different flavors, and confusing them causes real bugs.
Incremental (quadrature) encoders
An incremental encoder outputs a stream of pulses as the shaft turns. It has two channels, A and B, offset by 90 degrees — that's what "quadrature" means. By watching which channel leads, the roboRIO knows both how much the shaft moved (count the pulses) and which direction (compare the phase). Reverse the direction and the phase relationship flips.
The key limitation: an incremental encoder only measures change. It has no idea where it is at power-on — it starts counting from wherever it happens to be, which the code treats as zero. That's fine for a drivetrain wheel (you only care about distance traveled since auton started) but dangerous for an arm, because after a reboot the code thinks the arm is at zero no matter where it actually is.
Resolution is quoted in counts per revolution (CPR). Because quadrature has two channels each with rising and falling edges, decoding electronics can count 4 edges per cycle — "4x decoding." The REV Through Bore Encoder, for example, outputs 2048 cycles per revolution, which becomes 8192 counts per revolution in 4x quadrature mode, per the REV Through Bore Encoder datasheet. More counts means finer angular resolution.
Wiring is simple. Per the WPILib hardware docs, the roboRIO's onboard DIO ports are 5V-tolerant (reading high above 2.0V, low below 0.8V, up to a 5.25V maximum input) with built-in 40 kΩ pull-up resistors to 3.3V. A quadrature encoder needs one power pin, one ground pin, and two signal pins (A and B) landing on two DIO ports.
Absolute encoders
An absolute encoder reports its actual shaft angle at all times — even immediately after power-on, even if the shaft was moved while the robot was off. Internally it senses the position of a magnet (or an optical pattern) and outputs the true angle over a full rotation. This is exactly what you want for an arm pivot or a swerve steering module: the mechanism knows where it is the instant it boots, so you never need a homing routine.
Two common ways the angle gets to the roboRIO:
- PWM / duty-cycle output: the encoder encodes the angle as the width of a repeating pulse. The roboRIO measures the pulse on a DIO port and converts it to an angle. WPILib reads these with the
DutyCycleEncoderclass. The REV Through Bore Encoder's absolute duty-cycle output has 12-bit resolution — 4096 increments per revolution on the V2 (the V1 is 10-bit, 1024 increments per revolution), per REV — and is factory-calibrated to ±0.5° accuracy. - CAN output: the encoder is a full CAN device streaming its angle as data. No DIO port used, no pulse to decode.
The CANcoder
The CTRE CANcoder is the go-to absolute encoder for serious mechanisms, and it's what most swerve modules use for steering. It's a magnetic absolute encoder that talks over the CAN bus (both CAN 2.0 and CAN FD), reporting position at 4096 units per rotation (12-bit native resolution), per CTR Electronics. Because it's on CAN, you get a clean absolute angle without burning a DIO port or running a long, noise-prone signal wire back to the roboRIO — you just tap the CAN chain. In swerve drives, each of the four steering axes typically gets a CANcoder so the wheels snap to the correct heading at boot without any homing.
Integrated motor encoders
Modern brushless motor controllers ship with an encoder already inside. The Kraken X60, Falcon 500, and NEO all report rotor position and velocity straight through their controllers — no external sensor, no extra wiring. Phoenix 6 (CTRE) and the REV library expose this as rotations and rotations-per-second. For any mechanism driven by one of these motors, the integrated encoder is often all you need for velocity control and is the reason they've become the default — see our motor comparison for the full rundown.
The catch: an integrated encoder measures the motor rotor, upstream of the gearbox. If there's any gear reduction, chain slack, or belt stretch between the motor and the mechanism, the rotor's count doesn't perfectly equal the mechanism's true position. That's why arms and swerve steering often pair an integrated encoder (for smooth velocity control) with a separate absolute encoder mounted directly on the output shaft (for true position). More on that combo below.
Potentiometers — the analog cousin
A potentiometer is a variable resistor whose wiper voltage tracks shaft angle; the roboRIO reads it as a 0–5V analog signal. It's absolute and dirt cheap, but most FRC pots only turn about 10 turns or less, they wear out, and they're noisier than a magnetic encoder. They still show up on simple arms and as a low-cost absolute reference, but for anything precise, a magnetic absolute encoder has largely replaced them.
Encoder comparison
| Type | Absolute? | Interface | Typical resolution | Best for |
|---|---|---|---|---|
| Quadrature (e.g. Through Bore ABI) | No | 2 DIO | 8192 counts/rev (4x) | Drivetrain distance, velocity |
| Duty-cycle absolute (Through Bore PWM) | Yes | 1 DIO | 12-bit (4096/rev, V2) | Arm/wrist angle |
| CANcoder | Yes | CAN | 4096/rev | Swerve steering, arm pivots |
| Integrated (Kraken/Falcon/NEO) | No (rotor) | Motor controller | High, in rotor rotations | Velocity control on any mechanism |
| Potentiometer | Yes | 1 analog | Limited, noisy | Cheap simple arms |
Gyroscopes and IMUs: knowing your heading
An encoder tells you about a shaft. A gyroscope tells you about the whole robot's orientation in space. In FRC the practical job is measuring yaw — the robot's heading, its rotation about the vertical axis. This is essential for field-oriented swerve driving, for holding a straight line in autonomous, and for fusing with vision to localize on the field.
Modern FRC "gyros" are really IMUs (Inertial Measurement Units): a chip combining a 3-axis gyroscope (angular rate) and a 3-axis accelerometer, sometimes plus a magnetometer. The device integrates angular rate over time to produce a heading. The enemy of every gyro is drift — tiny rate errors accumulate, so a stationary robot slowly "rotates" in software even though it hasn't physically moved. Low drift is the single most important spec.
NavX2 (Kauai Labs)
The navX2-MXP plugs directly onto the roboRIO's MXP expansion port and is built around an industrial-grade ISM330DHCX IMU. Per the Kauai Labs navX2-MXP user guide, it delivers very low yaw drift — on the order of 0.5° per minute while moving and under 0.2° per hour when still — with a configurable update rate from 4 up to 200 Hz over SPI/I2C/USB (200 Hz = a fresh sample every 5 ms). It tolerates rotation rates up to 4000°/second and impacts up to 16G, so a hard collision won't corrupt your heading. There's also a navX2-Micro variant that connects over USB or I2C for teams not using the MXP header.
Pigeon 2.0 (CTR Electronics)
The Pigeon 2.0 is a 9-degrees-of-freedom IMU (accelerometer + gyroscope + magnetometer) that communicates over CAN and CAN FD, per CTR Electronics. Its headline features are convenience: no on-boot stillness, no boot calibration, and no temperature calibration are required, so you get useful heading the moment it powers on — the device predicts the gyroscope bias at startup and compensates for temperature drift internally rather than through a user calibration step. Yaw is reported continuously (it doesn't wrap at 360°), which is ideal for heading control loops. Because it's a CAN device, wiring is just power and the CAN chain — no MXP header needed, which many teams prefer.
Choosing a gyro
Both are excellent; the decision is mostly about your wiring and control architecture:
- On CANivore / heavy CAN swerve, or want zero-fuss boot: Pigeon 2.0 fits naturally onto the CAN bus alongside your CANcoders and Talons.
- Want the MXP header, a proven low-drift spec, or high configurable update rates: navX2-MXP.
- Mounting matters more than brand. Mount the IMU near the robot's center of rotation, rigidly, and away from vibration. A gyro bolted to a wobbly panel will report garbage no matter how good the chip is.
One rule that saves competitions: let the gyro finish its startup window before enabling, and don't move the robot during that time if your device calls for it. A yaw offset baked in at boot will haunt every autonomous run.
Limit switches: the simplest, most valuable sensor
A limit switch is a mechanical on/off switch — usually a lever or roller (a "snap-action" switch) — that closes a circuit when a mechanism reaches a physical position. It's the cheapest sensor on the robot and often the most important, because it protects mechanisms from destroying themselves.
Typical uses:
- End-of-travel protection: a switch at the top of an elevator or the hard stop of an arm cuts or reverses motor power before the mechanism slams into its frame. On a fast elevator or arm, this is the difference between a bent lead screw and a clean match.
- Homing / zeroing: because incremental encoders lose their reference at power-off, teams drive the mechanism slowly until it trips a limit switch, then set the encoder to a known value. Now relative counting has an absolute anchor.
Wiring is beautifully simple. Per WPILib, you connect a normally-open switch between the signal and ground pins of a DIO port — just two wires, no power needed. Thanks to the roboRIO's built-in pull-up, the port floats high when the switch is open and is pulled low when the switch closes to ground. Read it in code with WPILib's DigitalInput.
A few practical notes:
- Normally-open vs normally-closed: normally-closed wiring (the circuit is closed until tripped) fails safe — a cut wire reads the same as "tripped," so the robot stops rather than driving into a wall. It's worth the extra thought for critical end stops.
- Debounce in code if a switch chatters, and mount switches so the mechanism reliably actuates the lever without over-traveling and snapping it off.
- Many motor controllers have dedicated limit-switch inputs that can cut motor output in firmware, faster and more reliably than a round trip through robot code.
Beam breaks and proximity sensors: detecting game pieces
Limit switches detect your mechanism; beam-break and proximity sensors detect game pieces — the ball, disc, or other game piece sitting in an intake or indexer. Nailing "is a piece present, and where?" is what makes an intake reliable in a match.
Beam-break sensors
A beam-break is an emitter and a receiver facing each other. The emitter shines an (infrared) beam at the receiver; when a game piece passes between them and blocks the beam, the output changes state. Electrically it behaves just like a switch — it lands on a DIO port and reads as a clean digital high/low, so DigitalInput handles it. Beam breaks are the standard for indexers: place one where a piece must pass, and you get an unambiguous "piece is here" signal to trigger the next stage or stop a feed motor. Their weakness is alignment — emitter and receiver must stay pointed at each other, and bright arena lighting or a dusty lens can cause false reads if the beam is marginal.
Proximity sensors
Proximity sensors detect an object without a receiver on the far side:
- Optical/IR reflective sensors bounce light off an object and detect the return. Simple and cheap, but sensitive to surface color and ambient light.
- Inductive sensors detect nearby metal — useful for sensing a metal mechanism position without a physical switch to wear out.
- Time-of-flight (ToF) sensors measure actual distance by timing a light pulse's round trip, giving a millimeter-scale distance reading over I2C. These are great when you need "how far," not just "present or not" — for example, sensing how deep a game piece has seated. WPILib exposes I2C for these.
Proximity sensors typically output either a digital signal (present/absent, on a DIO port) or an analog voltage / I2C distance value, depending on the model. Match the output type to a free roboRIO port before you buy.
Choosing a presence sensor
- Piece passes through a channel: beam break — clean, binary, reliable.
- Piece approaches one surface: reflective proximity or ToF.
- Need distance, not just presence: time-of-flight over I2C.
- Detecting metal mechanism position: inductive proximity.
Current sensing: the sensor you already own
Your Power Distribution module is also a sensor. Both the CTRE PDP and the REV PDH measure the current flowing through each channel and report it over CAN. Per REV and WPILib, the PDH provides 20 high-current channels (40A max) plus a set of low-current channels, and both modules let you read per-channel current in robot code.
Why this matters:
- Stall and jam detection: a motor drawing near its stall current for more than a moment usually means a jammed intake or a mechanism against a hard stop. Watching current lets you back off automatically before you pop a breaker or cook a motor.
- Game-piece detection without a dedicated sensor: an intake roller's current spikes when it grabs a piece. Some teams use this as a free "piece acquired" signal — no beam break required.
- Brownout awareness: correlating channel current with battery voltage helps you understand what's pulling the pack down. A robot draws through its snap-action breakers (commonly up to 40A on the high-current channels), and those tolerate a brief overcurrent before tripping.
Current sensing is noisy and lags real events slightly, so it's best as a supporting signal or a coarse trigger — pair it with a proper position sensor when precision matters.
Putting it together: picking sensors for a mechanism
Real robots layer sensors. Here's how the choices usually shake out:
- Drivetrain (tank/swerve drive): integrated motor encoders for wheel distance and velocity, plus a gyro (Pigeon 2.0 or navX2) for heading. Swerve adds a CANcoder per steering axis so wheels know their angle at boot. This sensor set is what feeds odometry and PID heading control.
- Arm / pivot: an absolute encoder on the output shaft (Through Bore in PWM mode or a CANcoder) so the arm knows its true angle at power-on, often combined with the motor's integrated encoder for smooth velocity control. Add limit switches at the hard stops as a safety net.
- Elevator: an encoder (integrated or Through Bore) for height, a limit switch at the bottom to home the encoder to a known zero, and a switch or soft limit at the top. Watch current to catch a mechanism binding on its rails.
- Intake / indexer: a beam break (or two) to track pieces through the path, optionally backed by motor current sensing for a redundant "got it" signal.
Quick selection rules of thumb
- Need position after a reboot without homing? Use an absolute encoder (CANcoder or duty-cycle Through Bore).
- Only need distance or velocity, and homing is easy? An incremental or integrated encoder is cheaper and simpler.
- Out of DIO ports or facing a long wire run? Move to a CAN sensor (CANcoder, Pigeon 2.0) — it's just a tap on the bus.
- Protecting a mechanism from itself? A $5 limit switch beats any amount of clever code.
- Detecting a game piece? Beam break first; current sensing as a backup.
Whatever you choose, wire it cleanly — strain-relieve connectors, keep signal wires away from motor leads, and label everything. Half of all "sensor problems" at competition are really wiring problems; our robot wiring guide covers the practices that keep signals clean.
Frequently asked questions
What's the difference between an absolute and a relative (incremental) encoder, and when do I need each?
A relative/incremental encoder only measures change from wherever it started, so it reads zero at power-on regardless of the mechanism's real position — great for a drivetrain wheel where you only care about distance traveled. An absolute encoder reports the true shaft angle immediately at boot, even if you moved the mechanism while the robot was off. Use absolute encoders on arms, wrists, and swerve steering where the code must know the real position without a homing routine; use incremental (or integrated motor) encoders for drivetrain distance and velocity.
Do I really need a separate gyro if my motors already have encoders?
Yes. Motor encoders tell you how far each wheel turned, but they can't reliably tell you which way the whole robot is pointing — wheel scrub, slip, and small errors make encoder-only heading drift badly. A gyro/IMU (navX2 or Pigeon 2.0) measures rotation directly, which is what field-oriented swerve driving, straight-line autonomous, and vision fusion all depend on. Encoders and the gyro do different jobs; you want both.
Why does my incremental encoder read zero every time the robot powers on?
That's expected behavior — an incremental encoder has no memory of absolute position and starts counting from zero at boot. To give it an absolute reference, either home the mechanism against a limit switch and reset the encoder to a known value once it trips, or switch to an absolute encoder (like a CANcoder or the Through Bore's duty-cycle output) that knows its real angle immediately.
Can I use motor current to detect a game piece instead of buying a sensor?
Sometimes, yes. When an intake roller grabs a piece, its current spikes, and you can read per-channel current from the PDP/PDH over CAN and use that as a trigger. It's a free "piece acquired" signal, but it's noisy, lags the real event slightly, and can false-trigger on any load change. For reliable, precise detection — especially knowing where a piece is in an indexer — a beam break is far better. Current sensing works best as a backup or coarse trigger.
How do I wire a limit switch to the roboRIO?
Use a normally-open switch and connect two wires between the signal and ground pins of a DIO port — no power wire needed. The roboRIO's built-in pull-up resistor keeps the port reading high when the switch is open and pulls it low when the switch closes. Read it in code with WPILib's DigitalInput. For safety-critical end stops, consider normally-closed wiring so a cut wire fails to the "stop" state, and note that many motor controllers have dedicated limit inputs that cut output in firmware even faster than robot code.
Keep reading
More from the pit
Start learning FRC — free
Structured lessons and quizzes across every department. Create a free account to save your progress, track your team, and earn a certificate.