news 2026/5/27 19:06:01

我的机械臂动起来了:基于STM32F103和SG90舵机,从接线到代码调试的全记录

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
我的机械臂动起来了:基于STM32F103和SG90舵机,从接线到代码调试的全记录

从零构建二自由度机械臂:STM32F103与SG90舵机的实战指南

1. 项目缘起与核心器件选型

去年夏天,我在清理工作室时偶然发现了几只闲置的SG90舵机。这些橙色外壳的小家伙让我萌生了一个想法:能否用它们搭配手头的STM32F103开发板,打造一个简易的二自由度机械臂?这个看似简单的想法,最终演变成了一场充满挑战与惊喜的嵌入式系统实战之旅。

SG90舵机作为创客圈内的"国民级"执行器件,其核心优势在于:

  • 性价比突出:单价不足20元,却具备位置反馈功能
  • 控制简单:标准50Hz PWM信号即可驱动
  • 扭矩适中:1.5kg·cm扭矩足以支撑小型机械结构

与之配合的STM32F103RCT6开发板,则是嵌入式入门者的经典选择:

主要参数: - ARM Cortex-M3内核 - 72MHz主频 - 16个PWM输出通道 - 丰富的GPIO资源

2. 硬件架构设计与避坑实践

2.1 供电系统的关键细节

初次连接时,我犯了个典型错误——直接使用开发板的USB供电驱动两个舵机。当机械臂试图举起一支马克笔时,舵机突然出现"抽搐"现象。这个教训让我明白:

多舵机系统的供电要点:

  1. 独立电源供电(推荐5V/2A以上)
  2. 共地处理(连接开发板与电源地线)
  3. 加装大容量电容(470μF以上)滤除电压波动

实测发现:当两个舵机同时动作时,瞬时电流可能突破1A。使用示波器观察,电源电压会出现0.8V左右的跌落。

2.2 信号线布局的艺术

PWM信号线看似简单,却暗藏玄机。我的第二次失败是使用30cm长的杜邦线连接舵机,结果出现:

  • 角度控制不精确
  • 偶尔出现异常抖动

优化方案:

// 硬件PWM配置示例(TIM3通道1) void PWM_Init(void) { GPIO_InitTypeDef GPIO_InitStructure; TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure; TIM_OCInitTypeDef TIM_OCInitStructure; RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE); RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE); // GPIOA6配置为复用推挽输出 GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_Init(GPIOA, &GPIO_InitStructure); // 定时器基础配置(50Hz PWM) TIM_TimeBaseStructure.TIM_Period = 19999; // 20ms周期 TIM_TimeBaseStructure.TIM_Prescaler = 71; // 72MHz/(71+1)=1MHz TIM_TimeBaseInit(TIM3, &TIM_TimeBaseStructure); // PWM模式配置 TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1; TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; TIM_OCInitStructure.TIM_Pulse = 1500; // 初始1.5ms脉宽 TIM_OC1Init(TIM3, &TIM_OCInitStructure); TIM_Cmd(TIM3, ENABLE); }

3. 软件控制的核心算法

3.1 角度到脉宽的精确映射

SG90的理论控制范围是0-180°,但实测发现不同舵机存在个体差异。我开发了校准程序:

// 舵机校准函数 void Servo_Calibrate(uint8_t channel) { uint16_t pulse_min = 500; // 0.5ms uint16_t pulse_max = 2500; // 2.5ms for(int angle=0; angle<=180; angle+=10){ uint16_t pulse = pulse_min + (angle * (pulse_max-pulse_min)/180); PWM_SetPulse(channel, pulse); HAL_Delay(500); } }

3.2 运动轨迹规划

直接设置目标角度会导致机械臂动作生硬。通过引入缓动算法,运动变得流畅自然:

// 二次缓动函数 float easeOutQuad(float t) { return t*(2-t); } void SmoothMove(uint8_t channel, float start_angle, float end_angle, uint16_t duration) { uint32_t start_time = HAL_GetTick(); while(HAL_GetTick()-start_time < duration){ float progress = (float)(HAL_GetTick()-start_time)/duration; float current_angle = start_angle + (end_angle-start_angle)*easeOutQuad(progress); PWM_SetAngle(channel, current_angle); HAL_Delay(10); } }

4. 机械结构设计与优化

4.1 3D打印件设计要点

经过三次迭代,我的机械臂结构优化路径如下:

版本特点问题改进
V1单层结构刚性不足增加加强筋
V2全封闭设计散热不良增加通风孔
V3模块化连接拆装不便改用磁吸接口

