• 免费好用的星瞳AI云服务上线!简单标注,云端训练,支持OpenMV H7和OpenMV H7 Plus。可以替代edge impulse。 https://forum.singtown.com/topic/9519
  • 我们只解决官方正版的OpenMV的问题(STM32),其他的分支有很多兼容问题,我们无法解决。
  • 如果有产品硬件故障问题,比如无法开机,论坛很难解决。可以直接找售后维修
  • 发帖子之前,请确认看过所有的视频教程,https://singtown.com/learn/ 和所有的上手教程http://book.openmv.cc/
  • 每一个新的提问,单独发一个新帖子
  • 帖子需要目的,你要做什么?
  • 如果涉及代码,需要报错提示全部代码文本,请注意不要贴代码图片
  • 必看:玩转星瞳论坛了解一下图片上传,代码格式等问题。
  • 一直弹框错误怎么办:MemoryError:Out of fast Frame Buffer Stack Memory!



    • 0_1576119388800_微信图片_20191212105437.jpg
      经常弹这个错误,定位到find apriltags的位置。
      最初弹这个错误比较少,现在越来越频繁,周期越来越短。
      程序如下:

      ## 一次设置,导入模块 ##
      THRESHOLD = ( 37, 100, -29, 105, 15, 97)  # 设置巡回路线的阈值
      import sensor, image, time, pyb, math     # 调用传感器,图像,时间
      from pyb import Pin, Timer, ExtInt        # 导入引脚
      
      sensor.reset()
      sensor.set_vflip(True)               # 设置图像垂直方向翻转
      sensor.set_hmirror(True)             # 设置图像水平方向翻转
      sensor.set_pixformat(sensor.RGB565)  # 设置为彩图
      sensor.set_framesize(sensor.QQQVGA)  # 设置像素80x60 (4,800 pixels) - O(N^2) max = 2,3040,000.
      sensor.skip_frames(time = 2000)      # WARNING: If you use QQVGA it may take seconds
      
      sensor.set_auto_gain(False)          # must turn this off to prevent image washout...
      sensor.set_auto_whitebal(False)      # must turn this off to prevent image washout...
      tag_families = 0
      tag_families |= image.TAG16H5        # comment out to disable this family
      callback = lambda e: print("intr")
      #ext = ExtInt(Pin('P8'), ExtInt.IRQ_RISING, Pin.PULL_NONE, callback)
      clock = time.clock()                 # to process a frame sometimes.
      
      ain0 =  Pin('P0', Pin.OUT_PP)        # 伸缩杆收回右转
      ain1 =  Pin('P1', Pin.OUT_PP)        # 伸缩杆伸出左转
      ain2 =  Pin('P2', Pin.OUT_PP)
      ain3 =  Pin('P3', Pin.OUT_PP)
      ain4 =  Pin('P4', Pin.OUT_PP)
      ain5 =  Pin('P5', Pin.OUT_PP)
      pin6_in = pyb.Pin('P6', pyb.Pin.IN, pyb.Pin.PULL_DOWN)  #备用
      pin7_in = pyb.Pin('P7', pyb.Pin.IN, pyb.Pin.PULL_DOWN)  #方向推杆原点位置左侧传感器,原点处时为on
      pin8_in = pyb.Pin('P8', pyb.Pin.IN, pyb.Pin.PULL_DOWN)  #备用
      pin9_in = pyb.Pin('P9', pyb.Pin.IN, pyb.Pin.PULL_DOWN)  #方向推杆原点位置右侧传感器,原点处时为off
      ain1.low()  #引脚初始化为低电平
      ain2.low()  #引脚初始化为低电平
      h=0   #用于拐弯计数
      z=1   #运行流程标志位,z=1 初始化,z=2 正常运行,z=0 停止运行
      a=0   #存放调用子程序的序号标志位
      m=0   #存放转弯进行中的标志
      #--------------------------------------方向推杆初始化------
      while(z==1):      #初始化
          if pin7_in.value()==True and pin9_in.value()==True:      # 如果推杆维持右转状态,伸出推杆,回归到原点
              ain0.low()
              ain1.high()
          elif pin7_in.value()==False and pin9_in.value()==False:  # 如果推杆维持左转状态,收回推杆,回归到原点
              ain1.low()
              ain0.high()
          elif pin7_in.value()==True and pin9_in.value()==False:   # 如果推杆到原点,保持推杆位置,开始运行主程序
              ain0.low()          # 收回右转
              ain1.low()          # 伸出左转
              z=2
          else:
              ain0.low()
              ain1.low()
      #------------------------------------方向初始化完成--------
      while(z==2):     #正常运行
          clock.tick()               #关闭白平衡
          img = sensor.snapshot()    #截取图像
          for tag in img.find_apriltags(families=tag_families):  #识别apriltages标志,用于拐弯
              if m==0:
                   h=h+1             #Apriltag计数--用于拐弯
                   m=1
              elif m==1:             #直行拐弯前方向恢复原位
                   if  pin7_in.value()==False and pin9_in.value()==False:
                        ain1.low()          # 伸出左转
                        ain0.high()         # 收回右转
                   elif pin7_in.value()==True and pin9_in.value()==True:
                        ain0.low()          # 收回右转
                        ain1.high()         # 伸出左转
                   elif pin7_in.value()==True and pin9_in.value()==False:
                        ain0.low()          # 收回右转
                        ain1.low()          # 伸出左转
                        m=2
                   else:
                        ain0.low()
                        ain1.low()
              elif m==2:
                   if h==1 or h==3:
                        ain1.low()          # 伸出左转
                        ain0.high()         # 收回右转
                        pyb.delay(1700)
                        ain1.low()          # 伸出左转
                        ain0.low()          # 收回右转
                        pyb.delay(15000)
                        while(m==2):
                             if  pin7_in.value()==False and pin9_in.value()==False:
                                  ain1.low()          # 伸出左转
                                  ain0.high()         # 收回右转
                             elif pin7_in.value()==True and pin9_in.value()==True:
                                  ain0.low()          # 收回右转
                                  ain1.high()         # 伸出左转
                             elif pin7_in.value()==True and pin9_in.value()==False:
                                  ain0.low()          # 收回右转
                                  ain1.low()          # 伸出左转
                                  m=0
                                  break
                             else:
                                  ain0.low()
                                  ain1.low()
                   elif h==2:
                        ain1.low()          # 伸出左转
                        ain0.high()         # 收回右转
                        pyb.delay(2100)
                        ain1.low()          # 伸出左转
                        ain0.low()          # 收回右转
                        pyb.delay(14000)
                        while(m==2):
                             if  pin7_in.value()==False and pin9_in.value()==False:
                                  ain1.low()          # 伸出左转
                                  ain0.high()         # 收回右转
                             elif pin7_in.value()==True and pin9_in.value()==True:
                                  ain0.low()          # 收回右转
                                  ain1.high()         # 伸出左转
                             elif pin7_in.value()==True and pin9_in.value()==False:
                                  ain0.low()          # 收回右转
                                  ain1.low()          # 伸出左转
                                  m=0
                                  break
                             else:
                                  ain0.low()
                                  ain1.low()
                   else:h=0
          img = sensor.snapshot().binary([THRESHOLD])  # 截取一张图片,进行阈值分割,THRESHOLD为阈值,binary图像二值化
          line = img.get_regression([(100,100,0,0,0,0)], robust = True)  # 使用线性回归方法,反馈得到一条直线
          if h==0 or h==3:
              aim_width= 60             # 目标位置的偏移距离,距离目标线较近的路线上
              aim_theta= 0
          elif h==1 or h==2:
              aim_width= 23             # 目标位置的偏移距离,距离目标线较远的线路上
              aim_theta= 5
          else:
              aim_width= 0
              aim_theta = 0
          if (line and m==0):
              if line.theta()>90:                            # 直线的角度
                   theta_err = line.theta()-180
              else:
                   theta_err = line.theta()
              img.draw_line(line.line(), color = 127)        # line.line()返回一个直线元组(x1, y1, x2, y2)
              rho_err = abs(line.rho())-aim_width            # line.rho()返回直线p值;计算直线与目标位置的偏移距离
              aimtheta_dif= theta_err - aim_theta            #与目标角度的角度差
              print("行驶路线标号:",h,rho_err,aimtheta_dif)    #输出行驶路线标号:(0:最左;1:二左;2:二左;3:最右),偏移距离,偏移角度
              if h==0 or h==3:
                   rho_err_min = 3                           # 设定近距离范围
                   rho_err_max1 = 4                          # 向左最大偏移距离
                   rho_err_max2 = -4                         # 向右最大偏移距离
                   rho_err_maxx1 = 6                         # 向左急转偏移距离
                   rho_err_maxx2 = -6                        # 向右急转偏移距离
              elif h==1 or h==2:
                   rho_err_min = 2                           # 设定近距离范围
                   rho_err_max1 = 3                          # 向左最大偏移距离
                   rho_err_max2 = -3                         # 向右最大偏移距离
                   rho_err_maxx1 = 5                         # 向左急转偏移距离
                   rho_err_maxx2 = -5                        # 向右急转偏移距离
              else:
                   rho_err_min = 0                           # 设定近距离范围
                   rho_err_max1 = 0                          # 向左最大偏移距离
                   rho_err_max2 = 0                          # 向右最大偏移距离
                   rho_err_maxx1 = 0                         # 向左急转偏移距离
                   rho_err_maxx2 = 0                         # 向右急转偏移距离
      
              if abs(rho_err) <= rho_err_min and abs(aimtheta_dif) >=4:
                   if a==0:                                  # a=0没有调向其他子程序
                        theta_err_mid=(theta_err + aim_theta)/2        # 实际角度与目标角度的中间值,用作动作回位参考
                        if theta_err> aim_theta:
                             a=1                             # a=1近距离方向左偏,调用右转程序
                        elif theta_err< aim_theta:
                             a=2                             # a=2近距离方向右偏,调用左转程序
              elif rho_err > rho_err_max1 and rho_err < rho_err_maxx1 and aimtheta_dif >= -4: # 在目标线路左侧,角度偏移大于-4,呈远离趋势,调用右转程序
                   if a==0:
                        theta_err_mid=(theta_err + aim_theta-12)/2     # 目标角度-12度
                        a=1
              elif rho_err < rho_err_max2 and rho_err > rho_err_maxx2 and aimtheta_dif <= 4:  # 在目标线路右侧,角度偏移小于4,呈远离趋势,调用左转程序
                   if a==0:
                        theta_err_mid=(theta_err + aim_theta+12)/2     # 目标角度12度
                        a=2
              elif rho_err >= rho_err_maxx1 and aimtheta_dif >= -15:   # 在目标线路左侧极限距离外,右转,靠近中心线
                   if a==0:
                        theta_err_mid=(theta_err + aim_theta-20)/2     # 目标角度为-20
                        a=1
              elif rho_err <= rho_err_maxx2 and aimtheta_dif <= 15:    # 在目标线路右侧极限距离外,左转,靠近中心线
                   if a==0:
                        theta_err_mid=(theta_err + aim_theta+20)/2     # 目标角度为20
                        a=2
              if(a==1):                      # 右转子程序------------------------------------
                   if theta_err >theta_err_mid:
                        ain1.low()               # 伸出左转
                        ain0.high()              # 收回右转
                   elif (theta_err <=theta_err_mid):
                        if  pin7_in.value()==False and pin9_in.value()==False:
                             ain1.low()          # 收回右转
                             ain0.high()         # 伸出左转
                        elif pin7_in.value()==True and pin9_in.value()==True:
                             ain0.low()          # 收回右转
                             ain1.high()         # 伸出左转
                        elif pin7_in.value()==True and pin9_in.value()==False:
                             ain0.low()          # 收回右转
                             ain1.low()          # 伸出左转
                             a=0
                        else:
                             ain0.low()
                             ain1.low()
              if(a==2):                      # 左转子程序------------------------------------
                   if theta_err <theta_err_mid:
                        ain0.low()               # 收回右转
                        ain1.high()              # 伸出左转
                   elif (theta_err >=theta_err_mid):
                        if  pin7_in.value()==False and pin9_in.value()==False:
                             ain1.low()          # 收回右转
                             ain0.high()         # 伸出左转
                        elif pin7_in.value()==True and pin9_in.value()==True:
                             ain0.low()          # 收回右转
                             ain1.high()         # 伸出左转
                        elif pin7_in.value()==True and pin9_in.value()==False:
                             ain0.low()          # 收回右转
                             ain1.low()          # 伸出左转
                             a=0
                        else:
                             ain0.low()
                             ain1.low()
      
      


    • 你的代码需要外部硬件操作,我没办法运行测试,请给我一个方便测试的代码。



    • This post is deleted!


    • @kidswong999 这段程序拷进去,不需要硬件支持,等一段时间就会弹错误窗口。
      不过最初用这个程序没有问题,现在每次都会弹错误窗口。

      ## 一次设置,导入模块 ##
      THRESHOLD = ( 37, 100, -29, 105, 15, 97)  # 设置巡回路线的阈值
      import sensor, image, time, pyb, math     # 调用传感器,图像,时间
      from pyb import Pin, Timer, ExtInt        # 导入引脚
      
      sensor.reset()
      sensor.set_vflip(True)               # 设置图像垂直方向翻转
      sensor.set_hmirror(True)             # 设置图像水平方向翻转
      sensor.set_pixformat(sensor.RGB565)  # 设置为彩图
      sensor.set_framesize(sensor.QQQVGA)  # 设置像素80x60 (4,800 pixels) - O(N^2) max = 2,3040,000.
      sensor.skip_frames(time = 2000)      # WARNING: If you use QQVGA it may take seconds
      
      sensor.set_auto_gain(False)          # must turn this off to prevent image washout...
      sensor.set_auto_whitebal(False)      # must turn this off to prevent image washout...
      tag_families = 0
      tag_families |= image.TAG16H5        # comment out to disable this family
      callback = lambda e: print("intr")
      #ext = ExtInt(Pin('P8'), ExtInt.IRQ_RISING, Pin.PULL_NONE, callback)
      clock = time.clock()                 # to process a frame sometimes.
      
      ain0 =  Pin('P0', Pin.OUT_PP)        # 伸缩杆收回右转
      ain1 =  Pin('P1', Pin.OUT_PP)        # 伸缩杆伸出左转
      ain2 =  Pin('P2', Pin.OUT_PP)
      ain3 =  Pin('P3', Pin.OUT_PP)
      ain4 =  Pin('P4', Pin.OUT_PP)
      ain5 =  Pin('P5', Pin.OUT_PP)
      pin6_in = pyb.Pin('P6', pyb.Pin.IN, pyb.Pin.PULL_DOWN)  #备用
      pin7_in = pyb.Pin('P7', pyb.Pin.IN, pyb.Pin.PULL_DOWN)  #方向推杆原点位置左侧传感器,原点处时为on
      pin8_in = pyb.Pin('P8', pyb.Pin.IN, pyb.Pin.PULL_DOWN)  #备用
      pin9_in = pyb.Pin('P9', pyb.Pin.IN, pyb.Pin.PULL_DOWN)  #方向推杆原点位置右侧传感器,原点处时为off
      ain1.low()  #引脚初始化为低电平
      ain2.low()  #引脚初始化为低电平
      h=0   #用于拐弯计数
      z=1   #运行流程标志位,z=1 初始化,z=2 正常运行,z=0 停止运行
      a=0   #存放调用子程序的序号标志位
      m=0   #存放转弯进行中的标志
      #--------------------------------------方向推杆初始化------
      while(z==1):      #初始化
          if pin7_in.value()==True and pin9_in.value()==True:      # 如果推杆维持右转状态,伸出推杆,回归到原点
              ain0.low()
              ain1.high()
              z=2
          elif pin7_in.value()==False and pin9_in.value()==False:  # 如果推杆维持左转状态,收回推杆,回归到原点
              ain1.low()
              ain0.high()
              z=2
          elif pin7_in.value()==True and pin9_in.value()==False:   # 如果推杆到原点,保持推杆位置,开始运行主程序
              ain0.low()          # 收回右转
              ain1.low()          # 伸出左转
              z=2
          else:
              ain0.low()
              ain1.low()
              z=2
      #------------------------------------方向初始化完成--------
      while(z==2):     #正常运行
          clock.tick()               #关闭白平衡
          img = sensor.snapshot()    #截取图像
          for tag in img.find_apriltags(families=tag_families):  #识别apriltages标志,用于拐弯
              if m==0:
                   h=h+1             #Apriltag计数--用于拐弯
                   m=1
              elif m==1:             #直行拐弯前方向恢复原位
                   if  pin7_in.value()==False and pin9_in.value()==False:
                        ain1.low()          # 伸出左转
                        ain0.high()         # 收回右转
                   elif pin7_in.value()==True and pin9_in.value()==True:
                        ain0.low()          # 收回右转
                        ain1.high()         # 伸出左转
                   elif pin7_in.value()==True and pin9_in.value()==False:
                        ain0.low()          # 收回右转
                        ain1.low()          # 伸出左转
                        m=2
                   else:
                        ain0.low()
                        ain1.low()
              elif m==2:
                   if h==1 or h==3:
                        ain1.low()          # 伸出左转
                        ain0.high()         # 收回右转
                        pyb.delay(1700)
                        ain1.low()          # 伸出左转
                        ain0.low()          # 收回右转
                        pyb.delay(15000)
                        while(m==2):
                             if  pin7_in.value()==False and pin9_in.value()==False:
                                  ain1.low()          # 伸出左转
                                  ain0.high()         # 收回右转
                             elif pin7_in.value()==True and pin9_in.value()==True:
                                  ain0.low()          # 收回右转
                                  ain1.high()         # 伸出左转
                             elif pin7_in.value()==True and pin9_in.value()==False:
                                  ain0.low()          # 收回右转
                                  ain1.low()          # 伸出左转
                                  m=0
                                  break
                             else:
                                  ain0.low()
                                  ain1.low()
                   elif h==2:
                        ain1.low()          # 伸出左转
                        ain0.high()         # 收回右转
                        pyb.delay(2100)
                        ain1.low()          # 伸出左转
                        ain0.low()          # 收回右转
                        pyb.delay(14000)
                        while(m==2):
                             if  pin7_in.value()==False and pin9_in.value()==False:
                                  ain1.low()          # 伸出左转
                                  ain0.high()         # 收回右转
                             elif pin7_in.value()==True and pin9_in.value()==True:
                                  ain0.low()          # 收回右转
                                  ain1.high()         # 伸出左转
                             elif pin7_in.value()==True and pin9_in.value()==False:
                                  ain0.low()          # 收回右转
                                  ain1.low()          # 伸出左转
                                  m=0
                                  break
                             else:
                                  ain0.low()
                                  ain1.low()
                   else:h=0
          img = sensor.snapshot().binary([THRESHOLD])  # 截取一张图片,进行阈值分割,THRESHOLD为阈值,binary图像二值化
          line = img.get_regression([(100,100,0,0,0,0)], robust = True)  # 使用线性回归方法,反馈得到一条直线
          if h==0 or h==3:
              aim_width= 60             # 目标位置的偏移距离,距离目标线较近的路线上
              aim_theta= 0
          elif h==1 or h==2:
              aim_width= 23             # 目标位置的偏移距离,距离目标线较远的线路上
              aim_theta= 5
          else:
              aim_width= 0
              aim_theta = 0
          if (line and m==0):
              if line.theta()>90:                            # 直线的角度
                   theta_err = line.theta()-180
              else:
                   theta_err = line.theta()
              img.draw_line(line.line(), color = 127)        # line.line()返回一个直线元组(x1, y1, x2, y2)
              rho_err = abs(line.rho())-aim_width            # line.rho()返回直线p值;计算直线与目标位置的偏移距离
              aimtheta_dif= theta_err - aim_theta            #与目标角度的角度差
              print("行驶路线标号:",h,rho_err,aimtheta_dif)    #输出行驶路线标号:(0:最左;1:二左;2:二左;3:最右),偏移距离,偏移角度
              if h==0 or h==3:
                   rho_err_min = 3                           # 设定近距离范围
                   rho_err_max1 = 4                          # 向左最大偏移距离
                   rho_err_max2 = -4                         # 向右最大偏移距离
                   rho_err_maxx1 = 6                         # 向左急转偏移距离
                   rho_err_maxx2 = -6                        # 向右急转偏移距离
              elif h==1 or h==2:
                   rho_err_min = 2                           # 设定近距离范围
                   rho_err_max1 = 3                          # 向左最大偏移距离
                   rho_err_max2 = -3                         # 向右最大偏移距离
                   rho_err_maxx1 = 5                         # 向左急转偏移距离
                   rho_err_maxx2 = -5                        # 向右急转偏移距离
              else:
                   rho_err_min = 0                           # 设定近距离范围
                   rho_err_max1 = 0                          # 向左最大偏移距离
                   rho_err_max2 = 0                          # 向右最大偏移距离
                   rho_err_maxx1 = 0                         # 向左急转偏移距离
                   rho_err_maxx2 = 0                         # 向右急转偏移距离
      
              if abs(rho_err) <= rho_err_min and abs(aimtheta_dif) >=4:
                   if a==0:                                  # a=0没有调向其他子程序
                        theta_err_mid=(theta_err + aim_theta)/2        # 实际角度与目标角度的中间值,用作动作回位参考
                        if theta_err> aim_theta:
                             a=1                             # a=1近距离方向左偏,调用右转程序
                        elif theta_err< aim_theta:
                             a=2                             # a=2近距离方向右偏,调用左转程序
              elif rho_err > rho_err_max1 and rho_err < rho_err_maxx1 and aimtheta_dif >= -4: # 在目标线路左侧,角度偏移大于-4,呈远离趋势,调用右转程序
                   if a==0:
                        theta_err_mid=(theta_err + aim_theta-12)/2     # 目标角度-12度
                        a=1
              elif rho_err < rho_err_max2 and rho_err > rho_err_maxx2 and aimtheta_dif <= 4:  # 在目标线路右侧,角度偏移小于4,呈远离趋势,调用左转程序
                   if a==0:
                        theta_err_mid=(theta_err + aim_theta+12)/2     # 目标角度12度
                        a=2
              elif rho_err >= rho_err_maxx1 and aimtheta_dif >= -15:   # 在目标线路左侧极限距离外,右转,靠近中心线
                   if a==0:
                        theta_err_mid=(theta_err + aim_theta-20)/2     # 目标角度为-20
                        a=1
              elif rho_err <= rho_err_maxx2 and aimtheta_dif <= 15:    # 在目标线路右侧极限距离外,左转,靠近中心线
                   if a==0:
                        theta_err_mid=(theta_err + aim_theta+20)/2     # 目标角度为20
                        a=2
              if(a==1):                      # 右转子程序------------------------------------
                   if theta_err >theta_err_mid:
                        ain1.low()               # 伸出左转
                        ain0.high()              # 收回右转
                   elif (theta_err <=theta_err_mid):
                        if  pin7_in.value()==False and pin9_in.value()==False:
                             ain1.low()          # 收回右转
                             ain0.high()         # 伸出左转
                        elif pin7_in.value()==True and pin9_in.value()==True:
                             ain0.low()          # 收回右转
                             ain1.high()         # 伸出左转
                        elif pin7_in.value()==True and pin9_in.value()==False:
                             ain0.low()          # 收回右转
                             ain1.low()          # 伸出左转
                             a=0
                        else:
                             ain0.low()
                             ain1.low()
              if(a==2):                      # 左转子程序------------------------------------
                   if theta_err <theta_err_mid:
                        ain0.low()               # 收回右转
                        ain1.high()              # 伸出左转
                   elif (theta_err >=theta_err_mid):
                        if  pin7_in.value()==False and pin9_in.value()==False:
                             ain1.low()          # 收回右转
                             ain0.high()         # 伸出左转
                        elif pin7_in.value()==True and pin9_in.value()==True:
                             ain0.low()          # 收回右转
                             ain1.high()         # 伸出左转
                        elif pin7_in.value()==True and pin9_in.value()==False:
                             ain0.low()          # 收回右转
                             ain1.low()          # 伸出左转
                             a=0
                        else:
                             ain0.low()
                             ain1.low()
      
      


    • 应该是自动垃圾回收对你的代码可能有问题。

      可以设置自动垃圾回收来解决,以下两个方案选一个就可以。你试一下应该可以解决。

      1,设置阈值
      在最开始

      import gc
      gc.threshold(10000)
      

      对于OpenMV3可以设置为10000
      如果是OpenMV4可以设置为100000

      2,在死循环里调用gc.collect()手动处罚垃圾回收。

      PS:可以通过gc.mem_free()来查看还有多少内存可以用,正常来说,自动垃圾回收是可以用的。



    • @kidswong999 实验了一下,两种方案都用上,还是会弹错误窗口,格式化硬件后,错误弹出来的比较慢,但是一旦出现过一次错误,第二次错误很快就出来了



    • @3sop 你用的是OpenMV3还是OpenMV4.



    • @kidswong999 OpenMV3