PPM library not working with my signals.

Status
Not open for further replies.
I'm trying to use the PPM library to read the PPM signal from my RC receiver. It works fairly well, but I need 8 channels and I can only read 4. when I feed my receiver into pin 10 of the TEENSY 3.2 programmed with the loopback test. A scope shows that the signals from my RC receiver are slightly different than the TEENSY expects. My signal is HIGH during a 7mSec sync. It then goes LOW for 200uSec (like a START pulse) and then HIGH for channel 0 (1000-2000uSec), it goes LOW for 200uSec (which is the inter-channel space) and then HIGH for channel 1 etc. I can not find any configuration that works properly. I even inverted the pulse. That doesn't work either. The signal out of my receiver simply doesn't look like the PPM out that the TEENSY generates.

What I'm trying to accomplish: I want to get signals from my RC receiver and output them exactly as I receive them - unless certain conditions exist. At those times, I want to change the pulse width of two or three of the channels, regardless of what the inputs are.
 
I'm trying to use the PPM library to read the PPM signal from my RC receiver. It works fairly well, but I need 8 channels and I can only read 4. when I feed my receiver into pin 10 of the TEENSY 3.2 programmed with the loopback test. A scope shows that the signals from my RC receiver are slightly different than the TEENSY expects. My signal is HIGH during a 7mSec sync. It then goes LOW for 200uSec (like a START pulse) and then HIGH for channel 0 (1000-2000uSec), it goes LOW for 200uSec (which is the inter-channel space) and then HIGH for channel 1 etc. I can not find any configuration that works properly. I even inverted the pulse. That doesn't work either. The signal out of my receiver simply doesn't look like the PPM out that the TEENSY generates.

What I'm trying to accomplish: I want to get signals from my RC receiver and output them exactly as I receive them - unless certain conditions exist. At those times, I want to change the pulse width of two or three of the channels, regardless of what the inputs are.


I used a scope and measured more carefully. It seems that my signal has a HIGH sync, then goes low for 200uSec, then HIGH for the period -200uSec, then LOW again. So the pulse width is measured between two LOW edges. Hopefully, you can see what I mean from the attached screen shot. The sync
is the ~7ms HIGH, followed by a LOW (approx 200uSec) then a HIGH, which is the period minus the 200uSec.

PPM2.jpg.
 
Hmmm, your scope output looks just like the output from my SPEKTRUM transmitter's trainer cable (6 channels) hooked to logic analyzer:
spektrum.png
The low pulse width is 380 us and the high widths vary between 500us and 1500us, and the total period is about 20 ms. For the library you need to use
PulsePositionInput myIn(FALLING);

Using a Teensy 3.2 and 8 channels, and using FALLING for myIn and myOut, loopback example sketch output looks good with pin 9 jumpered to pin 10 (and scope).
Code:
#include <PulsePosition.h>

// Simple loopback test: create 1 output to transmit
// test pulses, and 1 input to receive the pulses
[COLOR="#FF0000"]PulsePositionOutput myOut(FALLING);
PulsePositionInput myIn(FALLING);
[/COLOR]
void setup() {
  Serial.begin(9600);
  while(!Serial);
  myOut.begin(9);  // connect pins 9 and 10 together...
  myIn.begin(10);
  myOut.write(1, 600.03);
  myOut.write(2, 1500);
  myOut.write(3, 759.24);
  // slots 4 and 5 will default to 1500 us
  myOut.write(6, 1234.56);
[COLOR="#FF0000"]  myOut.write(7, 1111.56);
  myOut.write(8, 999.56);[/COLOR]
}

int count=0;

void loop() {
  int i, num;

  // Every time new data arrives, simply print it
  // to the Arduino Serial Monitor.
  num = myIn.available();
  if (num > 0) {
    count = count + 1;
    Serial.print(count);
    Serial.print(" :  ");
    for (i=1; i <= num; i++) {
      float val = myIn.read(i);
      Serial.print(val);
      Serial.print("  ");
    }
    Serial.println();
  }
}
Code:
monitor output
21 :  600.02  1500.00  759.23  1500.00  1500.00  1234.54  1111.54  999.54  
22 :  600.02  1500.00  759.23  1500.00  1500.00  1234.54  1111.54  999.54  
23 :  600.02  1500.00  759.23  1500.00  1500.00  1234.54  1111.54  999.54

chnls8.png

8 channels works for me.

So your RC receiver has a PPM out pin? My RC receivers only have 3-pin servo pins for each channel. The receiver decodes the PPM radio signal into servo signals. https://www.sparkfun.com/tutorials/348 uses pulseIn() to measure servo pins, may need attachInterrupt(). Some FrSky receivers may have PPM out...
 
