Coding problem: problem with servo library?

Hi all,

I'm working with the arduino duemilanove. My problem is fairly specific so I hope somebody can help.
Here's my code currently:

#include <TextFinder.h>
#include <Servo.h> 

Servo myservo;

TextFinder  finder(Serial);  
const int NUMBER_OF_FIELDS = 2; // how many comma seperated fields we expect                                           
int values[NUMBER_OF_FIELDS];   // array holding values for all the fields

const int ledPin = 10;
const int ledPin2 = 11;

void setup() 
{ 
  Serial.begin(9600); 
  myservo.attach(12);
}  
  
void loop()
{
  int fieldIndex = 0;            // the current field being received
  if(finder.find("V1:") )
{  
  while(fieldIndex < NUMBER_OF_FIELDS)
    values[fieldIndex++] = finder.getValue();      
  Serial.println("All fields received:");
  for(fieldIndex=0; fieldIndex < NUMBER_OF_FIELDS; fieldIndex++)
    Serial.println(values[fieldIndex]);    
 
 
  if(values[0]== 1)
    {
      analogWrite(ledPin2,0);
      Serial.println("GREEN LIGHT");
      
      if(values[1]<=1) analogWrite(ledPin,255/10);
      else if(values[1]==2) analogWrite(ledPin,255/9);
      else if(values[1]==3) analogWrite(ledPin,255/8);
      else if(values[1]==4) analogWrite(ledPin,255/7);
      else if(values[1]==5) analogWrite(ledPin,255/6);
      else if(values[1]==6) analogWrite(ledPin,255/5);
      else if(values[1]==7) analogWrite(ledPin,255/4);
      else if(values[1]==8) analogWrite(ledPin,255/3);
      else if(values[1]==9) analogWrite(ledPin,255/2);
      else if(values[1]>=10) analogWrite(ledPin,255);
      
    }
  else if(values[0]== 2)
    {
      digitalWrite(ledPin2,LOW);
      Serial.println("GREEN LIGHT");
      if(values[1]==0) myservo.write(0);
      else if(values[1]==1) myservo.write(18);
      else if(values[1]==2) myservo.write(36);
      else if(values[1]==3) myservo.write(54);
      else if(values[1]==4) myservo.write(72);
      else if(values[1]==5) myservo.write(90);
      else if(values[1]==6) myservo.write(108);
      else if(values[1]==7) myservo.write(126);
      else if(values[1]==8) myservo.write(144);
      else if(values[1]==9) myservo.write(162);
      else if(values[1]==10) myservo.write(180);
    }
  else
    {
      digitalWrite(ledPin2,HIGH);
      digitalWrite(ledPin,LOW);
      Serial.println("RED LIGHT");
    }
}
}

basically how it's supposed to work is by sending the arduino serial messages structured a certain way. First theres a header (V1:) followed by 2 fields. If there's a 1 in the first field then the number in the second field will affect the ledPin (specifically the brightness of the attached LED). If there's a 2 in the first field then the number in the second field affects the position of a servo.

The code works fine for controlling the servo but it doesn't control the LED. It works however when the number in the second field is 10.

What I discovered is that if I take out the line that attaches the servo to pin 12, the lights work fine (and obviously the servo doesn't work because it's not attached).

I can't figure out how to successfully control the LED and servo with the same sketch. Is it possible that there is something in the servo.h library that is contradicting some part of my code? Please advise.

Servo - Arduino Reference, read this then move the led to a different pin with pwm.

I think what you are seeing is a conflict of timer usage. Both the servo library and analogWrite() utilize internal hardware timer(s) to function. The servo library when activated takes over the use of a timer(s) and any PWM pins that utilize that timer are disabled from the output pin.

From the servo source code:

Note that analogWrite of PWM on pins associated with the timer are disabled when the first servo is attached.
Timers are seized as needed in groups of 12 servos - 24 servos use two timers, 48 servos will use four.

From the arduino reference on analogWrite function:

On most Arduino boards (those with the ATmega168 or ATmega328), this function works on pins 3, 5, 6, 9, 10, and 11. On the Arduino Mega, it works on pins 2 through 13. Older Arduino boards with an ATmega8 only support analogWrite() on pins 9, 10, and 11. You do not need to call pinMode() to set the pin as an output before calling analogWrite().

As you are only assigning one servo then it will take over timer1 which I believe controls pwm pins 9 and 10.

So if you change const int ledPin = 10; to const int ledPin = 3; and change the led wiring from pin 10 to pin 3 you should avoid the timer usage conflict, as pwm pins 11 and 3 use timer3 (that from the following reference: http://www.arduino.cc/playground/Main/TimerPWMCheatsheet )

Note: Not tested, but I believe that is the root of your problem.

Lefty

WOW! That worked perfectly! Thanks so much :slight_smile: you're a boss retrolefty. I had no idea any of the PWM pins used the same timer. Have a good one!

I had no idea any of the PWM pins used the same timer

Good to hear that you have it working. I wonder if you had looked at the Servo reference and if you have any suggestions for making the PWM issue clearer