raspberrypi / pico-examples

BSD 3-Clause "New" or "Revised" License
2.62k stars 779 forks source link

pio_ppm - RC PPM protocol example works on GPIO 3 #414

Open elmot opened 10 months ago

elmot commented 10 months ago

An example of RC PPM protocol encoder using PIO Resolves raspberrypi/pico-examples#197

elmot commented 10 months ago

Needs to be fixed after testing with real hardware

lurch commented 10 months ago

Oh, this should be targeted at the develop branch of pico-examples, rather than the master branch.

elmot commented 10 months ago

Redirected

elmot commented 9 months ago

@lurch any progress here?

lurch commented 9 months ago

I don't have commit / merge rights on this repo, that's up to somebody else :slightly_smiling_face:

jschwob commented 7 months ago

Today I tested your code and found an issue. Using the ToolkitRC M6 Smart charger which includes a ppm monitor I found that the output could not be read. Since the device can also generate a PPM output I simply compared the waveforms and determined that that the signal was inverted. (This is common in the RC world. Blame futuba - Sbus is also inverted) Here is the update I made to invert the signal.

.program ppm
.side_set 1

    set pindirs, 1  side 0; Set pin to output
.wrap_target
    out x, 16 side 1
delay0:
    jmp x-- delay0 side 1
    out x, 16 side 0
delay1:
    jmp x-- delay1 side 0
    .wrap

I'm working on a project that will use this code to interface on the trainer port of RC Transmitters. I haven't performed any value tests yet. Will post an update if I find any timing issues which would cause an incorrect value to be returned to the rc transmitter.

lurch commented 7 months ago

determined that that the signal was inverted.

It might be easier to use gpio_set_outover with GPIO_OVERRIDE_INVERT, than to rewrite the PIO code? :shrug:

jschwob commented 7 months ago

That sounds like a great suggestion. I haven't had time to test it yet - my changes simply flipped the output bits. I also need to generate an inverted uart for Sbus so I'll give GPIO_Override_invert a shot and report my findings.

jschwob commented 7 months ago

I added this to the init portion: gpio_set_outover(pin, GPIO_OVERRIDE_INVERT); //Invert output as rc transmitters expect inverted signal.

worked as expected and my tester read the signal w/o issue. No changes are required to the assembly code. Just need to add this to the init portion.

Testing: Initial tests show values requested were output +2 high. I have only tested it on one device so far. I don't have an accurate oscilloscope to validate the signal properly however I do have multiple flight controllers and other rc transmitters to read the values to validate the ppm signal with. I'll post more as I continue testing. So far this is working great and +2 seems reasonable all things considered.

elmot commented 7 months ago

@jschwob that story with inverted signals looks a bit strange. Existing code works well with Ardupilot flight controller, and I never seen any articles where PPM signal looks inverted. Can you, please, provide the any?

jschwob commented 7 months ago

Please see above for my testing methodology. I'm using a standard hobby charger and signal tester. ToolkitRC M6 Smart charger which includes a ppm monitor. The tester can also generate a standard ppm signal that works with rc receivers. I used this output signal to determine that the signal 'appeared' to be inverted on a hobby grade scope. Most of this stuff goes back to the 60's and 70's where parts counts had to be at an absolute minimum for cost on rc electronics. Was before my time. I don't think there is an 'official' spec for ppm. Its down to what each manufacture used back in the day and is still in use today.

I checked the Ardupilot documentation and it appears that they use an auto detect routine. My guess is that part of the auto detect routine is to check the signal inverted and un-inverted.

jschwob commented 7 months ago

I'm still testing it and will post results when I connect it to a transmitter trainer port on one of my transmitters. For my application I will add a setting to allow the user to choose inverted as default or non inverted.