从玩具到智能硬件:手把手教你用STM32和SG90舵机DIY一个Wi-Fi遥控的智能小风扇
从玩具到智能硬件用STM32和SG90舵机打造Wi-Fi遥控智能风扇项目构思与硬件选型去年夏天我在书房工作时总被固定角度的桌面风扇困扰——要么风力太集中容易着凉要么角度不对完全吹不到。这让我萌生了制作一个能远程控制摆头角度的智能风扇的想法。经过多次迭代最终确定了以STM32为主控、SG90舵机为执行机构、ESP8266实现无线控制的方案。核心硬件选型考量组件型号关键参数选型原因主控芯片STM32F103C8T6ARM Cortex-M3, 72MHz性价比高PWM资源丰富舵机SG904.8V供电, 1.2kg·cm扭矩体积小适合小负载场景WiFi模块ESP-01S802.11 b/g/n成本低AT指令易用特别要注意SG90的供电问题实测发现USB供电5V/0.5A时舵机容易出现抖动改用独立5V/2A电源后运行稳定。这是因为舵机在启动瞬间电流可能达到500mA而STM32开发板的稳压芯片通常无法提供如此大的瞬时电流。硬件连接与PWM控制完整的接线方案如下STM32F103C8T6 ↔ 外围设备 ├── PA9(TX) → ESP-01S RX ├── PA10(RX) ← ESP-01S TX ├── PB6(TIM4_CH1)→ SG90信号线(橙色) ├── 5V → SG90电源线(红色) └── GND → SG90地线(棕色) ESP-01S GNDSG90的控制脉冲时序非常关键经过实测得出以下参数对照表脉冲宽度(ms)对应角度占空比(20ms周期)0.50°2.5%1.045°5.0%1.590°7.5%2.0135°10.0%2.5180°12.5%对应的STM32 PWM初始化代码void PWM_Init(void) { GPIO_InitTypeDef GPIO_InitStruct; TIM_TimeBaseInitTypeDef TIM_TimeBaseStruct; TIM_OCInitTypeDef TIM_OCInitStruct; // 使能时钟 RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM4, ENABLE); RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE); // 配置PB6为复用推挽输出 GPIO_InitStruct.GPIO_Pin GPIO_Pin_6; GPIO_InitStruct.GPIO_Mode GPIO_Mode_AF_PP; GPIO_InitStruct.GPIO_Speed GPIO_Speed_50MHz; GPIO_Init(GPIOB, GPIO_InitStruct); // 定时器基础配置 TIM_TimeBaseStruct.TIM_Period 199; // 自动重装载值 TIM_TimeBaseStruct.TIM_Prescaler 7199; // 预分频 TIM_TimeBaseStruct.TIM_ClockDivision 0; TIM_TimeBaseStruct.TIM_CounterMode TIM_CounterMode_Up; TIM_TimeBaseInit(TIM4, TIM_TimeBaseStruct); // PWM模式配置 TIM_OCInitStruct.TIM_OCMode TIM_OCMode_PWM1; TIM_OCInitStruct.TIM_OutputState TIM_OutputState_Enable; TIM_OCInitStruct.TIM_OCPolarity TIM_OCPolarity_High; TIM_OC1Init(TIM4, TIM_OCInitStruct); TIM_Cmd(TIM4, ENABLE); }调试技巧如果舵机出现异常抖动可以先断开机械负载用示波器检查PWM信号是否稳定。常见问题包括电源干扰、地线环路或PWM周期不准确。WiFi通信协议设计ESP-01S模块通过AT指令与STM32交互我设计了一套简单的文本协议指令格式: 命令:参数\r\n 示例: SET:90\r\n - 设置舵机到90度位置 GET:POS\r\n - 查询当前角度 SPEED:50\r\n - 设置转动速度(0-100)STM32端的串口中断处理逻辑void USART1_IRQHandler(void) { if(USART_GetITStatus(USART1, USART_IT_RXNE) ! RESET) { char ch USART_ReceiveData(USART1); if(ch \n) { process_command(buffer); buffer_index 0; memset(buffer, 0, sizeof(buffer)); } else if(buffer_index BUF_SIZE-1) { buffer[buffer_index] ch; } } }实际测试发现直接发送AT指令时容易出现响应超时。解决方法是在每次发送指令后添加100ms延时并实现重试机制int send_at_command(const char* cmd, char* resp, uint32_t timeout) { USART_SendString(USART1, cmd); uint32_t start get_tick(); while(get_tick() - start timeout) { if(USART_GetFlagStatus(USART1, USART_FLAG_RXNE)) { *resp USART_ReceiveData(USART1); } } *resp \0; return strstr(resp, OK) ! NULL; }系统集成与优化将风扇叶片安装在舵机上时发现两个关键问题叶片重量导致舵机在45°位置出现点头现象快速转动时电流激增引发电源电压跌落解决方案采用了软硬件结合的方式硬件改进在舵机电源端并联470μF电解电容使用3D打印的轻量化叶片支架PLA材料增加限位结构防止机械过载软件优化void smooth_move(uint8_t target_angle) { uint8_t current get_current_angle(); uint8_t step (target_angle current) ? 1 : -1; while(current ! target_angle) { current step; set_servo_angle(current); delay_ms(20); // 控制转动速度 // 在接近目标时减速 if(abs(current - target_angle) 10) { delay_ms(30); } } }最终成品的控制界面采用简约设计通过手机浏览器即可访问网页控制界面功能 1. 角度滑块0-180°实时调节 2. 预设按钮60°/90°/120°快速定位 3. 风速调节控制风扇电机PWM 4. 自动模式开关周期性左右扫风实测整机工作电流静态120mAWiFi模块待机舵机转动峰值450mA风扇全速300mA 建议使用5V/2A以上的电源适配器以保证稳定运行。