ServoTimer2 + VirtualWire

Hi all,

I have been working on making an RC car with two Arduino Unos (one for transmitting information from a controller, and one for receiving it on the car) and a motor shield (Arduino R3 version here: http://www.amazon.com/Arduino-Motor-Shi … B006UTE70E).

I originally ran into problems trying to use the motor shield, the virtualwire library, and the servo library. I learned there was a conflict of timer use and there just wasn’t enough hardware to work all of the boards at once.

Even with ServoTimer2, this wouldn’t work because as I understand it, VirtualWire uses Timer1, ServoTimer2 uses Timer2, and the Motor Shield uses both Timer0 and Timer2.

I tried to regain control of pins 3 and 11 (which are controlled by Timer2) by removing the pins from the motor shield that connect to those pins on the Arduino, and just plugging in my servo to pin 3. That did not work, however.

I have finally come to the realization I will just need to run the servo on its own microcontroller, but before I bought one, I wanted to make sure that the VirtualWire and Servotimer2 libraries can control a servo remotely.

To do this, I hooked up my 315MHz transmitter and receiver, and a servo, and wrote some code that will send a pulse width from the position of a slide pot through the transmitter and to the receiver. The receiver is connected to an Uno, and the servo is also on that Uno. The transmitted pulse widths are between 1300 and 2000uS, and the pulse widths will show up on the Serial Monitor on the receiving Uno with no problem. The issue occurs when I try to write the pulse width to the servo through any of the pins, even the ones not controlled by Timer1 (used by VW). The servo just jitters and doesn’t respond to input.

Here is my code on the receiving Uno:

// RF LINK RECEIVER CODE
#include <VirtualWire.h>
#include <ServoTimer2.h> 

char servoCharMsg[4]; 

//SERVO VARIABLES
ServoTimer2 servo; 
int servoPin=11;
int servoAngle;

void setup()
{
  
  servo.attach(servoPin);
  
 
  Serial.begin(9600);	// Debugging only
  Serial.println("Initialize RF Link Rx Code");

  //Initialize the IO and ISR
  vw_set_ptt_inverted(true); // Required for DR3100
  vw_setup(2000);	    // Bits per sec
  vw_set_rx_pin(2);         //Pin 2 is connected to "Digital Output" of receiver
  vw_rx_start();           // Start the receiver PLL running

  //Set pins for LED Output
  pinMode(8, OUTPUT);
  pinMode(3,OUTPUT);

  //Set pin for LED as status indicator
  pinMode (13, OUTPUT);
  digitalWrite(8,HIGH);
  delay(500);
  
  servo.write(1300);
  delay(1000);
  servo.write(2000);

}

void loop()
{
   digitalWrite(8,LOW);

  //Set buffer array based on max message length
  uint8_t buf[VW_MAX_MESSAGE_LEN];

  //Set variable to indicate buffer length
  uint8_t buflen = VW_MAX_MESSAGE_LEN;

  if (vw_get_message(buf, &buflen)) // Non-blocking
  {
    // Flash status LED to show received data
    digitalWrite(13, true); 
    

    for (int i = 0; i < buflen; i++)
    {
       servoCharMsg[i] = char(buf[i]);
    }
        
        servoCharMsg[buflen] = '\0';
        
        // Convert Sensor1CharMsg Char array to integer
        servoAngle = atoi(servoCharMsg); //now in microseconds
        
        Serial.println(servoAngle);
    }
    
    servo.write(servoAngle); //angle in us
    delay(10);
  
    }

When I use the example code that came with ServoTimer2, the servo responds just fine on its own. I have also connected the slide pot and servo on the same arduino and the servo will respond how it should with ServoTimer2. The issue is trying to use VirtualWire and ServoTimer2 at the same time.

I have been able to control the brightness of an LED with virtualwire on pin 6. Not sure if that helps with debugging. My only guess is that the LED brightness can be controlled because it only needs an 8bit timer, but the servo needs a higher resolution. Virtualwire uses the only 16bit timer on the Arduino. But since ServoTimer2 exists and works on its own, that doesn’t seem like the problem.

Any guidance would be appreciated. This is my first post on the forum so I hope I haven’t broken too many rules. Thanks for your help. Please let me know if I can provide any more information.

The issue is trying to use VirtualWire and ServoTimer2 at the same time.

You may be having difficulty with interrupt contention – interrupts are disabled when one interrupt is running, causing another interrupt to wait. This will lead to timing errors in critically timed events. If that is the case, there is no easy solution to the problem.

Consider using an independent servo controller like Pololu’s Maestro.

Thanks for your help jremington, I will look into that. I hadn’t thought about that kind of timing issue. Since I am actually getting the servo information on the receiving Arduino, hopefully there is a simple solution as far as actually moving the servo goes. I have worked with Pololu before and they made a good product, so I will consider trying to implement that controller. Thanks again!