<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
  <channel>
    <title>2026s on Mika Tuupola</title>
    <link>https://www.appelsiini.net/2026/</link>
    <description>Recent content in 2026s on Mika Tuupola</description>
    <generator>Hugo -- gohugo.io</generator>
    <language>en-us</language>
    <lastBuildDate>Mon, 23 Mar 2026 00:00:00 +0000</lastBuildDate>
    
	<atom:link href="https://www.appelsiini.net/2026/index.xml" rel="self" type="application/rss+xml" />
    
    
    <item>
      <title>Setup PX4 Drone From Scratch</title>
      <link>https://www.appelsiini.net/2026/setup-px4-drone-from-scratch/</link>
      <pubDate>Mon, 23 Mar 2026 00:00:00 +0000</pubDate>
      
      <guid>https://www.appelsiini.net/2026/setup-px4-drone-from-scratch/</guid>
      <description>&lt;p&gt;&lt;img src=&#34;https://www.appelsiini.net/img/2026/px4-geprc-pro.jpg&#34; alt=&#34;GEPRC Vapor-D6&#34;&gt;&lt;/p&gt;
&lt;p&gt;Configuring a PX4 flight controller is more involved than iNav or Betaflight.
Most commercial development is happening in PX4 because it has a permissive
license. While I fly all three, PX4 has the most advanced features for
autonomous flight.&lt;/p&gt;
&lt;h1 id=&#34;the-goal&#34;&gt;The Goal&lt;/h1&gt;
&lt;p&gt;A quad that is flyable using both traditional RC transmitter (TX) and a
&lt;a href=&#34;https://qgroundcontrol.com/&#34;&gt;Ground Control Station&lt;/a&gt; (GCS) using
&lt;a href=&#34;https://mavlink.io/&#34;&gt;MAVLink protocol&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;MAVLink protocol will be &lt;a href=&#34;https://www.expresslrs.org/software/mavlink/&#34;&gt;piggybacked over the ELRS&lt;/a&gt;
radio. This removes the need to include additional telemetry radios. The GCS
software will receive the MAVLink packets from the TX using a USB cable.
This is more reliable than using the transmitter-provided WiFi network.&lt;/p&gt;
&lt;h1 id=&#34;hardware&#34;&gt;Hardware&lt;/h1&gt;
&lt;p&gt;The flight controller is a &lt;a href=&#34;https://micoair.com/flightcontroller_micoair743v2/&#34;&gt;MicoAir743v2&lt;/a&gt;.
It is a standard 30.5mm x 30.5mm mount controller and also has a build target
for PX4.&lt;/p&gt;
&lt;p&gt;I used the &lt;a href=&#34;https://radiomasterrc.com/collections/nomad/products/nomad-dual-1-watt-gemini-xrossband-expresslrs-module&#34;&gt;Nomad Gemini Xrossband ExpressLRS Module&lt;/a&gt; but any external module
will do. You could fly without an external TX module, but it is
required for connecting to the ground control station via USB.&lt;/p&gt;
&lt;h1 id=&#34;radio-setup&#34;&gt;Radio Setup&lt;/h1&gt;
&lt;p&gt;Using an external radio module requires you to change to &lt;code&gt;External RF&lt;/code&gt; in
the model setup.&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;https://www.appelsiini.net/img/2026/jumper-t15-external.png&#34; alt=&#34;EdgeTX External RF&#34;&gt;&lt;/p&gt;
&lt;p&gt;Additionally there are two main things to configure in the transmitter.&lt;/p&gt;
&lt;h2 id=&#34;mavlink-mode&#34;&gt;MAVLink mode&lt;/h2&gt;
&lt;p&gt;Run the ExpressLRS script in the transmitter. You can find it from the SYS
menu. Make sure packet rate is &lt;code&gt;500 2.4G&lt;/code&gt; and link mode is &lt;code&gt;MAVLink&lt;/code&gt;. It
should also automatically change the telemetry ratio to &lt;code&gt;1:2 (9921 bps)&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;https://www.appelsiini.net/img/2026/jumper-t15-elrs-tx.png&#34; alt=&#34;ExpressLRS LUA script in TX&#34;&gt;&lt;/p&gt;
&lt;p&gt;Go to the other devices menu and also change the receiver RC protocol to &lt;code&gt;MAVLink&lt;/code&gt;.
Now they should talk MAVLink over ELRS with each other.&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;https://www.appelsiini.net/img/2026/jumper-t15-elrs-rx.png&#34; alt=&#34;ExpressLRS LUA script in RX&#34;&gt;&lt;/p&gt;
&lt;h2 id=&#34;flight-modes&#34;&gt;Flight modes&lt;/h2&gt;
&lt;p&gt;There will be seven different flight modes controlled by three physical switches:
SA, SC and SB. Additionally the SF switch is used as panic recovery if your brain
stops functioning. The idea is that left side has the simple flight modes.
Moving to the right, complexity increases, and the rightmost switch is the panic
button.&lt;/p&gt;
&lt;p&gt;These are flight modes I personally prefer. I use the same switch layout and
flight modes also with fixed wings.&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Switch&lt;/th&gt;
&lt;th&gt;Mode&lt;/th&gt;
&lt;th&gt;Notes&lt;/th&gt;
&lt;th&gt;Logical&lt;br/&gt;Switch&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;SA↑&lt;/td&gt;
&lt;td&gt;Stabilized&lt;/td&gt;
&lt;td&gt;Active when SB and SC are center (-)&lt;/td&gt;
&lt;td&gt;L10&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;SA-&lt;/td&gt;
&lt;td&gt;Acro&lt;/td&gt;
&lt;td&gt;Active when SB and SC are center (-)&lt;/td&gt;
&lt;td&gt;L11&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;SA↓&lt;/td&gt;
&lt;td&gt;Manual&lt;/td&gt;
&lt;td&gt;Active when SB and SC are center (-)&lt;/td&gt;
&lt;td&gt;L12&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;SC↑&lt;/td&gt;
&lt;td&gt;Mission&lt;/td&gt;
&lt;td&gt;Overrides SA&lt;/td&gt;
&lt;td&gt;L13&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;SC↓&lt;/td&gt;
&lt;td&gt;Offboard&lt;/td&gt;
&lt;td&gt;Overrides SA&lt;/td&gt;
&lt;td&gt;L14&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;SB↑&lt;/td&gt;
&lt;td&gt;Hold&lt;/td&gt;
&lt;td&gt;Overrides SA and SC&lt;/td&gt;
&lt;td&gt;L15&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;SB↓&lt;/td&gt;
&lt;td&gt;RTH/RTL&lt;/td&gt;
&lt;td&gt;Overrides SA and SC&lt;/td&gt;
&lt;td&gt;L16&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;SF↓&lt;/td&gt;
&lt;td&gt;Panic&lt;/td&gt;
&lt;td&gt;Overrides SA, SC and SB&lt;/td&gt;
&lt;td&gt;L17&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;PX4 firmware does not have a dedicated panic recovery. I currently use position
hold as a kludgish alternative.&lt;/p&gt;
&lt;h3 id=&#34;killswitch&#34;&gt;Killswitch&lt;/h3&gt;
&lt;p&gt;When first hitting a tree it might come as a surprise that unlike with iNav
or Betaflight the PX disarm switch will not kill the motors. That is because
disarming is allowed only after landing. Your drone will be hanging in the
tree with propellers spinning and there is nothing you can do.&lt;/p&gt;
&lt;p&gt;PX4 does have a killswitch but you cannot configure it to use the same channel
as arming. My solution for this is switch panic and disarm at the same time.&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Switch&lt;/th&gt;
&lt;th&gt;Action&lt;/th&gt;
&lt;th&gt;Notes&lt;/th&gt;
&lt;th&gt;Logical&lt;br/&gt;Switch&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;SE↑&lt;/td&gt;
&lt;td&gt;Disarm&lt;/td&gt;
&lt;td&gt;Works only after landing&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;SE↓&lt;/td&gt;
&lt;td&gt;Arm&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;SE↑ SF↓&lt;/td&gt;
&lt;td&gt;Kill motors&lt;/td&gt;
&lt;td&gt;Panic + Disarm == Kill, kill, kill&lt;/td&gt;
&lt;td&gt;L19&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;This will not mess with my muscle memory because iNav and Betaflight setups
will still disarm from the SE switch.&lt;/p&gt;
&lt;h3 id=&#34;but-how&#34;&gt;But how?&lt;/h3&gt;
&lt;p&gt;Configuring your radio to handle all this can be done in several ways. I chose
the Programmer Way (tm) and used logical switches. The 0.1 second delay is there
to avoid announcing a flight mode when SB or SC jumps over the center position.&lt;/p&gt;
&lt;p&gt;You can configure this either by using the transmitter menus or by using
the &lt;a href=&#34;https://edgetx.org/getedgetx/&#34;&gt;EdgeTX Companion&lt;/a&gt; software. I use the latter
since it is much faster to use.&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;https://www.appelsiini.net/img/2026/jumper-t15-ls.png&#34; alt=&#34;Logical switches in EdgeTX Companion&#34;&gt;&lt;/p&gt;
&lt;p&gt;Logical switches are used to override the channel 6 output via mixes. This is
what the flight controller reads to set the flight mode. Since offboard mode is
not an actual flight mode in PX4, it is enabled using channel 9.&lt;/p&gt;
&lt;p&gt;From the image you can also see channel 5 is used for arming, channel 7 for
beeper and channel 8 for configuring the OSD.&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;https://www.appelsiini.net/img/2026/jumper-t15-mixes.png&#34; alt=&#34;Mixes in EdgeTX Companion&#34;&gt;&lt;/p&gt;
&lt;p&gt;The flight mode announcements are done using special functions tied to logical
switches.&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;https://www.appelsiini.net/img/2026/jumper-t15-sf.png&#34; alt=&#34;Special functions in EdgeTX Companion&#34;&gt;&lt;/p&gt;
&lt;p&gt;If you have a Jumper T15 you can download above settings from
&lt;nobr&gt;&lt;a href=&#34;https://github.com/tuupola/edgetx-setups/tree/master&#34;&gt;tuupola/edgetx-setups&lt;/a&gt;&lt;/nobr&gt;
GitHub repository.&lt;/p&gt;
&lt;h1 id=&#34;firmware&#34;&gt;Firmware&lt;/h1&gt;
&lt;h2 id=&#34;build&#34;&gt;Build&lt;/h2&gt;
&lt;p&gt;The default build of PX4 includes everything and the kitchen sink. I want to disable some features
and also add support for MSP OSD. These instructions assume you have already
set up the &lt;a href=&#34;https://docs.px4.io/main/en/dev_setup/dev_env&#34;&gt;build environment&lt;/a&gt;.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-shell&#34; data-lang=&#34;shell&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;$ git clone https://github.com/PX4/PX4-Autopilot.git --recursive
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;$ cd PX4-Autopilot
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;$ make micoair_h743-v2_default boardconfig
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;After changing the settings you can check the changes with &lt;code&gt;git diff .&lt;/code&gt;.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-shell&#34; data-lang=&#34;shell&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;$ git diff . 
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;diff --git a/boards/micoair/h743-v2/default.px4board b/boards/micoair/h743-v2/default.px4board
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;index 320f1d29e9..f828f2ad1c &lt;span style=&#34;color:#ae81ff&#34;&gt;100644&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;--- a/boards/micoair/h743-v2/default.px4board
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;+++ b/boards/micoair/h743-v2/default.px4board
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;@@ -33,7 +33,8 @@ CONFIG_DRIVERS_POWER_MONITOR_INA238&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;y
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt; CONFIG_DRIVERS_POWER_MONITOR_VOXLPM&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;y
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt; CONFIG_DRIVERS_PPS_CAPTURE&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;y
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt; CONFIG_DRIVERS_PWM_OUT&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;y
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;-CONFIG_COMMON_RC&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;y
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;+CONFIG_DRIVERS_RC_CRSF_RC&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;y
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;+CONFIG_DRIVERS_RC_INPUT&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;y
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt; CONFIG_COMMON_RPM&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;y
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt; CONFIG_DRIVERS_SMART_BATTERY_BATMON&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;y
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt; CONFIG_DRIVERS_TAP_ESC&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;y
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;@@ -54,7 +55,6 @@ CONFIG_MODULES_EVENTS&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;y
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt; CONFIG_MODULES_FLIGHT_MODE_MANAGER&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;y
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt; CONFIG_MODULES_FW_ATT_CONTROL&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;y
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt; CONFIG_MODULES_FW_AUTOTUNE_ATTITUDE_CONTROL&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;y
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;-CONFIG_MODULES_FW_POS_CONTROL&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;y
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt; CONFIG_MODULES_FW_RATE_CONTROL&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;y
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt; CONFIG_MODULES_GIMBAL&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;y
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt; CONFIG_MODULES_GYRO_CALIBRATION&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;y
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;@@ -105,3 +105,4 @@ CONFIG_SYSTEMCMDS_UORB&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;y
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt; CONFIG_SYSTEMCMDS_USB_CONNECTED&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;y
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt; CONFIG_SYSTEMCMDS_VER&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;y
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt; CONFIG_SYSTEMCMDS_WORK_QUEUE&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;y
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;+CONFIG_ARCH_CHIP_STM32H7&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;y
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;After the build finishes you can see how much memory is being used.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-shell&#34; data-lang=&#34;shell&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;$ make micoair_h743-v2_default -j8
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;...
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Memory region         Used Size  Region Size  %age Used
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        ITCM_RAM:           &lt;span style=&#34;color:#ae81ff&#34;&gt;0&lt;/span&gt; B        &lt;span style=&#34;color:#ae81ff&#34;&gt;64&lt;/span&gt; KB      0.00%
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;           FLASH:     &lt;span style=&#34;color:#ae81ff&#34;&gt;1765492&lt;/span&gt; B      &lt;span style=&#34;color:#ae81ff&#34;&gt;1792&lt;/span&gt; KB     96.21%
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;       DTCM1_RAM:           &lt;span style=&#34;color:#ae81ff&#34;&gt;0&lt;/span&gt; B        &lt;span style=&#34;color:#ae81ff&#34;&gt;64&lt;/span&gt; KB      0.00%
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;       DTCM2_RAM:           &lt;span style=&#34;color:#ae81ff&#34;&gt;0&lt;/span&gt; B        &lt;span style=&#34;color:#ae81ff&#34;&gt;64&lt;/span&gt; KB      0.00%
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        AXI_SRAM:       &lt;span style=&#34;color:#ae81ff&#34;&gt;53684&lt;/span&gt; B       &lt;span style=&#34;color:#ae81ff&#34;&gt;512&lt;/span&gt; KB     10.24%
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;           SRAM1:           &lt;span style=&#34;color:#ae81ff&#34;&gt;0&lt;/span&gt; B       &lt;span style=&#34;color:#ae81ff&#34;&gt;128&lt;/span&gt; KB      0.00%
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;           SRAM2:           &lt;span style=&#34;color:#ae81ff&#34;&gt;0&lt;/span&gt; B       &lt;span style=&#34;color:#ae81ff&#34;&gt;128&lt;/span&gt; KB      0.00%
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;           SRAM3:           &lt;span style=&#34;color:#ae81ff&#34;&gt;0&lt;/span&gt; B        &lt;span style=&#34;color:#ae81ff&#34;&gt;32&lt;/span&gt; KB      0.00%
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;           SRAM4:           &lt;span style=&#34;color:#ae81ff&#34;&gt;0&lt;/span&gt; B        &lt;span style=&#34;color:#ae81ff&#34;&gt;64&lt;/span&gt; KB      0.00%
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;          BKPRAM:           &lt;span style=&#34;color:#ae81ff&#34;&gt;0&lt;/span&gt; B         &lt;span style=&#34;color:#ae81ff&#34;&gt;4&lt;/span&gt; KB      0.00%
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id=&#34;flash&#34;&gt;Flash&lt;/h2&gt;
&lt;p&gt;Flashing is best done using a USB cable.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-shell&#34; data-lang=&#34;shell&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;$ make micoair_h743-v2_default upload
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;...
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Bootloader version: PX4BLv1.15.4g
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Sn: 003d001f3233510d33353834
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Chip: &lt;span style=&#34;color:#ae81ff&#34;&gt;20036450&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Family: STM32H7&lt;span style=&#34;color:#f92672&#34;&gt;[&lt;/span&gt;4|5&lt;span style=&#34;color:#f92672&#34;&gt;]&lt;/span&gt;x
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Revision: V
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Flash: &lt;span style=&#34;color:#ae81ff&#34;&gt;1966080&lt;/span&gt; bytes
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Windowed mode: False
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Erase  : &lt;span style=&#34;color:#f92672&#34;&gt;[====================]&lt;/span&gt; 100.0%
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Program: &lt;span style=&#34;color:#f92672&#34;&gt;[====================]&lt;/span&gt; 100.0%
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Verify : &lt;span style=&#34;color:#f92672&#34;&gt;[====================]&lt;/span&gt; 100.0%
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Rebooting. Elapsed Time 25.219
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;You can now connect to the NuttX shell and configure the flight controller.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-shell&#34; data-lang=&#34;shell&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;$ ./Tools/mavlink_shell.py /dev/ttyACM0
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;NuttShell &lt;span style=&#34;color:#f92672&#34;&gt;(&lt;/span&gt;NSH&lt;span style=&#34;color:#f92672&#34;&gt;)&lt;/span&gt; NuttX-11.0.0
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;nsh&amp;gt; 
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;nsh&amp;gt; ver all
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;HW arch: MICOAIR_H743_V2
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;PX4 git-hash: 24bbf5efd90335d7533f6769db7ee3d23a0e7aa1
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;PX4 version: 1.17.0 &lt;span style=&#34;color:#ae81ff&#34;&gt;40&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;(&lt;/span&gt;17891392&lt;span style=&#34;color:#f92672&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;PX4 git-branch: main
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;OS: NuttX
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;OS version: Release 11.0.0 &lt;span style=&#34;color:#f92672&#34;&gt;(&lt;/span&gt;184549631&lt;span style=&#34;color:#f92672&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;OS git-hash: 29450774d75a2ad4748ac93b2d8759f1ada48883
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Build datetime: Mar &lt;span style=&#34;color:#ae81ff&#34;&gt;20&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;2026&lt;/span&gt; 17:48:19
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Build uri: localhost
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Build variant: default
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Toolchain: GNU GCC, 13.2.1 &lt;span style=&#34;color:#ae81ff&#34;&gt;20231009&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;PX4GUID: 000600000000333538343233510d003d001f
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;MCU: STM32H7&lt;span style=&#34;color:#f92672&#34;&gt;[&lt;/span&gt;4|5&lt;span style=&#34;color:#f92672&#34;&gt;]&lt;/span&gt;xxx, rev. V
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;...
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id=&#34;configure&#34;&gt;Configure&lt;/h2&gt;
&lt;h3 id=&#34;rc-input&#34;&gt;RC Input&lt;/h3&gt;
&lt;p&gt;First thing to configure is the RC input. Since we are using MAVLink over ELRS,
plug the receiver into &lt;code&gt;TELEM1&lt;/code&gt; and not the &lt;code&gt;RC&lt;/code&gt; port where it usually goes.&lt;/p&gt;
&lt;p&gt;Change RC input protocol to CRSF. The default is auto but explicitly setting it to
the desired protocol is a safer option. Also change the &lt;code&gt;TELEM1&lt;/code&gt; serial baud to
460800 to match the RX when running in MAVLink mode. &lt;code&gt;MAV_0&lt;/code&gt; rate should be
9600.&lt;/p&gt;
&lt;p&gt;These settings approximately match the transmitter which was configured for
500Hz packet rate resulting in 9921bps MAVLink rate.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-shell&#34; data-lang=&#34;shell&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;nsh&amp;gt; param set RC_INPUT_PROTO &lt;span style=&#34;color:#ae81ff&#34;&gt;6&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;nsh&amp;gt; param set SER_TEL1_BAUD &lt;span style=&#34;color:#ae81ff&#34;&gt;460800&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;nsh&amp;gt; param set MAV_0_RATE &lt;span style=&#34;color:#ae81ff&#34;&gt;9600&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id=&#34;rc-input-channels&#34;&gt;RC Input Channels&lt;/h3&gt;
&lt;p&gt;Map the four primary flight control axes to RC channels in PX4. This is the
standard AETR channel order.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-shell&#34; data-lang=&#34;shell&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;nsh&amp;gt; param set RC_MAP_ROLL &lt;span style=&#34;color:#ae81ff&#34;&gt;1&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;nsh&amp;gt; param set RC_MAP_PITCH &lt;span style=&#34;color:#ae81ff&#34;&gt;2&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;nsh&amp;gt; param set RC_MAP_THROTTLE &lt;span style=&#34;color:#ae81ff&#34;&gt;3&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;nsh&amp;gt; param set RC_MAP_YAW &lt;span style=&#34;color:#ae81ff&#34;&gt;4&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;nsh&amp;gt; param save
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;nsh&amp;gt; reboot
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Connect the flight controller to USB and start QGC to make sure channels are
mapped correctly. You should see matching stick movement in the &lt;code&gt;Radio&lt;/code&gt; tab.&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;https://www.appelsiini.net/img/2026/qgc-radio-config.png&#34; alt=&#34;QGC Radio Config&#34;&gt;&lt;/p&gt;
&lt;p&gt;If everything is ok click &lt;code&gt;Calibrate&lt;/code&gt; button to calibrate the sticks. Make sure
to also calibrate all the switches or you will have mysterious problems later.&lt;/p&gt;
&lt;h3 id=&#34;switch-channels&#34;&gt;Switch Channels&lt;/h3&gt;
&lt;p&gt;Set transmitter channels. Channel 5 for arming and channel 6 for flight mode.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-shell&#34; data-lang=&#34;shell&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;nsh&amp;gt; param set RC_MAP_ARM_SW &lt;span style=&#34;color:#ae81ff&#34;&gt;5&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;nsh&amp;gt; param set RC_MAP_FLTMODE &lt;span style=&#34;color:#ae81ff&#34;&gt;6&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id=&#34;flight-modes-1&#34;&gt;Flight Modes&lt;/h3&gt;
&lt;p&gt;Flight modes are: stabilized, acro, manual, mission, position hold, and RTH. These match
the radio setup explained above. Offboard mode is special. PX4 does not consider
it a flight mode and instead activates the mode from a separate channel 9.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-shell&#34; data-lang=&#34;shell&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;nsh&amp;gt; param set COM_FLTMODE1 &lt;span style=&#34;color:#ae81ff&#34;&gt;8&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;nsh&amp;gt; param set COM_FLTMODE2 &lt;span style=&#34;color:#ae81ff&#34;&gt;6&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;nsh&amp;gt; param set COM_FLTMODE3 &lt;span style=&#34;color:#ae81ff&#34;&gt;0&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;nsh&amp;gt; param set COM_FLTMODE4 &lt;span style=&#34;color:#ae81ff&#34;&gt;3&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;nsh&amp;gt; param set COM_FLTMODE5 &lt;span style=&#34;color:#ae81ff&#34;&gt;4&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;nsh&amp;gt; param set COM_FLTMODE6 &lt;span style=&#34;color:#ae81ff&#34;&gt;5&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;nsh&amp;gt; param set RC_MAP_OFFB_SW &lt;span style=&#34;color:#ae81ff&#34;&gt;9&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;nsh&amp;gt; param save
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;nsh&amp;gt; reboot
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Make sure flight modes work as expected. You can listen to vehicle status
in the NuttX shell. Look for changes in &lt;code&gt;nav_state&lt;/code&gt; parameter when you flip the
switches.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-shell&#34; data-lang=&#34;shell&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;nsh&amp;gt; listener vehicle_status -r &lt;span style=&#34;color:#ae81ff&#34;&gt;1&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Or use the QGC statusline.&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;https://www.appelsiini.net/img/2026/qgc-status-bar.png&#34; alt=&#34;QGC Status Bar&#34;&gt;&lt;/p&gt;
&lt;h3 id=&#34;motors&#34;&gt;Motors&lt;/h3&gt;
&lt;p&gt;Attach the battery. The motors will beep.&lt;/p&gt;
&lt;p&gt;In the &lt;code&gt;Actuators&lt;/code&gt; menu, set motor protocol to DShot300. With PX4 there really
is no point in using DShot600. Then click &lt;code&gt;Identify &amp;amp; Assign Motors&lt;/code&gt; and motors
will spin one by one. Click on the image to confirm which motor was spinning.&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;https://www.appelsiini.net/img/2026/qgc-identify-assign-motors.png&#34; alt=&#34;QGC Identify &amp;amp; Assign Motors&#34;&gt;&lt;/p&gt;
&lt;p&gt;Also make sure the motor is spinning in the correct direction. The direction
should match the image in QGC. If not, you can either swap two motor wires
or change it in the &lt;code&gt;Actuators&lt;/code&gt; menu.&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;https://www.appelsiini.net/img/2026/qgc-motor-direction.png&#34; alt=&#34;QGC Motor Direction&#34;&gt;&lt;/p&gt;
&lt;p&gt;Motors won&amp;rsquo;t beep anymore. Now you are ready to calibrate.&lt;/p&gt;
&lt;h2 id=&#34;calibrate&#34;&gt;Calibrate&lt;/h2&gt;
&lt;p&gt;Magnetometer calibration requires rotating the quad 360 degrees around every axis.
While possible with USB, it will be cumbersome. MicoAir flight controller has
Bluetooth support which makes the calibration process easier.&lt;/p&gt;
&lt;h3 id=&#34;configure-bluetooth&#34;&gt;Configure Bluetooth&lt;/h3&gt;
&lt;p&gt;First, turn on Bluetooth and find the address of your flight controller.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-shell&#34; data-lang=&#34;shell&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;$ bluetoothctl
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;[&lt;/span&gt;bluetooth&lt;span style=&#34;color:#f92672&#34;&gt;]&lt;/span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;# power on&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;[&lt;/span&gt;bluetooth&lt;span style=&#34;color:#f92672&#34;&gt;]&lt;/span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;# scan on&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;[&lt;/span&gt;bluetooth&lt;span style=&#34;color:#f92672&#34;&gt;]&lt;/span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;# devices&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Device 39:54:9E:52:09:D1 MicoAir743v2-78387
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;[&lt;/span&gt;bluetooth&lt;span style=&#34;color:#f92672&#34;&gt;]&lt;/span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;# pair 39:54:9E:52:09:D1&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;[&lt;/span&gt;bluetooth&lt;span style=&#34;color:#f92672&#34;&gt;]&lt;/span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;# trust 39:54:9E:52:09:D1&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;I was not able to make QGC connect directly to this Bluetooth device. Instead
I had to make a virtual serial device which is bound to the Bluetooth device.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-shell&#34; data-lang=&#34;shell&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;$ sudo rfcomm bind &lt;span style=&#34;color:#ae81ff&#34;&gt;0&lt;/span&gt; 39:54:9E:52:09:D1 &lt;span style=&#34;color:#ae81ff&#34;&gt;1&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;$ stty -F /dev/rfcomm0                  
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;speed &lt;span style=&#34;color:#ae81ff&#34;&gt;57600&lt;/span&gt; baud; line &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; 0;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;min &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; 0; time &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; 0;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;-brkint -icrnl -imaxbel
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;-opost
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;-isig -icanon -iexten -echo
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;In QGC, add a new serial connection &lt;code&gt;Comm settings -&amp;gt; Add new link&lt;/code&gt;. I call it &lt;code&gt;Bluetooth RFComm&lt;/code&gt;. You can now wirelessly connect to the FC with this connection.&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;https://www.appelsiini.net/img/2026/qgc-bt-rfcomm.png&#34; alt=&#34;QGC Bluetooth RFComm&#34;&gt;&lt;/p&gt;
&lt;h3 id=&#34;calibrate-sensors&#34;&gt;Calibrate sensors&lt;/h3&gt;
&lt;p&gt;Connect to the &lt;code&gt;Bluetooth RFComm&lt;/code&gt; and go to &lt;code&gt;Sensors&lt;/code&gt; tab. Calibrate all the sensors
one by one. Follow the instructions on the screen. Instructions are pretty self-explanatory.&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;https://www.appelsiini.net/img/2026/qgc-calibrate-compass.png&#34; alt=&#34;QGC Bluetooth RFComm&#34;&gt;&lt;/p&gt;
&lt;p&gt;After any major model rebuild you should calibrate the sensors again.
Especially the magnetometer is susceptible
to small changes in magnetic fields.&lt;/p&gt;
&lt;h3 id=&#34;test-flight&#34;&gt;Test Flight&lt;/h3&gt;
&lt;p&gt;Before attempting autonomous flight, this would be the time to make a
test flight. Make sure all the flight modes work. Triple check position
hold and return to home really work. If not, double check magnetometer
and flight controller orientations and redo calibration.&lt;/p&gt;
&lt;h1 id=&#34;configure-transmitter-usb&#34;&gt;Configure Transmitter USB&lt;/h1&gt;
&lt;p&gt;Connect the external TX module to your computer using USB. In QGC, add a new
serial connection. I call the connection &lt;code&gt;Transmitter USB&lt;/code&gt; but any name will
do.&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;https://www.appelsiini.net/img/2026/qgc-usb.png&#34; alt=&#34;QGC USB&#34;&gt;&lt;/p&gt;
&lt;p&gt;You can now connect to the FC with this connection.&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;https://www.appelsiini.net/img/2026/jumper-t15-ext-usb.jpg&#34; alt=&#34;Jumper T15 External TX Module USB&#34;&gt;&lt;/p&gt;
&lt;p&gt;You can now configure
the drone or even plan missions wirelessly. Congrats, the first autonomous
flight is pretty exciting.&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;https://www.appelsiini.net/img/2026/qgc-mission-plan.png&#34; alt=&#34;QGC Mission Plan&#34;&gt;&lt;/p&gt;
&lt;h1 id=&#34;additional-reading&#34;&gt;Additional Reading&lt;/h1&gt;
&lt;p&gt;See the &lt;a href=&#34;https://www.expresslrs.org/software/mavlink/&#34;&gt;ExpressLRS MAVLink documentation&lt;/a&gt;
for a more in-depth explanation of how to configure MAVLink over ELRS. If you prefer
a video, &lt;a href=&#34;https://www.youtube.com/@Painless360&#34;&gt;Painless360&lt;/a&gt; has a
&lt;a href=&#34;https://www.youtube.com/watch?v=w9MwdmYZPFk&#34;&gt;great clip&lt;/a&gt; on the same subject.&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;https://www.youtube.com/playlist?list=PLFPBjpbd5xKRECBsvI3MbmsS8NQJ8l8L9&#34;&gt;Ultimate PX4 Tuning Guide&lt;/a&gt;
by Chris Rosser for PID tuning, filter and everything else. This is an excellent
resource.&lt;/p&gt;
&lt;p&gt;See &lt;a href=&#34;https://www.appelsiini.net/2018/calibrate-magnetometer/&#34;&gt;How to Calibrate a Magnetometer&lt;/a&gt;
for theory and example code about how magnetometer calibration works.&lt;/p&gt;</description>
    </item>
    
  </channel>
</rss>