Friday, January 20, 2012

How To Read an RC Receiver With A Microcontroller - Part 1

Its a very common question, 'How do I read an RC Receiver with my micro controller' and the answer is often very simple however the simple answer is close to useless in a real world application.

The approach outlined in this series of posts has been tested in an RC Race car running at 40+ Kmh at a range of 100 meters.

The approach is reliable, resilient, easy to understand and easy to modify. It has been tested using using 27Mhz AM radio equipment and entry level electronics. Use of better quality electronics and radio equipment will provide improvements in range and signal quality however as the development process has demonstrated, even low end equipment can be interfaced with Arduino for control of an RC Race car.

Update 05/11/12 Read multiple RC channels with a smoother, faster library -
http://rcarduino.blogspot.com/2012/11/how-to-read-rc-channels-rcarduinofastlib.html
For the background to this and the original sketch before optimisation see - 
http://rcarduino.blogspot.com/2012/04/how-to-read-multiple-rc-channels-draft.html


Update 04/11/12 - For those of you looking to read a PPM Stream instead of individual channels, I will have a small fast library up this week - will post an update with the link here -
http://rcarduino.blogspot.ae/2012/11/how-to-read-rc-receiver-ppm-stream.html


Background Information

What are we looking for when we read from an RC Receiver ? Its not what I originally expected, my guess was that it was an analogue signal that would be amplified by the speed controller or servo controller to drive the motors. Its not analogue at all, its actually mostly empty space.

Each channel decoded by your receiver is sent to your ESCs and Servos as a train of pulses, these pulses are sent about 50 times a second but the suprising part is, each pulse only lasts between one and two milliseconds (1/1000 to 2/1000 of a second). Before the next pulse arrives, there is a gap of 10 times the length of the even longest pulse.

In an Electric RC Car a pulse width of 1000 is full reverse or brake, a pulse width of 2000 is full throttle and a pulse of 1500 is neutral. Note that these may be reversed, but the nature and range of the signal does not change.

This pulse train as it comes from the receiver could not be used to drive anything, not even a toy motor. The ESC or Servo control circuitry takes the pulse train as an input and generates a very different output, not just in power, but also in profile and even polarity in the case of reversing a motor.


The Simple Approach and Why Its Wrong

A common suggestion is to connect the receiver to the microcontroler such that there is a common ground (GND) between the two devices and then attach the white or orange signal wire from the receiver to one of the digital input microcontroller pins.

From here there are a variety of approaches to reading the values from the pins -

PulseIn (a blocking polling approach)

PulseIn is a function available with the Arduino that implements an approach know as 'poling'. It essentially sits around waiting for something to happen, until something happens the rest of your code is blocked. This is okay for a simple lab exercise to read and print values from a receiver but it is a hopeless approach for a real world application. Fortunately there are better approaches that do not require a major learning curve.

Timers

There is an example in the Arduino Playground which uses timers ReadReceiver. It may offer greater resolution than the method I am using, but it is also considerably more complicated and as I will show in a follow up post, the source receiver signal degrades rapidly as you move outside the lab rendering the increased accuracy less valuable.

Interrupts

The Timer example and my own approach both use Interrupts. Interrupts allow you to declare your interest in an event and then have the micro controller 'interrupt' your code whenever the event occurs.

Lets take a closer look at the channel signal and determine which bits we should be interested in -



If all we are interested in is the pulse duration, why not use pulseIn ? after all there is nothing else of interest in the signal.

The Arduino UNO is able to perform 16 million operations in one second. In the 2 milli second duration of a full throttle pulse, the Arduino could have performed 32,000 operations ! Thats a lot of wasted power. But it gets worse, what if you call pulseIn immediately after a pulse, you will have to wait a whole 20 milliseconds for the next pulse to arrive and complete. Thats a full 320,000 operations useful operations your code could have completed.

On average you can expect to call pulseIn in the center between two pulses, this means that over an extended period, half or your available processing power is wasted just waiting for the next pulse to arrive and complete. If you add more inputs, the approach becomes quickly unsustainable as you can only give your attention to a single input at a time.

Don't Use Pulse In !

Here are some updates showing the code in action - 

Active Yaw Control Of An RC Race Car
http://rcarduino.blogspot.com/2012/07/rcarduino-yaw-control-part-2.html 

Mapping RC Car Controls To A  Tank Tracked Robot
http://rcarduino.blogspot.com/2012/05/interfacing-rc-channels-to-l293d-motor.html 


Using an interrupt to efficiently detect new pulses and output to serial

For reading multiple RC Channels see - 

http://rcarduino.blogspot.co.uk/2012/04/how-to-read-multiple-rc-channels-draft.html


// First Example in a series of posts illustrating reading an RC Receiver with
// micro controller interrupts.
//
// Subsequent posts will provide enhancements required for real world operation
// in high speed applications with multiple inputs.
//
// http://rcarduino.blogspot.com/
//
// Posts in the series will be titled - How To Read an RC Receiver With A Microcontroller

// See also http://rcarduino.blogspot.co.uk/2012/04/how-to-read-multiple-rc-channels-draft.html 

#define THROTTLE_SIGNAL_IN 0 // INTERRUPT 0 = DIGITAL PIN 2 - use the interrupt number in attachInterrupt
#define THROTTLE_SIGNAL_IN_PIN 2 // INTERRUPT 0 = DIGITAL PIN 2 - use the PIN number in digitalRead

#define NEUTRAL_THROTTLE 1500 // this is the duration in microseconds of neutral throttle on an electric RC Car

