article / 11 min
Set up a Limelight on your FRC robot: wiring, power, static IP networking, the web UI, building pipelines, AprilTag botpose, and NetworkTables in Java.
/ 2,438 words / 11 sections
A Limelight is the fastest way to give an FRC robot eyes. It is a self-contained smart camera: an image sensor, a small Linux computer, and LEDs in one housing that runs vision pipelines on-board and publishes results to your robot over NetworkTables. You do not process pixels in your roboRIO code — you read a handful of numbers like "how far left is the target" and "where am I on the field," and act on them. That trade of flexibility for speed is exactly why so many teams reach for one when they need aiming or AprilTag localization working before their next event.
This guide walks the whole setup end to end: choosing and mounting the camera, powering and networking it, first configuration in the web UI, building a pipeline, standing up AprilTag pose estimation with MegaTag, and finally reading the values in your Java code. Everything here is checked against the current Limelight documentation as of the 2026 season. Where a detail is model- or firmware-specific, it is called out so you can confirm against the docs for your exact hardware.
Limelight has shipped several generations — Limelight 1, 2/2+, 3, 3A, 3G, and 4. For AprilTag-heavy games the meaningful split is between the color-capable models and the monochrome long-range models:
The exact FOV, sensor, and on-board IMU details differ per model and are version-specific — check the hardware comparison page in the Limelight docs before you buy. If you are still deciding between platforms entirely, our Limelight vs PhotonVision comparison breaks down the trade-offs.
Mounting quality determines how much you can trust the numbers coming back. A camera that flexes or vibrates produces noisy tx/ty readings and, worse, unstable pose estimates.
Mounting tips: Bolt the Limelight to a rigid part of the frame or superstructure, not to thin sheet metal or anything that oscillates when the robot drives. Aim it so your primary targets sit in the center third of the frame at typical scoring range. A slight upward tilt often helps see AprilTags on field walls without catching ceiling glare.
For AprilTag localization, the physical position of the camera relative to your robot's center matters just as much as rigidity, because the Limelight uses it to convert what the camera sees into where the robot is. Measure that offset carefully in meters and degrees — you will enter it in the web UI later. Getting it wrong by a few centimeters shifts every pose estimate by the same amount.
Limelights run on your robot's 12V system, but not directly off an unprotected battery lead. The documented method is to run two 18-20 AWG wires from the camera's power leads to an open slot on your PDP/PDH, protected by a 5A breaker in that slot.
The input range is 4.1V-16V on current models (the 2025 "red button" variant accepts 4.1V-24V, with a 30V absolute maximum). That range comfortably covers a normal FRC battery, but it is why you should never feed it through a boost regulator or an unfused tap.
Limelights can also be powered over Ethernet using a passive PoE injector on the network run — support and connectors vary by model, so confirm the exact scheme for your unit on the Limelight wiring page before cutting anything.
Wiring tip: Keep the Ethernet run to the radio short and strain-relieved. A flaky Ethernet connection is the single most common cause of "the Limelight disappears mid-match." Note that the Limelight talks over Ethernet, not the CAN bus — it does not share the CAN chain with your motor controllers.
The Limelight joins your robot's network and speaks NetworkTables. Limelight OS runs a NetworkTables 4 client that auto-connects to the NT4 server on your robot based on the team number you set in the web UI's Settings tab. All of its data is published to a table named after the device (default: limelight).
Set a static IP rather than relying on DHCP. The docs recommend this because a static IP shaves several seconds off boot time and sidesteps DHCP/mDNS problems that teams have historically hit on real FRC fields with event radio firmware. Configure it in Settings as:
10.TE.AM.11 — replace TE.AM with your team number (team 916 → 10.9.16.11)255.255.255.010.TE.AM.1The .11 is a convention that keeps the Limelight clear of the roboRIO (.2) and radio (.1); if you run multiple Limelights, give each its own address and its own device name.
Power the robot, connect to the same network, and open the Limelight dashboard at http://limelight.local:5801, or at http://<your-static-ip>:5801 once you have set one. You can also launch the Limelight Hardware Manager to scan for devices on the network. If the camera is brand new, use the Hardware Manager's Flash OS tab over a USB-C cable to image it with the latest Limelight OS before anything else.
The dashboard shows a live camera feed, the current pipeline's tuning controls on the side panels, and the live NetworkTables values at the bottom. This is where you will spend most of your setup time. A second stream is available at http://<ip>:5800 for putting the feed on a driver-station dashboard like Shuffleboard or Elastic.
A pipeline is a saved set of vision settings. The Limelight stores up to 10 (indices 0-9), and you switch between them at runtime by writing the pipeline key. Each pipeline has a type, and the two you will use most are:
tx, ty, ta, and tv.tx/ty to a specific ID and full 3D field localization.To build a color pipeline, put a target in view, drop the exposure until the image is dark except for your lit target, then widen the HSV thresholds just enough to cover the target under match lighting. Lower exposure is your friend — it cuts ambient light and makes thresholding stable. Save it to a pipeline index and note that index for your code.
For AprilTag work, set pipeline 0 to the AprilTag type and enable its 3D/localization functionality. Then do two things in the web UI:
.fmap) so the Limelight knows where every tag lives on the field.With both set, the Limelight computes botpose: your robot's position and rotation in field space, published as an array of x, y, z (meters) and roll, pitch, yaw (degrees) plus latency data. For 2024 and later, always use the blue-origin variant — botpose_wpiblue — because WPILib and path-planning tools standardize on a blue-corner field origin regardless of alliance. Our AprilTags explainer covers the tag families and field layout in more depth.
Limelight offers two localization solvers:
MT2's cost is one obligation: you must call SetRobotOrientation(name, yaw, 0,0,0,0,0) every loop before you read the estimate, so the camera has a current heading. Read the result from botpose_orb_wpiblue (or getBotPoseEstimate_wpiBlue_MegaTag2() in code). The 3G and 4 can fuse an external/on-board IMU for even steadier MT2 headings.
Everything the Limelight knows shows up as keys in its NetworkTables table. These are the ones you will actually use:
| Key | Meaning | Notes |
|---|---|---|
tv | Valid target? | 1 if a target exists, 0 if not |
tx | Horizontal offset to target | Degrees, negative = target is left of crosshair (~±29.8° on LL2-class lenses) |
ty | Vertical offset to target | Degrees; pair with a known height to estimate distance |
ta | Target area | Percent of the image, 0-100; a rough distance proxy |
tl | Pipeline latency | Milliseconds; add capture latency cl for the total |
tid | Primary AprilTag ID | The in-view tag the solver is keyed on |
getpipe | Active pipeline index | 0-9, the pipeline currently running |
botpose_wpiblue | Robot pose, blue origin | [x, y, z, roll, pitch, yaw, latency, …]; MegaTag1 |
botpose_orb_wpiblue | Robot pose, blue origin | MegaTag2 estimate; requires SetRobotOrientation |
pipeline | Set active pipeline | Write 0-9 to switch pipelines |
ledMode | LED control | Force on/off/blink or let the pipeline decide |
snapshot | Capture a still | Increment to trigger a snapshot for later tuning |
You can read these keys straight from the NetworkTable, but the official LimelightHelpers class (a single Java file you drop into your project) wraps all of them cleanly. Here is a minimal proportional-aim example that turns the robot until the target is centered:
import frc.robot.LimelightHelpers;
public void teleopPeriodic() {
boolean hasTarget = LimelightHelpers.getTV("limelight"); // valid target?
double tx = LimelightHelpers.getTX("limelight"); // degrees left/right of crosshair
double ty = LimelightHelpers.getTY("limelight"); // degrees up/down
double ta = LimelightHelpers.getTA("limelight"); // % of image filled
if (hasTarget) {
double kP = 0.02; // tune this
double turn = -tx * kP; // drive tx toward 0
drivetrain.arcadeDrive(0.0, turn);
}
}
Pass the device name ("limelight", or whatever you named it) to every call so the code works even with multiple cameras. For per-tag detail, LimelightHelpers.getRawFiducials("limelight") returns a RawFiducial[], each with id, txnc, tync, ta, distToCamera, distToRobot, and ambiguity.
For localization you do not aim — you fuse the Limelight's field pose into your drivetrain's pose estimator. The MT2 pattern each loop is: call LimelightHelpers.SetRobotOrientation("limelight", gyro.getYaw(), 0,0,0,0,0), then grab LimelightHelpers.PoseEstimate mt = LimelightHelpers.getBotPoseEstimate_wpiBlue_MegaTag2("limelight"). The PoseEstimate gives you mt.pose (a Pose2d), mt.timestampSeconds, and mt.tagCount. Reject bad frames — skip when mt.tagCount == 0 or when your gyro's angular velocity exceeds 360°/s — then hand the rest to WPILib:
m_poseEstimator.addVisionMeasurement(mt.pose, mt.timestampSeconds);
That single call blends vision into your odometry, correcting drift while your wheel encoders and gyro carry you between tag sightings.
tx = 0 means "on target" for your mechanism.ty over ta for distance. Target area changes with pipeline settings and lighting; ty combined with a fixed mounting angle and known target height gives a much steadier distance estimate.PoseEstimate (or tl + cl) when feeding the estimator, so WPILib knows the measurement describes where you were, not where you are.snapshot key to capture frames during a real match, then re-tune against them in the pit instead of guessing.DHCP usually works on the bench, but the docs recommend a static IP (10.TE.AM.11, netmask 255.255.255.0) for competition. It boots faster and avoids DHCP/mDNS issues that have historically bitten teams on real fields with event radio firmware.
Almost always one of three things: no AprilTag is in view, you have not uploaded the season field map, or the pipeline is not set to the AprilTag type with 3D enabled. Confirm a valid tid first, then check that botpose_wpiblue populates.
MegaTag2 for nearly everyone. It resolves the single-tag ambiguity that makes MT1 jittery, but it requires feeding your gyro heading via SetRobotOrientation every loop. If you have a reliable gyro, MT2 is more accurate and more stable.
You can switch a single camera between an aiming pipeline and an AprilTag pipeline by writing the pipeline key, but you cannot do both simultaneously on one unit. Teams that need both at once typically run two Limelights with different device names.
Grab the table with NetworkTableInstance.getDefault().getTable("limelight") and read entries like getEntry("tx").getDouble(0.0). LimelightHelpers just wraps this and adds typed pose parsing, so it is worth using, but the raw keys are always available.
No. It communicates entirely over Ethernet/NetworkTables and draws power from a PDP/PDH slot behind a 5A breaker. It does not occupy a CAN ID, a PWM port, or a roboRIO DIO.
Once the camera is mounted rigidly, powered through a 5A breaker, addressed statically, and publishing a clean botpose, the hard part is over — the rest is tuning kP values and deciding which vision measurements to trust. Start with a single AprilTag pipeline and MegaTag2 into your pose estimator, get that solid, and add aiming pipelines from there. For more programming and hardware walkthroughs, browse the rest of our guides.
where this came from
This article is AI-assisted: drafted from primary sources, then reviewed and edited by hand. Errors still get through. When one is reported we fix it and write down what changed, in public, in the corrections log.
dept / programming-software
You came for one answer. These teach the same subject properly, in the order a team actually learns it. All 51 are free, and none of them need an account to read.
if you want to keep the ticks
LearnFRC has 394 free FRC lessons across every department. Create a free account to save your place, track your progress, and earn a certificate.
Create a free accountReading never needs one. This is only for saving where you got to.
these are the closest, not the newest
8 min read
AprilTags in FRC are the fiducial markers robots use to see the field and know their exact position. How the tags, cameras, and pose estimation actually work.
read it7 min read
Where FRC robot weight actually concentrates, which cuts save pounds without losing strength, what to leave alone, and how to track weight from kickoff to ship week.
read it13 min read
Your WPILib deploy is failing? Work the decision tree: wrong folder in VS Code, team number, roboRIO image, JDK version, macOS network privacy. Fixes for each.
read itend of sheet
Keep going with the other 102 articles, or work through all 394 lessons across 11 departments.