Triple IR Line Tracking Sensor

Details

Triple IR Line Tracking Sensor — 3-channel reflectance module

Summary

The Triple IR Line Tracking Sensor combines three reflective IR sensors (left/center/right) to detect dark lines on light surfaces (or vice-versa). Each channel outputs a digital signal via an onboard comparator (often with adjustable threshold), and some variants also expose analog outputs.

Tip: For best results, mount 2–8 mm above the surface and adjust the trimmers until each channel cleanly toggles when passing over the line.

Pins & Adjustments
  • VCC: 3.3–5 V (check your board’s silkscreen)
  • GND: Ground
  • D0 / D1 / D2: Digital outputs (active state depends on board; often active LOW on dark line)
  • A0 / A1 / A2 (if present): Analog reflectance level
  • TRIM POTS: One per channel to set the digital threshold
  • LEDs: Power and/or channel status indicators (varies by version)

Note: Some boards invert logic (LOW = line). If readings look backwards, invert in code.

Mounting & Wiring

Keep the sensor parallel to the surface. Connect VCC/GND and three outputs to your controller.

Triple IR sensor wiring: VCC, GND, D0/D1/D2 (or A0/A1/A2) to controller
Arduino Code

Read 3 Digital Channels

// Triple IR — digital read (invert if your board is active-high)
const int L = 4, C = 3, R = 2;  // D4,D3,D2 -> sensor D0,D1,D2
void setup(){ Serial.begin(115200); pinMode(L,INPUT_PULLUP); pinMode(C,INPUT_PULLUP); pinMode(R,INPUT_PULLUP); }
void loop(){
  bool l = digitalRead(L)==LOW;  // LOW = line (typical)
  bool c = digitalRead(C)==LOW;
  bool r = digitalRead(R)==LOW;
  Serial.print("L:");Serial.print(l); Serial.print(" C:");Serial.print(c); Serial.print(" R:");Serial.println(r);
  delay(60);
}

Simple Line-Follow (Differential Drive)

// Basic P-control using L/C/R for two motors (A: left, B: right)
const int L=4, C=3, R=2;
const int MA1=5, MA2=6, MB1=9, MB2=10; // motor driver pins (PWM capable)
int base=140, kp=80; // tune for your chassis

void setup(){
  pinMode(L,INPUT_PULLUP); pinMode(C,INPUT_PULLUP); pinMode(R,INPUT_PULLUP);
  pinMode(MA1,OUTPUT); pinMode(MA2,OUTPUT); pinMode(MB1,OUTPUT); pinMode(MB2,OUTPUT);
}

void drive(int left, int right){
  left = constrain(left, -255, 255);
  right= constrain(right,-255, 255);
  analogWrite(MA1, left>0? left:0);  analogWrite(MA2, left<0? -left:0);
  analogWrite(MB1, right>0?right:0); analogWrite(MB2, right<0? -right:0);
}

void loop(){
  bool l=(digitalRead(L)==LOW), c=(digitalRead(C)==LOW), r=(digitalRead(R)==LOW);
  int err = (r?1:0) - (l?1:0);      // right minus left
  int corr = kp*err;                // proportional correction
  int left = base - corr;
  int right= base + corr;
  if(!l && !c && !r){ left=right=0; } // lost line: stop (or spin search)
  drive(left,right);
  delay(10);
}

Optional: Read Analog Channels

// If your board exposes A0/A1/A2 (wired to A0/A1/A2 on Arduino)
void setup(){ Serial.begin(115200); }
void loop(){
  int l=analogRead(A0), c=analogRead(A1), r=analogRead(A2);
  Serial.print("L:");Serial.print(l); Serial.print(" C:");Serial.print(c); Serial.print(" R:");Serial.println(r);
  delay(40);
}

Tip: If your outputs read HIGH on dark lines, invert the logic in code or tweak the trimmers.

Raspberry Pi

Use 3 GPIO inputs for digital outputs. For analog sensing, add an ADC (e.g., MCP3008).

Read 3 Digital Channels

# sudo apt install python3-rpi.gpio
import time, RPi.GPIO as GPIO
L,C,R = 17,27,22  # BCM pins
GPIO.setmode(GPIO.BCM)
for p in (L,C,R): GPIO.setup(p, GPIO.IN, pull_up_down=GPIO.PUD_UP)
try:
    while True:
        l = GPIO.input(L)==GPIO.LOW  # LOW = line (typical)
        c = GPIO.input(C)==GPIO.LOW
        r = GPIO.input(R)==GPIO.LOW
        print(f"L:{int(l)} C:{int(c)} R:{int(r)}")
        time.sleep(0.06)
finally:
    GPIO.cleanup()

Read Analog via MCP3008 (optional)

# pip install adafruit-circuitpython-mcp3xxx
import time, board, busio
from digitalio import DigitalInOut
from adafruit_mcp3xxx.mcp3008 import MCP3008
from adafruit_mcp3xxx.analog_in import AnalogIn

spi = busio.SPI(clock=board.SCK, MISO=board.MISO, MOSI=board.MOSI)
cs  = DigitalInOut(board.CE0)
mcp = MCP3008(spi, cs)
l = AnalogIn(mcp, MCP3008.P0)
c = AnalogIn(mcp, MCP3008.P1)
r = AnalogIn(mcp, MCP3008.P2)

