Tuesday, February 5, 2013

RCArduino Libraries FAQ

A central point for questions and help on using the RCArduino Libraries.

The RCArduino Libraries provides servo output, PPM input and individual RC Channel input.

Its been created to reduce servo jitter in projects that need to both read and output RC Channels. If you want smooth focus for camera work, animatronics that don't twitch around or fast smooth control of your RC Vehicle, read on.

1) Why a new servo and RC library ?

The standard Arduino Servo library is very good, its well documented and well supported, it also has some challenges when used in projects that read incoming RC Signals. The RCArduino Servo library addresses these challenges to provide smoother output. This is achieved through faster interrupt service routines which reduce clashes and glitches.

A major improvement is also acheived by not resetting timer1 as the standard servo library can. This allows us to use timer1 for timing incoming RC Signals as well as generating the servo outputs.



An detailed explanation can be found here -

http://rcarduino.blogspot.com/2012/11/how-to-read-rc-channels-rcarduinofastlib.html

2) Can I use the library to read PPM signals and output RC Channels ?

Yes, an example is provided here, but come back here for more documentation if you need it.

http://rcarduino.blogspot.com/2012/11/how-to-read-rc-receiver-ppm-stream.html

3) Can I use the library to read individual RC Channels and output RC Channels ? 

Yes, an example is provided here, but come back here for more documentation and if your planning to use a mega look out for an update with an example using the six Arduino Mega interrupts instead of the pinchangeint library which is used in the UNO version to provide more than the standard two interrupts.

http://rcarduino.blogspot.com/2012/11/how-to-read-rc-channels-rcarduinofastlib.html

Some background on the pinchangeint library if you need more than 2 interrupts on an UNO or more than 6 on a Mega -

http://rcarduino.blogspot.com/2012/03/need-more-interrupts-to-read-more.html
How do we use the library ?

The RCArduino library uses arrays internally to record the channel input and output values. This is slightly more efficient than the linked lists used by the servo library however its also a little less user friendly. Unlike the Servo library which allows us to attach servos at runtime, the RCArduino library requires that we set the number of servos at compile time. Similarly if you plan to use the PPM Input capability you will need to specify the number of input channels at compile time.

To make this as simple as possible, two #define's are used  in the RCArduinoFastLib.h file.

To set the number of input channels if your going to read a PPM Stream change the number here -
// Change to set the number of channels in PPM Input stream
#define RC_CHANNEL_IN_COUNT 3

To set the number of servos in your project change the number here -

// Change to set the number of servos/ESCs
#define RC_CHANNEL_OUT_COUNT 4

Set the RC_CHANNEL_OUT_COUNT to one more servo than you need, the library is able to generate higher refresh rate signals than the standard Servo library which forces a 50Hz refresh rate. To set the refresh rate we create an additional entry in the servo array. We use the 'setFrameSpace' function on this last entry to set the frame space which sets the refresh rate. While this is initially an awkward additional step, it also gives us a lot more flexibility, for example we can use the library to drive high refresh rates upto 500Hz.

To generate a 50Hz refresh rate which is equivalent to the standard servo library we can use the following calculation -

1/50 = 20,000 microseconds
frame space = 20,000 - (2,000 * number of servos)

An Example -
To drive 8 servos we would set RC_CHANNEL_OUT_COUNT to (8 + 1)= 9. Remember the additional entry is for our framespace.

#define RC_CHANNEL_OUT_COUNT 9

we can then calculate

frame space = 20,000 - (2,000 * (RC_CHANNEL_OUT_COUNT - 1) )

Note we take away 1 so that we do not include the framespace in the framespace calculation

frame space = 20,000 - (2,000 * 8)
frame space = 4,000

So to set the frame space to give a refresh rate of 50 Hz for 8 servos we call

CRCArduinoFastServos::setFrameSpaceA(SERVO_FRAME_SPACE,4000);

Why the maths ?
 
While this is more complex than the standard servo library it is also more flexible and provides a quick and easy way to drive the high frequency ESCs and Servos that are becoming more popular.

If your unsure about the frame space calculation or would like to try the RCArduino libraries with 500Hz ESCs and Servos use the comments or contact me Duane B through the Arduino forum.

