DJI Spark Gimbal Calibration

Table of Contents

UPDATE 01/19/2022: I no longer have a DJI Spark but it looks like they have changed the commands for the DJI serial tools.  My Air2 is working great so I haven’t had to use this yet but specifying –port before your COM port and -vv before your model will likely give the desired results.

First, special thanks to Brian Stigall and his video on YouTube showing how to do this.  I figured it would be helpful to make the commands used easily accessible and to be copied and pasted.


Just an obligatory disclaimer that I am not responsible for any damages that may result to your equipment including PC, drone, or other devices that could be affected by these scripts. Please understand what you are doing and how these tools work before just running commands on your PC and/or your drone.  This worked well for my DJI Spark and it should work for other drones that do not have Gimbal Calibration in their Go Fly App.  Documentation related to the DJI Firmware Tools can be found on the github page here:

My Story

If you find yourself with a tilted or drifting horizon or basically a gimbal that just won’t stay level this will be your fix.  Below you will read what happened to me and the steps that were able to successfully fix the problem.

I recently lost a propeller (aftermarket set) about 3 seconds after take off and my Spark took off at an angle and lodged straight in a tree. I recovered my bird and upon inspection 2 of my other propellers had damage but otherwise appeared fine so I went to Amazon and ordered some Genuine DJI Spark Propellers. You can get them from Amazon by clicking here..  My current propellers at the time were an aftermarket set along with some aftermarket spares.  I have seen other people have a lot of luck with aftermarket propellers, but it is no longer worth it to me to risk an expensive drone by saving $5 on propellers.

A few days later I received the new genuine propellers, installed them, and while I was doing my pre-flight checks I noticed that my camera wasn’t level.  I adjusted the gimbal roll for my first time ever and it appeared level.  After take off everything was still level however I quickly noticed after getting to my desired location to record some footage that my gimbal was out of level again.  I adjusted it again and soon learned that after any yaw or roll movements that my gimbal was not going back to level and during extended roll movements I could watch the tilt grow more and more!  I landed my Spark and returned to my place where I could do a good IMU calibration and compass calibration as those were some suggestions I found in my initial search.  I then did some motions with the Spark in my hand and found the issue was still happening.  I hunted the Go Fly App for the ability to do the gimbal calibration which some other model DJI Drones appear to have, but had no luck finding it with the Spark.  I posted to Reddit asking for suggestions and was directed to the video by Brian linked to at the beginning of this post.

My Tilted Horizon

Tilted horizon on DJI Spark

Needless to say it worked and wanted to give back and document in writing for those that like to follow written directions. Below you will find the procedure to calibrate the gimbal for a DJI Spark and likely other DJI drones that do not have the option in the DJI App.  I don’t wish this problem on anyone, but if you happen to find yourself with it hopefully this will help.  The DJI Firmware Tools are written in Python which is a high level programming language and can be used on any major operating system such as Windows, Linux, or even Mac.  The instructions below are for Windows but they can easily be adopted for other operating systems.

After The Fix

Level Gimbal on my DJI Spark

What is needed:

Download and Install Python

Download the Python 3.7.0 installation linked above.  Any version of Python 3 should work, but 3.7.0 is documented and linked to for this tutorial.  I chose to install Python with a ‘Custom Installation’ to C:\DJI\python\  and Add Python to environment variables which allows it be ran by just typing ‘python’ in the command line. Python is easy to run because you just type ‘python’ however I used a short path C:\DJI for all of these extractions so that it is easy to navigate to from the command line which we will be doing shortly.

Download & Extract pyserial

The pyserial archive is a .tar.gz file.  This is a tarball archive (.tar extension) with GNU Zip (.gz extension) which is basically a different type of zip archive that Windows does not natively support. Because of this you will need to use 7zip, which is linked above, or another compatible utility to extract the pyserial files. After installing 7zip or another compatible tool just open the pyserial-3.4.tar.gz file.  Because of the way .tar.gz files are archived you will go through a few folder levels before you get to the actual needed content folder.  I extracted the meat and potatoes of pyserial to C:\DJI\pyserial

