Saturday, June 23, 2012

Read RX Channels with Arduino

This is so easy, their is no reason you shouldnt use a remote control RX/TX(or uber cheap) in your next project :)

Connect the RX module to power(in my case +5v and GND), and then plug in each of the signal lines for each channel into a separate digital pin. Then just two lines of code:
pinMode(CHpin, INPUT); //make digital pin connected to signal a input
unsigned long CHvalue = pulseIn(CHpin, HIGH); //pulse in on HIGH, depends on what type of signal you have
That's it; CHvalue holds the value of whatever channel of the RX.

Reading PPM sum a little bit different, but still similar to the above code:


#define channumber 4 //number of ppm sum channels
int value[channumber]; //holds PPM values
#define PPMsumPin 3

void setup()
{
  Serial.begin(115200); //Serial Begin
  pinMode(PPMsumPin, INPUT); //Pin 3 as input, this is where the ppm sum pin from the RX is connected
}
void loop()
{
  while(pulseIn( PPMsumPin , LOW) < 5000){
  } //Wait for the beginning of the frame
  for(int x=0; x<=channumber-1; x++)//Loop to store all the channel position
  {
    value[x]=pulseIn( PPMsumPin, LOW); //LOW depends on what type of signal you have
    Serial.print(" CH");
    Serial.print(x);
    Serial.print(": ");
    Serial.print(value[x]); //Print the value
    value[x]=0; //Clear the value after is printed
  }
  Serial.println(""); //Start a new line
}

16 comments:

  1. Was using a turnigy 9x rc transmitter with er9x firmware to generate a ppmsum signal. The default pulse width is 300us. This code was missing some of the pulses. The code responded properly after increasing the pulse width to ~750us. Arduino uno. Gonna use some code that utilizes interupts for my project. This code was helpful . Thanks

    ReplyDelete
    Replies
    1. so thats why my values were so jump.. thanks!

      Delete
  2. Tried with DX7, had to change to HIGH, but seems to mix up the channels
    CH 0 was right
    Ch 1 showed up to be channel 4&5
    CH 2 showed up to be channel 1

    ReplyDelete
    Replies
    1. yep. some TXs have pos PPM (HIGH), some have nneg (LOW) ppm. and the PPM channel order is different too depending on brand.

      why now you guys post here :D

      Delete
    2. Hi
      Channels are mixed up, I'm looking at scope and the enummering in your sketch.
      I'm working with Head-tracker, and wanted a simple solution instead for rig RX+plane etc. up.
      Linked to servo libraries and set two servos on pin, se if it controls right.

      Max

      Delete
  3. All that Serial.print destroyed it all.
    Look at this, it works with right channels!

    #include
    Servo channel0;
    Servo channel1;
    Servo channel2;

    #define channumber 8 //number of ppm sum channels
    int value[channumber]; //holds PPM values
    #define PPMsumPin 5 //PPMin Pin

    int position;
    void setup()
    {
    pinMode(PPMsumPin, INPUT);
    channel2.attach(2);
    }
    void loop()
    {
    while(pulseIn( PPMsumPin , HIGH) < 6000){ //meassure HIGH time
    } //Wait for the beginning of the frame
    for(int x=0; x<=channumber-1; x++)
    {
    value[x]=pulseIn( PPMsumPin, HIGH);
    if (x==0){
    position = map(value[x], 600, 1600, 0, 180);
    channel0.write(position);
    }
    if (x==1){
    position = map(value[x], 600, 1600, 0, 180);
    channel1.write(position);
    }
    if (x==2){
    position = map(value[x], 600, 1600, 0, 180);
    channel2.write(position);
    }
    }
    }

    ReplyDelete
    Replies
    1. That makes sense that the Serial.print would slow it down. I'll give this a try. thanks

      Delete
  4. hi all,
    i use the 1st code to control the four motors by the throttle as shown
    .......................................................................................
    #include
    int throttle = 5;
    int val = 0;
    Servo myservo1;
    Servo myservo2;
    Servo myservo3;
    Servo myservo4;
    unsigned long duration;

    void setup()
    {
    pinMode(throttle, INPUT);
    pinMode(7, OUTPUT);
    pinMode(8, OUTPUT);
    pinMode(9, OUTPUT);
    pinMode(10, OUTPUT);
    myservo1.attach(7);
    myservo2.attach(8);
    myservo3.attach(9);
    myservo4.attach(10);

    }

    void loop()
    {
    duration = pulseIn(throttle, HIGH);
    duration = map(duration,1000,2000,0,179);

    myservo1.write(duration);
    myservo2.write(duration);
    myservo3.write(duration);
    myservo4.write(duration);
    }
    ...................................................................................
    but the problem is that when i set the throttle in a certain position the motors take a certain velocity then decrease its velocity then back again to its certain velocity through cycle ... if any one know what is the problem please help

    ReplyDelete
    Replies
    1. so you mean oscillations? read the very first comment. you may need to adjust the pulse width.

      Delete
  5. Yes, that's exactly what I need. But, how I can apply the adjustment of pulse width in the code.

    ReplyDelete
    Replies
    1. you cant. the pulse width is set by the source, aka TX/RX. the arduino only reads it

      Delete
  6. So, how can I change it from the source (turnigy 9X) :)

    ReplyDelete
    Replies
    1. i think you'll have to upgrade to the er9x firmware.

      Delete
    2. Thanx jordan,I think I got it wish u good luck :)

      Delete
    3. i also have a post on that ;) (the er9x mod)

      Delete