I am also considering automating the calculation through a convenience function in a future release, stay tuned.

Now that we have that out of the way, its all very easy.

Attaching A Servo
To attach a servo we call the attach function supply the index of the servo we want to attach (they start at 0, remember they are held in an array) and the Arduino pin we want to attach it to.

CRCArduinoFastServos::attach(SERVO_THROTTLE/* Servo index */,THROTTLE_OUT_PIN /* the pin we want it attached to */);

The final thing we need to do inside out set up function is to call the begin function, this initialises timer1 for use by the library and attaches the interrupt routines.

Understanding The Library and Reading and Writing Channels

The key to understanding and using the library is to be aware of the RC_CHANNEL_IN_COUNT and RC_CHANNEL_OUT_COUNT settings and also to understand that the channel values are stored in arrays which are accessed by the index you supply when calling the read and write functions -

CRCArduinoFastServos::writeMicroseconds(SERVO_STEERING /* 0 based index into servo array */,unSteeringIn);
CRCArduinoPPMChannels::getChannel(SERVO_STEERING /* 0 based index into PPM input array */);

You can create your own indexes into the arrays by defining them in your sketch, the number of input channels does not need to match the number of output channels. You can also have a different index for an input channel that you use for the output channel, in fact you will sometimes find that channels within the PPM stream are in a different order than the printed channel numbers on your receiver.

To get started try the examples provided -

http://rcarduino.blogspot.com/2012/11/how-to-read-rc-channels-rcarduinofastlib.html

http://rcarduino.blogspot.com/2012/11/how-to-read-rc-receiver-ppm-stream.html

For any help, use the comments section below

Duane B

