当前位置:   article > 正文

基于micropython编写的esp32 mpu6050驱动_micropython mpu6050

micropython mpu6050

前言

文章分两部分,第一部分是全部代码展示,复制即用;第二部分是代码分段解释。

用的是esp32的I2C(0),默认scl接GPIO18,sda接GPIO19

关键词:micropython,esp32,mpu6050

所有代码展示

  1. from machine import Pin,I2C
  2. import time
  3. import math
  4. class MPU6050():
  5. def __init__(self, i2c, addr=0x68):
  6. self.iic = i2c
  7. self.addr = addr
  8. self.accelScale=16384
  9. self.gyroScale=131
  10. # 唤醒
  11. self.iic.writeto(self.addr, bytearray([107, 0]))
  12. self.iic.writeto(self.addr,bytearray([26,0]))
  13. # 配置加速度计量程
  14. self.iic.writeto(self.addr,bytearray([27,0]))
  15. # 配置角速度计量程
  16. self.iic.writeto(self.addr,bytearray([28,0]))
  17. # 配置量程系数
  18. AFS_SEL=(self.iic.readfrom_mem(self.addr,27,1))[0]&0x18
  19. if AFS_SEL==0:
  20. self.accelScale=16384
  21. elif AFS_SEL==0x08:
  22. self.accelScale=8192
  23. elif AFS_SEL==0x10:
  24. self.accelScale=4096
  25. elif AFS_SEL==0x18:
  26. self.accelScale=2048
  27. AFS_SEL=(self.iic.readfrom_mem(self.addr,28,1))[0]&0x18
  28. if(AFS_SEL==0):
  29. self.gyroScale=131
  30. elif AFS_SEL==0x08:
  31. self.gyroScale=65.5
  32. elif AFS_SEL==0x10:
  33. self.gyroScale=32.8
  34. elif AFS_SEL==0x18:
  35. self.gyroScale=16.4
  36. self.calibraton=self.calibrate()
  37. # 读取寄存器原生数据
  38. def get_raw_values(self):
  39. reg_data=self.iic.readfrom_mem(self.addr, 59, 14)
  40. return reg_data[:6],reg_data[8:]
  41. # 将原生数据转6轴数据
  42. def raw_to_ints(self):
  43. a,g=self.get_raw_values()
  44. aX=self.bytes_toint(a[0],a[1])/self.accelScale
  45. aY=self.bytes_toint(a[2],a[3])/self.accelScale
  46. aZ=self.bytes_toint(a[4],a[5])/self.accelScale
  47. gX=self.bytes_toint(g[0],g[1])/self.gyroScale
  48. gY=self.bytes_toint(g[2],g[3])/self.gyroScale
  49. gZ=self.bytes_toint(g[4],g[5])/self.gyroScale
  50. return [aX,aY,aZ,gX,gY,gZ]
  51. # 定义转换规则
  52. def bytes_toint(self, firstbyte, secondbyte):
  53. if not firstbyte & 0x80:
  54. return firstbyte << 8 | secondbyte
  55. return - (((firstbyte ^ 255) << 8) | (secondbyte ^ 255) + 1)
  56. # 处理后的6轴参数
  57. def get_values(self,calibration):
  58. return [a+b for a, b in zip(self.raw_to_ints(), calibration)]
  59. # 获取修正数组
  60. def calibrate(self):
  61. calibrationArray = [0,0,0,0,0,0]
  62. for i in range(100):
  63. calibtation=self.raw_to_ints()
  64. calibrationArray[0] += calibtation[0]
  65. calibrationArray[1] += calibtation[1]
  66. calibrationArray[2] += calibtation[2]
  67. calibrationArray[3] += calibtation[3]
  68. calibrationArray[4] += calibtation[4]
  69. calibrationArray[5] += calibtation[5]
  70. for i in range(6):
  71. calibrationArray[i]/=100
  72. if i==2:
  73. calibrationArray[i]=1-calibrationArray[i]
  74. else:
  75. calibrationArray[i]=-calibrationArray[i]
  76. return calibrationArray
  77. # 计算欧拉角
  78. def get_angles(self,angle_data,calibration,k=0.95):
  79. data=self.get_values(calibration)
  80. aPitch=math.atan(data[0]/data[2])*57.3
  81. aRow=math.atan(data[1]/data[2])*57.3
  82. gRow=data[3]/7500
  83. gPitch=data[4]/7500
  84. gYaw=data[5]/7500
  85. pitch=(1-k)*angle_data['pitch']+k*(aPitch+gPitch)
  86. row=(1-k)*angle_data['row']+k*(aRow+gRow)
  87. yaw=(1-k)*angle_data['yaw']+k*(angle_data['yaw']+gYaw)
  88. return {'pitch':pitch,'yaw':yaw,'row':row}
  89. # 使用demo
  90. i2c=I2C(0)
  91. a=MPU6050(i2c)
  92. angle={'pitch':0,'row':0,'yaw':0}
  93. cali=a.calibrate()
  94. while True:
  95. angle=a.get_angles(angle,cali)
  96. print(angle)
  97. time.sleep(0.5)

代码解释

总体分为两部分,导包MPU6050类的定义

导包

  1. from machine import Pin,I2C
  2. import time
  3. import math

定义MPU6050类

包含几个类函数:

