This project was completed as part of the Freefly Movi Inertial Control API Test Challenge, which involved creating an embedded C program for an ARM Cortex-M4F microcontroller to control a Freefly gimbal using inertial data.
The hardware provided included:
Freefly Movi Cinema Robot
STM32F3 Discovery Board with onboard 3-axis gyroscope (L3GD20) and accelerometer (LSM303DLHC)
UART Communication Cable for interfacing with the gimbal
Required USB cables for programming and charging
The control logic was implemented on the STM32F3 Discovery, reading accelerometer and gyroscope data, calculating Tilt and Roll, and sending absolute position commands to the gimbal using the Freefly QX Protocol.
The challenge required:
Developing embedded firmware using Keil uVision IDE
Implementing sensor data acquisition from onboard IMU (I2C/SPI)
Sending gimbal control commands over 3.3V UART at 111,111 baud
Supporting single-axis or multi-axis control
Demonstrating functionality in a short video
The final implementation:
Reliably reads and filters IMU data
Sends stable gimbal control commands via UART
Maintains smooth motion while respecting hardware safety limits
Fully integrates into the provided Keil project structure
MCU: STM32F3-Discovery (ARM Cortex-M4F)
Toolchain: Keil uVision IDE
Protocol: Freefly QX Protocol (FreeflyAPI)
Sensors: L3GD20 Gyroscope, LSM303DLHC Accelerometer
Language: Embedded C
I extended the provided Keil MDK project by:
Reading IMU Data
Used STM32 HAL drivers to acquire accelerometer and gyroscope readings.
Verified axis alignment using Keil debugger watch window during manual board movements.
Angle Computation & Filtering
Calculated Tilt and Roll using trigonometric relations (atan2).
Applied a low-pass filter to reduce noise while maintaining responsiveness.
Stable Control Loop
Set control frequency to 50 Hz for smoother gimbal response (100 Hz caused vibration issues).
Command Transmission
Sent FreeflyAPI ABSOLUTE control type packets over UART (PC4 RX, PC5 TX).
Safety Limits
Added clamping (Tilt ±55°, Roll +110°/-90°) to avoid mechanical overdrive.
Gyroscope Not Initializing:
Corrected the I_AM_L3GD20 device ID from 0xD4 to 0xD3 in l3gd20.h.
Noisy Sensor Data:
Implemented tuned low-pass filter.
Control Loop Oscillations:
Reduced update rate from 100 Hz to 50 Hz.
Axis Mapping Confusion:
Verified via debug watch window.
Motor Strain from Excessive Commands:
Implemented clamping logic.