{"id":19667215,"url":"https://github.com/joshbuker/mcu-ppm-input","last_synced_at":"2026-05-16T07:36:57.568Z","repository":{"id":143686323,"uuid":"344003694","full_name":"joshbuker/mcu-ppm-input","owner":"joshbuker","description":"Reading the ppm output from an fs-ia6b receiver using a microcontroller.","archived":false,"fork":false,"pushed_at":"2021-03-29T18:15:23.000Z","size":2120,"stargazers_count":4,"open_issues_count":1,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-01-10T02:52:52.981Z","etag":null,"topics":["ppm","receiver"],"latest_commit_sha":null,"homepage":"","language":"C++","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/joshbuker.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE.md","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2021-03-03T04:42:11.000Z","updated_at":"2024-09-15T15:41:53.000Z","dependencies_parsed_at":null,"dependency_job_id":"e729547a-18ea-4bba-ac5f-3f27ab6d6383","html_url":"https://github.com/joshbuker/mcu-ppm-input","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/joshbuker%2Fmcu-ppm-input","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/joshbuker%2Fmcu-ppm-input/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/joshbuker%2Fmcu-ppm-input/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/joshbuker%2Fmcu-ppm-input/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/joshbuker","download_url":"https://codeload.github.com/joshbuker/mcu-ppm-input/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":240976351,"owners_count":19887472,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["ppm","receiver"],"created_at":"2024-11-11T16:31:09.199Z","updated_at":"2026-05-16T07:36:57.532Z","avatar_url":"https://github.com/joshbuker.png","language":"C++","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Reading values from a PPM based RX receiver\n\nI had quite a bit of trouble figuring out exactly how to read PPM signals from\nmy radio receiver (the fs-ia6b), so I figured I'd share my solution to help\nanyone else who runs into similar trouble.\n\n## Code Examples\n\nExamples for the following MCUs have been implemented so far:\n\n* [Arduino](arduino_example.ino)\n* [Microbit](microbit_example.py) - Has some issues with interrupt timing, START_FRAME_LENGTH may need to be tuned\n* [Photon](photon_example.ino) - This example includes the RGBW example code mentioned below.\n\n## Hardware Used\n\n![](images/hardware_used.png)\n\n* Radio Transmitter\n  * Flysky FS-i6X - [Amazon Link](https://www.amazon.com/gp/product/B0744DPPL8/)\n* Arduino\n  * Elegoo UNO - [Amazon Link](https://www.amazon.com/gp/product/B01EWOE0UU/)\n\n## What is PPM?\n\nPPM is a method of communicating using pulses of high/low signal, similar to\nPWM. For this particular receiver, each \"frame\" of data is represented by a\nstarting pulse of 2ms/2000μs (milliseconds/microseconds), followed by a pulse\nbetween 700-1700μs for each data channel. Each pulse/signal is separated by a\n300μs low signal, creating a minimum pulse of 1000μs and maximum of 2000μs for\neach channel. There is a padding delay between each frame of data, such that\neach frame lasts around 22.5ms in total.\n\nOne important thing to note is that a falling edge is preferred over a rising\nedge for setting up your pin interrupt, as it better handles the delay between\nPPM frames. See the following diagram:\n\n![](images/rising_vs_falling_edge.jpg)\n\nWith everything properly setup, you can get all the available channels stored\nwithin an array, to be used by whatever applications you may have for it. Some\nexamples that I've done is using 3 of the joystick channels for controlling RGB\non a RGBW neopixel array, and one of the flip switches to turn the W LEDs\non/off. Another use-case is translating the third channel (the throttle joystick\nY axis) to control an ESC 1:1.\n\nWith the provided example code, you should be able to plug the receiver into pin\n2, and view the serial plotter:\n\n![](images/serial_plotter.png)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjoshbuker%2Fmcu-ppm-input","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fjoshbuker%2Fmcu-ppm-input","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjoshbuker%2Fmcu-ppm-input/lists"}