Problem adding IR receiver to smart car

I’m making a smart car using an arduino uno, sensor shield v5, motor control with a L298N and a servo motor + HC-SR04 ultrasound sensor. I want to add a IR receiver on the board so I can also control the car with a remote.

The problem is when I add in the code for the IR Receiver and make the 3 additional connections, the right motor doesn’t respond anymore, it only moves at the beginning, though slower than the left one during the initial setup, then only the left motor functions properly.

Here is the whole code with comments next to the IR-Receiver specific code:

#include <Servo.h>
#include <IRremote.h> //IR Receiver
Servo servo ;
const int trigPin = 13;
const int echoPin = 12;
const int servoPin = 11;
const int enAPin = 6;
const int in1Pin = 7;
const int in2Pin = 5;
const int in3Pin = 4;
const int in4Pin = 2;
const int enBPin = 3;
const int receiverPin = 9; //IR Receiver

IRrecv irrecv(receiverPin);  //IR Receiver
decode_results signals; //IR Receiver


enum Motor { LEFT, RIGHT };
void go(enum Motor m, int speed)
{
  digitalWrite (m == LEFT ? in1Pin : in3Pin , speed > 0 ? HIGH : LOW );
  digitalWrite (m == LEFT ? in2Pin : in4Pin , speed <= 0 ? HIGH : LOW );
  analogWrite(m == LEFT ? enAPin : enBPin, speed < 0 ? -speed : speed );
}



void testMotors ()
{
  static int speed[8] = { 128, 255, 128, 0 , -128, -255, -128, 0};
  go(RIGHT, 0);
  for (unsigned char i = 0 ; i < 8 ; i++)
    go(LEFT, -speed[i]), delay(200);
  
  for (unsigned char i = 0 ; i < 8 ; i++)
    go(RIGHT, speed[i]), delay(200);
}

unsigned int readDistance()
{
  digitalWrite(trigPin, HIGH);
  delayMicroseconds(10);
  digitalWrite(trigPin, LOW);
  unsigned long period = pulseIn(echoPin, HIGH);
  return period * 343 / 2000;
}



#define NUM_ANGLES 7
unsigned char sensorAngle[NUM_ANGLES] = {60, 70, 80, 90, 100, 110, 120};
unsigned int distance [NUM_ANGLES];

void readNextDistance()
{
  static unsigned char angleIndex = 0;
  static signed char step = 1;
  distance[angleIndex] = readDistance();
  angleIndex += step ;
  if (angleIndex == NUM_ANGLES - 1) step = -1;
  else if (angleIndex == 0) step = 1;
  servo.write(sensorAngle[angleIndex]);
}


void setup () {
  Serial.begin(9600);  //IR Receiver
  irrecv.enableIRIn();  //IR Receiver

  pinMode(trigPin , OUTPUT);
  pinMode(echoPin, INPUT);
  digitalWrite(trigPin, LOW);
  pinMode(enAPin, OUTPUT);
  pinMode(in1Pin, OUTPUT);
  pinMode(in2Pin, OUTPUT);
  pinMode(in3Pin, OUTPUT);
  pinMode(in4Pin, OUTPUT);
  pinMode(enBPin, OUTPUT);
  servo.attach(servoPin);
  servo.write(90);
  go(LEFT, 0);
  go(RIGHT, 0);
  testMotors();
  servo.write(sensorAngle[0]);
  delay(200);
  for (unsigned char i = 0 ; i < NUM_ANGLES ; i ++)
    readNextDistance(), delay (200);
}



void loop () {

 //IR Receiver:
  if (irrecv.decode(&signals)) {
        Serial.println(signals.value);
        irrecv.resume();
        if (signals.value == 0xFFA25D) {
          Serial.println("yeees");
        }
  }


  readNextDistance ();
  
  unsigned char tooClose = 0;
  for (unsigned char i = 0 ; i < NUM_ANGLES ; i++)
    if (distance[i] < 200)
      tooClose = 1;
  
  if (tooClose) {
    go(LEFT, 180);
    go(RIGHT, -80);
  } else {
    go(LEFT, -180);
    go(RIGHT, 180);
  }
  delay (50);
}

Motor slowing could be motor timing or power available. Lack of power seems most often the issue, and the biggest power consumer is the L298N. I assume you are using a battery pack for power. What is the capacity of your battery pack?

I am using a 4x AA batteries. After some more testing I'm not sure power is really the issue. In fact I think the library IRremote somehow interferes with the rest as the line causing this issue is the starting of the receiver: irrecv.enableIRIn();. Without this particular library, the receiver works perfectly as well as both motors...

Apparently it's a well known problem already from what I just found with some more researching. Both motors and IRremote are using the same "timers" which leads to a software conflict. Will try to find a way to make them use different, or find another library...

Yes, that is what I was hinting in post #2... but I hoped it was just a power issue.

You will find this simulation useful. It does not use a servo library (no library, no interference). It moves the servos by adjusting the pulse length. You could use this method in an indexing fashion (that is to say; non-blocking, not inside a loop, rather "x++... if x = degrees...) .

The basics to position a servo are: Every 20ms, start a pulse with a width from 1ms to 2ms (1ms = 0 degrees, 2ms = 180 degrees). Exact pulse width will vary with every servo.

Ok thanks I’ll give it a try!

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