while True:
    print(f"L:{l.value} C:{c.value} R:{r.value}")  # 0..65535
    time.sleep(0.05)
ESP Coding

ESP32/ESP8266 (Arduino core): Sensor works at 3.3–5 V; ESP GPIO is 3.3 V. Use INPUT_PULLUP on the three digital channels. For analog variants, read with ADC-capable pins.

ESP32: Read 3 Digital Channels

#include 
const int L=13, C=12, R=14; // GPIOs to D0/D1/D2 (adjust as wired)

void setup(){
  Serial.begin(115200);
  pinMode(L, INPUT_PULLUP);
  pinMode(C, INPUT_PULLUP);
  pinMode(R, INPUT_PULLUP);
}

void loop(){
  bool l = digitalRead(L)==LOW;  // LOW = line (typical)
  bool c = digitalRead(C)==LOW;
  bool r = digitalRead(R)==LOW;
  Serial.printf("L:%d C:%d R:%d\n", l, c, r);
  delay(60);
}

ESP32: Simple Line-Follow (LEDC PWM)

#include 
const int L=13, C=12, R=14;
const int MA1=25, MA2=26, MB1=27, MB2=33; // motor driver pins (PWM-capable)
const int CH_A1=0, CH_A2=1, CH_B1=2, CH_B2=3;

int base=140, kp=80; // tune for your chassis

void pwmWrite(int ch, int val){ ledcWrite(ch, constrain(val,0,255)); }

void setup(){
  Serial.begin(115200);
  pinMode(L,INPUT_PULLUP); pinMode(C,INPUT_PULLUP); pinMode(R,INPUT_PULLUP);
  ledcSetup(CH_A1, 20000, 8); ledcAttachPin(MA1, CH_A1);
  ledcSetup(CH_A2, 20000, 8); ledcAttachPin(MA2, CH_A2);
  ledcSetup(CH_B1, 20000, 8); ledcAttachPin(MB1, CH_B1);
  ledcSetup(CH_B2, 20000, 8); ledcAttachPin(MB2, CH_B2);
}

void drive(int left, int right){
  left = constrain(left,-255,255);
  right= constrain(right,-255,255);
  pwmWrite(CH_A1, left>0? left:0);  pwmWrite(CH_A2, left<0? -left:0);
  pwmWrite(CH_B1, right>0?right:0); pwmWrite(CH_B2, right<0? -right:0);
}

void loop(){
  bool l=(digitalRead(L)==LOW), c=(digitalRead(C)==LOW), r=(digitalRead(R)==LOW);
  int err = (r?1:0) - (l?1:0);
  int corr = kp*err;
  int left = base - corr;
  int right= base + corr;
  if(!l && !c && !r){ left=right=0; } // lost line
  drive(left,right);
  delay(10);
}

ESP8266: Read 3 Digital Channels

#include 
// Choose GPIOs that exist on your module (e.g., D5=14, D6=12, D7=13 on NodeMCU)
const int L=D5, C=D6, R=D7;

void setup(){
  Serial.begin(115200);
  pinMode(L, INPUT_PULLUP);
  pinMode(C, INPUT_PULLUP);
  pinMode(R, INPUT_PULLUP);
}
void loop(){
  bool l = digitalRead(L)==LOW, c = digitalRead(C)==LOW, r = digitalRead(R)==LOW;
  Serial.printf("L:%d C:%d R:%d\n", l, c, r);
  delay(60);
}

ESP-IDF: Use GPIO inputs with internal pull-ups and poll/ISR as needed. For motor control, use ledc PWM. See Espressif links in Resources below.

Drivers

The sensor itself requires no drivers. If you use a USB-serial bridge for logging/control, you may need:

Resources
Specifications
Channels 3 (Left / Center / Right)
Operating Voltage 3.3–5 V (typ.)
Outputs Digital (comparator) per channel; some boards also provide analog
Indicators Per-channel LEDs (varies)
Adjustments Trimmer potentiometer(s) for threshold
Sensing Height ~2–8 mm above surface (tune to surface)
Use Case Line following, edge detection, basic reflectance sensing
Interface 3× digital pins (plus optional 3× analog)
Dimensions Module-dependent

Note: Polarity of “line detected” (HIGH vs LOW) and pin names can vary — follow your PCB silkscreen.

FAQ
Sensor doesn’t detect the line
Lower the module closer to the surface, adjust the trimmers, slow the robot, and ensure strong contrast (e.g., black tape on light floor).
Readings inverted (line = HIGH)
Invert logic in code or tweak threshold. Some boards use active-high comparators by default.
Noisy outputs at edges of the line
Add small hysteresis in code (debounce or majority voting), and tune the trimmers to avoid borderline switching.
Safety & Compliance

Important Notice For educational, prototype, experimental, laboratory and R&D use only. (non-RoHs)

WEEE

Not subject to WEEE marking; obligations apply to final equipment.

Manufacturer

Little Muffins Things Limited
166 River Heights, 90 High Street
London E15 2GQ
littlemuffinsthings.com

EU Responsible Person

eucomply OU
Parnu mnt. 139b–141
13117 Tallinn, Estonia
hello@eucompliancepartner.com