Download & Extract DJI Firmware Tools

I extracted the DJI Firmware Tools folder dji-firmware-tools-master contents using 7zip to C:\DJI\firmware-tools Make sure you review the file to understand what these tools do and how they operate!

Connect your DJI Spark and Find the COM Port

Place your Spark on a level surface, power it on, and connect via a Micro USB cable to the port beside of your SD Card slot.  There is no need to connect the controller.


To find the COM port your USB connection is using press the Win+X keys (The ‘Win’ key or Windows Key is usually between Ctrl and Alt on the left side of your keyboard with the Windows logo on it) to open the Power Users menu and select Device Manager. Expand the Ports (COM & LPT) section and you should see USB Serial Device (COM#). If there are multiple devices you can disconnect and reconnect the Spark to see which device disappears and reappears.  Note the COM port number because you will need it later.  You can now close the Device Manager.

Find DJI Spark COM Port in Device Manager

Install pyserial

Now we need to open an Administrator Command Prompt or PowerShell Session.  Press Win+X keys to open the Power Users menu and select Command Prompt (Admin) or Windows PowerShell (Admin) and accept the User Account Control warning about making changes to your device.

Once you are in Command Prompt or PowerShell we need to navigate to the pyserial folder we just extracted and install pyserial.  to do this use these commands.  If you extracted to a different folder you will need to substitute that folder in the commands below.

cd c:\DJI\pyserial
python install

Calibrate the Gimbal

Now for the moment of truth!  We need to navigate to the DJI Firmware Tools folder and execute the commands to get our gimbal recalibrated.  Staying in the Administrator Command Prompt or PowerShell session we will now run the following commands to calibrate. The –port specification is new and I have not tested this syntax but it should work.

cd c:\DJI\firmware-tools
python --port com3 -vv SPARK GimbalCalib JointCoarse
python --port com3 -vv SPARK GimbalCalib LinearHall

During each of the the commands your gimbal will bounce around and then hopefully finish with a Summary ending in “result: Pass”.

Test & Fly

Hopefully your calibration was successful.  Disconnect the Micro USB and connect your remote along with your phone or tablet.  Your picture should now be level.  I attempted some motions with the drone in my hand and everything looked good.  Next I preformed my pre-flight check and took it up for a quick test flight to verify everything was working as it should and let out a big sigh of relief.

Special thanks again to Brian Stigall and the kind folks on Reddit who pointed me in the right direction.

View more DJI Batteries on Amazon

Last updated on 2023-05-26 / Affiliate links / Images from Amazon Product Advertising API

Share This Post

More Posts

40 Responses

  1. Do you think this will work for a phantom with a yaw motor swap or gimbal esc swap? The Phantom series usually require you to swap out the casing but if you have to switch the esc board (which is calibrated to the magnets in that yaw motor) it won’t work as only DJI can calibrate the gimbal with the new motor or esc (they have a utility that they will not share since it’s has proprietary information in it) . I currently have a P4 that keeps showing an overload and I think the esc may be the culprit and the calibration option available does not seem to fix the problem I am trying to prevent replacing the entire gimbal.

  2. Hello kevin, thank you for your explanation.
    I could do it with my mac with some changes.
    I used “terminal” for execute the command “python3 install” to install the pyserial.
    In the other hand i type in terminal “ls /dev/tty.*” to establish de name that mac used to my spark.
    Then the command i used in the folder “dji-firmware-tools-master” was “./ /dev/tty.usbmodem2415 -vv SPARK GimbalCalib JointCoarse”. You will have to change the “usbmodem2415” part for your own spark identification.
    The second command is “./ /dev/tty.usbmodem2415 -vv SPARK GimbalCalib LinearHall”. Remember to change the “usbmodem2415” for your own.
    I hope this will helpful.

  3. Hello. Please help, I have a Mac osx system! How does calibration work on a Mac? Can you give me a link to that? thank you very much

    1. Enrique gave these instructions in another comment:

      Hello kevin, thank you for your explanation.
      I could do it with my mac with some changes.
      I used “terminal” for execute the command “python3 install” to install the pyserial.
      In the other hand i type in terminal “ls /dev/tty.*” to establish de name that mac used to my spark.
      Then the command i used in the folder “dji-firmware-tools-master” was “./ /dev/tty.usbmodem2415 -vv SPARK GimbalCalib JointCoarse”. You will have to change the “usbmodem2415” part for your own spark identification.
      The second command is “./ /dev/tty.usbmodem2415 -vv SPARK GimbalCalib LinearHall”. Remember to change the “usbmodem2415” for your own.
      I hope this will helpful.

  4. I did with my Spark Calibration and system show:” Calibration time exceeded; calibration must have ended. Summary: took 22.6 sec; received 233 reports; result:UNSURE”

  5. MAVIC PRO: WM220
    MAVIC 2: WM240
    MAVIC AIR: WM230
    MAVIC AIR 2: WM231
    MATRICE 100: MAT100
    MATRICE 200: MAT200
    MATRICE 600: MAT600
    INSPIRE 1: WM610
    INSPIRE 2: WM620
    AGRAS MG-1: MG1
    SPARK: WM100
    OSMO X3: WM610_FC350*
    OSMO X5: WM610_FC550

  6. Mavic mini does not appear as a USB Serial Port. What could be the reason for this? When I connect the Mavic mini via USB it shows up as WM160 Disk drive. How can I overcome this problem? If I overcome this problem, I will have a chance to try Gimbal Calibration. Thank you.

      1. The mini has a serial mode that has to be manually enabled on each boot. If you plug the mini to your computer and wait a few seconds, it will present itself to the pc as a mass storage drive. Serial mode can be enabled before this mass storage mode is enabled. This can be easily done by sending the GetVersion command with

        It looks like you will have to try what is suggested here to get it to go into serial mode. Looks like it would be easier to do on Linux though.

    1. Hi Alper,
      I have solved this issue by installing DJI assistant 2 for Mavic. This software will install the correct drivers and will allow the Mini to be in Serial COM mode.
      Important: in order for the DJI FIRMWARE TOOLS to be able to communicate with your drone, you will need to quit DJI Assistant after the drone has been successfully connected.

      In the command Prompt I have used WM160 to call the drone.

  7. Thank you very much for sharing this information. With a few filename tweaks it worked perfectly.

    1. Hi Mac,
      I upgraded to the Mavic Air 2 and have not attempted a gimbal replacement. Beyond checking for binding that is limiting gimbal movement and using air duster to make sure nothing is wedged inside of the mechanism I don’t have much for suggestions. Wish I could be of more assistance!

  8. Hi Clin, I tried but i have this answer C:\DJI\dji-firmware-tools-master>python com3 WM160 GimbalCalib JointCoarse

    Info: The Gimbal will move through its boundary positions, then it will fine-tune its central position. It will take around 15 seconds.

    Error: Unrecognized response to calibration command JointCoarse request.

    C:\DJI\dji-firmware-tools-master>python com3 WM160 GimbalCalib LinearHall

    Info: The Gimbal will slowly move through all positions in all axes, several times. It will take around 30 seconds.

    Error: Unrecognized response to calibration command LinearHall request.

    Please can you help me ? thanks

    1. Sorry, I missed this comment when it was originally posted. Unfortunately I no longer have the Spark and have upgraded to an Air 2. From what I can tell the response from the drone to the software was not what was expected. This could be due to a problem in the drone itself or possibly a damaged USB cable. I would also make sure you are using the most recent version of the DJI Firmware tools and the most recent DJI Firmware for the Spark.

  9. Please Help!! I have a mini 2 which I replaced the gimbal after a crash and I can not get this to work! I have watched several youtube videos and tried for several days but I keep getting stuck around the same step. When I connect my mini 2 it does appear in ports (COM & LPT) for a few seconds then it disappears. The only way I am able to get it to show up is if I open DJI Assistant 2 and once it shows up on there I close the program and my mini 2 appears as COM8. Everything works exactly as it is suppose to following these step except once I past the command to calibrate gimbal, ¨python com8 WM160 GimbalCalib JointCoarse ¨ I get this message…

    Finished processing dependencies for pyserial==3.5

    c:\DJI\pyserial>cd c:\DJI\firmware-tools

    c:\DJI\firmware-tools>py com8 WM160 GimbalCalib JointCoarse
    usage: [-h] (–port PORT | –bulk) [-b BAUDRATE]
    [-w TIMEOUT] [–dry-test] [-v] [–version]
    product command … error: argument product: invalid choice: ‘COM8’ (choose from ‘A2’, ‘P330’, ‘P330V’, ‘P330Z’, ‘P330VP’, ‘WM610’, ‘P3X’, ‘P3S’, ‘MAT100’, ‘P3C’, ‘MG1’, ‘WM325’, ‘WM330’, ‘MAT600’, ‘WM220’, ‘WM620’, ‘WM331’, ‘MAT200’, ‘MG1S’, ‘WM332’, ‘WM100’, ‘WM230’, ‘WM335’, ‘WM240’, ‘WM245’, ‘WM246’, ‘WM160’, ‘WM231’, ‘WM232’, ‘WM260’)


    Any insight anyone is able to provide I would GREATLY appreciate it.

  10. Hello. Thank you very much for the tutorial, but I have a problem. When I run python com3 wm100 GimbalCalib JointCoarse I get the error that –port PORT or –BULK is required.
    Can you help me? Thanks

    1. Sorry for the long delay. This was sitting in junk comments. Try this where comX is your com port: --port comX SPARK GimbalCalib JointCoarse --port comX SPARK GimbalCalib LinearHall

  11. Alguna solución a esta respuesta del CMD?
    usage: [-h] (–port PORT | –bulk) [-b BAUDRATE]
    [-w TIMEOUT] [–dry-test] [-v] [–version]
    product command … error: argument product: invalid choice: ‘COM3’ (choose from ‘A2’, ‘P330’, ‘P330V’, ‘P330Z’, ‘P330VP’, ‘WM610’, ‘P3X’, ‘P3S’, ‘MAT100’, ‘P3C’, ‘MG1’, ‘WM325’, ‘WM330’, ‘MAT600’, ‘WM220’, ‘WM620’, ‘WM331’, ‘MAT200’, ‘MG1S’, ‘WM332’, ‘WM100’, ‘WM230’, ‘WM335’, ‘WM240’, ‘WM245’, ‘WM246’, ‘WM160’, ‘WM231’, ‘WM232’, ‘WM260’)

    1. See my edited response and updated post. Apparently they now require you to specify the –port COMX and –vv SPARK. I don’t have a Spark anymore and my other DJI drones are working great so I have no way to test the command syntax.

  12. HI can you help, I have replace gimbal, have done all the Python and pyserial
    when now in dos,
    cd\dji and then run the JoinCoarse command Line, the gimbal goes through the motions, For calibration, but when the LinearHall command is run I have no response at all.
    Can anyone help.

Leave a Reply

Your email address will not be published. Required fields are marked *

Related Content

Microsoft Office 2021

Updating MS Office with Microsoft Endpoint Manager

My apologies that this isn’t really a technical write-up.  I just got really frustrated trying to find answers as to why I was stuck at “Install Pending” and feel like this part of the process is skipped in any existing Microsoft Office Volume documentation.  Of course always setup a deployment test group and verify it is successful there first!

Read More »