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



    • 0_1696988976060_f9b9f350c07dcdc3520c6c805c60a28.jpg

      请在这里粘贴代码
      from micropython import const
      import ustruct
      import time
      import utime
      import pyb
      from pyb import Pin, Timer
      import sensor, time, image
      from machine import I2C
      
      _IO_TIMEOUT = 1000
      _SYSRANGE_START = const(0x00)
      _EXTSUP_HV = const(0x89)
      _MSRC_CONFIG = const(0x60)
      _FINAL_RATE_RTN_LIMIT = const(0x44)
      _SYSTEM_SEQUENCE = const(0x01)
      _SPAD_REF_START = const(0x4f)
      _SPAD_ENABLES = const(0xb0)
      _REF_EN_START_SELECT = const(0xb6)
      _SPAD_NUM_REQUESTED = const(0x4e)
      _INTERRUPT_GPIO = const(0x0a)
      _INTERRUPT_CLEAR = const(0x0b)
      _GPIO_MUX_ACTIVE_HIGH = const(0x84)
      _RESULT_INTERRUPT_STATUS = const(0x13)
      _RESULT_RANGE_STATUS = const(0x14)
      _OSC_CALIBRATE = const(0xf8)
      _MEASURE_PERIOD = const(0x04)
      
      lens_mm = 2.8 # Standard Lens.
      average_head_height_mm = 232.0 # https://en.wikipedia.org/wiki/Human_head
      image_height_pixels = 240.0 # QVGA
      sensor_h_mm = 2.952 # For OV7725 sensor - see datasheet.
      offest_mm = 100.0 # Offset fix...
      
      class TimeoutError(RuntimeError):
          pass
      
      
      class VL53L0X:
          def __init__(self, i2c, address=0x29):
              self.i2c = i2c
              self.address = address
              self.init()
              self._started = False
      
          def _registers(self, register, values=None, struct='B'):
              if values is None:
                  size = ustruct.calcsize(struct)
                  data = self.i2c.readfrom_mem(self.address, register, size)
                  values = ustruct.unpack(struct, data)
                  return values
              data = ustruct.pack(struct, *values)
              self.i2c.writeto_mem(self.address, register, data)
      
          def _register(self, register, value=None, struct='B'):
              if value is None:
                  return self._registers(register, struct=struct)[0]
              self._registers(register, (value,), struct=struct)
      
          def _flag(self, register=0x00, bit=0, value=None):
              data = self._register(register)
              mask = 1 << bit
              if value is None:
                  return bool(data & mask)
              elif value:
                  data |= mask
              else:
                  data &= ~mask
              self._register(register, data)
      
          def _config(self, *config):
              for register, value in config:
                  self._register(register, value)
      
          def init(self, power2v8=True):
              self._flag(_EXTSUP_HV, 0, power2v8)
      
              # I2C standard mode
              self._config(
                  (0x88, 0x00),
      
                  (0x80, 0x01),
                  (0xff, 0x01),
                  (0x00, 0x00),
              )
              self._stop_variable = self._register(0x91)
              self._config(
                  (0x00, 0x01),
                  (0xff, 0x00),
                  (0x80, 0x00),
              )
      
              # disable signal_rate_msrc and signal_rate_pre_range limit checks
              self._flag(_MSRC_CONFIG, 1, True)
              self._flag(_MSRC_CONFIG, 4, True)
      
              # rate_limit = 0.25
              self._register(_FINAL_RATE_RTN_LIMIT, int(0.25 * (1 << 7)),
                             struct='>H')
      
              self._register(_SYSTEM_SEQUENCE, 0xff)
      
              spad_count, is_aperture = self._spad_info()
              spad_map = bytearray(self._registers(_SPAD_ENABLES, struct='6B'))
      
              # set reference spads
              self._config(
                  (0xff, 0x01),
                  (_SPAD_REF_START, 0x00),
                  (_SPAD_NUM_REQUESTED, 0x2c),
                  (0xff, 0x00),
                  (_REF_EN_START_SELECT, 0xb4),
              )
      
              spads_enabled = 0
              for i in range(48):
                  if i < 12 and is_aperture or spads_enabled >= spad_count:
                      spad_map[i // 8] &= ~(1 << (i >> 2))
                  elif spad_map[i // 8] & (1 << (i >> 2)):
                      spads_enabled += 1
      
              self._registers(_SPAD_ENABLES, spad_map, struct='6B')
      
              self._config(
                  (0xff, 0x01),
                  (0x00, 0x00),
      
                  (0xff, 0x00),
                  (0x09, 0x00),
                  (0x10, 0x00),
                  (0x11, 0x00),
      
                  (0x24, 0x01),
                  (0x25, 0xFF),
                  (0x75, 0x00),
      
                  (0xFF, 0x01),
                  (0x4E, 0x2C),
                  (0x48, 0x00),
                  (0x30, 0x20),
      
                  (0xFF, 0x00),
                  (0x30, 0x09),
                  (0x54, 0x00),
                  (0x31, 0x04),
                  (0x32, 0x03),
                  (0x40, 0x83),
                  (0x46, 0x25),
                  (0x60, 0x00),
                  (0x27, 0x00),
                  (0x50, 0x06),
                  (0x51, 0x00),
                  (0x52, 0x96),
                  (0x56, 0x08),
                  (0x57, 0x30),
                  (0x61, 0x00),
                  (0x62, 0x00),
                  (0x64, 0x00),
                  (0x65, 0x00),
                  (0x66, 0xA0),
      
                  (0xFF, 0x01),
                  (0x22, 0x32),
                  (0x47, 0x14),
                  (0x49, 0xFF),
                  (0x4A, 0x00),
      
                  (0xFF, 0x00),
                  (0x7A, 0x0A),
                  (0x7B, 0x00),
                  (0x78, 0x21),
      
                  (0xFF, 0x01),
                  (0x23, 0x34),
                  (0x42, 0x00),
                  (0x44, 0xFF),
                  (0x45, 0x26),
                  (0x46, 0x05),
                  (0x40, 0x40),
                  (0x0E, 0x06),
                  (0x20, 0x1A),
                  (0x43, 0x40),
      
                  (0xFF, 0x00),
                  (0x34, 0x03),
                  (0x35, 0x44),
      
                  (0xFF, 0x01),
                  (0x31, 0x04),
                  (0x4B, 0x09),
                  (0x4C, 0x05),
                  (0x4D, 0x04),
      
                  (0xFF, 0x00),
                  (0x44, 0x00),
                  (0x45, 0x20),
                  (0x47, 0x08),
                  (0x48, 0x28),
                  (0x67, 0x00),
                  (0x70, 0x04),
                  (0x71, 0x01),
                  (0x72, 0xFE),
                  (0x76, 0x00),
                  (0x77, 0x00),
      
                  (0xFF, 0x01),
                  (0x0D, 0x01),
      
                  (0xFF, 0x00),
                  (0x80, 0x01),
                  (0x01, 0xF8),
      
                  (0xFF, 0x01),
                  (0x8E, 0x01),
                  (0x00, 0x01),
                  (0xFF, 0x00),
                  (0x80, 0x00),
              )
      
              self._register(_INTERRUPT_GPIO, 0x04)
              self._flag(_GPIO_MUX_ACTIVE_HIGH, 4, False)
              self._register(_INTERRUPT_CLEAR, 0x01)
      
              # XXX Need to implement this.
              #budget = self._timing_budget()
              #self._register(_SYSTEM_SEQUENCE, 0xe8)
              #self._timing_budget(budget)
      
              self._register(_SYSTEM_SEQUENCE, 0x01)
              self._calibrate(0x40)
              self._register(_SYSTEM_SEQUENCE, 0x02)
              self._calibrate(0x00)
      
              self._register(_SYSTEM_SEQUENCE, 0xe8)
      
          def _spad_info(self):
              self._config(
                  (0x80, 0x01),
                  (0xff, 0x01),
                  (0x00, 0x00),
      
                  (0xff, 0x06),
              )
              self._flag(0x83, 3, True)
              self._config(
                  (0xff, 0x07),
                  (0x81, 0x01),
      
                  (0x80, 0x01),
      
                  (0x94, 0x6b),
                  (0x83, 0x00),
              )
              for timeout in range(_IO_TIMEOUT):
                  if self._register(0x83):
                      break
                  utime.sleep_ms(1)
              else:
                  raise TimeoutError()
              self._config(
                  (0x83, 0x01),
              )
              value = self._register(0x92)
              self._config(
                  (0x81, 0x00),
                  (0xff, 0x06),
              )
              self._flag(0x83, 3, False)
              self._config(
                  (0xff, 0x01),
                  (0x00, 0x01),
      
                  (0xff, 0x00),
                  (0x80, 0x00),
              )
              count = value & 0x7f
              is_aperture = bool(value & 0b10000000)
              return count, is_aperture
      
          def _calibrate(self, vhv_init_byte):
              self._register(_SYSRANGE_START, 0x01 | vhv_init_byte)
              for timeout in range(_IO_TIMEOUT):
                  if self._register(_RESULT_INTERRUPT_STATUS) & 0x07:
                      break
                  utime.sleep_ms(1)
              else:
                  raise TimeoutError()
              self._register(_INTERRUPT_CLEAR, 0x01)
              self._register(_SYSRANGE_START, 0x00)
      
          def start(self, period=0):
              self._config(
                (0x80, 0x01),
                (0xFF, 0x01),
                (0x00, 0x00),
                (0x91, self._stop_variable),
                (0x00, 0x01),
                (0xFF, 0x00),
                (0x80, 0x00),
              )
              if period:
                  oscilator = self._register(_OSC_CALIBRATE, struct='>H')
                  if oscilator:
                      period *= oscilator
                  self._register(_MEASURE_PERIOD, period, struct='>H')
                  self._register(_SYSRANGE_START, 0x04)
              else:
                  self._register(_SYSRANGE_START, 0x02)
              self._started = True
      
          def stop(self):
              self._register(_SYSRANGE_START, 0x01)
              self._config(
                (0xFF, 0x01),
                (0x00, 0x00),
                (0x91, self._stop_variable),
                (0x00, 0x01),
                (0xFF, 0x00),
              )
              self._started = False
      
          def read(self):
              if not self._started:
                  self._config(
                    (0x80, 0x01),
                    (0xFF, 0x01),
                    (0x00, 0x00),
                    (0x91, self._stop_variable),
                    (0x00, 0x01),
                    (0xFF, 0x00),
                    (0x80, 0x00),
                    (_SYSRANGE_START, 0x01),
                  )
                  for timeout in range(_IO_TIMEOUT):
                      if not self._register(_SYSRANGE_START) & 0x01:
                          break
                      utime.sleep_ms(1)
                  else:
                      raise TimeoutError()
              for timeout in range(_IO_TIMEOUT):
                  if self._register(_RESULT_INTERRUPT_STATUS) & 0x07:
                      break
                  utime.sleep_ms(1)
              else:
                  raise TimeoutError()
              value = self._register(_RESULT_RANGE_STATUS + 10, struct='>H')
              self._register(_INTERRUPT_CLEAR, 0x01)
              return value
      
      def rect_size_to_distance(r): # r == (x, y, w, h) -> r[3] == h
          return ((lens_mm * average_head_height_mm * image_height_pixels) / (r[3] * sensor_h_mm)) - offest_mm
      
      
      sensor.reset()
      sensor.set_contrast(1)
      sensor.set_gainceiling(16)
      sensor.set_framesize(sensor.QVGA)
      #sensor.set_pixformat(sensor.GRAYSCALE)
      sensor.set_pixformat(sensor.RGB565)
      
      face_cascade = image.HaarCascade("frontalface", stages=25)
      print(face_cascade)
      
      i2c = I2C(sda=pyb.Pin('P5'), scl=pyb.Pin('P4'), freq=400000)
      mysensor=VL53L0X(i2c)
      
      mysensor.start()
      
      #now = time.time()
      now = time.ticks_ms()
      clock = time.clock()
      clock.tick()
      
      while (True):
          clock.tick()
      
          for i in range(0,5000):
              img = sensor.snapshot()
              objects = img.find_features(face_cascade, threshold=0.75, scale_factor=1.25)
              print(mysensor.read(),time.ticks_diff(time.ticks_ms(),now))
              for i in range(len(objects)):
                  img.draw_rectangle(objects[i])
                  img.draw_string(objects[i][0] - 16, objects[i][1] - 16, "Distance %d mm" % rect_size_to_distance(objects[i]))
      
          clock.tick()
      
      

      0_1696989125934_f9b9f350c07dcdc3520c6c805c60a28.jpg



    • 这个你得看芯片的数据手册,还是很麻烦的。