Most "my IR sensor doesn't work" problems aren't hardware problems — they're missing a calibration step. This is a hands-on, code-included walkthrough for calibrating it right way, so your robot actually knows the difference between line and floor before it tries to follow either.
CALIBRATION & FINE-TUNING

The sensor isn't broken. It's just uncalibrated.
Note: Even though this blog is structed around Arc-8 and Arc-16 still you can refer it for most general ir sensor calibration and commonly faced issues.
Here's the pattern almost every new builder hits: the ARC-8 or ARC-16 is wired correctly, the indicator LEDs glow steady, analogRead() prints numbers to the Serial Monitor — and the robot still weaves off the line or ignores it completely.
The instinct is to blame the sensor. Nine times out of ten, the real issue is that the firmware is using a hardcoded "this counts as line" number that was never actually measured on your track, under your lighting, at your sensor height. Raw IR readings shift with the whiteness of your floor, the mounting gap, ambient light, and even which individual sensor unit you're holding — no two builds see identical numbers. A threshold that works perfectly on a forum tutorial's track can be meaningless on yours.
Calibration fixes this in under two minutes, and it's the single most common step new line follower builders skip.
What calibration is actually doing
Skip the code for a second and understand the idea first.
Every IR sensor channel outputs a raw analog value — a number roughly between 0 and 1023 — that represents how much infrared light bounced back. A perfectly white floor reflects a lot of light; a black line absorbs most of it. But "a lot" and "most" aren't fixed numbers. They're relative to your track.
Calibration is just this: sweep the sensor across both the line and the floor, record the lowest and highest number each channel ever reports, and use that specific range — not someone else's, not a guess — to translate every future reading into a normalized scale (say, 0 to 1000). Once a channel knows its own personal minimum and maximum, a "500" means the same thing every time: dead center between line and floor, regardless of what the raw voltage happened to be.
It's the same reason you calibrate a thermostat to a room instead of trusting a factory default — the room's real minimum and maximum are what matter, not what the box shipped with.
Before you calibrate: a 60-second checklist
Skipping these makes the calibration itself untrustworthy, so confirm all four first:
Mounting height is 3–10mm from the track surface. Too high and contrast drops; the array can't tell line from floor confidently.
Power supply is stable 5V, ideally through a regulator like the mp1584 or LM7805 — not a raw, sagging battery. Unstable power shows up as calibration values that drift every time you re-run the sketch.
You're on your actual competition-quality track, or as close to it as possible. Calibrating on a photocopy of a photocopy will give you numbers your real track won't match.
Every sensor is actually receiving IR. Point your phone camera at the array — IR light shows up as a faint purple glow on camera even though it's invisible to your eyes. No glow on a channel means check that connection before you calibrate anything.
If you're running the ARC-16, also confirm the E (enable) pin is wired and held LOW, and all four select lines (S0–S3) are connected to digital pins — the calibration code below won't read real values without them.
Step-by-step: calibrating the ARC-8
The ARC-8 is the simpler case — all 8 channels are direct analog pins, no multiplexer involved. Wire it into your controller's analog rail (the Blueprint 01 exposes all 8 on A0–A7), then upload this:
Upload the sketch, then immediately pick the robot up and slowly slide the sensor bar back and forth across both the black line and the white floor.
calibrate()runs for roughly 2,000 loops right at boot — that's your window.Cover every channel. Make sure each of the 8 sensors individually passes over both surfaces, not just the middle ones.
Open the Serial Monitor once
loop()starts. You'll now see normalized values (0–1000) instead of raw ones — hold the array over pure white and pure black to sanity-check that you're seeing numbers near the two extremes.
Step-by-step: calibrating the ARC-16
The ARC-16 reads all 16 channels through a single analog pin via its 16:4 multiplexer, so the code looks a little different — you're cycling through channels with the S0–S3 select lines instead of reading 16 separate pins.
Same physical process as the ARC-8 — sweep over both surfaces while calibrate() runs — just with more channels to cover. If values stay unstable after a clean calibration on a genuinely low-contrast track, that's the specific case where switching the Arduino's analog reference to 3.3V (analogReference(EXTERNAL), with AREF wired to 3.3V) can widen the usable range — that's a track-contrast fix, not a calibration bug.
How to know it actually worked
Don't just trust that the sketch ran — check the numbers:
Look at the spread, not just the values. A healthy channel usually shows several hundred raw units of separation between its recorded min and max. If min and max are close together (say, within 50–100 of each other), that channel never saw real contrast during your sweep — check mounting height and track quality before assuming it's a wiring fault.
Hold the array over pure white, then pure black. Normalized readings should land near 0 and near 1000 respectively. Landing in the middle for both means the sweep didn't actually cover both surfaces.
Every channel should behave the same way. One outlier channel reading oddly while the rest look clean almost always points to that one sensor's connection, not your code.
Common calibration mistakes
Only calibrating once, ever. A new track, a new room's lighting, or a different battery charge level all shift raw values enough to matter. Recalibrate whenever any of those change — it's part of your pre-race firmware routine, not a one-time setup step.
Sweeping over the line but not the floor (or vice versa). Both extremes have to be physically shown to the sensor during the calibration window, or
min/maxfor that channel is meaningless.Calibrating on a weak or dying battery. Voltage sag changes your readings; numbers gathered on a low battery won't match how the robot behaves on a fresh charge.
Copy-pasting someone else's min/max values from a forum post. They calibrated their track, their lighting, their sensor height — not yours. Those numbers are almost guaranteed to be wrong for your build.
Conclusion
Calibration isn't a formality before "the real coding starts" — it is the real first step, because every piece of navigation logic downstream, from simple threshold following to a full PID loop, is only as good as the numbers it's reacting to. Uncalibrated sensor data means your robot is making decisions based on noise, not the actual line.
Run the sketch, sweep both surfaces, check your spread — and once your array is reporting clean, consistent 0–1000 values, you're ready for the part that actually steers the robot: PID control, explained from the ground up.
What kind of min/max spread did your array come back with — and did any channel surprise you?
Done reading? Return to the field notes index or keep exploring TechGeeks robotics parts.


