Go Down

Topic: (Solved) Problem running 2 motors (Read 5672 times) previous topic - next topic

CyberBob

Aug 09, 2013, 12:22 pm Last Edit: Aug 12, 2013, 11:50 am by CyberBob Reason: 1
I have set up a servo motor to control steering. I do this using an old TV remote control. Similarly, I have set up a 6V continuous, reversable motor to control direction (forward and reverse) and speed using the same TV remote control. Both work fine on their own. They are both connected to the same Arduino Duemilanove (the continuous motor via a dual H-Bridge board).

When I have merged the programs, I can only have one or the other working. If I run the sketch 'as is', the direction servo works and the continuous motor doesn't. If I comment out line 25 i.e. myservo.attach(7); , the direction servo doesn't work (obviously) but the continuous motor does work.

Any help would be very much appreciated.

Here's the code:

Code: [Select]

#include <IRremote.h>
int RECV_PIN = 8;
IRrecv irrecv(RECV_PIN);
decode_results results;
#include <Servo.h>
Servo myservo; // create servo object to control a servo
int pos = 0; // variable to store the servo position

// OUTPUT: Pulse-width Modulation (PWM) pins: 3, 5, 6, 9, 10, and 11
//See: http://arduino.cc/en/Main/arduinoBoardUno
//and http://arduino.cc/en/Main/ArduinoBoardDuemilanove  
int dir1PinA = 10; // direction
int dir2PinA = 11; // direction
int speedPinA = 9;  // pin ENA on the motor shield

unsigned long time;
int speed;
int dir;
int x = 0; // variable to store the motor speed


void setup ()
{
 myservo.attach(7); // attaches the servo on pin 7 to the servo object
 pos=90;
 pinMode (dir1PinA, OUTPUT);
 pinMode (dir2PinA, OUTPUT);
 pinMode (speedPinA, OUTPUT); // SPEED A
 //Serial.begin(9600);
 irrecv.enableIRIn(); // Start the receiver

}

void loop ()

{
 pos=constrain(pos,0,180);
 myservo.write(pos);

 if (irrecv.decode(&results)) {
   irrecv.resume(); // Receive the next value
 }

 if (results.value == 12583000)  //UP BUTTON : FORWARD
 {    
   analogWrite (speedPinA, x); // change the number from 1-255 to get the speed you want
   digitalWrite (dir1PinA, LOW); //  pin 10 Low, pin 11 High
   digitalWrite (dir2PinA, HIGH); // change between LOW and HIGH
   delay(100);
 }

 if (results.value == 12583001)  //DOWN BUTTON : REVERSE
 {
   analogWrite (speedPinA, x); // change the number from 1-255 to get the speed you want
   digitalWrite (dir1PinA, HIGH); //  pin 10 High, pin 11 Low
   digitalWrite (dir2PinA, LOW); // change between HIGH and LOW
   delay(100);  
 }

 if (results.value == 12583041)  //HELP BUTTON : INCREASE SPEED
 {
   x++; //INCREASE SPEED
   analogWrite (speedPinA, x); //SPEED ZERO  
   delay(100);
 }

 if (results.value == 12582972)  // TEXT BUTTON : REDUCE SPEED
 {
   x--; //REDUCE SPEED
   analogWrite (speedPinA, x); //SPEED ZERO  
   delay(100);
 }

 if (results.value == 12583043)  //BACKUP BUTTON : HOLD SPEED
 {
   x=x; //HOLD SPEED AT LATEST VALUE
   analogWrite (speedPinA, x); // change the number from 1-255 to get the speed you want
   delay(100);
 }

 if (results.value == 12583040)  //SKY BUTTON : STOP MOTOR
 {
   analogWrite (speedPinA, 0); //SPEED ZERO  
   delay(100);
 }

 if (results.value == 12583002)  //RIGHT BUTTON : TURN RIGHT
 {
   x=x; //HOLD SPEED AT LATEST VALUE
   pos++;
   delay(15); // waits 15ms for the servo to reach the position
 }

 if (results.value == 12583003)  //LEFT BUTTON : TURN LEFT
 {
   x=x; //HOLD SPEED AT LATEST VALUE
   pos--;
   delay(15); // waits 15ms for the servo to reach the position
 }

 if (results.value == 12583004)  //SELECT BUTTON : HOLD POSITION
 {
   x=x; //HOLD SPEED AT LATEST VALUE
   pos = pos;
   delay(15); // waits 15ms for the servo to reach the position
 }
}

 

