先說BUG,最近要做項目需要樹莓派和陀螺儀,資金充足的話肯定是買一個硬體卡爾曼濾波的感測器類似JY901模塊,資金不足的就買MPU6050。 網上關於MPU6050在樹莓派上的代碼還能用,關於JY901的代碼真的是千奇百怪,而且複製現象特別嚴重,有很多系統本身有問題,導致很多像我一樣的新手在上面浪費 ...
先說BUG,最近要做項目需要樹莓派和陀螺儀,資金充足的話肯定是買一個硬體卡爾曼濾波的感測器類似JY901模塊,資金不足的就買MPU6050。
網上關於MPU6050在樹莓派上的代碼還能用,關於JY901的代碼真的是千奇百怪,而且複製現象特別嚴重,有很多系統本身有問題,導致很多像我一樣的新手在上面浪費了很多的時間。
本篇主要把這一個多星期折騰樹莓派陀螺儀的經歷總結一下,順便幫助下其他像我一樣的新手,把時間用在系統設計上。
網上的代碼有 try except 判斷,把運行時遇到的IOError全部判0處理,然後讀出好像是陀螺儀旋轉角度的數據,當然這樣肯定是沒有問題的,但是如果你拿到你的JY901模塊用代碼運行發現有大量的0數據出現,而且讀出的數據壓根跟陀螺儀旋轉角度沒有直接的關係。
那麼我告訴你,你買的模塊是錯誤的,仔細看下你的模塊是不是每個邊是不是4個引腳,看清模塊上的晶元是不是MPU6050,用i2cdetect -y -1顯示的硬體地址是不是0x68。模塊類似
如果是我上面說的那三種情況,就不要瞎折騰了,你拿到的模塊根本不是JY901,而是JY61,JY901使用MPU9250,而JY61用的是MPU6050,這裡說下個人對這兩模塊認識到的區別:JY901可以修改I2C通訊地址,JY61不可以;JY901的I2C通訊地址初始化為0x50,JY61初始化地址是0x68。
一開始運行0數據特別少,後面0數據特別多,甚至都是0數據,是因為JY61模塊預設是串口模式,用上位機選晶元型號JY61,既可以調成I2C工作模式,這樣用網上關於樹莓派 MPU6050的代碼即可運行,數據穩定正常。
我就是正這個問題上糾結了一個多星期,嚴重的延後了我個人的工作計劃,這個問題肯定絕大部分是我個人原因不夠仔細導致的,但是還有一部分原因是因為某些店家,頁面介紹,發給你的資料全部都是關於JY901,導致新手拿到感測器的時候先入為主,深深的記住了自己買的是JY901,當在樹莓派上使用時出現了上面的這些問題,一直懷疑是自己代碼的問題或者硬體電路的問題,一直谷歌百度解決各種莫名其妙的玄學問題。本人這一星期出現的問題有:1、運行 i2cdetect -y 1 有時候有顯示硬體地址,有時候會消失,這也就是網上代碼的IOError問題,就是因為I2c地址有時候找不到的原因導致的,解決辦法就是用上位機選JY61晶元型號,改成I2C工作模式,就不會有I2C地址有時候會消失的這個問題了。2、上位機修改不了I2C地址, 歸根揭底都是沒弄對模塊的問題,
同時還有一個註意的地方,因為樹莓派在SDA和SCL引腳上有上拉電阻,所以在多I2C模塊連接時不需要加上拉電阻,下麵時JY901的圖和兩個JY901模塊連接的硬體圖示
========================================分割線===========================================
代碼如下:
#!/usr/bin/pythonimport smbus
import math
import types
import ctypes
import time
import subprocess
bus = smbus.SMBus(1) # or bus = smbus.SMBus(1) for Revision 2 boards
addr1= 0x50
addr2 = 0x48
def calc_angle_value(x_angle,y_angle,z_angle): x = ((x_angle[1] << 8) | x_angle[0])/32768 * 180
y = ((y_angle[1] << 8) | y_angle[0])/32768 * 180
z = ((z_angle[1] << 8) | z_angle[0])/32768 * 180
if(x >= 180):
x -= 360
if(y >= 180):
y -= 360
if(z >= 180):
z -= 360
return x,y,z
def ReadData(address): x_angle = bus.read_i2c_block_data(address,0x3d,2)
y_angle = bus.read_i2c_block_data(address,0x3e,2)
z_angle = bus.read_i2c_block_data(address,0x3f,2) x,y,z = calc_angle_value(x_angle,y_angle,z_angle)
return x,y,z
while(True):
try:
right_x,right_y,right_z = ReadData(addr1)
left_x,left_y,left_z = ReadData(addr2) print("Right Data: {:.4} {:.4} {:.4}".format(right_x,right_y,right_z))
print("Left Data: {:.4} {:.4} {:.4}".format(left_x,left_y,left_z))
except ValueError: continue