{"id":21369017,"url":"https://github.com/stronnag/msp_set_rx","last_synced_at":"2025-07-23T15:07:22.098Z","repository":{"id":41436415,"uuid":"157437113","full_name":"stronnag/msp_set_rx","owner":"stronnag","description":"INAV MSP_SET_RAW_RC example","archived":false,"fork":false,"pushed_at":"2025-01-22T16:45:09.000Z","size":162,"stargazers_count":13,"open_issues_count":0,"forks_count":5,"subscribers_count":3,"default_branch":"master","last_synced_at":"2025-07-13T05:39:46.962Z","etag":null,"topics":["automation","inav"],"latest_commit_sha":null,"homepage":"","language":"Go","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/stronnag.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"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,"zenodo":null}},"created_at":"2018-11-13T19:48:55.000Z","updated_at":"2025-05-25T21:18:37.000Z","dependencies_parsed_at":"2024-06-21T19:18:05.677Z","dependency_job_id":"a7afc80d-7b04-4a64-a95d-3a056b42edd3","html_url":"https://github.com/stronnag/msp_set_rx","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/stronnag/msp_set_rx","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/stronnag%2Fmsp_set_rx","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/stronnag%2Fmsp_set_rx/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/stronnag%2Fmsp_set_rx/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/stronnag%2Fmsp_set_rx/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/stronnag","download_url":"https://codeload.github.com/stronnag/msp_set_rx/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/stronnag%2Fmsp_set_rx/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":266699697,"owners_count":23970543,"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","status":"online","status_checked_at":"2025-07-23T02:00:09.312Z","response_time":66,"last_error":null,"robots_txt_status":null,"robots_txt_updated_at":null,"robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"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":["automation","inav"],"created_at":"2024-11-22T07:29:53.071Z","updated_at":"2025-07-23T15:07:22.077Z","avatar_url":"https://github.com/stronnag.png","language":"Go","funding_links":[],"categories":[],"sub_categories":[],"readme":"# MSP_SET_RAW RC \"considered harmful?\"\n\n## Overview\n\nThis golang program exercises `MSP_SET_RAW_RC`. This is intended to be a learning / experimental / educational tool rather than an end user application.\n\n### Why\n\nEvery few months, someone will come along on INAV Github / RC Groups / Telegram / Discord / some other random support channel and state that `RX_MSP` / `set receiver_type = MSP`  doesn't work.\n\nWell it does, if you do it correctly. This example demonstrates usage.\n\nAs Go is available on pretty much any OS, you can even verify that it works, with this small application.\n\n**NOTE: The previous, verbose, timer activated version of this tool is now in the `legacy` branch, should you really want to play with that**\n\n## FC Prerequisites\n\n* A supported FC\n* INAV v6 or later, earlier versions may also work\n* The FC should have been configured to a state in which it can be armed:\n  - The sensors are calibrated\n  - Required sensors are powered (e.g. GPS requiring battery)\n  - If necessary `nav_extra_arming_safety` may be set to `ALLOW_BYPASS`\n  - The arming channel is defined, with a range (min-max) less than 1000\n\n### Set the correct RX type\n\nModern firmware (e.g INAV 1.8 and later)\n```\nset receiver_type = MSP\n```\n\nFor older versions of this example, with INAV prior to INAV 1.8, you can try:\n```\n# for ancient firmware\nfeature RX_MSP\n```\nHowever, don't be surprised if ancient versions fail to work with `msp_set_rx`.\n\n## Building\n\n* Clone this repository\n* Build the test application\n\n### POSIX (*BSD, Linux, macOS) platforms\n ```\n# gmake on 'BSD\nmake\n ```\n\nThis should result in a `msp_set_rx` application.\n\n### Windows\n\nFor Windows (cross compile on non-Windows:)\n```\nGOOS=windows go build -ldflags \"-w -s\" -o msp_set_rx.exe msp.go msp_set_rx.go btaddr_other.go inav_misc.go event_loop.go\n```\nNatively, drop the `GOOS=windows` bit. With msys2, you can (probably) use the Makefile.\n\n## Usage\n\n```\n$ msp_set_rx --help\nUsage of msp_set_rx [options]\n  -auto-arm\n    \tAuto-arm FC when ready\n  -b int\n    \tBaud rate (default 115200)\n  -d string\n    \tSerial Device\n  -every int\n    \tRefresh time (ms) (default 100)\n  -throttle int\n    \tLow throttle (µs) (default -1)\n  -verbose\n    \tlog Rx/Tx stanzas\n```\n\nWhen initialised, the application will accept keypresses:\n\n* `A`, `a` : Toggle arming state\n  - If the FC is in a \"ready to arm\" condition, it will be armed\n  - If the FC is armed, it will be disarmed\n* `Q`,`q`,`Ctrl-C` : Clean exit. If the FC is armed, it will be disarmed first.\n* `F`: Unclean exit, potentially causing fail-safe. Be prepared to handle the consequences.\n* `v`, `V`: Toggle verbose\n\nIf a `-throttle` value has been specified, then, when armed it will run the motors at that value and the throttle will not be randomly perturbed. Two additional keypresses are recognised:\n\n* `+`, `-` raise / lower throttle by 25µs\n\nIf the application is exited uncleanly, then on restarting `msp_set_rx`, the FC should recover from fail-safe (note roll and pitch are perturbed to force F/S recovery).\n\n```\n$ ./msp_set_rx -d /dev/ttyUSB0 [-b baud]\n# and hence, probably, for example\nC:\\\u003e msp_set_rx.exe -d COM42 -b 115200\n# Linux, autodetect\n$ ./msp_set_rx\n```\n\nNote: On Linux, `/dev/ttyUSB0` and `/dev/ttyACM0` are automatically detected.\n\nWhile this tool attempts to arm at a safe throttle value, removing props or using a current limiter is recommended. Using the [INAV_SITL](https://github.com/iNavFlight/inav/blob/master/docs/SITL/SITL.md) may be a better option. A suitable configuration for such experiments is described in the [fl2sitl wiki](https://github.com/stronnag/bbl2kml/wiki/fl2sitl#sitl-configuration)\n\nPlease also note that if you do not define a \"low throttle\" (`-throttle`) value, then when armed, the motors will run at randomly changing throttle between 1100us and 1300us. Please ensure you and your hardware are content with this.\n\nBy default, the RC values are refreshed every 100ms (10Hz), twice the required minimum refresh rate. With `-every 200`, then RC values are updated every 200ms (5Hz). This should not failsafe, however any value greater than 200 will failsafe.\n\n* `-every 200` : works\n* `-every 201` : never comes out of failsafe.\n\n## Examples\n\n### FC example\n\n```\n./msp_set_rx\n[msp_set_rx] 19:20:08.885594 Using device /dev/ttyACM0\nINAV v7.0.0 WINGFC (497c01eb) API 2.5\nnav_extra_arming_safety: 2 (bypass true)\nmap: AETR\nname: \"BENCHYMCTESTY\"\nbox: ARM;PREARM;MULTI FUNCTION;ANGLE;HORIZON;TURN ASSIST;HEADING HOLD;CAMSTAB;NAV POSHOLD;LOITER CHANGE;NAV RTH;NAV WP;NAV CRUISE;NAV COURSE HOLD;HOME RESET;GCS NAV;WP PLANNER;MISSION CHANGE;SOARING;NAV ALTHOLD;MANUAL;NAV LAUNCH;SERVO AUTOTRIM;AUTO TUNE;AUTO LEVEL TRIM;BEEPER;BEEPER MUTE;OSD OFF;BLACKBOX;KILLSWITCH;FAILSAFE;CAMERA CONTROL 1;CAMERA CONTROL 2;CAMERA CONTROL 3;OSD ALT 1;OSD ALT 2;OSD ALT 3;MIXER PROFILE 2;MIXER TRANSITION;\nchan:  5, start: 1300, end: 1700 NAV POSHOLD\nchan:  5, start: 1700, end: 2100 NAV RTH\nchan:  6, start: 1300, end: 2100 NAV WP\nchan:  7, start: 1700, end: 2100 NAV ALTHOLD\nchan:  7, start: 1700, end: 2100 NAV COURSE HOLD\nchan:  8, start: 1375, end: 1600 NAV LAUNCH\nchan: 10, start: 1500, end: 2100 ARM\nchan: 11, start: 1450, end: 2100 MANUAL\nchan: 12, start: 1600, end: 2100 BEEPER\nArming set for channel 10 / 1800us\nKeypresses: 'A'/'a': toggle arming, 'Q'/'q': quit, 'F': quit to failsafe\n[msp_set_rx] 19:20:09.101738 Start TX loop\n[msp_set_rx] 19:20:09.228487 Box: FAILSAFE (40000000) Arm: RCLink (0x40000)\n[msp_set_rx] 19:20:09.932720 Box:  (0) Arm: Ready to arm (0x0)\n```\nDepending on how early in the boot process you start `msp_set_rx`, you may also see some calibration messages.\n\nHaving reached the \"Ready to arm\" state, if you press `A`, the FC will be armed:\n```\n[msp_set_rx] 19:31:55.324435 Box: ARM (1) Arm: Armed (0xc)\n```\n\nAnd if `A` is pressed again, the FC is disarmed:\n```\n[msp_set_rx] 19:33:36.633957 Box:  (0) Arm: Ready to arm (0x8)\n```\n\nPressing `Q` or `Ctrl-C` will exit the application, if the FC is armed, it will be disarmed first.\n\n```\n$ ./msp_set_rx\n...\n[msp_set_rx] 08:55:50.226087 Start TX loop\n[msp_set_rx] 08:55:50.327397 Box: FAILSAFE (40000000) Arm: Ever armed RCLink (0x40028)\n[msp_set_rx] 08:55:51.027408 Box:  (0) Arm: Ever armed RCLink (0x40028)\n[msp_set_rx] 08:55:51.127391 Box:  (0) Arm: Ready to arm (0x28)\n[msp_set_rx] 08:55:53.107915 Arming commanded  # \u003c---------- Press A key\n[msp_set_rx] 08:55:53.228029 Box: ARM (1) Arm: Armed (0x2c)\n[msp_set_rx] 08:55:55.511591 Quit commanded    # \u003c---------- Press Q key\n[msp_set_rx] 08:55:55.828115 Box:  (0) Arm: Ready to arm (0x28)\n\n```\n\nUse `F` key press to exit without disarming, causing fail-safe:\n\n```\n$ ./msp_set_rx\n...\nmsp_set_rx] 08:57:56.794411 Box:  (0) Arm: Ready to arm (0x28)\n[msp_set_rx] 08:57:57.998486 Arming commanded\n[msp_set_rx] 08:57:58.195017 Box: ARM (1) Arm: Armed (0x2c)\n[msp_set_rx] 08:58:01.214484 Exit to F/S commanded # \u003c---------- Press F key\n```\n\nIf we restart after failsafe:\n```\n$ ./msp_set_rx\n...\n[msp_set_rx] 08:58:48.488756 Start TX loop\n[msp_set_rx] 08:58:48.590155 Box: ARM,ANGLE,FAILSAFE (40000009) Arm: Armed (0x2c)\n[msp_set_rx] 08:58:49.489689 Box: ARM (1) Arm: Armed (0x2c)\n```\n\nNote the FC \"Box\" state shows `ARM,ANGLE,FAILSAFE`, and that we are still armed. It then quickly recovers (0.5s, i.e. meeting the required RX update rate) to a normal armed state, from which we can disarm /  quit cleanly.\n\n### SITL example\n\nYou can also use the INAV SITL to test. This has the advantage of not requiring hardware. The same arming prerequisites apply.\n\nHere we specify the armed throttle and auto-arm:\n\n```\n$ ./msp_set_rx -d tcp://localhost:5761 -throttle 1200 -auto-arm\n[msp_set_rx] 21:09:56.436998 Using device localhost\nINAV v7.0.0 SITL (3a2412e5) API 2.5\nnav_extra_arming_safety: 2 (bypass true)\nmap: AETR\nname: \"BENCHYMCTESTY\"\nbox: ARM;PREARM;MULTI FUNCTION;ANGLE;HORIZON;TURN ASSIST;HEADING HOLD;CAMSTAB;NAV POSHOLD;LOITER CHANGE;NAV RTH;NAV WP;NAV CRUISE;NAV COURSE HOLD;HOME RESET;GCS NAV;WP PLANNER;MISSION CHANGE;SOARING;NAV ALTHOLD;MANUAL;NAV LAUNCH;SERVO AUTOTRIM;AUTO TUNE;AUTO LEVEL TRIM;BEEPER;BEEPER MUTE;OSD OFF;BLACKBOX;KILLSWITCH;FAILSAFE;CAMERA CONTROL 1;CAMERA CONTROL 2;CAMERA CONTROL 3;OSD ALT 1;OSD ALT 2;OSD ALT 3;\nchan:  5, start: 1300, end: 1700 NAV POSHOLD\nchan:  5, start: 1700, end: 2100 NAV RTH\nchan:  6, start: 1300, end: 2100 NAV WP\nchan:  7, start: 1700, end: 2100 NAV ALTHOLD\nchan:  7, start: 1700, end: 2100 NAV COURSE HOLD\nchan:  8, start: 1375, end: 1600 NAV LAUNCH\nchan: 10, start: 1500, end: 2100 ARM\nchan: 11, start: 1450, end: 2100 MANUAL\nchan: 12, start: 1600, end: 2100 BEEPER\nArming set for channel 10 / 1800us\nKeypresses: 'A'/'a': toggle arming, 'Q'/'q': quit, 'F': quit to failsafe\n            '+'/'-' raise / lower throttle by 25µs\n[msp_set_rx] 09:01:06.155880 Start TX loop\n[msp_set_rx] 09:01:06.256949 Box: FAILSAFE (40000000) Arm: Ever armed RCLink (0x40028)\n[msp_set_rx] 09:01:06.956972 Box:  (0) Arm: Ever armed RCLink (0x40028)\n[msp_set_rx] 09:01:07.056953 Box:  (0) Arm: Ready to arm (0x28)\n[msp_set_rx] 09:01:07.256960 Box: ARM (1) Arm: Armed (0x2c)\n[msp_set_rx] 09:01:11.826990 Throttle commanded: 1225\n[msp_set_rx] 09:01:13.493910 Throttle commanded: 1250\n[msp_set_rx] 09:01:14.971894 Throttle commanded: 1275\n[msp_set_rx] 09:01:21.384503 Throttle commanded: 1250\n[msp_set_rx] 09:01:21.943347 Throttle commanded: 1225\n[msp_set_rx] 09:01:22.515390 Throttle commanded: 1200\n[msp_set_rx] 09:01:23.069359 Throttle commanded: 1175\n[msp_set_rx] 09:01:29.362560 Quit commanded\n[msp_set_rx] 09:01:29.756786 Box:  (0) Arm: Ready to arm (0x28)\n```\nNote that the SITL captures some of the early status / calibration changes.\n\n* The FC was armed as soon as it was ready, without user input. When armed, the user adjusted the throttle. The effects may be noted using the configurator on tcp://localhost:5760.\n* The /- keys are used to manually change the throttle value.\n\n#### SITL usage\n\n* Configure two MSP ports, one can be used for the MSP RX, the other to inspect the RX channels in the configurator.\n\nIn one terminal (with `eeprom.bin` pre-configured for MSP receiver), POSIXally at least:\n```\n((fl2sitl --minimal\u0026) \u0026\u0026 inav_SITL --path ~/sitl-eeproms/fw-eeprom.bin --sim xp)\n```\nThen (another terminal / tab):\n```\nmsp_set_rx -d tcp://localhost:5761 [other otptions...]\n```\n\nNote that in order for the SITL to arm, a simulator is needed.In the example we use [fl2sitl](https://github.com/stronnag/bbl2kml/wiki/fl2sitl) with `-minimal` to provide the simplest simulation that will unlock the SITL sensors and allow arming.\n\n* The configurator can be connected to tcp://localhost:5760 (UART1)\n* The MSP RX is connected to tcp://localhost:5761 (UART2)\n\n## arm_status\n\nThere is a simple tool to interpret arming status `arm_status`. It accepts one or more numeric status codes and displays human readable interpretation:\n\n```\n./arm_status 28 84c00\nStatus 00000028:\n 00000008 =\u003e Ever Armed\n 00000020 =\u003e SITL\nStatus 00084c00:\n 00000400 =\u003e Overload\n 00000800 =\u003e Navigation unsafe\n 00004000 =\u003e Arm switch\n 00080000 =\u003e Throttle\n```\nCopy it onto `$PATH` if you wish.\n\n## Other examples\n\nThe [flightlog2kml](https://github.com/stronnag/bbl2kml) project contains a tool [fl2sitl](https://github.com/stronnag/bbl2kml/wiki/fl2sitl) that replays a blackbox log using the [INAV SITL](https://github.com/iNavFlight/inav/blob/master/docs/SITL/SITL.md). Specifically, this uses MSP and MSP_SET_RAW_RC to establish vehicle characteristics, monitor the vehicle status, arm the vehicle and set RC values for AETR and switches during log replay simulation to effectively \"fly\" the SITL for the recorded flight.\n\nThe MSP initialisation, MSP status monitoring and MSP RC management code is in [msp.go](https://github.com/stronnag/bbl2kml/blob/master/pkg/sitlgen/msp.go), specifically the `init()` and `run()` functions. Arming / disarming in [sitlgen.go](https://github.com/stronnag/bbl2kml/blob/master/pkg/sitlgen/sitlgen.go), `arm_action()` function.\n\nThis is more comprehensive (and complex) example.\n\n## Caveats\n\n* Ensure you provide (at least) 5Hz RX data, but don't overload the FC; MSP is a request-response protocol, don't just \"spam\" the FC via a high frequency timer and ignore the responses.\n* Ensure you've set a correct, valid AUX range to arm. In particular and for safety, the ARM range must be less or equal to 1000 in order to allow disarming.\n* Ensure you've met the required arming conditions\n* Use a supported FC or the **inav_SITL**\n* Remove the props etc.\n\n## Postscript\n\nReally, it's all about preparation, in particular the interrogation of the FC prior to sending any `MSP_SET_RAW_RC` data in order to get the box names and switch settings that will be necessary to arm and monitor the \"box\" and \"arming\" flags that enable your application to monitor the state of the automated FC.\n\n## Licence\n\nWhatever approximates to none / public domain in your locale. 0BSD (Zero clause BSD)  if an actual license is required by law.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fstronnag%2Fmsp_set_rx","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fstronnag%2Fmsp_set_rx","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fstronnag%2Fmsp_set_rx/lists"}