volatile int nThrottleIn = NEUTRAL_THROTTLE; // volatile, we set this in the Interrupt and read it in loop so it must be declared volatile
volatile unsigned long ulStartPeriod = 0; // set in the interrupt
volatile boolean bNewThrottleSignal = false; // set in the interrupt and read in the loop
// we could use nThrottleIn = 0 in loop instead of a separate variable, but using bNewThrottleSignal to indicate we have a new signal
// is clearer for this first example

void setup()
{
  // tell the Arduino we want the function calcInput to be called whenever INT0 (digital pin 2) changes from HIGH to LOW or LOW to HIGH
  // catching these changes will allow us to calculate how long the input pulse is
  attachInterrupt(THROTTLE_SIGNAL_IN,calcInput,CHANGE);

  Serial.begin(9600);
}

void loop()
{
 // if a new throttle signal has been measured, lets print the value to serial, if not our code could carry on with some other processing
 if(bNewThrottleSignal)
 {

   Serial.println(nThrottleIn); 

   // set this back to false when we have finished
   // with nThrottleIn, while true, calcInput will not update
   // nThrottleIn
   bNewThrottleSignal = false;
 }

 // other processing ...
}

void calcInput()
{
  // if the pin is high, its the start of an interrupt
  if(digitalRead(THROTTLE_SIGNAL_IN_PIN) == HIGH)
  {
    // get the time using micros - when our code gets really busy this will become inaccurate, but for the current application its
    // easy to understand and works very well
    ulStartPeriod = micros();
  }
  else
  {
    // if the pin is low, its the falling edge of the pulse so now we can calculate the pulse duration by subtracting the
    // start time ulStartPeriod from the current time returned by micros()
    if(ulStartPeriod && (bNewThrottleSignal == false))
    {
      nThrottleIn = (int)(micros() - ulStartPeriod);
      ulStartPeriod = 0;

      // tell loop we have a new signal on the throttle channel
      // we will not update nThrottleIn until loop sets
      // bNewThrottleSignal back to false
      bNewThrottleSignal = true;
    }
  }
}



Next up - Part 2 including what does the signal really look like ? and more of the code to deal with it.

For reading multiple channels using an interrupt driven technique see -

http://rcarduino.blogspot.co.uk/2012/04/how-to-read-multiple-rc-channels-draft.html

