Arduino ServoTimer2 and VirtualWire 433MHz Receiver





Introduction: Arduino ServoTimer2 and VirtualWire 433MHz Receiver

The Idea:

  • Use low cost radio control components + Arduino to control the movements of a Servo

The Challenges

Other Solutions


The Breakthrough

  • The Servo and Receiver do not like to play together so make them play apart.


  • In most examples the servo is attached in the setup function. Similarly, the receiver is started in the setup function.
  • However, I guessed there might be a function to undo an attached servo and similarly to stop a receiver. A little investigation revealed that that was the case.

Step 1: Components & Code


  • 10K Trimpot
  • 2 x Arduino (e.g. Uno, Duemilanove)
  • 433 MHz Transmitter & Receiver
  • Servo [I have a full rotation servo]
  • The usual prototyping paraphernalia - Computer, Breadboard, USB cables, Hookup wires

Virtual Wire


Step 2: Transmitter

The transmitter is the easy part.

  1. Read value from a Potentiometer
  2. Send it

Step 3: Receiver

NOTE: You may get a compile error that has the text:

error: conflicting declaration 'typedef uint8_t boolean'

This is easy to resolve

  • Use a Text Editor to edit ServoTimer2.h
  • Comment out the two offending lines (lines 76 and 77) and SAVE

typedef uint8_t boolean;
typedef uint8_t byte;

Change these lines to:

// typedef uint8_t boolean;
// typedef uint8_t byte;

This seems to be due to ServoTimer2 being written a while ago before those types were defined.

Step 4: Conclusion

I wasn't expecting it to be so hard to get these components to work together.

I learnt a bit about timers & libraries along the way which was interesting.

