IR Sensor Not Detecting Signals Properly in My Project

Hello,

I’m working on a project that involves a robot can follow an IR beacon. It involves an IR sensor, but I’m running into issues where the IR sensor is not detecting signals consistently. The signal detection works intermittently, it detects the signal properly, but most of the time, it says "No signal detected." My test code works but my main code doesn't

Here’s a brief overview of my setup:

  • IR Sensor: I’m using the IR receiver connected to pin A2 on my Arduino.
  • Library: I’m using the IRremote library (version 2.6.0).
  • Arduino Model: Arduino Uno.
  • Signal: I’m trying to detect a continuous IR signal emitted by an IR beacon.
  • Issue: The IR sensor works only sporadically and sometimes detects a signal but with an incorrect value or no value at all. The signal changes every time, and it's not consistent.

Here is the test code I am using:

#include <IRremote.h>

const int IR_RECEIVER_PIN = A2;  // IR receiver pin
IRrecv irrecv(IR_RECEIVER_PIN);  // Create IRrecv object
decode_results results;          // Variable to store received data

void setup() {
  Serial.begin(9600);
  irrecv.enableIRIn();  // Start the IR receiver
  Serial.println("IR Receiver initialized. Awaiting signals...");
}

void loop() {
  if (irrecv.decode(&results)) {  // Check if a signal is received
    Serial.print("Signal received: ");
    Serial.println(results.value, HEX);  // Print the signal in HEX
    irrecv.resume();  // Prepare to receive the next signal
  }
}

It is not a hardware issue and is an issue with my main code.
Main code:

#include <Wire.h>
#include <Adafruit_MotorShield.h>
#include "utility/Adafruit_MS_PWMServoDriver.h"
#include <IRremote.h>
#include <Servo.h>

// Initialize the Adafruit Motor Shield object
Adafruit_MotorShield AFMS = Adafruit_MotorShield();

// Define motors
Adafruit_DCMotor *motor1 = AFMS.getMotor(1); // Left Front Motor
Adafruit_DCMotor *motor2 = AFMS.getMotor(2); // Left Rear Motor
Adafruit_DCMotor *motor3 = AFMS.getMotor(3); // Right Front Motor
Adafruit_DCMotor *motor4 = AFMS.getMotor(4); // Right Rear Motor

// Pin Assignments
const int IR_RECEIVER_PIN = A2; // IR receiver connected to A2

// Ultrasonic Sensor Pins
const int TRIG_PIN = A0;  // Ultrasonic sensor TRIG pin
const int ECHO_PIN = A1;  // Ultrasonic sensor ECHO pin

// Servo Pin
const int SERVO_PIN = 12;  // Servo motor for ultrasonic rotation

// Signal Strength Thresholds (raw signal strength)
const int STRONG_SIGNAL_THRESHOLD = 1000;  // Strong signal (higher raw value)
const int WEAK_SIGNAL_THRESHOLD = 200;     // Weak signal (lower raw value)

// Obstacle Detection Threshold (in cm)
const int OBSTACLE_DISTANCE = 15;  // Stop if an obstacle is within 15 cm

// IR Receiver Setup
IRrecv irrecv(IR_RECEIVER_PIN);  // Define IR receiver object
decode_results results;          // Variable to store IR data

// Servo setup
Servo ultrasonicServo;

void setup() {
  Serial.begin(9600);
  Serial.println("Initializing...");

  // Start the motor shield
  if (!AFMS.begin()) {
    Serial.println("Motor shield not detected. Check connections.");
    while (1);
  }

  Serial.println("Motor shield initialized.");

  // Ultrasonic Sensor Pins Setup
  pinMode(TRIG_PIN, OUTPUT);
  pinMode(ECHO_PIN, INPUT);

  // Servo Setup
  ultrasonicServo.attach(SERVO_PIN);

  // Start IR Receiver
  irrecv.enableIRIn();  // Initialize IR receiver (this is needed in version 4.x)

  // Center servo initially
  ultrasonicServo.write(90);

  // Test motors
  testMotors();

  Serial.println("Setup complete.");
}

void testMotors() {
  Serial.println("Testing Motors...");

  // Set motor speeds and run them forward for testing
  motor1->setSpeed(100);
  motor1->run(FORWARD);

  motor2->setSpeed(100);
  motor2->run(FORWARD);

  motor3->setSpeed(100);
  motor3->run(FORWARD);

  motor4->setSpeed(100);
  motor4->run(FORWARD);
  delay(500);

  // Stop motors
  motor1->run(RELEASE);
  motor2->run(RELEASE);
  motor3->run(RELEASE);
  motor4->run(RELEASE);

  Serial.println("Motors stopped");
}