4.2 配重与力矩平衡

在末端执行器加装摄像头时,发现第二个关节出现"点头"现象。解决方案:

  • 在前臂添加配重块
  • 改用金属齿轮舵机(MG90S)
  • 降低运动速度

5. 人机交互实现

5.1 摇杆控制方案

采用PS2摇杆模块作为输入设备,其ADC值转换为角度:

#define JOYSTICK_DEADZONE 50 uint8_t Joystick_GetAngle(uint16_t adc_val) { if(adc_val < 1024/2 - JOYSTICK_DEADZONE){ return 90 + (adc_val * 90)/(1024/2 - JOYSTICK_DEADZONE); } else if(adc_val > 1024/2 + JOYSTICK_DEADZONE){ return 90 + ((adc_val - 1024/2 - JOYSTICK_DEADZONE) * 90)/(1024/2 - JOYSTICK_DEADZONE); } return 90; // 中位值 }

5.2 手机蓝牙控制

通过HC-05模块实现手机APP控制,协议设计如下:

字节含义
0帧头(0xFF)
1通道号
2角度高字节
3角度低字节
4校验和

6. 进阶技巧与性能提升

6.1 多舵机同步控制

传统顺序控制会导致机械臂动作不连贯。采用定时器中断实现同步:

// 在定时器中断中更新所有通道 void TIM2_IRQHandler(void) { if(TIM_GetITStatus(TIM2, TIM_IT_Update)){ static uint8_t count = 0; if(++count >= 20){ // 50Hz更新 count = 0; for(int i=0; i<SERVO_NUM; i++){ PWM_SetPulse(i, target_pulse[i]); } } TIM_ClearITPendingBit(TIM2, TIM_IT_Update); } }

6.2 负载自适应算法

通过检测电流变化判断是否发生堵转:

#define CURRENT_THRESHOLD 800 // mA void Safety_Check(void) { uint16_t current = ADC_Read(CURRENT_SENSOR_CH); if(current > CURRENT_THRESHOLD){ PWM_DisableAll(); Buzzer_Alert(); } }

在完成这个项目后,最让我惊喜的不是最终成品的机械臂能完成多少动作,而是在解决各种意外问题时积累的实战经验。比如发现用热熔胶固定舵机齿轮能有效消除回程间隙,这个技巧现在已经成为我的秘密武器。嵌入式开发的魅力,往往就藏在这些看似微不足道的细节之中。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/5/27 19:04:14

构建开源LLM记忆层:为AI应用打造持久化外部大脑

1. 项目概述&#xff1a;为什么我们需要一个开源记忆层最近在折腾大语言模型应用时&#xff0c;我遇到了一个挺普遍但又很棘手的问题&#xff1a;如何让AI记住“我”是谁&#xff0c;以及“我们”之前聊过什么。无论是用OpenAI的API&#xff0c;还是部署开源的Llama、ChatGLM&a…

作者头像 李华
网站建设 2026/5/27 19:02:55

想跟上Agent风口,先学平台还是先看认证体系?

面对 AI Agent&#xff08;智能体&#xff09;呈爆发式增长的岗位需求&#xff0c;很多技术人、职场新人甚至大厂架构师都开始有了紧迫感。然而&#xff0c;在真正准备卷入这个新赛道时&#xff0c;大家往往会面临一个非常实际的纠结&#xff1a;“我是应该先注册个平台开始摸索…

作者头像 李华
网站建设 2026/5/27 19:01:04

初次使用Taotoken从注册到成功发出第一个API请求的整体流程体验

&#x1f680; 告别海外账号与网络限制&#xff01;稳定直连全球优质大模型&#xff0c;限时半价接入中。 &#x1f449; 点击领取海量免费额度 初次使用Taotoken从注册到成功发出第一个API请求的整体流程体验 1. 注册与登录 访问 Taotoken 官方网站&#xff0c;点击注册按钮…

作者头像 李华
网站建设 2026/5/27 19:00:13

【ThreadX全家桶】STM32CubeMX+NetX Duo:中断驱动与数据包管理实战

1. 理解ThreadX全家桶与NetX Duo的核心价值 在嵌入式网络开发领域&#xff0c;ThreadX全家桶提供了一套完整的实时操作系统解决方案&#xff0c;其中NetX Duo作为其网络协议栈组件&#xff0c;专门为资源受限的嵌入式设备设计。我第一次接触这个组合是在一个工业网关项目上&…

作者头像 李华