Last edited:
Thank you very much! I was using (0) for falling and (1) for rising instead of (FALLING) and (RISING). I should have looked in the library more closely.







QUOTE=manitou;289271]Hmmm, your scope output looks just like the output from my SPEKTRUM transmitter's trainer cable (6 channels) hooked to logic analyzer:
View attachment 25966
The low pulse width is 380 us and the high widths vary between 500us and 1500us, and the total period is about 20 ms. For the library you need to use
PulsePositionInput myIn(FALLING);

Using a Teensy 3.2 and 8 channels, and using FALLING for myIn and myOut, loopback example sketch output looks good with pin 9 jumpered to pin 10 (and scope).
Code:
#include <PulsePosition.h>

// Simple loopback test: create 1 output to transmit
// test pulses, and 1 input to receive the pulses
[COLOR="#FF0000"]PulsePositionOutput myOut(FALLING);
PulsePositionInput myIn(FALLING);
[/COLOR]
void setup() {
  Serial.begin(9600);
  while(!Serial);
  myOut.begin(9);  // connect pins 9 and 10 together...
  myIn.begin(10);
  myOut.write(1, 600.03);
  myOut.write(2, 1500);
  myOut.write(3, 759.24);
  // slots 4 and 5 will default to 1500 us
  myOut.write(6, 1234.56);
[COLOR="#FF0000"]  myOut.write(7, 1111.56);
  myOut.write(8, 999.56);[/COLOR]
}

int count=0;

void loop() {
  int i, num;

  // Every time new data arrives, simply print it
  // to the Arduino Serial Monitor.
  num = myIn.available();
  if (num > 0) {
    count = count + 1;
    Serial.print(count);
    Serial.print(" :  ");
    for (i=1; i <= num; i++) {
      float val = myIn.read(i);
      Serial.print(val);
      Serial.print("  ");
    }
    Serial.println();
  }
}
Code:
monitor output
21 :  600.02  1500.00  759.23  1500.00  1500.00  1234.54  1111.54  999.54  
22 :  600.02  1500.00  759.23  1500.00  1500.00  1234.54  1111.54  999.54  
23 :  600.02  1500.00  759.23  1500.00  1500.00  1234.54  1111.54  999.54

View attachment 25968

8 channels works for me.

So your RC receiver has a PPM out pin? My RC receivers only have 3-pin servo pins for each channel. The receiver decodes the PPM radio signal into servo signals. https://www.sparkfun.com/tutorials/348 uses pulseIn() to measure servo pins, may need attachInterrupt(). Some FrSky receivers may have PPM out...[/QUOTE]
 
I tried (FALLING)

PulsePositionOutput myOut(FALLING);
PulsePositionInput myIn(FALLING);

And the loopback works great. But it DOES NOT work with my receiver. When I connect my receiver to pin #10, I get 4 good channels, but no more.
 
Another clue: I loaded the pgm PPMReader, which works slightly differently. I modified PPMReader.CPP to trigger the interrupt on negative edges. I set the maximum pulse width (sync timeout) to 5 mSec.

But I STILL get only 4 channels! All 4 channels report correctly, but 5 - 8 do not show up. My scope proves that I'm sending 8 channels. All the channels that don't work report 1500 uSec as the pulse width.
 
Another clue: I loaded the pgm PPMReader, which works slightly differently. I modified PPMReader.CPP to trigger the interrupt on negative edges. I set the maximum pulse width (sync timeout) to 5 mSec.

But I STILL get only 4 channels! All 4 channels report correctly, but 5 - 8 do not show up. My scope proves that I'm sending 8 channels. All the channels that don't work report 1500 uSec as the pulse width.

maybe zoom in with your scope between pulse 4 and 5 and see if there is a spurious spike or some such ? Also with scope confirm that channels 5 thru 8 are in fact not 1500 us (the photo in post #2 suggests that they are 1500 us??)

in the loop back test, if your pulse is less than 300 us ( myOut.write(6, 299); ), the lib will report channel 6 as 1500 us. ( TX_MINIMUM_SIGNAL 300.0)

when running with receiver, don't have pin 9 and 10 jumpered together and try commenting out all of myOut lines in the loopback sketch.
also insure receiver and T3.2 have a common ground ...
 
Last edited:
FOUND IT! Of course it was my own error. My controller can control multiple "models", and I use different ones at different times. All the models EXCEPT the one I was using with the TEENSY had 8 channels programmed. The one I was testing with only had 4.

I appreciate the feedback and apologize for my (hopefully temporary) ignorance.

Thanks.
 
Status
Not open for further replies.
Back
Top