l_x_s_ 2025-07-25 21:12 采纳率: 0%
浏览 8

为什么我输出给电机一个固定的PWM,在上位机上看我的编码器的输出,有时候会突变,电机的输出也是瞬间突变

为什么我输出给电机一个固定的PWM,在上位机上看我的编码器的输出,有时候会突变,会比稳定的时候大两倍,电机的输出也是瞬间突变

  • 写回答

4条回答 默认 最新

  • 檀越@新空间 2025-07-25 21:13
    关注

    晚上好🌙🌙🌙
    本答案参考通义千问

    你提到的问题是:“输出给电机一个固定的PWM,在上位机上看编码器的输出,有时候会突变,甚至比稳定时大两倍,电机的输出也是瞬间突变。”

    这个问题可能由多个原因引起,下面我将详细分析并给出解决方案


    一、问题可能的原因

    1. 编码器信号干扰或采样不稳定
    2. 电机驱动电路存在噪声或电压波动
    3. PWM控制逻辑存在异常(如死区时间不匹配)
    4. 编码器与电机之间的机械连接松动或打滑
    5. 软件处理逻辑错误(如计数器溢出、中断未及时处理等)
    6. 电源不稳定导致电机和编码器工作异常

    二、重点问题分析(加粗部分)

    1. 编码器信号干扰或采样不稳定

    • 现象:编码器输出突变,可能是由于信号线受到电磁干扰(EMI),或者编码器本身质量不佳。
    • 影响:编码器读数不稳定,导致位置反馈错误,进而影响电机控制。

    2. 电机驱动电路存在噪声或电压波动

    • 现象:电机在固定PWM下出现瞬时突变,可能是由于供电不稳定或驱动模块有毛刺。
    • 影响:电机转速不稳定,编码器反馈也出现异常。

    3. PWM控制逻辑存在异常

    • 现象:PWM输出虽然固定,但实际作用到电机上的电压波形可能有畸变。
    • 影响:电机运行不平稳,导致编码器读数突变。

    4. 编码器与电机之间机械连接问题

    • 现象:编码器读数突然跳变,可能是由于机械松动、齿轮打滑或联轴器磨损。
    • 影响:编码器反馈与实际运动不一致,造成控制误差。

    三、解决方案(有序列表)

    1. 检查编码器信号线是否屏蔽良好

    • 建议:使用屏蔽双绞线连接编码器,并确保接地良好。
    • 修改代码示例(仅示例)
      // 如果你在使用GPIO读取编码器信号,请确保配置正确
      GPIO_InitTypeDef GPIO_InitStruct;
      GPIO_InitStruct.Pin = ENCODER_A_PIN | ENCODER_B_PIN;
      GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
      GPIO_InitStruct.Pull = GPIO_NOPULL;  // 不使用内部上拉/下拉
      HAL_GPIO_Init(ENCODER_PORT, &GPIO_InitStruct);
      

    2. 增加编码器滤波逻辑

    • 建议:在软件中加入滤波算法(如滑动平均、中值滤波等)以消除误触发。
    • 修改代码示例
      int16_t encoder_values[10];  // 缓冲区
      int index = 0;
      
      void update_encoder() {
          encoder_values[index] = read_encoder();
          index = (index + 1) % 10;
          int sum = 0;
          for (int i = 0; i < 10; i++) {
              sum += encoder_values[i];
          }
          filtered_value = sum / 10;
      }
      

    3. 检查电机驱动板供电稳定性

    • 建议:使用稳压电源,并在驱动板附近增加电容(如100μF电解电容)来滤波。
    • 硬件建议:检查驱动板是否有烧毁、电容鼓包等现象。

    4. 检查PWM输出波形是否正常

    • 建议:使用示波器查看PWM波形是否失真,尤其是高/低电平是否稳定。
    • 代码示例(STM32)
      // 设置PWM频率和占空比
      TIM_OCInitTypeDef TIM_OCStruct;
      TIM_OCStruct.TIM_OCMode = TIM_OCMode_PWM1;
      TIM_OCStruct.TIM_OutputState = TIM_OutputState_Enable;
      TIM_OCStruct.TIM_Pulse = PWM_VALUE;  // 固定值
      TIM_OCStruct.TIM_OCPolarity = TIM_OCPolarity_High;
      TIM_OC1Init(TIM3, &TIM_OCStruct);
      TIM_OC1PreloadConfig(TIM3, TIM_OCPreload_Enable);
      

    5. 检查机械连接是否牢固

    • 建议:检查编码器与电机轴的连接是否松动,是否存在打滑或磨损。
    • 工具建议:使用百分表检测电机轴的径向跳动。

    6. 增加软件防抖机制

    • 建议:在编码器读数变化超过一定阈值时进行过滤。
    • 代码示例
      #define THRESHOLD 5
      
      int16_t last_encoder = 0;
      int16_t current_encoder = 0;
      
      if (abs(current_encoder - last_encoder) > THRESHOLD) {
          // 说明有突变,忽略该值
          current_encoder = last_encoder;
      } else {
          last_encoder = current_encoder;
      }
      

    四、总结

    | 问题点 | 解决方案 | |--------|----------| | 编码器信号干扰 | 使用屏蔽线,增加滤波 | | 电机驱动不稳定 | 稳压电源,增加去耦电容 | | PWM波形异常 | 检查PWM配置,使用示波器验证 | | 机械连接松动 | 检查并紧固连接部件 | | 软件逻辑错误 | 加入滤波和防抖机制 |


    如果你能提供具体的代码片段硬件平台信息(如使用的是STM32、Arduino、ESP32等),我可以进一步帮你定位具体问题。

    评论

报告相同问题?

问题事件

  • 创建了问题 7月25日