The full rotation servo that I have stutters along because it is attached & detached. I don't have any other type of servo so I'd be interested in how different types of servo respond using the same setup.



    • Epilog Challenge 9

      Epilog Challenge 9
    • Trash to Treasure

      Trash to Treasure
    • Paper Contest 2018

      Paper Contest 2018

    We have a be nice policy.
    Please be positive and constructive.




    No compiling error. That's good but the new servo library that given above is not working for me!

    A lot has happened in the Arduino world and I have learnt a bit too since I made this instructable. You can buy a couple of NRF24L01 modules for a couple of bucks from ebay. This would be a much better solution with no library issues at a very similar price. I'm in the process of making a remote controlled car using NRF24L01 modules and Arduino nano - instructable coming soon - maybe...

    hi there

    thank you very much for this post and the continuous help, i finally got the circuit working as expected.

    Hey can you please share your code that you used to run three servo with three potentiometer. And did you have to use more than two arduino or just two.


    i tried to follow your instructions and modify your codes, but i didnt get the result i wanted as all 3 potentiometers are only controlling one servo. i have attached my tx and rx codes for you to have a look and correct if you find mistakes. please bare in mind i am a beginner at programming.

    tx code:

    #include <VirtualWire.h>

    // Digital pin for LED

    const int led_pin = 13;

    // Digital pin for transmitter

    const int transmit_pin = 3;

    // Analog pin for Pot

    int potPin1 = 3;

    int potPin2 = 4;

    int potPin3 = 5;

    int potVal1 = 0;

    int potVal2 = 0;

    int potVal3 = 0;

    byte encodedVal[6];

    void setup()


    // Initialise the transmitter


    vw_setup(2000); // Bits per sec

    // The LED isn't necessary but gives a visual

    // indication that something is happening

    pinMode(led_pin, OUTPUT);


    void loop()


    // Read the pot

    potVal1 = analogRead(potPin1);

    potVal2 = analogRead(potPin2);

    potVal3 = analogRead(potPin3);

    // Convert int (PotVal) to byte array (encodedVal)

    encode1(potVal1, encodedVal);

    digitalWrite(led_pin, HIGH);

    encode2(potVal2, encodedVal);

    digitalWrite(led_pin, HIGH);

    encode3(potVal3, encodedVal);

    // Flash a light to show transmitting

    digitalWrite(led_pin, HIGH);

    // Send the byte array using the transmitter


    digitalWrite(led_pin, LOW);

    // Wait a little bit before repeating



    // Convert int to a 2 byte array

    void encode1(int val1, byte *encoded ) {

    encoded[0] = lowByte(val1);

    encoded[1] = highByte(val1);


    void encode2(int val2, byte *encoded ) {

    encoded[2] = lowByte(val2);

    encoded[3] = highByte(val2);


    void encode3(int val3, byte *encoded ) {

    encoded[4] = lowByte(val3);

    encoded[5] = highByte(val3);


    // Send byte array

    void send (byte *message)


    vw_send(message, sizeof(message));

    vw_wait_tx(); // Wait until the whole message is gone


    rx code:

    #include <VirtualWire.h>

    #include <ServoTimer2.h>

    #define MIN_PULSE 750

    #define MAX_PULSE 2250

    const int led_pin = 13;

    const int receive_pin = 4;

    const int servo_pin1 = 10;

    const int servo_pin2 = 11;

    const int servo_pin3 = 12;

    // a buffer to store the incoming messages

    byte message[VW_MAX_MESSAGE_LEN];

    // the size of the message

    byte messageLength = VW_MAX_MESSAGE_LEN;

    // Value decoded from message

    int decodedVal1;

    int decodedVal2;

    int decodedVal3;

    // Value mapped from Pot to Servo

    int mappedVal1;

    int mappedVal2;

    int mappedVal3;

    ServoTimer2 servo1;

    ServoTimer2 servo2;

    ServoTimer2 servo3;

    void setup()


    pinMode(led_pin, OUTPUT);

    // Initialise the IO and ISR


    vw_setup(2000); // Bits per sec


    void loop()




    void readMessage() {





    void tryGetMessage(int times) {

    bool gotMessage = false;

    int i = 0;

    while(i++ < times && !gotMessage) {

    if (vw_get_message(message, &messageLength)) {

    if (message[7] ==0) {

    gotMessage = true;

    // Flash a light to show received good message

    digitalWrite(led_pin, HIGH);

    decode1(message, decodedVal1);

    decode2(message, decodedVal2);

    decode3(message, decodedVal3);

    mappedVal1 = map(decodedVal1, 0, 1023, MAX_PULSE_WIDTH, MIN_PULSE_WIDTH);

    mappedVal2 = map(decodedVal2, 0, 1023, MAX_PULSE_WIDTH, MIN_PULSE_WIDTH);

    mappedVal3 = map(decodedVal3, 0, 1023, MAX_PULSE_WIDTH, MIN_PULSE_WIDTH);

    digitalWrite(led_pin, LOW);





















    // Convert the two bytes back to int

    void decode1(byte * encoded, int & decoded ) {

    decoded = (short)(((encoded[1]) & 0xFF) << 8 | (encoded[0]) & 0xFF);


    // Convert the two bytes back to int

    void decode2(byte * encoded, int & decoded ) {

    decoded = (short)(((encoded[3]) & 0xFF) << 8 | (encoded[2]) & 0xFF);


    // Convert the two bytes back to int

    void decode3(byte * encoded, int & decoded ) {

    decoded = (short)(((encoded[5]) & 0xFF) << 8 | (encoded[4]) & 0xFF);


    I presume you have a roll, pitch and yaw. I would be inclined to use an additional arduino at the receiver. I was just wanting to see if this could be done with only 1 Arduino at the receiver end. What I have shown is that it can be done but it's not the best technique. The movement is jerky due to all those delays + time taken to attach/detach.

    Have a look at this instructable that I referenced earlier


    I'm not sure that the check is even valid in my original code but change (message[7] ==0) to (message[6] == 0).

    You can use Serial.print as a debugging tool. You don't need to write 3 functions that do basically the same thing. E.g. instead of your 3 decode functions you can have one:

    void decode(byte * encoded, int & decoded, int idx ) {

    decoded = (short)(((encoded[idx+1]) & 0xFF) << 8 | (encoded[idx]) & 0xFF);


    Fewer functions = fewer places for things to go wrong + less code to check.

    after changing those 2 lines in the receiver code, here the error i get:

    void decode(byte * encoded, int & decoded, int idx ) {


    Multiple libraries were found for "ServoTimer2.h"

    Used: C:\Program Files (x86)\Arduino\libraries\ServoTimer2

    Not used: C:\Users\elijah\Documents\Arduino\libraries\ServoTimer2-master

    exit status 1

    too few arguments to function 'void decode(byte*, int&, int)'

    Hmmm... The example I gave is such that you need to pass an additional parameter. I'll leave it to you to work out what you should pass in that parameter/

    Ok. One more thing though. Apparently it's only sending the first 2 bytes from the first potententiometer. Only one servo is rotating. What do you think could be the problem? Is it on my tx side or my rx side?

    How do you know whether it is sending only the first two bytes? Did you use Serial.print as I suggested? There is no point to guessing what is happening in the code - just use Serial.print to find out what is actually happening.