资讯详情

基于OpenMV的QMC5883L三轴地磁场传感器应用

  • 上学期有一门团队项目课程,就是做一辆智能跟踪避障的车。老师上来的时候把它拿走了arduino给树莓派等高性能芯片ban所以我们选择了OpenMV实现这个项目。
  • OpenMV库和例程都很好,PID我直接使用程序。
  • 关于QMC5883L如果的介绍datasheet不想看,可以看https://blog.csdn.net/sandwich_iot/article/details/116587230介绍,这里的连接方式和主要寄存器都很清楚。
  • from pyb import I2C import math   RATES = {     10: 0,     50: 1,     100: 2,     200: 3, }  OSR = {     64: 3,     128: 2,     256: 1,     512: 0, }  #register address REG_OUT_X_LSB = 0x00 REG_OUT_X_MSB = 0x01 REG_OUT_Y_LSB = 0x02 REG_OUT_Y_MSB = 0x03 REG_OUT_Z_LSB = 0x04 REG_OUT_Z_MSB = 0x05 REG_CONF_1 = 0x09 REG_CONF_2 = 0x0a REG_RST_PERIOD = 0x0b REG_CHIP_ID = 0x0d TEMP_CORR = 47  # Just a first value   class QMC5883L(object):     def __init__(self,                  adress=13,                  cont_mode=True,                  rate=200,                  full_scale=True,                  over_sampling_rate=512,                  interupt=True,                  pointer_roll=False,                  restore=False                  ):         if over_sampling_rate in OSR:             self.over_sampling_rate = OSR.get(over_sampling_rate)         else:             raise ValueError('oversampling rate is not a allwed value') # verify oversampling rate         if rate in RATES:             self.rate = RATES.get(rate)         else:             raise ValueError('rate is not a allowed value') # verify rate          self.bus = I2C(2, I2C.MASTER)         self.adress = adress         self.full_scale = full_scale         self.interupt = interupt         self.pointer_roll = pointer_roll         self.restore = restore         self.cont_mode = cont_mode           if self.bus.read_byte_data(self.adress, REG_CHIP_ID) != 0xff:             print("Wrong Chip ID, are you shure this is the correct Chip?") # verify chip address         self.set_config()      # mode options     def set_config(self):         if self.cont_mode:             self.cntrl_reg1 = 1         if self.full_scale:             self.cntrl_reg1 = self.cntrl_reg1   1 * (2**2)         self.cntrl_reg1 = self.cntrl_reg1   self.over_sampling_rate * (2**4)         self.cntrl_reg1 = self.cntrl_reg1   self.rate * (2**6)         self.cntrl_reg2 = self.interupt         self.cntrl_reg2 = self.cntrl_reg2   self.pointer_roll * (2 ** 6)         self.cntrl_reg2 = self.cntrl_reg2   self.restore * (2 ** 7)         self.bus.mem_write(self.cntrl_reg1, self.adress, REG_CONF_1)         self.bus.mem_write(self.cntrl_reg2, self.adress, REG_CONF_2)       # binary data operation     def _convert_data(self, data, offset):         if self.full_scale:             max_mag = 8         else:             max_mag = 2         magval = ((data[offset   1] << 8)   data[offset])         if magval > (2 ** 15) - 1:             magval = magval - (2 ** 16)         magval = magval * max_mag / 2 ** 15         return magval      # angle reading     def get_magnet(self):         data = self.bus.mem_read(6, self.adress, REG_OUT_X_LSB)         x = self._convert_data(data, REG_OUT_X_LSB)         y = self._convert_data(data, REG_OUT_Y_LSB)         z = self._convert_data(data, REG_OUT_Z_LSB)                 Heading = math.atan2(y-0.9, x-0.52)# offset mearsued on the spot         if Heading < 0:             Heading  = 2*math.pi         if Heading > 2*math.pi:             Heading -= 2*math.pi         heading = Heading*180/math.pi         degrees = round(heading)         return degrees

    当然,如果只用最大采样效率来做可以简化一大部分代码。

  • from pyb import I2C import math  # register  REG_OUT_X_LSB = 0x00 REG_OUT_X_MSB = 0x01 REG_OUT_Y_LSB = 0x02 REG_OUT_Y_MSB = 0x03 REG_OUT_Z_LSB = 0x04 REG_OUT_Z_MSB = 0x05 REG_CONF_1 = 0x09 REG_CONF_2 = 0x0a REG_RST_PERIOD = 0x0b REG_CHIP_ID = 0x0d TEMP_CORR = 47  # Just a first value   class QMC5883L(object):     def __init__(self,                  adress=13,                  rate=200,                  over_sampling_rate=512,                  full_scale = True                  ):         self.bus = I2C(2, I2C.MASTER)         self.adress = adress         self.full_scale = full_scale      def set_config_on(self):         self.bus.mem_write(0x1d, 13, REG_CONF_1)     def set_config_off(self):         self.bus.mem_write(0x00, 13, REG_CONF_1)      def _convert_data(self, data, offset):         if self.full_scale:             max_mag = 8         else:             max_mag = 2         magval = ((data[offset   1] << 8)   data[offset])         if magval > (2 ** 15) - 1:             magval = magval - (2 ** 16)         magval = magval * max_mag / 2 ** 15         return magval      def get_magnet(self):         data = self.bus.mem_read(memaddr = REG_OUT_X_LSB, addr = 13, data = 6)         x = self._convert_data(data, REG_OUT_X_LSB)         y = self._convert_data(data, REG_OUT_Y_LSB)         z = self._convert_data(ata, REG_OUT_Z_LSB)
    
    
            Heading = math.atan2(y-0.95, x-0.501)//
            if Heading < 0:
                Heading += 2*math.pi
            if Heading > 2*math.pi:
                Heading -= 2*math.pi
            heading = Heading*180/math.pi
            degrees = round(heading)
            return degrees

    主函数里面就直接调用这个get_magnet就可以了,因为设置的持续采样模式,所以在主函数里面可以from time import sleep,然后用sleep来设置采样间隙。

  • 在实际上用OpenMV驱动QMC5883L的时候,我们老是得到EIO这样的错误,检查了连线没有问题又换了好几块同样的传感器,后来换了HMC5883L这个问题得到了解决。所以我猜想是否因为QMC5883L和OpenMV不兼容?或者我们这个问题只是个例,这个东西我们不得而知。

标签: 传感器hmc5883l

锐单商城拥有海量元器件数据手册IC替代型号,打造 电子元器件IC百科大全!

锐单商城 - 一站式电子元器件采购平台