类初始化

  1. def __init__(self, i2c, addr=0x68):
  2. self.iic = i2c
  3. self.addr = addr
  4. # 初始化加速度计量程系数(默认+-2g)
  5. self.accelScale=16384
  6. # 初始化陀螺仪量程系数(默认+-250°)
  7. self.gyroScale=131
  8. # 唤醒
  9. self.iic.writeto(self.addr, bytearray([107, 0]))
  10. self.iic.writeto(self.addr,bytearray([26,0]))
  11. # 配置加速度计量程
  12. self.iic.writeto(self.addr,bytearray([27,0]))
  13. # 配置角速度计量程
  14. self.iic.writeto(self.addr,bytearray([28,0]))
  15. # 根据寄存器值配置量程系数
  16. AFS_SEL=(self.iic.readfrom_mem(self.addr,27,1))[0]&0x18
  17. if AFS_SEL==0:
  18. self.accelScale=16384
  19. elif AFS_SEL==0x08:
  20. self.accelScale=8192
  21. elif AFS_SEL==0x10:
  22. self.accelScale=4096
  23. elif AFS_SEL==0x18:
  24. self.accelScale=2048
  25. AFS_SEL=(self.iic.readfrom_mem(self.addr,28,1))[0]&0x18
  26. if(AFS_SEL==0):
  27. self.gyroScale=131
  28. elif AFS_SEL==0x08:
  29. self.gyroScale=65.5
  30. elif AFS_SEL==0x10:
  31. self.gyroScale=32.8
  32. elif AFS_SEL==0x18:
  33. self.gyroScale=16.4
  34. # 调用矫正函数进行初始矫正
  35. self.calibraton=self.calibrate()
'
运行

获取原生6轴数据

  1. # 读取寄存器原生数据,返回加速度和陀螺仪的12个数据
  2. def get_raw_values(self):
  3. reg_data=self.iic.readfrom_mem(self.addr, 59, 14)
  4. return reg_data[:6],reg_data[8:]

将原生6轴数据转化

  1. # 将原生数据转6轴数据
  2. def raw_to_ints(self):
  3. # 获取原生6轴数据
  4. a,g=self.get_raw_values()
  5. # 调用bytes_toint方法进行转化,除以量程系数将数据映射到范围内
  6. aX=self.bytes_toint(a[0],a[1])/self.accelScale
  7. aY=self.bytes_toint(a[2],a[3])/self.accelScale
  8. aZ=self.bytes_toint(a[4],a[5])/self.accelScale
  9. gX=self.bytes_toint(g[0],g[1])/self.gyroScale
  10. gY=self.bytes_toint(g[2],g[3])/self.gyroScale
  11. gZ=self.bytes_toint(g[4],g[5])/self.gyroScale
  12. # 返回处理后的6轴数据
  13. return [aX,aY,aZ,gX,gY,gZ]

原生数据转化规则

  1. # 定义转换规则
  2. def bytes_toint(self, firstbyte, secondbyte):
  3. if not firstbyte & 0x80:
  4. return firstbyte << 8 | secondbyte
  5. return - (((firstbyte ^ 255) << 8) | (secondbyte ^ 255) + 1)

定义矫正函数

  1. def calibrate(self):
  2. # 矫正数组初始化
  3. calibrationArray = [0,0,0,0,0,0]
  4. # 取100次数据累加后取平均
  5. for i in range(100):
  6. calibtation=self.raw_to_ints()
  7. calibrationArray[0] += calibtation[0]
  8. calibrationArray[1] += calibtation[1]
  9. calibrationArray[2] += calibtation[2]
  10. calibrationArray[3] += calibtation[3]
  11. calibrationArray[4] += calibtation[4]
  12. calibrationArray[5] += calibtation[5]
  13. # 当静止且水平时,理论输出的6轴数组[0,0,1,0,0,0]
  14. # 只有z轴受1g的加速度
  15. for i in range(6):
  16. calibrationArray[i]/=100
  17. if i==2:
  18. calibrationArray[i]=1-calibrationArray[i]
  19. else:
  20. calibrationArray[i]=-calibrationArray[i]
  21. return calibrationArray
'
运行

返回矫正后的6轴数据

  1. def get_values(self,calibration):
  2. # 处理后的6轴数据与矫正数组相加得到矫正的数据
  3. return [a+b for a, b in zip(self.raw_to_ints(), calibration)]
'
运行

计算欧拉角

  1. """
  2. 参数说明:
  3. angle_data 上一时刻欧拉角数据
  4. calibration 矫正数组
  5. k 权重系数
  6. """
  7. def get_angles(self,angle_data,calibration,k=0.95):
  8. # 获取矫正后的6轴数据
  9. data=self.get_values(calibration)
  10. aPitch=math.atan(data[0]/data[2])*57.3
  11. aRow=math.atan(data[1]/data[2])*57.3
  12. gRow=data[3]/7500
  13. gPitch=data[4]/7500
  14. gYaw=data[5]/7500
  15. # 本次数据与上一时刻数据加权求和,减少扰动
  16. pitch=(1-k)*angle_data['pitch']+k*(aPitch+gPitch)
  17. row=(1-k)*angle_data['row']+k*(aRow+gRow)
  18. yaw=(1-k)*angle_data['yaw']+k*(angle_data['yaw']+gYaw)
  19. # 返回欧拉角字典
  20. return {'pitch':pitch,'yaw':yaw,'row':row}

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/正经夜光杯/article/detail/795453
推荐阅读
相关标签
  

闽ICP备14008679号