Thanks

drewdavis

How is your servo attached? It should be like this...

CyberBob

Hi

The servo is wired :

Red = +5v (on Arduino)
Brown = GND (on Arduino)
Orange = Signal (pin 7)


drewdavis

That is a bad idea. Connect the servo like I did in the photo. (you can keep it on pin 7)

CyberBob

Hi Drew

Would the way that I've wired up affect the operation of both motors? The servo has been working fine using the current wiring. I'll have to find an external power supply for the servo so that I can try your wiring scheme.

In the meantime, I think that the problem is with the sketch

Thanks

Rob

drewdavis

The Arduino might not have enough current thus causing problems, but I will look at your code.

CyberBob

Drew

I've just tried it with the servo attached to an external power supply. The result is the same; I can only get one or the other of the motors to work. This is the line of code that seems to cause the problems:

myservo.attach(7);

When it's there, only the small servo works. When commented out, the continuous motor works


Thanks

Rob

AnalysIR

The IR remote library uses PWM & Timers (Timer2)  & although you are not sending IR it might be a problem that IR remote is conflicting the PWM or Timers of the servo.

Not sure about this but may be an avenue for you to check out.

Minor: your code could be improved if you used a 'switch case' approach or even 'else if' , if speed of execution is an issue.

CyberBob

I had a look in the servo library folder and opened the Servo CPP file in Notepad. I found the following:

Quote
Note that analogWrite of PWM on pins associated with the timer are disabled when the first servo is attached


Hmmmm! If I move the continuous motor from pins 9, 10 and 11 will that work (they are PWM pins)? I have pins 4, 12 and 13 free.

AnalysIR

I think it s referring to PWM associated with the Analoguewrite function, which I dont think is used by IRremote. However, if both the servo & IRremote are using Timers & PWM (directly) then there is a good chance of a conflict. Unless you find someone who has used both librarires together, it looks like you will need to do a wider search.

Sorry I can't be of more help...

CyberBob

Hi AnalysIR

Thanks for pointing me in the right direction. I'll do some more digging around

Rob

AnalysIR

I was curious..so look here
https://github.com/shirriff/Arduino-IRremote/issues/5

