(Solved) Problem running 2 motors

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:

#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

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

servo-wire.jpg

Hi

The servo is wired :

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

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

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

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

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

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.

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

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.

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...

Hi AnalysIR

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

Rob

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

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 -

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.

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).

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.

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.

#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
  }

}
myservo.attach(8); // attaches the servo on pin 7 to the servo object

I know which one the compiler believes.
(you may as well leave such comments out altogether - the purpose is obvious from the function call)

Well spotted! Overlooked this whilst swapping pins around. Also I should have said avoiding analogWrite to PWM pins 9, 10, and 11 which the servo library blocks

Also I should have said avoiding analogWrite to PWM pins 9, 10, and 11

Or you could just refer the reader to the library documentation.
I didn't think pin 11 was affected.