GPS-guided autonomous lawnmower built on STM32H743VITx using FreeRTOS. The system integrates RTK GPS/IMU navigation, 4G connectivity, remote control (SBUS), and Python telemetry for precision lawn mowing with path tracking.
USER CODE BEGIN/END blocks)UART1 (921600) -> Debug output (DBG_Printf)
UART2 (115200) -> GPS module (GPRMI/GPIMU protocol)
UART3 (115200) -> 4G module (AT commands)
UART4 (100000) -> SBUS remote control (inverted, 9-bit, even parity)
UART5 (921600) -> Python telemetry link (JSON reports)
UART6 (115200) -> Bluetooth module
GPS_GetGPRMI() / GPS_GetGPIMU() for position (ENU) + headingMC_Compute() calculates forward speed + yaw ratePythonLink_ReportControl() sends JSON to Python at 75 HzMotionControl_TaskEntry runs at 75 Hz (13ms period) for real-time controlapp_task polls all modules (GPS, Internet, SBUS, Python) with 5ms semaphore timeoutapp_task via app_trigger_from_isr() for low-latency processingNEVER edit HAL init code outside USER CODE BEGIN/END markers in Core/Src/main.c, stm32h7xx_it.c. Regeneration will overwrite unprotected code. Place user logic in:
- Peripheral init: USER CODE BEGIN 2 (after MX_*_Init())
- Main loop: USER CODE END WHILE
- Custom includes: USER CODE BEGIN Includes
All UART communication uses centralized Uart_Register() + Uart_Init():c Uart_Register(UART_ID_GPS, &huart2); // Bind HAL handle ST_UartInit init = { .m_eRxMode = UART_RX_MODE_DMA, .m_pu8RxBuf = rx_buffer, .m_u32RxBufSize = 256 }; Uart_Init(UART_ID_GPS, &init);
GPS_RecvFsm() state machine recognizes $GPRMI (23 fields: lat/lon/alt, velocity, attitude) and $GPIMU (9 fields: accel, gyro, temp)GPS_GetGPRMI(&gprmi) and check gprmi.m_bValid before using dataGeo_GprmiToENU() converts WGS84 to local ENU (origin at MC_CFG_ORIGIN_LAT_DEG/LON_DEG)FML/motion_path_data.c with ENU (x,y) waypointsFML/motion_config.h (heading_kp, xtrack_kp, lookahead distances)MC_CFG_PWM_CENTER_US = 1500?s) if GPS invalid >200msMC_STAGE_GOTO_START ¡ú MC_STAGE_FOLLOW_PATH ¡ú MC_STAGE_FINISHEDAll runtime config in g_com_map[] (512-entry array) defined in APL/global_param.h:
- Network: IP_0..3, UDP_PORT, TCP_IP_0..3, TCP_PORT
- Device: DEV_ID, VERSION
- Control: RTKCTRL_INDEX, GPS_HZ
Save changes via save_com_map_to_flash() to persist across reboots.
MDK-ARM/STM32H743.uvprojxUSE_HAL_DRIVER, STM32H743xx, _USE_OS_ (FreeRTOS)MDK-ARM/DebugConfig/)MDK-ARM/STM32H743/STM32H743.hexconfigENABLE_FPU = 1) - hardware floating-point acceleration activeuseUlib = 1) - required for printf float supportconfigTOTAL_HEAP_SIZE)main() - likely due to DMA coherency issuesDBG_Init() in app startup)uxTaskGetStackHighWaterMark() reports minimum free stack (already in motion task)g_com_map[MAP_SIGN_INDEX] != 0x55AA (corruption check in IdleTask())FML/NewModule.c/.h with NewModule_Init(), NewModule_Poll()app_main(): Uart_Register(UART_ID_NEW, &huartX)NewModule_Poll() to app_task() main loopUart_Send(UART_ID_NEW, data, len) for TXg_motion_path_xy[] in FML/motion_path_data.c (ENU coordinates in meters)g_motion_path_point_countlookahead_max_m for smoother curves, decrease for tighter followingbase_speed_mps (0.5-2.0 m/s typical for lawn mowing)heading_kp=2.0, heading_kd=0.1; increase Kp if response too slowJSON reports via UART5 (921600 baud):
- Control: {"type":"control","forward":1.2,"turn":0.3,"freq":75.0,...} (75 Hz)
- Pose: {"type":"pose","pos":[10.5,5.2,0.1],"heading":45.0,...} (1 Hz)
- Stack: {"type":"stack","task":"Motion","free":512,...} (0.1 Hz)
ST_CamelCase (structs), E_CamelCase (enums), FN_CamelCase (function pointers)Module_PascalCase() (public), l_camelCase() (static local)m_prefix (struct members), g_prefix (globals), l_prefix (static locals)_prefixName for function arguments.h + .c (even for small modules)Module_Init() called once, Module_Poll() called in main loopHIDO_OK (0) / HIDO_ERR (-1) for success/failure*_valid flags before using GPS/IMU dataFML/GPS_GPRMI_GPIMU_ʵÏÖ˵Ã÷.mdHIDO_ATLite parser)FML/SBUS_ʹÓÃ˵Ã÷.mdHIDOLibrary/Include/Drivers/STM32H7xx_HAL_Driver/Generated for STM32H7 autonomous lawnmower project. Last updated: 2025-11-24