(Changing Ir rx pin from 3->11 (?)

and here
http://tech.cyborg5.com/2013/04/13/irlib-tutorial-lesson-2-controlling-a-servo-using-an-ir-remote/

IRlib is a similar library to IRremote

CyberBob

I have managed to successfully get the servo working from IR commands as well as the continuous rotation motor; so the IR library and the servo library work fine together in these instances -

Quote
I have set up a servo motor to control steering. I do this using an old TV remote control. Similarly, I have set up a 6V continuous, reversable motor to control direction (forward and reverse) and speed using the same TV remote control. Both work fine on their own.


The problem arises when I try and operate both at the same time. The 'blocking' of the continuous rotation motor is due to the servo library, in particular the  myservo.attach() line in the code disabling the analogWrite.

Quote
Note that analogWrite of PWM on pins associated with the timer are disabled when the first servo is attached


The way around this maybe is to either put the continuous rotation motor on different pins or use a separate microcontroller for each motor (not ideal).

CyberBob

I've narrowed this down to the servo library blocking analogWrite. Does anyone know a way around this (maybe getting the servo to work with a different library or without a library at all)? Your help would be very much appreciated.

CyberBob

With altering the pins around, I have managed to get both the continuous rotation motor and the servo working together with the same sketch. By avoiding PWM pins for the analogWrite, all works perfectly. For anyone who is trying to achieve similar, here is the sketch.

Code: [Select]

#include <IRremote.h>
int RECV_PIN = 9;
IRrecv irrecv(RECV_PIN);
decode_results results;
#include <Servo.h>
Servo myservo; // create servo object to control a servo
int pos = 0; // variable to store the servo position

// OUTPUT: Pulse-width Modulation (PWM) pins: 3, 5, 6, 9, 10, and 11
//See: http://arduino.cc/en/Main/arduinoBoardUno
//and http://arduino.cc/en/Main/ArduinoBoardDuemilanove 
int dir1PinA = 4; // direction
int dir2PinA = 7; // direction
int speedPinA = 5;  // pin ENA on the motor shield

unsigned long time;
int speed;
int dir;
int x = 0; // variable to store the motor speed


void setup ()
{
  myservo.attach(8); // attaches the servo on pin 7 to the servo object
  pos=90;
  pinMode (dir1PinA, OUTPUT);
  pinMode (dir2PinA, OUTPUT);
  pinMode (speedPinA, OUTPUT); // SPEED A
  //Serial.begin(9600);
  irrecv.enableIRIn(); // Start the receiver

}

void loop ()

{
  pos=constrain(pos,0,180);
  myservo.write(pos);

  if (irrecv.decode(&results)) {
    irrecv.resume(); // Receive the next value
  }

  if (results.value == 12583000)  //UP BUTTON : FORWARD
  {   
    analogWrite (speedPinA, x); // change the number from 1-255 to get the speed you want
    digitalWrite (dir1PinA, LOW); //  pin 10 Low, pin 11 High
    digitalWrite (dir2PinA, HIGH); // change between LOW and HIGH
    delay(100);
  }

  if (results.value == 12583001)  //DOWN BUTTON : REVERSE
  {
    analogWrite (speedPinA, x); // change the number from 1-255 to get the speed you want
    digitalWrite (dir1PinA, HIGH); //  pin 10 High, pin 11 Low
    digitalWrite (dir2PinA, LOW); // change between HIGH and LOW
    delay(100); 
  }

  if (results.value == 12583041)  //HELP BUTTON : INCREASE SPEED
  {
    x++; //INCREASE SPEED
    analogWrite (speedPinA, x); //SPEED ZERO 
    delay(100);
  }

  if (results.value == 12582972)  // TEXT BUTTON : REDUCE SPEED
  {
    x--; //REDUCE SPEED
    analogWrite (speedPinA, x); //SPEED ZERO 
    delay(100);
  }

  if (results.value == 12583043)  //BACKUP BUTTON : HOLD SPEED
  {
    x=x; //HOLD SPEED AT LATEST VALUE
    analogWrite (speedPinA, x); // change the number from 1-255 to get the speed you want
    delay(100);
  }

  if (results.value == 12583040)  //SKY BUTTON : STOP MOTOR
  {
    analogWrite (speedPinA, 0); //SPEED ZERO 
    delay(100);
  }

  if (results.value == 12583002)  //RIGHT BUTTON : TURN RIGHT
  {
    x=x; //HOLD SPEED AT LATEST VALUE
    pos++;
    delay(15); // waits 15ms for the servo to reach the position
  }

  if (results.value == 12583003)  //LEFT BUTTON : TURN LEFT
  {
    x=x; //HOLD SPEED AT LATEST VALUE
    pos--;
    delay(15); // waits 15ms for the servo to reach the position
  }

  if (results.value == 12583004)  //SELECT BUTTON : HOLD POSITION
  {
    x=x; //HOLD SPEED AT LATEST VALUE
    pos = pos;
    delay(15); // waits 15ms for the servo to reach the position
  }

}



Go Up