My aim is to create a simple obstacle avoiding robot using Arduino.
I have used L293D motor shield to drive the DC motors and supply it all with 12 V. I am using a sonar module to detect the obstacles. I have used an IR Receiver to control the motors of the robot.
From the serial prints I can tell that every IR signal is received and the expected functions are called. Unfortunately, when I press the button to start the motor, the motor does not start.
When I remove IR Receiver and start robot the code works fine.
In my code posted below I have commented some code so that it only calls the startFan()
function.
What is wrong with my code? And how do I fix it?
#include <AFMotor.h>
#include <NewPing.h>
#include <Servo.h>
#include <boarddefs.h>
#include <IRremote.h>
#include <IRremoteInt.h>
#include <ir_Lego_PF_BitStreamEncoder.h>
#define TRIG_PIN A4
#define ECHO_PIN A5
#define MAX_DISTANCE 200
#define MAX_SPEED 75 // sets speed of DC motors
NewPing sonar(TRIG_PIN, ECHO_PIN, MAX_DISTANCE);
AF_DCMotor motor1(1, MOTOR12_1KHZ);
AF_DCMotor motor2(3, MOTOR12_1KHZ);
AF_DCMotor motor3(2, MOTOR12_1KHZ);
Servo myservo;
boolean goesForward = false;
int distance = 100;
int speedSet = 0;
int DisObstaclePin = 0; // This is our input pin
int DisObstacle = HIGH; // HIGH MEANS NO OBSTACLE
int receiver = 6; // Signal Pin of IR receiver to Arduino Digital Pin 11
int power_status ;
IRrecv irrecv(receiver); // create instance of 'irrecv'
decode_results results; // create instance of 'decode_results'
//----( SETUP: RUNS ONCE )----//
void setup()
{
Serial.begin(9600);
Serial.println("IR Receiver Button Decode");
int power_status = 0;
motor3.setSpeed(150);
motor3.run(FORWARD);
pinMode(DisObstaclePin, INPUT);
myservo.attach(9);
myservo.write(115);
delay(1000);
distance = readPing();
delay(100);
distance = readPing();
delay(100);
DisObstacle = digitalRead(DisObstaclePin);
delay(100);
irrecv.enableIRIn(); // Start the receiver
}
void loop() /*----( LOOP: RUNS CONSTANTLY )----*/
{
Serial.println("Begin loop");
delay(1000);
if (irrecv.decode(&results)) // have we received an IR signal?
{
Serial.println("wada");
translateIR();
irrecv.resume(); // receive the next value
delay(500);
}
/* else {
if (power_status == 1) {
Serial.println("POWER ON");
int distanceR = 0;
int distanceL = 0;
delay(40);
if (distance <= 25 || DisObstacle == HIGH)
{
Serial.print("Turning");
moveStop();
delay(100);
moveBackward();
delay(300);
moveStop();
delay(200);
distanceR = lookRight();
delay(200);
distanceL = lookLeft();
delay(200);
if (distanceR >= distanceL)
{
turnRight();
moveStop();
} else
{
turnLeft();
moveStop();
}
} else
{
moveForward();
Serial.print("Forword");
}
distance = readPing();
delay(50);
DisObstacle = digitalRead(DisObstaclePin);
delay(50);
}if (power_status == 0) {
Serial.print("POWER OFF");
}
}
*/
}/* --(end main loop )-- */
/*-----( Functions )-----*/
void translateIR() // takes an action based on the IR code received
{
switch (results.value)
{
case 0xFF30CF: Serial.println("Movement-ON- 1");
power_status = 1;
break;
case 0xFF18E7: Serial.println("Movement-OFF -2");
power_status = 0;
break;
case 0xFF10EF: Serial.println("Fan-on-3");
startFan();
break;
case 0xFF38C7: Serial.println("Fan-off-4");
stopFan();
break;
default:
Serial.println(" other button ");
}
delay(500); // Do not get immediate repeat
} //END translateIR
int lookRight()
{
myservo.write(50);
delay(500);
int distance = readPing();
delay(100);
myservo.write(115);
return distance;
}
int lookLeft()
{
myservo.write(170);
delay(500);
int distance = readPing();
delay(100);
myservo.write(115);
return distance;
delay(100);
}
int readPing() {
delay(70);
int cm = sonar.ping_cm();
if (cm == 0)
{
cm = 250;
}
return cm;
}
void moveStop() {
motor1.run(RELEASE);
motor2.run(RELEASE);
delay(100);
}
void moveForward() {
if (!goesForward)
{
goesForward = true;
motor1.run(FORWARD);
motor2.run(FORWARD);
motor1.setSpeed(100); //set the speed of the motors, between 0-255
motor2.setSpeed(100);
delay(100);
motor1.setSpeed(55); //set the speed of the motors, between 0-255
motor2.setSpeed(55);
}
}
void moveBackward() {
goesForward = false;
motor1.run(BACKWARD);
motor2.run(BACKWARD);
motor1.setSpeed(100); //set the speed of the motors, between 0-255
motor2.setSpeed(100);
delay(500);
}
void turnRight() {
motor1.run(FORWARD);
motor2.run(BACKWARD);
delay(300);
motor1.run(FORWARD);
motor2.run(FORWARD);
}
void turnLeft() {
motor1.run(BACKWARD);
motor2.run(FORWARD);
delay(300);
motor1.run(FORWARD);
motor2.run(FORWARD);
}
void startFan() {
motor3.setSpeed(150);
motor3.run(FORWARD);
Serial.println("FAN start ");
delay(2000);
}
void stopFan() {
motor3.run(RELEASE);
Serial.println("FAN stop ");
delay(2000);
}
==============After change pin attachment ============================= I will change my code as follow and remove , 0,1 pin attachment sensor. Now code like below.
#include <AFMotor.h>
#include <NewPing.h>
#include <Servo.h>
#include <boarddefs.h>
#include <IRremote.h>
#include <IRremoteInt.h>
#include <ir_Lego_PF_BitStreamEncoder.h>
#define TRIG_PIN A4
#define ECHO_PIN A5
#define MAX_DISTANCE 200
#define MAX_SPEED 75 // sets speed of DC motors
NewPing sonar(TRIG_PIN, ECHO_PIN, MAX_DISTANCE);
AF_DCMotor motor1(1, MOTOR12_1KHZ);
AF_DCMotor motor3(2, MOTOR12_1KHZ);
AF_DCMotor motor2(3, MOTOR12_1KHZ);
Servo myservo;
boolean goesForward = false;
int distance = 100;
int speedSet = 0;
int DisObstaclePin = 2; // This is our input pin
int DisObstacle = HIGH; // HIGH MEANS NO OBSTACLE
int receiver = 13; // Signal Pin of IR receiver to Arduino Digital Pin 11
//int power_on;
int fan_status,power_on;
IRrecv irrecv(receiver); // create instance of 'irrecv'
decode_results results; // create instance of 'decode_results'
//----( SETUP: RUNS ONCE )----//
void setup()
{
Serial.begin(9600);
Serial.println("IR Receiver Button Decode");
power_on = 1;
fan_status = 0;
pinMode(DisObstaclePin, INPUT);
myservo.attach(9);
myservo.write(115);
delay(1000);
distance = readPing();
delay(100);
distance = readPing();
delay(100);
DisObstacle = digitalRead(DisObstaclePin);
delay(100);
irrecv.enableIRIn(); // Start the receiver
}
void loop() /*----( LOOP: RUNS CONSTANTLY )----*/
{
Serial.println("Begin loop");
delay(1000);
if (irrecv.decode(&results)) // have we received an IR signal?
{
Serial.print("Start reciving");
translateIR();
irrecv.resume(); // receive the next value
}
//delay(2000);
if (power_on == 1) {
Serial.println("POWER ON");
int distanceR = 0;
int distanceL = 0;
delay(40);
if (distance <= 25 || DisObstacle == HIGH)
{
Serial.print("Turning");
moveStop();
delay(100);
moveBackward();
delay(300);
moveStop();
delay(200);
distanceR = lookRight();
delay(200);
distanceL = lookLeft();
delay(200);
if (distanceR >= distanceL)
{
turnRight();
moveStop();
} else
{
turnLeft();
moveStop();
}
} else
{
moveForward();
Serial.print("Forword");
}
distance = readPing();
delay(50);
DisObstacle = digitalRead(DisObstaclePin);
delay(50);
}
if (fan_status == 1) {
startFan();
delay(50);
} else {
stopFan();
delay(50);
}
// irrecv.resume(); // receive the next value
}/* --(end main loop )-- */
/*-----( Functions )-----*/
void translateIR() // takes action based on IR code received
{
switch (results.value)
{
case 0xFF30CF: Serial.println("Movement-ON- 1");
//power_on = 1;
break;
case 0xFF18E7: Serial.println("Movement-OFF -2");
//power_on = 0;
break;
case 0xFF10EF: Serial.println("Fan-on-3");
fan_status = 1 ;
break;
case 0xFF38C7: Serial.println("Fan-off-4");
fan_status = 0;
break;
default:
Serial.println(" other button ");
}
delay(500); // Do not get immediate repeat
} //END translateIR
int lookRight()
{
myservo.write(50);
delay(500);
int distance = readPing();
delay(100);
myservo.write(115);
return distance;
}
int lookLeft()
{
myservo.write(170);
delay(500);
int distance = readPing();
delay(100);
myservo.write(115);
return distance;
delay(100);
}
int readPing() {
delay(70);
int cm = sonar.ping_cm();
if (cm == 0)
{
cm = 250;
}
return cm;
}
void moveStop() {
motor1.run(RELEASE);
motor2.run(RELEASE);
delay(100);
}
void moveForward() {
if (!goesForward)
{
goesForward = true;
motor1.run(FORWARD);
motor2.run(FORWARD);
motor1.setSpeed(100); //set the speed of the motors, between 0-255
motor2.setSpeed(100);
delay(100);
motor1.setSpeed(55); //set the speed of the motors, between 0-255
motor2.setSpeed(55);
}
}
void moveBackward() {
goesForward = false;
motor1.run(BACKWARD);
motor2.run(BACKWARD);
motor1.setSpeed(100); //set the speed of the motors, between 0-255
motor2.setSpeed(100);
delay(500);
}
void turnRight() {
motor1.run(FORWARD);
motor2.run(BACKWARD);
delay(300);
motor1.run(FORWARD);
motor2.run(FORWARD);
}
void turnLeft() {
motor1.run(BACKWARD);
motor2.run(FORWARD);
delay(300);
motor1.run(FORWARD);
motor2.run(FORWARD);
}
void startFan() {
motor3.setSpeed(30);
motor3.run(FORWARD);
Serial.println("FAN start ");
delay(100);
}
void stopFan() {
motor3.setSpeed(RELEASE);
Serial.println("FAN stop ");
delay(100);
}
Now I notice the M1 motor is not working. My question is also same as this: Motor shield question But I couldn't understand how to resolve it using my code. Other trouble I notice, a lot of the time the IR Receiver receives my signal. It executes without noticing a new signal. Sometimes it catches my signal.
-
2You use L293D motor shield, but using AFmotor (Adafruit driver motor) libs, which is odd. Posting Schematics would help.duck– duck2016年11月21日 03:51:55 +00:00Commented Nov 21, 2016 at 3:51
-
2Don't cross post on other SE sites.gre_gor– gre_gor2016年11月21日 13:49:56 +00:00Commented Nov 21, 2016 at 13:49
-
1After reading @dpw's post can you confirm the version of the AdaFruit motor shield you are using? And the version of AFMotor library that you are using? v1 and v2 are not cross compatible.Code Gorilla– Code Gorilla2016年11月21日 15:13:23 +00:00Commented Nov 21, 2016 at 15:13
-
1You are using the I2C pins for the ultrasonic sensor(?) would changing them to A0 & A1 be possible. (Its unlikely to be the problem, but...)Code Gorilla– Code Gorilla2016年11月21日 16:19:40 +00:00Commented Nov 21, 2016 at 16:19
-
1I haven't seen error on your code, what is the output of serial monitor from your edited code? After a bit browsing, perhaps the problem lies with the "irrecv.recume()"duck– duck2016年11月22日 06:25:01 +00:00Commented Nov 22, 2016 at 6:25
1 Answer 1
Based on this thread:
- https://forums.adafruit.com/viewtopic.php?f=31&t=27069
- https://stackoverflow.com/questions/18705363/arduino-uno-pwm-pins-conflict
- http://forum.arduino.cc/index.php?topic=97133.0
Both AFmotor library and IRremote are using timer feature. And in addition, IRremote also use TIMER_RESET, which probably causing the motor not function as expected (on comment section)
So the solution available is :
- Use another library to drive motor, or you can make you own. See this tutorial.
- Edit the library (IRremote or AFmotor) timer configuration (as you can found in the last post of the link I posted)
Explore related questions
See similar questions with these tags.