106 comments:

  1. Really Good Post!!

    San Francisco Bay Area 220/240 Volt 50 Hz Appliance & 110/220 Volt Transformer/Adapter Specialists.220 Volt 50 HZ appliance

    ReplyDelete
    Replies
    1. hi

      Im a Quadriplegic and after 20 years in a wheelchair Im going crazy so I need a hobby

      I watched these videos and I was thinking we could use either a raspberry pi or Beaglebone PC with a Bluetooth chip and 2.4ghz mounted on a shield, that way we can eliminate the PC and Wii remote. Mind you I'm no hacker or electronics guy either.

      I saw one video where the guy used a PC based oscilloscope to map the wave form generated by the R/C cars transmitter only to replicate it on an Arduino board, could this be accomplished using the Beaglebone a bluetooth chip and 2.4ghz transmitter

      Are the 2.4ghz transmitters and ZigBee chips available designed to send and receive this type of data, the new remote control car transmitters and receivers use a 2.4ghz system that utilises automatic frequency hoping digital system (AFHDS) without crystals like the old radios, they can use 60 or more randomly picked channels to operate on, I'm not sure if this type of technology is used in the Arduino world.

      Here's a few links on how it works

      http://www.powershow.com/view1/20586b-ZDc1Z/NIBLUM_Non-invasive_Bluetooth_Mouse_for_Wheelchair_Users_powerpoint_ppt_presentation

      http://www.youtube.com/playlist?list=PL41C821BE875FDE9B

      I'm guessing we would need their USB Bluetooth dongle if we build ours with its own would you know anyone you can forward my message and email deauzie@gmail.com to who could help.

      To test it until my new wheelchair arrives we could use a cheap analogue arcade joystick and mini wireless expansion board

      As I said Im no technician

      Paul

      Delete
    2. Rcarduino: How To Read An Rc Receiver With A Microcontroller - Part 1 >>>>> Download Now

      >>>>> Download Full

      Rcarduino: How To Read An Rc Receiver With A Microcontroller - Part 1 >>>>> Download LINK

      >>>>> Download Now

      Rcarduino: How To Read An Rc Receiver With A Microcontroller - Part 1 >>>>> Download Full

      >>>>> Download LINK 5r

      Delete

    3. Really Work Fast,******************

      Fast and reliable solution for Herpes Cure

      I was cured from Herpes with herbal med..

      Contact him for Relationship/marital problem,

      He will give you the best..

      Thanks to [[[robinsonbucler @ gmail com]]]

      Delete
  2. Thanks, its always nice to get some feedback.

    ReplyDelete
  3. I've just finished reading though pretty much everything on this blog. Awesome stuff!
    How many channels can be read using your method? As many as the used Arduino has interrupts?

    ReplyDelete
  4. Hi, I am in the process of migrating my projects to use an interrupt library which will allow me to read as many interrupts as the Arduino has IO PINs. Without this library the Arduino firmware limits you to two.

    Library details here - http://arduino.cc/playground/Main/PinChangeInt

    Its also very easy to drive multiple servos and ESCs through the Arduino.

    Duane B

    ReplyDelete
    Replies
    1. Thank you for your quick reply! I've got a few rc projects I'd like to use an arduino in. One is a tugboat for which I'd like an adjustable propeller/rudder mixer (only requires 2 rc channels so can be done with current code).
      I'll be following your blog with great interest to see what you come up with!

      Delete
  5. I like your code but have some questions born out of ignorance.

    It would appear that, due to noise (my guess), the interrupt is constantly triggered. In that case doesn't if effectively block the code?

    Any pointers on how to use this approach with both interrupts? I want to drive a robot with the arduino and need forward/reverse as well as right/left capability. I am not driving servos, I am drivng a motor controller.

    I'd sure like to communicate with you directly about some of these things.

    Thanks,

    Jim

    ReplyDelete
  6. Hi,
    I have tested similar code with 700 interrupts per second, this used less than one percent of the Arduino processing power, see here - http://rcarduino.blogspot.com/2012/03/need-more-interrupts-to-read-more.html

    If you try to do any processing inside your interrupts you will block your main code from running, but with a simple ISR you should be able to get much higher frequencies than I have tested.

    What sensors are you using and why do you think you have so much noise ?

    Duane

    ReplyDelete
  7. This isn’t simple. In fact there is a lot of technicality involved-Though the steps here make it pretty comprehensible.

    Neo Poly Dex

    ReplyDelete
  8. Hey. I finally received my Servo extension cables in the post and got this working straight away! My target project (not for any particular reason, other than to see if i can do it) is to take two inputs, a vertical axis, and a horizontal axis on a single stick, and translate them into "tank" movement. (equatable to two vertical axis)

    I figure if I can get the Arduino to map the two axis to integers, giving a range of say, -10 to 10, representing stick position for each axis, I can then get it to add the value for the horizontal stick, onto the value for the vertical axis, causing the theoretical vehicle to turn.
    maybe :s

    ReplyDelete
  9. This uses RC signals but does more or less the same thing using the map function to translate from separate forward/reverse left/right signals into left and right track speeds -

    http://rcarduino.blogspot.com/2012/05/rc-arduino-robot.html

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

    Duane B

    ReplyDelete
  10. Cant get this to work, serial monitor just shows random numbers from 10 to 10000 and moving the stick doesnt make any difference

    ReplyDelete
    Replies
    1. I think you should check your Serial Monitor speed. It must be the same, that Arduino uses(in this case 9600).

      Delete
  11. Here you go then

    1) Does your receiver work at all - can it drive a servo directly ?

    2) How are you connecting the receiver to Arduino, which pins where ?

    3) How are you powering the receiver ?

    Duane B

    ReplyDelete
  12. I have tested the reciever with external battery pack and servos, its working fine
    I have the reciever connected from one channels signal to pin 2 on arduino and gnd and + to recievers battery channel and I know which pins are which on tje reciever.
    Also sorry for my bad english

    ReplyDelete
  13. Try powering the receiver with its own battery, you will still need to connect the Arduino ground to the battery/receiver ground.

    Do you have anywhere you can post a picture of your set up ?

    ReplyDelete
    Replies
    1. Thanks for help I got it working, and used the tank code on a small chinese rc tank toy, and an sn754410 motor controller.

      Delete
  14. My serialPPM signal from the receiver is inverted (the synch and channel data is high and the interchannel pulses are low). Is there anything in the code I need to change for it to work correctly - I notice that the INT0 is set for execution on a FALLING edge.

    regards Peter

    ReplyDelete
  15. Hi, a very simple solution would be to use a transistor or opamp to invert the signal - in this case two wrongs should make a right.

    Duane B

    ReplyDelete
  16. Thanks for the info!

    I think you may have mixed up your units in the graph

    ReplyDelete
  17. Am I correct in saying that the SPI library uses one of the two (UNO board) interrupts
    and therefore I will not be able to use this for throttle and direction without using the pinchangeint library?

    ReplyDelete
  18. hi,
    I don't think that the SPI Library uses any of the external interrupts. It might have its own dedicated interrupt to indicate when a transfer is complete but that will not clash with anything in the example sketch. try it and let me know how you get on.

    Duane B

    ReplyDelete
  19. Hi.

    Just getting round to testing this code for my own application. If it works, it'll be awesome, and I'll for sure send some of the credit your way.

    one thing confuses me though. (doesn't matter all that much because it seems to work, but..)

    in your code, you define two pins:

    #define THROTTLE_SIGNAL_IN 0 // INTERRUPT 0 = DIGITAL PIN 2 - use the interrupt number in attachInterrupt
    #define THROTTLE_SIGNAL_IN_PIN 2 // INTERRUPT 0 = DIGITAL PIN 2 - use the PIN number in digitalRead

    one with a zero, the other with a two. then you say they are both interupt 1, corresponding to digital pin 2. Correspondingly, in my setup, I only have a physical connection to pin 2. if I define the throttle_signal_in as 0:

    #define THROTTLE_SIGNAL_IN 0

    the code works. but if I define it as anything else:

    #define THROTTLE_SIGNAL_IN 1 or
    #define THROTTLE_SIGNAL_IN 2 or
    #define THROTTLE_SIGNAL_IN 3 ,

    it doesn't. the serial port doesn't display anything. I'm obviously missing something. indeed, when the throttle signal in is set to one, the interupt routine never gets called. I tested this by putting a println statement inside the interrupt code. Interestingly, this causes the code to crash at random spots during the printing of the line (you get fractional lines), but at least there is proof that it is called at least once, where it isn't called at all if throttle signal in is 1, and presumably if it is 2 or 3, or anything else.

    -mike



    ReplyDelete
    Replies
    1. Hi,
      Its slightly confusing, but on and Arduino UNO interrupt number 0 is on pin 2 and interrupt 1 is on pin 3.

      Its more confusing if your using a Leonardo because its the other way around, INT0 is on pin 3 and INT1 on pin2.

      Thats why I have the two separate definitions, one for the interrupt number used in attachInterrupt and one for the pin number which we need to read with digitalRead.

      Theres a bit more covering some other Arduino variants here -

      http://rcarduino.blogspot.com/2013/04/the-problem-and-solutions-with-arduino.html

      Duane B

      Delete
  20. 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
  21. Hi,
    I am going to respond under the FAQ because your using code from a few different posts.

    See here - http://rcarduino.blogspot.ae/2013/02/rcarduino-libraries-faq.html

    Duane B

    ReplyDelete
  22. Hi I almost have this working.

    I have 6 pulses in my ppm signal. Therefore, if my calculations are correct.

    RC_CHANNEL_OUT_COUNT 6+1
    RC_CHANNEL_IN_COUNT 6
    SERVO_FRAME_SPACE,8000=6*2000-20000

    I don't seem to all the channels accounted for, and I'm not sure why.

    I think my ppm signal may be inverted. If so would I have this partial success of 3 channels working?

    I thought it was the time between pulses that givs the channel position data. If I have 6 Pulses that means I only have 5 between puls positions to measure. What is the relation between PPM pulses and number of channels.?

    ReplyDelete
  23. One quick test you can do is to invert your PPM signal in hardware between the Arduino and the receiver. You can use a transistor as a switch to do this or an op-amp if you have one.

    Let me know if you don't have the hardware and I will suggest something else

    Duane.

    ReplyDelete
  24. Hi Duane,

    As a model pilot (R/C airplanes) and IT guy, this blog is very interesting to me. Tried it today and .... 'tada' : never so happy to see numbers between 980 and 1932 flashing by. Thanks a lot. This is cool stuff ! My next step will be to try and find the PPM signal on my receiver :-)

    Patrick.

    ReplyDelete
  25. Hi Duane,
    This looks like it might be just what I need to control a set of landing lights on an RC aircraft but I don't have space for an Arduino.
    My question is can your code be run on an Attiny85?
    I only need to monitor one channel (gear) to set lights on / off.
    I also use this MCU to run a simple blink and fade sketch to control the strobes and anti collision lights.

    gizmoDave

    ReplyDelete
  26. Great Article, but where is part 2?

    ReplyDelete
  27. Here is the link for part 2. You have to do some digging around as Duane's site is organized like my work bench, what you need is here its just not likely in plain view :)

    http://rcarduino.blogspot.com/2012/01/how-to-read-rc-receiver-with_20.html

    ReplyDelete
    Replies
    1. Got it Dave. Thanks very much old Chap. Keep up the good work

      Delete
  28. Hi, great article but I have a question; I can't understand the first condition before the boolean AND in this line: "if(ulStartPeriod && (bNewThrottleSignal == false)". Could you explain it to me?
    Thank You
    Fabio

    ReplyDelete
  29. Hi,
    It might have been more clear if i used this instead if((ulStartPeriod > 0) && (bNewThrottleSignal == false))

    if(ulStartPeriod) just means if ulStartPeriod is not false. The value zero represents false so in the original code we are basically saying if ulStartPeriod is not zero

    Its worth having a look at the multichannel code as well, there are a few posts that build in a series of improvements over the code in this first post in the series.

    Duane B

    ReplyDelete
  30. Thank for the code! its really helpful. very clean and neat explanation

    ReplyDelete
  31. The graphic in Decoded Single Channel Signal from RC Receiver shows pulse widths in microseconds. I believe these should be milliseconds.

    ReplyDelete
  32. I am unable to get it working. I have connected Pin 2 of Arduino (uno) to the receiver pin on my RC car. My car uses following circuit for receiving and decoding the signal from remote.
    http://www.circuitstoday.com/5-channel-radio-remote-control
    I am using Pin 14 of the IC (RXB) to drive the pin 2 of Arduino.

    thanks,
    ravi

    ReplyDelete
  33. Hi Ravi, The code and circuits throughout rcarduino assume you are using a proportional radio. The chips you are using are not proportional, they provide simple on off signals. You should try reading them using digitalRead(pinNumber);

    Duane B.

    ReplyDelete
  34. Hi, I am into RC and want to control two motors proportionally for a tank. Which Arduino board do I need, UNO? In the simple case of proportionally controlling (with programe mode and reverse capability) a single motor, which is the Arduino board needed? Thanks

    ReplyDelete
  35. Why not to use pulsein? It will not sit forever waiting for new pulses as the RC transmitter is always sending pulse trains no matter the joystick position. I have written a simpler code that uses pulsein to read two channels with the same results.

    ReplyDelete
  36. If I use pulseIn to read channel1, by the time the pulseIn function returns the channel2 pulse will have already started, pulseIn will miss this as it hasn't been called yet so when is called its going to sit there for the entire frame waiting for a new pulse and the whole time your project cannot do anything else but sit and wait. Multiply this by 3,4,5,6,7 or 8 channels and it just keeps getting worse.

    While the output might look similar, an interrupt driven approach will use about 1% of Arduino processing power, where as a pulseIn approach will use 100%, this does not become obvious until you try and do some processing or realtime control - this would not work with pulseIn - http://www.youtube.com/watch?v=TXTCxaamZFU See here for more - http://rcarduino.blogspot.ae/2012/07/rcarduino-yaw-control-part-2.html

    Duane

    ReplyDelete
  37. you code is really good for standalone applications. However, I think your code donot use all the available resources in an efficient manner. You can use hardware interrupts instead and try to minimize the delay as you are trying to measure the pulse high time. Have a look at this post http://hobbylogs.me.pn/?p=110 , it shows a very simple way of using the hardware interrupts for read RC signals

    ReplyDelete
  38. Hi Omer, Why do you think this code does not use hardware interrupts ?

    Duane B

    ReplyDelete
  39. Hi, I have tried your code without success :/ I think it is mainly my fault, cause for a lot of people it is working perfectly.
    I have a Duemilanove, but i am not sure about it, it could be a chinese replica.
    I have connected to Digital PIN 3 (as far as i know it is also an external interrupt pin).
    So i changed the code for the reason that the signal could change during the pulse, so i have written a procedure for a RISING edge and an other for the FALLING edge, and in the rising edge procedure i counted the interrupts but not an even interrupt happened :(
    I have tested my reciever and i use it day to day.

    I would be very pleased if you can help me.
    Here is my code:

    #define THROTTLE_PIN 3

    volatile unsigned long timer_start;
    volatile unsigned long IRQs;
    volatile int pulse_time;

    void startThrottlecalc(){
    timer_start = micros();
    IRQs++;
    }

    void endThrottlecalc(){
    pulse_time =((volatile int)micros() - timer_start);
    timer_start = 0;
    }

    void setup(){
    Serial.begin(19200);
    timer_start = 0;
    IRQs = 0;
    pinMode(THROTTLE_PIN,INPUT);
    attachInterrupt(THROTTLE_PIN,startThrottlecalc,RISING);
    attachInterrupt(THROTTLE_PIN,endThrottlecalc,FALLING);
    }

    void loop(){
    Serial.print(pulse_time);
    Serial.print('\t');
    Serial.print(IRQs);
    Serial.print('\n');
    delay(20);
    }

    ReplyDelete
    Replies
    1. Your code is not going to work but before I get into the reasons why, have you successfully tried the example code given in the blog post ?

      Duane B

      Delete
    2. The reason you code won't work is that pin numbers and interrupt numbers are different. So to attach an interrupt to INT0 you use 0, but the pin number is digital pin 2, for int1, its digital pin 3. Its confusing and different on all the different Arduino models, there is a small table here that gives the interrupt numbers and corresponding pin numbers for each board - http://rcarduino.blogspot.ae/2013/04/the-problem-and-solutions-with-arduino.html

      In your case, change #define THROTTLE_PIN 3 to 2 and it should work. If it still doesnt work, go back and try the test sketch in the blog post and make sure you receiver has a common ground with the Arduino.

      Delete
  40. Hi,

    I tried to control several servos with this code. I copied it 3x and adapted it. Now I can read 3 channels from my receiver. But then i attached 'servo.h' and 2 of the channels hadn't a stable signal. every 1 to 2 seconds or so the value of the read channel falls and raise again. Do you have any idea what the problem is?

    greetings from Germany
    Thomas

    ReplyDelete
  41. sOLVED IT DUH!!!! COM10 FOR 2560

    ReplyDelete
  42. I have used your code a couple times .You did a good job.

    But I would like to make the following suggestion.

    attachInterrupt(digitalPinToInterrupt(THROTTLE_SIGNAL_IN_PIN),calcInput,CHANGE);

    That way you only need to know the signal pin and not the interrupt number.

    ReplyDelete
    Replies
    1. This worked well for me, and I modified the code to use two receiver channels for tanks style steering.

      Delete
  43. Thanks for an excellent post...very informative. Can't wait to read further....


    ReplyDelete
  44. I’m a great fan of your blog; I regularly visit this site to get further details from here.

    ReplyDelete
  45. Hello,
    I have an old receiver 'acoms am 2ch receiver, AR201, 27MHz'.
    Struggling to find the clock pin in order to get the ppm signal.
    Are their any hard and fast rules for identifying it?

    ReplyDelete
  46. Easiest way is to look for the chip numbers and google them, one should be a counter or divider and this is the one that will have the clock pin. Alternatively just use some of the other code from the blog to read the channel outputs directly without having to open or solder your receiver. This will be the best approach for 1,2 or 3 channels. As you get to higher number of channels so its worth the extra effort of finding the PPM but in your case it might be better to go direct. How many channels does your system have ?

    Duane

    ReplyDelete
  47. It's only 2 channels and I've used some code to read the signals whilst probing the different pins. Think I've found it as one pin seems to output changes for both channels when I adjust the controller. Will try and confirm with an oscilloscope before soldering anything. I did look up the chip number but couldn't find anything directly. However I think I've found the chip it's based on. Many thanks for the help, should be testing it in the next few days. If I run out of talent then I'll probably just go direct; still a complete amateur!

    ReplyDelete
  48. Decoding is the reverse of encoding. In decoding, it makes the information easier to understand.
    Signals Decoding

    ReplyDelete
  49. Hi guys,
    Thank you so much for this wonderful article really!
    If someone want to know more about the rc cars I think this is the right place for you!

    ReplyDelete
  50. Umm, I'm sorry if this is a silly question; I promise I read the article(s) very carefully. Is it a correct statement that this single channel interrupt variation does not work on the UNO analog pins? That there are only two "external interrupts" available on UNO and they are dig-pins 2,3? I ask because I am using a motorshield and most of the UNO dig-pins are consumed. I do have 6 very nice analog pins though... :D

    ReplyDelete
    Replies
    1. I should be clear as to my design goal: I want to control stepper motors with my r/c inputs. I am using an Arduino UNO and an ADAFRUIT Motorshield V2. The Adafruit products have their own library; so I will have to try to integrate the use of interrupts and their stepper calls. The feed from "pulseIn" and we know that doesn't work well. Same terrible performance as servos.

      Delete
    2. I found the answer on another page that explains what I need to know and do. Thanks for writing such an awesome R/C website. Everyone really appreciates you!
      https://rcarduino.blogspot.com/2012/03/need-more-interrupts-to-read-more.html

      Delete
  51. Nice post. I learn something more challenging on different blogs everyday. It will always be stimulating to read content from other writers and practice a little something from their store. I’d prefer to use some with the content on my blog whether you don’t mind. I’ll give you a link on your web blog. I recently came to know about http://toysuae.com/, their RC Cars Toy are very effective.
    RC Cars Toy Thanks for sharing.

    ReplyDelete
  52. I am super angry right now. I am new to arduino so i cannot even get past the hardware pins. Where does the cable go from receiver to arduino and where does the cable go from arduino to ESC throttle wire. Your code comments just confuses me.. I am not even new to programming either but this is really confusing! help

    ReplyDelete
  53. I was able to get the code working that he linked to at the bottom of his post. It is very clear what pins they are if you look at the 6 #define lines near the top. The down side is you need to understand libraries.

    After that you put code in to modify the signal values in the "if(bUpdateFlags & STEERING_FLAG)" statement. Other code can be put in or just above that section.

    ReplyDelete
  54. Could anyone tell, what is precision of this code on reading PWM values ? I bet it will be 4us, so servo will constantly move. I implemented similar code with Interrupt and Micros() function, and readed PWM constant values were differ to 8us. I solved this using some big RC control library with much better result.

    ReplyDelete
  55. Hi all,
    it can be adopted to run multiple channels

    // Channel 1
    #define THROTTLE_SIGNAL_IN 0 // INTERRUPT 0 = DIGITAL PIN 2 - use the interrupt number in attachInterrupt
    #define THROTTLE_SIGNAL_IN_PIN 2 // INTERRUPT 0 = DIGITAL PIN 2 - use the PIN number in digitalRead
    #define NEUTRAL_THROTTLE 1500 // this is the duration in microseconds of neutral throttle on an electric RC Car

    // Channel 1
    volatile int nThrottleIn = NEUTRAL_THROTTLE; // volatile, we set this in the Interrupt and read it in loop so it must be declared volatile
    volatile unsigned long ulStartPeriod = 0; // set in the interrupt
    volatile boolean bNewThrottleSignal = false; // set in the interrupt and read in the loop
    // we could use nThrottleIn = 0 in loop instead of a separate variable, but using bNewThrottleSignal to indicate we have a new signal
    // is clearer for this first example

    // Channel 2
    #define THROTTLE_SIGNAL_INB 1 // INTERRUPT 1 = DIGITAL PIN 3 - use the interrupt number in attachInterrupt
    #define THROTTLE_SIGNAL_IN_PINB 3 // INTERRUPT 1 = DIGITAL PIN 3 - use the PIN number in digitalRead
    #define NEUTRAL_THROTTLEB 1440 // This value may require changing the DX4e (Reading 1420 as nutral

    // Channel 2
    volatile int nThrottleInB = NEUTRAL_THROTTLEB; // volatile, we set this in the Interrupt and read it in loop so it must be declared volatile
    volatile unsigned long ulStartPeriodB = 0; // set in the interrupt
    volatile boolean bNewThrottleSignalB = false; // set in the interrupt and read in the loop

    void setup() {

    // tell the Arduino we want the function calcInput to be called whenever INT0 (digital pin 2)
    // changes from HIGH to LOW or LOW to HIGH
    // catching these changes will allow us to calculate how long the input pulse is
    attachInterrupt(digitalPinToInterrupt(THROTTLE_SIGNAL_IN_PIN),calcInput,CHANGE);

    delay(10); // allows for Interrupts and I can afford to wait 100th of second to process interrupts

    // tell the Arduino we want the function calcInput to be called whenever INT0 (digital pin 3)
    // changes from HIGH to LOW or LOW to HIGH
    // catching these changes will allow us to calculate how long the input pulse is
    attachInterrupt(digitalPinToInterrupt(THROTTLE_SIGNAL_IN_PINB),calcInputB,CHANGE);
    }

    void loop () {
    // Channel 1 Processing
    if (nThrottleIn <=1400) {
    analogWrite(Pin9, 255); // This will set Pin 9 +5 ****REVERSE*****
    }
    else {
    analogWrite(Pin9, 0);
    }
    DO MORE STUFF Channel 2 etc....

    }
    void calcInput() {

    if(digitalRead(THROTTLE_SIGNAL_IN_PIN) == HIGH){
    ulStartPeriod = micros();
    }
    else
    {
    if(ulStartPeriod && (bNewThrottleSignal == false)){
    nThrottleIn = (int)(micros() - ulStartPeriod);
    ulStartPeriod = 0;
    bNewThrottleSignal = true;
    }
    }
    }

    void calcInputB() {

    if(digitalRead(THROTTLE_SIGNAL_IN_PINB) == HIGH){
    ulStartPeriodB = micros();
    }
    else
    {
    if(ulStartPeriodB && (bNewThrottleSignalB == false)){
    nThrottleInB = (int)(micros() - ulStartPeriodB);
    ulStartPeriodB = 0;
    bNewThrottleSignalB = true;
    }
    }
    }


    ReplyDelete
  56. mantap gan,, nuhun pisan...aslina iyeu ti kamari ngoprek euy

    ReplyDelete
  57. Hi Dear,

    i Like Your Blog Very Much..I see Daily Your Blog ,is A Very Useful For me.

    Speed Muscle Remote Control RC Buggy 2.4Ghz 1:16 Scale Truggy Ready to Run w/ Suspension Toy (Green Color) …



    Visit Now - https://www.amazon.com/Speed-Muscle-Remote-Control-2-4Ghz/dp/B01M712G8Y/ref=sr_1_1?m=A3KIGJ5D7AQK8I&s=merchant-items&ie=UTF8&qid=1504848759&sr=1-1&keywords=B01M712G8Y

    Remote Control Car

    ReplyDelete
  58. Hi Dear,

    i Like Your Blog Very Much..I see Daily Your Blog ,is A Very Useful For me.

    remote control car Buy RC Remote Control Car 2.4 GHz Monster Formula Car 3-in-1 DIY Interchangeable Transforming Kit Toy Car 1:16 RECHARGEABLE (Black/Green): Toy RC Vehicles - Amazon.com ✓ FREE DELIVERY possible on eligible purchases

    ReplyDelete
  59. How to translate that signal from RC receiver to Arduino digital pins. I understand that we got the duty cycle of the signal from receiver but how do I forward it to output pin of Arduino which will carry this signal to electronic speed controller (ESC).

    ReplyDelete
  60. thank you, we ofer ZTW Brushless ESC for Rc car,and RC Boat
    http://www.ztwshop.com

    thank you very much, i like your article
    it can help me
    Rc airplane

    ReplyDelete
  61. may I ask a different question:

    is there any receiver but instead of radio antenna input
    we can have digital inputs?
    in other word can we control the receiver directly by uC digital signal
    "instead of radio transmitter"
    and use its output to run the servo motors

    ReplyDelete
  62. Just a big thank you for this great post. Keep up the good work!
    Works great for on my RC tractor :)

    ReplyDelete
  63. Just stumbled across this blog. Can you change the timing in the diagram (Decode timing) to 1ms,1.5ms and 2ms respectively instead of usec. It was so wrong.

    ReplyDelete
  64. On the off chance that you are seeing some issue with your Brother Printer as it is associated yet not printing, the explanation could be anything behind it. Nonetheless, you can fix this issue by doing some essential investigating. What's more, to assist you with this, this post has presented to you some data and guidelines to follow. Fix Brother printer not printing problemThus, go thoroughly.To start with, you should check for the paper stuck issue in your Brother Printer. There are times when you don't used the printer for quite a while and dust gets gathered in the printer that prompts trouble.Also, you need to check the ink filled in the cartridge whether it is filled deficiently or void. For this situation, you will not get any printer issues like Brother Printer associated yet not printing.In expansion, an unfilled or half-filled cartridge causes the issue yet additionally when the ink is filled more than the necessary ink it likewise raises a ruckus in getting prints.When you fill ink in the cartridge more than the necessary sum, it might flood and can impede the printer head.

    ReplyDelete
  65. "Why Hamdan car rental service?
    best rent a car in islamabad Hamdan car rental service is providing the best service all over Pakistan Karachi Lahore Islamabad Multan Faisalabad Peshawar Quetta Sukkur Sahiwal Abbottabad Mansehra Haripur Murree Naran Kagan Hunza Gilgit Balochistan Chicha Watani Hyderabad China Border Kashmir Malakand And More Areas. Hamdan Rent Car is available with the largest flat service in Pakistan. Rent a car in islamabad.
    rent a car in islamabad
    rent a car islamabad to lahore
    best car rental islamabad
    rent a car service in islamabad"

    ReplyDelete
  66. I am open to share my experience with bitcoin investment and losing money to scammers. However, yes it is possible to recover your stolen bitcoins. I never believed in bitcoin recovery because I was made to understand that it was not possible. However, sometime in JumeI fell for a forex scam which promised overly high returns and I ended up losing close to $55,000. I searched for a month for help until I finally came across an article on reddit in regards to recovering stolen cryptocurrency so I reached out to them, vitorzprogrammer @ gmail com, I was so scared and skeptical because I have heard of bad experiences but I decided to give them a try and to my greatest surprise I was able to get all my stolen bitcoins recovered from the scammers within a very short time frame. If you are experience same problem simply contact him Whats App (+1) 519 / / 398 / / 1460

    ReplyDelete
  67. Looking For Top Apple TV Siri Remote Control in Uae, 4th Generation Apple TV Remote Control in Uae, Black Remote Control in Uae
    https://gccgamers.com/accessories/media-players/apple-tv-siri-remote-control-for-the-4th-generation-apple-tv-black-mg2q2.html

    ReplyDelete
  68. Rcarduino: How To Read An Rc Receiver With A Microcontroller - Part 1 >>>>> Download Now

    >>>>> Download Full

    Rcarduino: How To Read An Rc Receiver With A Microcontroller - Part 1 >>>>> Download LINK

    >>>>> Download Now

    Rcarduino: How To Read An Rc Receiver With A Microcontroller - Part 1 >>>>> Download Full

    >>>>> Download LINK

    ReplyDelete
  69. Консоли от корпорации Microsoft не сразу завоевали всемирную известность и доверие игроков. 1-ая консоль под названием Xbox, вышедшая в далеком 2001 году, существенно уступала PlayStation 2 по количеству проданных приставок. Но все поменялось с выходом Xbox 360 - консоли седьмого поколения, которая стала по-настоящему "народной" для жителей России и государств СНГ - игры для xbox 360 скачать торрент. Веб-сайт Ru-Xbox.Ru является пользующимся популярностью ресурсом среди поклонников приставки, поскольку он предлагает игры для Xbox 360, которые поддерживают все имеющиеся версии прошивок - совсем бесплатно! Для чего играть на оригинальном железе, в случае если есть эмуляторы? Для Xbox 360 игры выходили длительное время и находятся как посредственными проектами, так и хитами, многие из которых даже сегодня остаются эксклюзивными для это консоли. Некоторые пользователи, желающие сыграть в игры для Xbox 360, смогут задать вопрос: зачем нужны игры для прошитых Xbox 360 freeboot либо различными версиями LT, в случае если есть эмулятор? Рабочий эмулятор Xbox 360 хоть и существует, однако он просит производительного ПК, для покупки которого потребуется вложить существенную сумму. К тому же, различные артефакты в виде исчезающих текстур, отсутствия некоторых графических эффектов и освещения - могут значительно испортить впечатления об игре и отбить желание для ее предстоящего прохождения. Что предлагает этот сайт? Наш портал на сто процентов посвящен играм для приставки Xbox 360. У нас вы можете совершенно бесплатно и без регистрации загрузить игры на Xbox 360 через torrent для следующих версий прошивок консоли: - FreeBoot; - LT 3.0; - LT 2.0; - LT 1.9. Каждая прошивка имеет свои особенности обхода встроенной защиты. Поэтому, для запуска той или иной игры будет нужно загрузить специальную ее версию, которая полностью приспособлена под одну из 4 вышеперечисленных прошивок. На нашем портале вы можете без труда найти желаемый проект под подходящую прошивку, поскольку возле каждой игры присутствует название версии (FreeBoot, LT 3.0/2.0/1.9), под которую она адаптирована. Пользователям данного ресурса доступна особая категория игр для 360-го, созданных для Kinect - специального дополнения, которое считывает все движения 1-го или нескольких игроков, и позволяет управлять с помощью их компьютерными персонажами. Большой выбор ПО Кроме способности скачать игры на Xbox 360 Freeboot либо LT различных версий, здесь можно подобрать программное обеспечение для консоли от Майкрософт: - разные версии Dashboard, которые позволяют кастомизировать интерфейс консоли под свои нужды, сделав его более удобным и нынешним; - браузеры; - просмотрщики файлов; - сохранения для игр; - темы для консоли; - программы, для конвертации образов и записи их на диск. Помимо перечисленного выше игры на Xbox 360 Freeboot можно запускать не с дисковых, а с USB и многих других носителей, используя программу x360key, которую вы можете достать на нашем портале. Посетителям доступно огромное количество полезных статей, а также форум, где вы можете пообщаться с единомышленниками или попросить совета у более опытнейших владельцев консоли.

    ReplyDelete
  70. Роль финансов в гос системе велика. Как финансовая категория деньги предполагают собой денежные отношения, связанные с формированием, распределением и внедрением особых фондов денежных средств в целях обеспечивания условий расширенного воспроизводства и реализации функций и задач государства. Также деньги выражают финансовые отношения по поводу производства, рассредотачивания и использования валового внутреннего продукта dividend-center. Фактически они выражают дела насчет стоимости окончательных товаров и предложений, произведенных резидентами этой государства на ее земли за конкретный период медли, и национального заработка. По содержанию деньги – это своего рода связующее звено меж творением и использованием стоимости валового внутреннего продукта и национального заработка.

    ReplyDelete
  71. Thanks for sharing content and such nice information for me. I hope you will share some more content about. Please keep sharing
    Hiace for rent in Islamabad

    ReplyDelete
  72. This is such a nice post. I really liked it. Keep posting such content.
    Rent a Car in Islamabad

    ReplyDelete
  73. If you're looking for printer servicing in Dubai, we highly recommend RTN.ae. They offer a wide range of services, including printer maintenance and repairs.
    Thanks
    Printer servicing in Dubai

    ReplyDelete
  74. Если у вас выйдет имитировать природную коммуникацию с постояльцами сколько нужно ссылок для продвижения сайта модных вебсайтов, которые освещают темы, схожие с вашей, вы получите заинтересованные переходы. Не стоит предполагать на их огромное количество. Часто такие известья воспринимаются, как мусор и удаляются администрацией.

    ReplyDelete
  75. We are grateful that you shared this useful post with us. Find the best collection of Glue Gun at DsaTech.

    ReplyDelete
  76. I thoroughly enjoyed reading your blog post on how to read an RC receiver with Arduino. It's a topic that I've been curious about for a while, and your explanations and instructions were incredibly helpful.
    New Born Baby Clothes

    ReplyDelete
  77. Thank you for sharing your expertise, and I look forward to exploring more of your Arduino-related content. For those looking to cut costs on electronic components, "can i use my walmart gift card for gas" could be a beneficial resource to explore.

    ReplyDelete
  78. "This blog is a ray of light in the online world. The author's knowledge and commitment to sharing it are truly inspiring. Thank you for making learning so enjoyable."
    hollister employee discount

    ReplyDelete
  79. "The author's dedication to their craft is evident in the thought-provoking and meticulously researched articles. It's a testament to their expertise."
    lowes 10 coupon generator

    ReplyDelete
  80. Intriguing insights into decoding RC receivers with a microcontroller in Part 1! The precision discussed in the blog resonates with the attention to detail needed for electronics projects. When sourcing components, a Jewson discount might just be the key to cost-effective experimentation. Looking forward to the next installment!

    ReplyDelete
  81. Thank you! We're delighted that you found our discussion thread amazing.
    refer Rent a car Karachi

    ReplyDelete
  82. I appreciate your kind words! Thank you for your support! Rent a car Rawalpindi

    ReplyDelete
  83. I'm thrilled you found it impressive! Your encouragement fuels my motivation. Thank you! Rent a car Lahore

    ReplyDelete
  84. I'm really grateful for your kind words! It means a lot to me. Thank you! Rent a car Lahore

    ReplyDelete
  85. Your appreciation is truly uplifting! Thank you for your kind words—it means a lot! receiptify

    ReplyDelete
  86. Your praise is truly uplifting! Thank you for brightening my day with your kind words! receiptify

    ReplyDelete
  87. I'm delighted you found it delightful! Your positive feedback brightens my day. Thank you! DGME

    ReplyDelete
  88. I'm delighted you found it inspiring! Your feedback truly brightens my day. Thank you! DGME Login

    ReplyDelete