34 comments:

  1. Everything works great now. Signals are so smooth from all channels. Thanks for the best blog on the whole web and thanks a lot for your help and patience :)

    Samir

    ReplyDelete
  2. So is it right that i can't generate 4*400Hz Signals for every single ESC of my 4 ESCs on my Quadrocopter with the Arduino Uno?
    The max. frequency would be 4*2ms = 8ms --> 125Hz?

    Is there a way to achive this on the Uno?

    ReplyDelete
  3. Hi,
    You can do this on the UNO. Your maths is a bit wrong, 4 * 400Hz signals are still 400Hz signals but its not a problem as the Arduino runs at 16Mhz.

    To generate these signals you can use a variation of the library here -

    http://rcarduino.blogspot.ae/2012/11/how-to-read-rc-channels-rcarduinofastlib.html

    I can talk you through the modification although I have no 400Hz equipment to test against so the risk is on you.

    Let me know

    Duane B.

    ReplyDelete
  4. Hi Duane!

    I would appreciate if you talk me trough the modification! And my hardware is 100% 400Hz suitable.

    Thanks,
    tobawp

    ReplyDelete
  5. Hi,
    First of all, get the library code and test sketch from this post -

    http://rcarduino.blogspot.com/2012/11/how-to-read-rc-channels-rcarduinofastlib.html

    Install the code on your system and upload it to your Arduino with no hardware connected.

    Once you have this in place, let me know and I will tell which bits to change.

    Duane B

    ReplyDelete
  6. Hey Duane, everything in place, I'm curious what to change!
    I was just confused by your comment when i first saw the lib code because there was something like:

    // 10 servos at 1500us = 15ms = 66Hz
    // 4 Servos at 1500us = 6ms = 166Hz
    // if you wanted to go even higher, run two servos on each timer
    // 2 Servos at 1500us = 3ms = 333Hz

    So i assumed that it isn't possible to run 4 ESCs@400Hz because of a lack of timers on the UNO (or something like that)...

    Thanks in advance,
    tobawo

    ReplyDelete
  7. Hi,
    Its my mistake, the high frequency ESCs use a narrow pulse width, typically 500 to 1000 us so 2 Servos at 1000us = 2ms = upto 500Hz. If we add a frame space of 500us or more we get 2.5ms = 400hz.

    Once you have the standard code compiled, let me know and I will advise the changes.

    The changed code will give a variable frame rate with a maximum of 400Hz, if the variable framerate is a problem for you equipment its simple enough to change it for a fixed frame rate.

    Duane B

    ReplyDelete
  8. Okay the standard code was compiled properly.
    Actually I'm not quite shure if my ESCs will handle the narrow pulse width. That are ESCs with SimonK firmware.

    When I first tested these with the std. servo lib. with 50Hz they accepted only the normal 1-2ms pulse width...

    ReplyDelete
  9. Do you have a link to the ESC and the firmware version ? Or are you in contact with SimonK, if so can you confirm the pulsewidth directly with him ?

    Duane B

    ReplyDelete
  10. Found it here -

    https://github.com/sim-/tgy

    It uses the standard signal range of 1 to 2ms, but in the features section clearly says 'Accepts any PWM update rate (minimum ~5microseconds PWM low time)'

    There is a process to calibrate it to a narrower signal however in the short term I can get you running standard signals at around 300Hz which is a lot better than the standard 50Hz.

    Duane B

    ReplyDelete
  11. Hey Duane! Okay cool sounds great!
    How is it done?
    With the narrower signal you mean something like 1-1.5ms? Because I think values below 1ms aren't possible.

    P.S. These are the ESCs i have:
    http://flyduino.net/Flyduino-NFET-HEXFET-20A-ESC-SimonK-Firmware_1

    Thanks!
    tobawo

    ReplyDelete
  12. The configuration we want is mostly in the rcarduinofastlib.h file.

    The library is able to run two banks of ten servos for a total of 20 servos. Although you only want 4, you want them to refresh quickly. To do this we split the servos into two banks of two servos.

    1) Uncomment this line to enable the second bank of servos

    Change this -
    // COMMENT OR UNCOMMENT THIS LINE TO ENABLE THE SECOND BANK OF SERVOS
    //#define MORE_SERVOS_PLEASE 1

    to this -

    // COMMENT OR UNCOMMENT THIS LINE TO ENABLE THE SECOND BANK OF SERVOS
    #define MORE_SERVOS_PLEASE 1

    2) Next we want two servos in each bank and one more servo in each bank which we are going to use to set the frame space

    change this -

    #define RC_CHANNEL_OUT_COUNT 4

    to this -

    #define RC_CHANNEL_OUT_COUNT 3 // 2 servos + 1 frame space

    Thats it for the .h file

    There are a few changes to make to the sketch, but if you have an existing test sketch we might as well make the changes in that, do you have one ?

    Duane B

    ReplyDelete
  13. Hi Duane!
    Sorry for the late answer, I was bussy...
    I've made the changes in the .h file that you posted.
    Till now I have no test sketch based on the rcarduinofastlib, just a sketch using the standard servo lib.

    Thanks!
    tobawo

    ReplyDelete
  14. Hi,
    Based on the library documentation which states 'any pwm frequency provided the low time is > 5us' it should be possible to run the library without a frame space for a much higher frequency. I will have a look for something to use as a test sketch for this approach and send it to you to try.

    Duane B

    ReplyDelete
  15. Try this, I have no equipment to test the output on so be very careful and be ready to disconnect quickly if the unexpected happens -

    #include "RCArduinoFastLib.h"

    // Generating a high frequency ESC Signal using the RCArduinoFastLib
    //
    // The sketch assumes -
    // The ESC Software uses the normal pulse width range of 1000 to 2000 microseconds
    // The ESC Software supports a variable frequency provided that there is a space of greater than 5 microseconds between pulses
    // The test sketch requires a 10K potentiometer attached to A0 to set the output speed.

    // These are your output pins, connect servos and ESCs to these
    #define FRONTLEFT_OUT_PIN 8
    #define FRONTRIGHT_OUT_PIN 9
    #define REARRIGHT_OUT_PIN 10
    #define REARLEFT_OUT_PIN 11

    // Assign servo indexes - don't change this
    #define FRONTLEFT_CHANNEL 0
    #define FRONTRIGHT_CHANNEL 1
    #define REARLEFT_CHANNEL 2
    #define REARRIGHT_CHANNEL 3

    void setup()
    {
    Serial.begin(115200);

    CRCArduinoFastServos::attach(FRONTLEFT_CHANNEL,FRONTLEFT_OUT_PIN);
    CRCArduinoFastServos::attach(FRONTRIGHT_CHANNEL,FRONTRIGHT_OUT_PIN);
    CRCArduinoFastServos::attach(REARRIGHT_CHANNEL,REARRIGHT_OUT_PIN);
    CRCArduinoFastServos::attach(REARLEFT_CHANNEL,REARLEFT_OUT_PIN);

    // start the servos
    CRCArduinoFastServos::begin();
    }

    void loop()
    {
    // read an analog input (0) and map the speed to the value from the analog input
    uint16_t unSpeed = map(analogRead(0),0,1024,1000,2000);

    CRCArduinoFastServos::writeMicroseconds(FRONTLEFT_CHANNEL,unSpeed);
    CRCArduinoFastServos::writeMicroseconds(FRONTRIGHT_CHANNEL,unSpeed);
    CRCArduinoFastServos::writeMicroseconds(REARRIGHT_CHANNEL,unSpeed);
    CRCArduinoFastServos::writeMicroseconds(REARLEFT_CHANNEL,unSpeed);
    }

    Let me know what happens

    Duane B

    ReplyDelete
  16. Thanks Duane, that worked perfectly fine!
    What ist the current update rate with this code?

    Regards,
    tobawo

    ReplyDelete
  17. Hi,
    Change this line in the header file

    #define RC_CHANNEL_OUT_COUNT 3 // 2 servos + 1 frame space

    to

    #define RC_CHANNEL_OUT_COUNT 2 // 2 servos with no frame space

    and you should get a variable frequency of between 500Hz and 250Hz.

    The frequency is a direct result of the channel pulse width, so to channels sending 1ms will give 2*1ms = 2ms, 1/2ms = 500Hz. At the other extreme, 2*2ms = 4ms, 1/4ms = 250Hz. In practice your frequency will vary between the highest and lowest (500hz - 250Hz)

    The ESC Software you are using will be happy with this and it is five to ten times more responsive than the standard Arduino servo library.

    Duane B

    ReplyDelete
  18. Moved by Duane B - Original question by Derek Bode

    Duane,

    I have this code working well for operating a robot that my students have built. Thank you very much for this entry by the way. But the issue we are having now is that we would like to have a sweeping ultrasonic sensor on the front to avoid obstacles. I have the coding seeming all well and good to make that work, but the problem is that I am getting an error that I have posted below in trying to include the standard Servo.h library. Do you know how I would get one servo working on the standard angle system and the others working on you writemicrosecond commands? Any help would be greatly appreciated to help us get our project rolling again before school is out for the year.

    Thanks,
    Derek

    Error:

    Servo/Servo.cpp.o: In function `__vector_11':
    /Users/wcsstaff/Documents/WHS/Course Files/Principles of Tech II/Arduino Info/Arduino Programming/Arduino.app/Contents/Resources/Java/libraries/Servo/Servo.cpp:103: multiple definition of `__vector_11'
    RCArduinoFastLib/RCArduinoFastLib.cpp.o:/Users/wcsstaff/Documents/Arduino 1.0/libraries/RCArduinoFastLib/RCArduinoFastLib.cpp:51: first defined here

    ReplyDelete
    Replies
    1. Hi,
      I can see that you are using both the RCArduinoFastLib and the Servo library in the same sketch.

      You will not be able to do this, the RCArduinoFastLib is a replacement for the servo library and uses some of the same resources.

      I assume you are doing this because you want to use Servo.write to send angles to the servo instead of microseconds ?

      Internally servos do not think in angles but pulse widths - effectively microseconds. If you look at the standard servo library you will see that the write function converts the angle to micro seconds and then calls servo.writeMicroseconds

      An interesting exercise for your students would be to have a look at the map function, this function takes a value in one range, for example degrees and converts it to another range i.e. microseconds.

      How about getting your students to add a write function which takes and angle to the RCArduinoFastLib, internally it should call map (from angles to microseconds) and then call writeMicroseconds with the new value.

      If they do a good job and you send me the code, I will add it to the original library with a comment giving them credit and a little bit of fame.

      If you need some help with this let me know

      Duane B

      Delete
    2. This is actually our first class doing any robotics and our first build with Arduino or any other platform, so I am doing the programming and then walking them through it and how it functions. And I'm just teaching myself how to program an Arduino as well. I'll take a stab at it and see what I can come up with, but I do get what your talking about with the map function. Thanks for the help so far.

      -Derek

      Delete
    3. Below is the code that I am trying to integrate. I have already corrected all of the movement commands to match the RCArduinoFastLib commands, but the angles are used heavily. It seems that I should be able to create one function to make the conversion for that one servo.

      -Derek, floundering.

      Delete
    4. Sorry, forgot to paste the code:

      #include

      const int motor1APin = 11; // H-bridge leg 1
      const int motor2APin = 6; // H-bridge leg 2
      const int motor3APin = 10; // H-bridge leg 1
      const int motor4APin = 5; // H-bridge leg 2
      const int enablePin = 12; // H-bridge enable pin

      const int Trig = 3; //Ultrasonic
      const int Echo = 2;

      Servo myservo;



      void setup()
      {
      // set all the other pins you're using as outputs:
      pinMode( enablePin, OUTPUT);
      pinMode( motor1APin, OUTPUT);
      pinMode( motor2APin, OUTPUT);
      pinMode( motor3APin, OUTPUT);
      pinMode( motor4APin, OUTPUT);
      pinMode(Trig, OUTPUT);
      pinMode(Echo, INPUT);

      // set enablePin high so that motor can turn on:
      digitalWrite(enablePin, HIGH);

      myservo.attach(8);

      }

      unsigned int time_us=0;
      unsigned int distance_sm=0;
      unsigned int circle=0;
      unsigned int dist_f=0;
      unsigned int dist_l=0;
      unsigned int dist_r=0;
      unsigned int dist_45=0;
      unsigned int dist_135=0;
      unsigned int t=15;

      void loop()
      {
      if (circle==0)
      {
      myservo.write(0); //initial parameters
      dist_r=sonar();
      motion('w',0,45,t);
      dist_45=sonar();
      motion('w',45,90,t);
      dist_f=sonar();
      motion('w',90,135,t);
      dist_135=sonar();
      motion('w',135,180,t);
      dist_l=sonar();
      }
      circle++;

      if(dist_f>=25)
      {
      a:
      motion('f',180,135,t);
      dist_135=sonar();
      front_motion(t);
      motion('f',135,90,t);
      dist_f=sonar();
      front_motion(t);
      motion('f',90,45,t);
      dist_45=sonar();
      front_motion(t);
      motion('f',45,0,t);
      dist_r=sonar();
      front_motion(t);
      motion('f',0,45,t);
      dist_45=sonar();
      front_motion(t);
      motion('f',45,90,t);
      dist_f=sonar();
      front_motion(t);
      motion('f',90,135,t);
      dist_135=sonar();
      front_motion(t);
      motion('f',135,180,t);
      dist_l=sonar();
      front_motion(t);
      if (dist_f>=25)
      goto a;
      }

      else
      {
      if(dist_f<5)
      {
      motion_back(t);
      dist_f=sonar();
      }

      if(dist_l>=dist_r || dist_135>dist_r)
      {
      motion('l',180,90,t);
      dist_f=sonar();
      }
      if(dist_l=prev_angle)
      a=15;
      else
      a=-15;

      if (dimention=='f')
      {
      int i=prev_angle;
      while( i!=next_angle)
      {
      i+=a;
      myservo.write(i);
      forward();
      delay(time);
      }
      }
      if (dimention=='l')
      {
      int i=prev_angle;
      while( i!=next_angle)
      {
      i+=a;
      myservo.write(i);
      left();
      delay(time);
      }
      }
      if (dimention=='r')
      {
      int i=prev_angle;
      while( i!=next_angle )
      {
      i+=a;
      myservo.write(i);
      right();
      delay(time);
      }
      }
      if (dimention=='b')
      {
      int i=prev_angle;
      while( i!=next_angle )
      {
      i+=a;
      myservo.write(i);
      back();
      delay(time);
      }
      }
      if (dimention=='w')
      {
      int i=prev_angle;
      while( i!=next_angle )
      {
      i+=a;
      myservo.write(i);
      wait();
      delay(time);
      }
      }

      }

      void front_motion( int time )
      {
      if(dist_45<=9)
      {
      left();
      delay(3*time);
      }
      if(dist_135<=9)
      {
      right();
      delay(3*time);
      }
      }

      void motion_back( int time )
      {
      motion('b',180,90,2*time);
      /*if(dist_l>=dist_r)
      {
      do
      {
      left();
      delay(time);
      dist_f=sonar();
      }while(dist_f<=20);
      }

      if(dist_l<dist_r)
      {
      do
      {
      right();
      delay(time);
      dist_f=sonar();
      }while(dist_f<=20);
      } */
      }

      Delete
    5. Duane,

      Not sure if it's right, but it is starting to work. I basically just swapped all the write commands for the FastServo writeMicroseconds and changed all of the values to be in microseconds instead of degrees. I just have to tweek the values of the distances from the sensor to have it react in time. Thanks again for all of your work on your blog. You have put a lot of time into it I can see.

      Thanks again,

      Derek

      Delete
  19. I am quite new to Arduino, but I am trying to figure out whether I can utilize the RCArduinoFastLib to decode PPM stream from the VEX 75 MHz Transmitter & Receiver (http://www.vexrobotics.com/vex/products/accessories/control/276-2153.html).

    The Vex transmitter and receiver utilize a 4P4C connection port to outputs a PPM stream (so you should be able to retrieve the PPM signal from either receiver or directly from the transmitter). I was reading up on the Vex transmitter and decoding from the following sites for reference:

    http://www.vexforum.com/showthread.php?t=24931
    http://profmason.com/?p=602
    http://profmason.com/wp-content/uploads/2008/08/js-6.pdf

    I assume need I connect the PPM output from the transmitter (or receiver) to an Arduino (Nano) as follows, in order to be able to read the PPM signal.

    VDD to 5V
    VSS to Ground
    PPM to D2 (with 10k pull-up resistor across VDD and D2)

    I edited the RCArduinoFastLib.h file to correspond to the Vex transmitter's 6 channels.

    #define RC_CHANNEL_OUT_COUNT 7
    ...
    #define RC_CHANNEL_IN_COUNT 6



    In my sketch I set the frame space as follows:


    #define PPM_FRAME_SPACE 6
    ...
    CRCArduinoFastServos::setFrameSpaceA(PPM_FRAME_SPACE,8000);


    Upon trying to read the value from each channel in serial monitor and I receive 01 for each channel.

    Example channel 1:

    #define PPM_CHANNEL1_RGT_X_STK 0
    ...
    const int CHANNEL1_OUT_PIN=4;
    ...
    CRCArduinoFastServos::attach(PPM_CHANNEL1_RGT_X_STK,CHANNEL1_OUT_PIN);
    ...
    uint16_t unChannel1In = Serial.print(CRCArduinoPPMChannels::getChannel (PPM_CHANNEL1_RGT_X_STK));
    ...
    if(unChannel2In) {
    Serial.print(unChannel2In);
    }
    The values do not change with any transmitter stick movement or press of the buttons.

    I am not sure if it is my wiring or I am printing the wrong value. Any suggestion would be helpful.

    Thanks

    ReplyDelete
  20. After reviewing my set up, I think I found the 10k pull-up resistor was incorrectly wired. Once this was corrected, I was successfully able to decode all 6 individual channels values in the PPM stream from the Vex transmitter tether port. The value changes corresponding to transmitter stick movement (channel 1-4) and button presses (channel 5-6).

    The good news is the RCArduinoFastLib is able to decode the Vex transmitter PPM stream.

    The only issue I am still seeing, is resulting values appear to be higher then expected.

    Example of Transmitter idle values

    Channel 1 Channel 2 Channel 3 Channel 4 Channel 5 Channel 6
    15254 15184 15234 15154 15194 15184

    Where the channel neutral is around 15000, full positive is around 20000 and full negative is around 10000. I expected the values would be neutral = 1500, full positive = 2000 and full negative = 1000.

    Any idea what would cause this?

    Thanks



    ReplyDelete
  21. glad you were able to figure it out. The 1,000 to 2,000 us range with 1,500 as the center is a rough guide, in practice you will find that the channel centers and end points will be off byas much as 200 us as in your case. For some projects where you are just passing thevaluesthrough, this does not matter. For other projects where you are calculating outputs based on the current input and its position within the input range, you will need to calibrate your project. There is an example on the blog that shows calibration, if yoy cant find it, let me know and i will post the link here. Its part of the RCArduino Robot posts.

    Duane

    ReplyDelete
  22. Calibration - how and why here -
    http://rcarduino.blogspot.com/2012/05/interfacing-rc-channels-to-l293d-motor.html

    Duane B

    ReplyDelete
  23. Sir,
    My name is Hari..
    I had been trying to make a quadcopter using arduino Mega.So i tried using the rcarduinofastlib.I tried it first in UNO and got it working succesfully.But when i changed to Mega,with the pins changed from 5,6,7 in UNO to 10,11,12 in Mega and the ESCs from 8,9,10 to 5,6,7.
    These changes were made since,i came to know about the issues with the Interupts.
    These changes were made as mentioned already in this blog.I also tried to make it work using the analog pins from 6 to 15,but couldn't make it.
    I would like to know whether i should change anything more from the test code given by you here:

    http://rcarduino.blogspot.co.uk/2012/11/how-to-read-rc-channels-rcarduinofastlib.html?m=1

    Any help will be deeply appreciated.
    Thanking you in anticipation
    Hari

    ReplyDelete
    Replies
    1. Hi,

      Send me your current code through a PM to DuaneB on the Arduino forum and I will have a look.

      Duane B

      Delete
    2. Sir,
      Thank you for your quick response.
      I just started building my quad,since i got most of my components two days back only.However,i have custom made a 6 axis IMU in the mean time,which is working with its code.

      Once my RC controller arrived,i just tried to read the receiver data from my arduino and control servos using it .Though it was working,it was damn slow because of pulsein and servolib.
      And from this blog,i tried the rcarduinofastlib in my uno with just the test code given by you here and it worked perfectly for me.I hadn't integrated my IMU into this code.
      I tried to change from uno to mega(with your same test sketch,changing the pins as mentioned).So,the current code is just the test code that you have provided in this link here:

      http://rcarduino.blogspot.co.uk/2012/11/how-to-read-rc-channels-rcarduinofastlib.html?m=1


      with the pins changed as mentioned by you like this:


      to

      // Assign your channel in pins
      #define THROTTLE_IN_PIN 10
      #define STEERING_IN_PIN 11
      #define AUX_IN_PIN 12

      // Assign your channel out pins
      #define THROTTLE_OUT_PIN 5
      #define STEERING_OUT_PIN 6
      #define AUX_OUT_PIN 7

      Also,in the end of that post,you said,you will make a mega specific version that weekend.I also searched for that mega specific code everywhere,bu couldn't find it.


      Basically,i am a mechanical engg. 2nd year student.So,i am not that comforatble with Interuppts/Timers.

      Thanks again!

      Delete
    3. Ok, so what does not work ? are your servos not being pulsed or are you not receiving any incoming interrupts or something else ?

      Duane.

      Delete
  24. Duane,

    I am feeling overwhelmed by all of the fantastic info here. Please point me in the right direction for what I want to do...

    I want to use my six-channel 2.4 GHz radio to control up to 4 motors with PWM via H-bridges. Should I use the RCArduinoFastLib library to read the PPM from the receiver and then manually map/constrain those to PWM values or is there a better way that I have not seen?

    BTW, my son and I were admiring your traction control setup! Pretty neat stuff.

    -dtp

    ReplyDelete
  25. Hi,
    Yes, you will need to read the PPM and than map it to PWM for the H-Bridges. The most reliable way to do this is to include some calibration code, you will find that your receiver does not output 1000-1500-2000us for reverse, neutral and full speed ahead. Here is a post with an explanation and some sample code, it reads individual channels directly rather than from a PPM Stream but it would be easy enough to convert.

    http://rcarduino.blogspot.ae/2012/05/interfacing-rc-channels-to-l293d-motor.html

    Duane

    ReplyDelete
  26. Hi Duane

    I would like to use this library to receive code from my Hitech RX with PPM output. but I have a strange question, is there a limit to how long the wire can be that the PPM stream is travelling on before info will be lost ?

    ReplyDelete