• OpenMV VSCode 扩展发布了,在插件市场直接搜索OpenMV就可以安装
  • 如果有产品硬件故障问题,比如无法开机,论坛很难解决。可以直接找售后维修
  • 发帖子之前,请确认看过所有的视频教程,https://singtown.com/learn/ 和所有的上手教程http://book.openmv.cc/
  • 每一个新的提问,单独发一个新帖子
  • 帖子需要目的,你要做什么?
  • 如果涉及代码,需要报错提示全部代码文本,请注意不要贴代码图片
  • 必看:玩转星瞳论坛了解一下图片上传,代码格式等问题。
  • 我没有pwm输出,是配置有问题吗



    • 我使用openmv h7 plus,固件库4.59,import sensor
      import time
      from pyb import Pin, Timer
      import math

      sensor.reset()
      sensor.set_pixformat(sensor.GRAYSCALE)
      sensor.set_framesize(sensor.QVGA)
      sensor.skip_frames(time=2000)
      clock = time.clock()

      调节曝光和增益

      sensor.set_auto_exposure(False, exposure_us=25000)
      sensor.set_auto_gain(False, gain_db=12)
      sensor.skip_frames(time=2000)

      图像中心坐标

      CENTER_X = 160 # QVGA宽度320的一半
      CENTER_Y = 120 # QVGA高度240的一半

      舵机控制参数

      SERVO_MIN_ANGLE = 0 # 舵机最小角度
      SERVO_MAX_ANGLE = 180 # 舵机最大角度
      SERVO_CENTER_X = 90 # X轴舵机中心角度
      SERVO_CENTER_Y = 90 # Y轴舵机中心角度
      SERVO_SENSITIVITY = 0.5 # 舵机控制灵敏度

      创建舵机控制定时器 (50Hz PWM)

      servo_tim = Timer(4, freq=50) # 50Hz对应20ms周期

      X轴舵机 (水平方向)

      servo_x = servo_tim.channel(1, Timer.PWM, pin=Pin("P7"))
      servo_x.pulse_width_percent(0) # 初始化为0

      Y轴舵机 (垂直方向)

      servo_y = servo_tim.channel(2, Timer.PWM, pin=Pin("P8"))
      servo_y.pulse_width_percent(0) # 初始化为0

      激光笔控制

      laser = Pin('P6', Pin.OUT_PP)
      laser.high()

      def set_servo_angle(servo_channel, angle):
      """设置舵机角度 (0-180度)"""
      # 确保角度在有效范围内
      angle = max(SERVO_MIN_ANGLE, min(SERVO_MAX_ANGLE, angle))

      # 将角度转换为PWM占空比
      # 舵机控制信号:0.5ms (0度) 到 2.5ms (180度) 脉冲宽度
      # 20ms周期(50Hz)下,0.5ms = 2.5% 占空比,2.5ms = 12.5% 占空比
      pulse_width = 0.5 + (angle / 180.0) * 2.0  # 0.5ms - 2.5ms
      duty_cycle = (pulse_width / 20.0) * 100    # 转换为百分比
      
      # 设置PWM占空比
      servo_channel.pulse_width_percent(int(duty_cycle))
      

      初始化舵机到中心位置

      set_servo_angle(servo_x, SERVO_CENTER_X)
      set_servo_angle(servo_y, SERVO_CENTER_Y)
      time.sleep(1) # 给舵机时间移动到初始位置

      PID控制器参数

      kp = 0.1 # 比例系数
      ki = 0.01 # 积分系数
      kd = 0.05 # 微分系数

      PID控制器状态

      prev_error_x = 0
      integral_x = 0
      prev_error_y = 0
      integral_y = 0

      while True:
      clock.tick()
      img = sensor.snapshot().binary([(0,50)])

      # 寻找最大的有效矩形
      rect = None
      rect_max_mag = 0
      for r in img.find_rects(threshold=100000):
          # 过滤掉太小的矩形
          if r.w() < 50 or r.h() < 50:
              continue
      
          # 选择最大的矩形
          if r.magnitude() > rect_max_mag:
              rect = r
              rect_max_mag = r.magnitude()
      
      if not rect:
          print("未检测到矩形")
          # 没有检测到目标时保持当前位置
          continue
      
      # 计算矩形中心点
      cx = rect.x() + rect.w()/2
      cy = rect.y() + rect.h()/2
      
      # 计算与图像中心的偏差
      error_x = cx - CENTER_X
      error_y = cy - CENTER_Y
      
      # PID控制器计算 (X轴)
      integral_x += error_x
      derivative_x = error_x - prev_error_x
      output_x = kp * error_x + ki * integral_x + kd * derivative_x
      prev_error_x = error_x
      
      # PID控制器计算 (Y轴)
      integral_y += error_y
      derivative_y = error_y - prev_error_y
      output_y = kp * error_y + ki * integral_y + kd * derivative_y
      prev_error_y = error_y
      
      # 计算舵机目标角度
      target_angle_x = SERVO_CENTER_X - output_x * SERVO_SENSITIVITY
      target_angle_y = SERVO_CENTER_Y - output_y * SERVO_SENSITIVITY
      
      # 设置舵机角度
      set_servo_angle(servo_x, target_angle_x)
      set_servo_angle(servo_y, target_angle_y)
      
      # 可视化
      img.draw_rectangle(rect.rect(), color=127)
      img.draw_cross(int(cx), int(cy), color=127, size=10)
      img.draw_cross(CENTER_X, CENTER_Y, color=255, size=10)  # 图像中心
      
      # 显示帧率
      print("FPS: %.1f | X: %.1f° | Y: %.1f°" %
            (clock.fps(), target_angle_x, target_angle_y))
      

      这个代码,但是我打电压好像没有pwm输出,接舵机也没有反应,我升级了固件库到4.70,但是还是没有作用,不是很明白,求指教



    • OpenMV有专门的舵机API:https://singtown.com/cn/learn/50541