void loop() {
  // Check for obstacles and adjust motor behavior
  if (isObstacleDetected()) {
    Serial.println("Obstacle detected, avoiding...");
    avoidObstacle();
  } else {
    adjustDirection();
  }
  delay(50);  // Adjust delay
}


// Ultrasonic Sensor Function to Detect Obstacles
bool isObstacleDetected() {
  int distance = measureDistance();

  // Debug: Print distance
  Serial.print("Distance: ");
  Serial.print(distance);
  Serial.println(" cm");

  // Return true if the obstacle is within the defined threshold
  return (distance > 0 && distance <= OBSTACLE_DISTANCE);
}

// Measure Distance Function
int measureDistance() {
  // Send ultrasonic pulse
  digitalWrite(TRIG_PIN, LOW);
  delayMicroseconds(2);
  digitalWrite(TRIG_PIN, HIGH);
  delayMicroseconds(10);
  digitalWrite(TRIG_PIN, LOW);

  // Measure pulse duration
  long duration = pulseIn(ECHO_PIN, HIGH);

  // Convert duration to distance in cm
  int distance = duration * 0.034 / 2;
  return distance;
}

void moveForward() {
  Serial.println("Moving forward...");
  motor1->run(FORWARD);
  motor2->run(FORWARD);
  motor3->run(FORWARD);
  motor4->run(FORWARD);
}

void moveBackward() {
  Serial.println("Moving backward...");
  motor1->run(BACKWARD);
  motor2->run(BACKWARD);
  motor3->run(BACKWARD);
  motor4->run(BACKWARD);
}

void turnLeft() {
  Serial.println("Turning left...");
  motor1->run(BACKWARD); // Left motors backward
  motor2->run(BACKWARD); 
  motor3->run(FORWARD);  // Right motors forward
  motor4->run(FORWARD);
}

void turnRight() {
  Serial.println("Turning right...");
  motor1->run(FORWARD);  // Left motors forward
  motor2->run(FORWARD);
  motor3->run(BACKWARD); // Right motors backward
  motor4->run(BACKWARD);
}

void stopMotors() {
  motor1->run(RELEASE);
  motor2->run(RELEASE);
  motor3->run(RELEASE);
  motor4->run(RELEASE);
  Serial.println("Motors stopped");
}

// Obstacle Avoidance Logic
void avoidObstacle() {
  // Move backward briefly
  moveBackward();
  delay(500);  // Adjust as needed
  stopMotors();

  // Look left
  ultrasonicServo.write(45);  // Rotate servo left
  delay(500);  // Allow time for servo to rotate
  int leftDistance = measureDistance();

  // Look right
  ultrasonicServo.write(135);  // Rotate servo right
  delay(500);  // Allow time for servo to rotate
  int rightDistance = measureDistance();

  // Center the servo again
  ultrasonicServo.write(90);
  delay(500);

  // Decide direction based on more space
  if (leftDistance > rightDistance) {
    turnLeft();
    Serial.println("Turning left...");
  } else {
    turnRight();
    Serial.println("Turning right...");
  }

  // Move forward again
  moveForward();
  delay(1000);  // Adjust as needed
  stopMotors();
}

void adjustDirection() {
  if (irrecv.decode(&results)) {
    unsigned long irSignal = results.value;  // Get the received signal value
    int signalStrength = results.rawlen;      // Get the signal strength (raw length)

    Serial.print("IR Signal: ");
    Serial.println(irSignal, HEX);  // Print signal value in HEX format
    Serial.print("Signal Strength: ");
    Serial.println(signalStrength); // Print signal strength

    // Check signal strength to determine response
    if (signalStrength > STRONG_SIGNAL_THRESHOLD) {
      moveForward();  // Strong signal detected, move forward
    } 
    else if (signalStrength > WEAK_SIGNAL_THRESHOLD) {
      Serial.println("Weak signal detected. Adjusting direction.");
      turnLeft();  // Adjust direction for weak signals
    } 
    else {
      stopMotors();  // No valid or very weak signal
    }

    irrecv.resume();  // Resume IR receiver to listen for the next signal
  } else {
    Serial.println("No IR signal detected.");  // Debugging message
  }
}

Any suggestions or advice would be greatly appreciated. Thank you in advance!

How do you know that?

Try it with using

(signalStrength - 2) / 3

Because I run my test code and it works perfectly fine, and then I run my main code afterwards and it doesn't, meaning there is an issue with my main code.

Thanks for the suggestion, but I don't understand why (I'm kind of slow). May you please explain why I should use this?

a brilliant conclusion

A brilliant conclusion!

Why do I use (signalstrength-2)/3?

Its a direct consequence of the logic of your main code :slight_smile:

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.