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