A Four-Way Line Tracking Sensor
| Difficulty | Intermediate |
|---|---|
| Category | Sensors |
| Supported boards | Arduino Uno R3 and compatible ATmega328P boards |
| Time needed | 55 minutes |
| Prerequisites | Flame Detection with an Infrared Sensor |
| Tested board | Not yet verified |
| Tested on | Not yet verified |
| Arduino IDE version | Not yet verified |
| Library | Not yet verified |
What it does
Four infrared reflectance sensors, each looking straight down at the floor. A white surface reflects the infrared back; black tape absorbs it. So each sensor answers one question: is the floor under me light or dark?
Four of those answers, read a hundred times a second, is enough to follow a line. It is the sensing half of a line-following robot, and the reason four is better than one is the whole idea of the part.
Before you begin
Required parts and tools
- An Arduino Uno or compatible board.
- One four-way tracking sensor set. This is Siratek product 2943.
- Black electrical tape and a sheet of white paper or card, to make a line.
- A small screwdriver for the trimmers.
- Six jumper wires.
What is in the set
The Siratek photographs show two kinds of board, and this is the thing that makes this part nicer than it first looks:
One main board, red, carrying a comparator chip, four blue trimmers and four indicator LEDs, with an output header along one edge.
Four separate sensor heads, each a small red board with an infrared emitter and a receiver and a three-pin connector, joined to the main board by a ribbon of coloured leads.
Because the heads are separate, you can space them to suit your chassis. A fixed four-in-a-row board makes you build the robot around the sensor; this one lets you put the sensors where the geometry wants them. That is worth more than it sounds when you come to mount it.
Telling the emitter from the receiver
Each head has two LED-shaped parts, marked on the silkscreen:
DT, the clear one: the transmitter. It emits infrared, which your eye cannot see.DR, the dark one: the receiver. The dark package is a filter that blocks visible light so only infrared gets through.
A phone camera sees infrared where your eye does not, so pointing one at the clear LED while the board is powered is a quick way to prove the emitter is working.
Height matters more than anything
These sensors have a narrow working range. Too far from the floor and the reflection is too weak to read; too close and the emitter’s light floods the receiver whatever colour is underneath.
Somewhere around 5 to 15 millimetres is usual, and the right figure is the one that works on your surface with your trimmer setting. Mount the heads so the height is fixed and the same for all four, because a sensor sitting two millimetres lower than its neighbours behaves like a differently adjusted one.
If one channel refuses to behave no matter how you set its trimmer, check its height before anything else.
Digital out only, and what that costs
Each channel gives one digital output: light or dark, with the threshold set by its trimmer. There is no analog pin, as on the flame sensor.
That makes the wiring and the code simple, and it means the trimmers are the calibration and you have to set them by watching the LEDs. The procedure is below.
For line following it is enough. For anything that needs to know how dark, an analog reflectance sensor is the part to look for.
Pin reference
| Pin | Connect to | Purpose |
|---|---|---|
VCC |
Uno 5V |
Power for the board and the emitters |
GND |
Uno GND |
Ground |
D1 |
Uno D4 |
Leftmost sensor |
D2 |
Uno D5 |
Centre left |
D3 |
Uno D6 |
Centre right |
D4 |
Uno D7 |
Rightmost |
Which physical head is D1 depends on how you plug the ribbon in, and the first sketch below settles it rather than assuming.
Wiring steps
- Unplug the USB cable.
- Connect the four sensor heads to the main board with the supplied leads.
GNDtoGND,VCCto5V.D1toD4,D2toD5,D3toD6,D4toD7.- Plug the USB cable back in. All four indicator LEDs should light or go out as you pass something light or dark under the heads.
Software and libraries
No library is required. Four digitalRead() calls.
Setting the trimmers
Do this before writing any logic. It takes five minutes and nothing works properly without it.
- Lay out your line: black tape on white card is ideal.
- Hold the sensors at the height they will be mounted at, over the white surface.
- Turn each trimmer until its indicator LED just changes state, then back it off slightly so it sits reliably on the “white” side.
- Move that head over the black tape. Its LED should change.
- Move it back. It should change back.
- Repeat for all four, and check them all again at the end, because adjusting one does not affect the others but your hand position will have drifted.
The run below makes this easier by printing all four states together.
Minimal working example
// Siratek: what each channel sees, and which physical head is which.
const int sensorPins[4] = {4, 5, 6, 7};
void setup() {
for (int i = 0; i < 4; i++) {
pinMode(sensorPins[i], INPUT);
}
Serial.begin(9600);
Serial.println("Siratek: cover each head in turn to find out which is which.");
}
void loop() {
Serial.print("[ ");
for (int i = 0; i < 4; i++) {
// On most of these boards the output is LOW over black. Confirm yours.
Serial.print(digitalRead(sensorPins[i]) == LOW ? "#" : ".");
Serial.print(" ");
}
Serial.println("]");
delay(150);
}
Cover one head at a time with your finger and watch which position in the display changes. That tells you the physical order, which is not necessarily left to right.
Then slide the whole assembly across your line and watch the pattern move: . # . . becoming . . # . and so on. Seeing that is the moment the part makes sense.
Check the polarity while you are there. If covering a head makes the display show . rather than #, your board reads the other way round, and the one comparison in the sketch is where to change it.
Turning four readings into a position
The useful abstraction is a single number: how far off-centre the line is.
// Siratek: a position from -3 (hard left) to +3 (hard right), or no line.
const int sensorPins[4] = {4, 5, 6, 7};
const int weights[4] = {-3, -1, 1, 3}; // leftmost to rightmost
const int NO_LINE = 99;
int linePosition() {
int total = 0;
int seen = 0;
for (int i = 0; i < 4; i++) {
if (digitalRead(sensorPins[i]) == LOW) { // dark: the line
total += weights[i];
seen++;
}
}
if (seen == 0) {
return NO_LINE;
}
return total / seen;
}
void setup() {
for (int i = 0; i < 4; i++) {
pinMode(sensorPins[i], INPUT);
}
Serial.begin(9600);
}
void loop() {
int position = linePosition();
if (position == NO_LINE) {
Serial.println("no line");
} else {
Serial.print("position ");
Serial.println(position);
}
delay(100);
}
Three things this gives you that four separate readings do not.
One number to steer by. Negative means the line is to the left, positive to the right, zero means centred. A motor sketch can use it directly.
It handles two sensors seeing the line at once, which happens constantly when the line is wider than the gap between heads. Averaging the weights puts the position between them.
It reports losing the line separately. NO_LINE is not zero, and the difference matters: a robot that treats “no line” as “centred” drives confidently off the table.
What to do when the line is lost
The honest answer is that losing the line is normal, especially on corners, and the behaviour you choose defines how the robot feels.
The simplest useful rule: remember which way you were last turning, and keep turning that way. If the line vanished to the left, it is probably still to the left.
int lastSeen = 0;
void loop() {
int position = linePosition();
if (position != NO_LINE) {
lastSeen = position;
// steer according to position
} else {
// steer hard in the direction we last saw it
}
}
A time limit belongs here too: if the line has been missing for a second, stop rather than continuing to spin.
All four dark means something
Four sensors reading dark at once is not a line. It is usually one of:
- A junction or a crossing in the course.
- The end of the line, marked with a wide band, which is a common convention.
- The sensors lifted off the surface, so nothing reflects.
Handle it deliberately rather than letting the averaging return zero and the robot drive straight on.
Expected result
Four indicator LEDs following light and dark under their heads, and a serial display whose pattern moves as you slide the assembly across a line.
Over plain white, all four should read light. Over the tape, the one or two over it should read dark.
Troubleshooting
| Symptom | Likely cause | Check or fix |
|---|---|---|
| One channel never changes | Height wrong for that head | Check all four sit at the same height |
| One channel never changes, height fine | Trimmer past its range | Turn it back through the whole range |
| All four always read the same | Too close to the surface | Raise them; the emitter is flooding the receiver |
| All four always read light | Too far from the surface | Lower them |
| Readings inverted | Board reads the other way | Change the one comparison |
| Unreliable in sunlight | Infrared in daylight | Shade the sensors; they are indoor parts |
| Works on paper, not on a shiny floor | Specular reflection | Matte surfaces work best |
| Pattern jumps about | Loose lead, or a wobbling mount | Fix the height mechanically |
| Robot drives off on a corner | “No line” treated as centred | Report it separately and act on it |
| Adjusting one trimmer upsets another | It does not; your hand moved | Recheck all four at the end |
Next steps
- Easier first: Flame Detection with an Infrared Sensor, which is one sensor of this kind.
- Related products: the geared motor and wheel set, and the L298N driver, which turn a position into movement.
- Next project: a line following robot, which is this position number driving two motors.
Sources and attribution
All text, wiring guidance and code in this tutorial are original Siratek work.
- The main comparator board with four trimmers and four indicator LEDs, the four separate sensor heads on leads, and the
DTandDRsilkscreen marking the transmitter and receiver were read from the Siratek product photographs for item 2943.
Working height depends on the surface and the trimmer setting, so a range is given with a procedure for finding the right value. Output polarity varies between boards of this kind, so the tutorial has the reader confirm it. No third-party tutorial text, diagrams, photographs or code has been reproduced here.

