关于M5StickV的SH200Q使用
M5StickV目前集成的加速计有两个版本,一种是MPU6886,一种是SH200Q,我手上买到的是SH200Q,下面来说明一下如何获取SH200Q的数据,传感器配置参考M5StickC的Arduino库中关于SH200Q的.H文件。import machine
import time
import lcd
import utime
from machine import I2C #导入必要的包
i2c = I2C(I2C.I2C0, freq=100000, scl=28, sda=29)#I2C初始化
devices = i2c.scan() #扫描I2C地址 SH200Q为0x6C MPU6886为0X68
print("IC2:", devices)
time.sleep(1)
# LCD
lcd.init() #屏幕初始化
# Chip ID
tempdata = i2c.readfrom_mem(108, 0x30, 1)#读取芯片ID
print ("ChipID:", tempdata)
time.sleep(1)
tempdata = i2c.readfrom_mem(108, 0xC2, 1)
tempdata = tempdata | 0x04 #配置寄存器 参照arduino
i2c.writeto_mem(108, 0xC2, bytearray());
time.sleep(1)
tempdata = tempdata | 0xFB
i2c.writeto_mem(108, 0xC2, bytearray());
#
tempdata = i2c.readfrom_mem(108, 0xD8, 1)
tempdata = tempdata | 0x80
i2c.writeto_mem(108, 0xD8, bytearray());
time.sleep(1)
tempdata = tempdata & 0x7F;
i2c.writeto_mem(108, 0xD8, bytearray());
i2c.writeto_mem(108, 0x78, bytearray());
time.sleep(1)
i2c.writeto_mem(108, 0x78, bytearray());
# set acc odr 256hz
i2c.writeto_mem(108, 0x0e, bytearray());
# set gyro odr 500hz
i2c.writeto_mem(108, 0x0f, bytearray());
# set gyro dlpf 50hz
i2c.writeto_mem(108, 0x11, bytearray());
# set no buffer mode
i2c.writeto_mem(108, 0x12, bytearray());
# set acc range +-8G
i2c.writeto_mem(108, 0x16, bytearray());
# set gyro range +-2000¶È/s
i2c.writeto_mem(108, 0x2B, bytearray());
i2c.writeto_mem(108, 0xBA, bytearray());
tempdata = i2c.readfrom_mem(108, 0xCA, 1)
tempdata = tempdata | 0x10
# ADC Reset
i2c.writeto_mem(108, 0xCA, bytearray());
time.sleep(1)
tempdata = tempdata | 0xEF
i2c.writeto_mem(108, 0xCA, bytearray());
time.sleep(10)
# get acceralator data. 读取加速计数据
while True:
lcd.clear()
accel = i2c.readfrom_mem(108, 0x00, 6) 读取6个数据,其中1,3,5为XYZ的加速值
accel_x = accel
accel_y = accel
accel_z = accel
print ("accel:", accel_x, accel_y, accel_z)
print ("gyro:", gyro_x, gyro_y, gyro_z)
lcd.draw_string(10, 10, "accel:" + str(accel_x) + "," + str(accel_y) + "," + str(accel_z), lcd.RED, lcd.BLACK)
utime.sleep_ms(100)
请问LZ在获取芯片ID的时候,有没有出现这样的情况,就是只能读取1次,可以获得正确的ID,后面再读就会收到00啊?我最近在试MPU6886,结果一直出现这个问题。怀疑是初始化的问题,但也查了寄存器,配置上应该没有问题的。
谢谢! xinchen8776 发表于 2019-11-4 09:49
请问LZ在获取芯片ID的时候,有没有出现这样的情况,就是只能读取1次,可以获得正确的ID,后面再读就会收到0 ...
这段代码你测试一下import image
import time
import lcd
import machine
from machine import I2C
# I2C Check
i2c = I2C(I2C.I2C0, freq=100000, scl=28, sda=29)
devices = i2c.scan()
print("IC2:",devices)
time.sleep(1)
#LCD
lcd.init()
# LCD Backlight
AXP192_ADDR=0x34
Backlight_ADDR=0x91
level=50
val = (level+7) << 4
i2c.writeto_mem(AXP192_ADDR, Backlight_ADDR,int(val))
# IMU6866 define
MPU6886_ADDRESS=0x68
MPU6886_WHOAMI=0x75
MPU6886_ACCEL_INTEL_CTRL=0x69
MPU6886_SMPLRT_DIV=0x19
MPU6886_INT_PIN_CFG= 0x37
MPU6886_INT_ENABLE=0x38
MPU6886_ACCEL_XOUT_H=0x3B
MPU6886_TEMP_OUT_H=0x41
MPU6886_GYRO_XOUT_H= 0x43
MPU6886_USER_CTRL= 0x6A
MPU6886_PWR_MGMT_1=0x6B
MPU6886_PWR_MGMT_2=0x6C
MPU6886_CONFIG=0x1A
MPU6886_GYRO_CONFIG= 0x1B
MPU6886_ACCEL_CONFIG=0x1C
MPU6886_ACCEL_CONFIG2= 0x1D
MPU6886_FIFO_EN= 0x23
# IMU6866 Initialize
def write_i2c(address, value):
i2c.writeto_mem(MPU6886_ADDRESS, address, bytearray())
time.sleep_ms(10)
write_i2c(MPU6886_PWR_MGMT_1, 0x00)
write_i2c(MPU6886_PWR_MGMT_1, 0x01<<7)
write_i2c(MPU6886_PWR_MGMT_1,0x01<<0)
write_i2c(MPU6886_ACCEL_CONFIG,0x10)
write_i2c(MPU6886_GYRO_CONFIG,0x18)
write_i2c(MPU6886_CONFIG,0x01)
write_i2c(MPU6886_SMPLRT_DIV,0x05)
write_i2c(MPU6886_INT_ENABLE,0x00)
write_i2c(MPU6886_ACCEL_CONFIG2,0x00)
write_i2c(MPU6886_USER_CTRL,0x00)
write_i2c(MPU6886_FIFO_EN,0x00)
write_i2c(MPU6886_INT_PIN_CFG,0x22)
write_i2c(MPU6886_INT_ENABLE,0x01)
# Button_A
fm.register(board_info.BUTTON_A, fm.fpioa.GPIO1)
but_a=GPIO(GPIO.GPIO1, GPIO.IN, GPIO.PULL_UP)
# Button_B
fm.register(board_info.BUTTON_B, fm.fpioa.GPIO2)
but_b = GPIO(GPIO.GPIO2, GPIO.IN, GPIO.PULL_UP)
but_a_pressed = 0
but_b_pressed = 0
# Read IMU6866 and Scaling
def read_imu():
aRes=255/4096/2
offset=128
accel = i2c.readfrom_mem(MPU6886_ADDRESS, MPU6886_ACCEL_XOUT_H, 6)
accel_x = (accel<<8|accel)
accel_y = (accel<<8|accel)
accel_z = (accel<<8|accel)
if accel_x>32768:
accel_x=accel_x-65536
if accel_y>32768:
accel_y=accel_y-65536
if accel_z>32768:
accel_z=accel_z-65536
ax=int(accel_x*aRes+offset)
if ax<0: ax=0
if ax>255: ax=255
ay=int(accel_y*aRes+offset)
if ay<0: ay=0
if ay>255: ay=255
az=int(accel_z*aRes+offset)
if az<0: az=0
if az>255: az=255
accel_array =
return accel_array
cnt=0
mode=0
save_flg=0
pic_no=0
accel_array_zero=(255,255,255)
#IMU_Image
w_size=8
view_size=120
imu_Image = image.Image()
imu_Image = imu_Image.resize(w_size, w_size)
image_data_array = []
while(True):
lcd.clear()
accel_array = read_imu()
lcd.draw_string(10, 10, "accel:" + str(accel_array) + "," + str(accel_array) + "," + str(accel_array), lcd.RED, lcd.BLACK)
utime.sleep_ms(100)
view_Image = image.Image()
# IMU Data to Image
accel_array = read_imu()
w=cnt%w_size
h=int(cnt/w_size)
imu_Image.set_pixel(w, h, accel_array)
width=imu_Image.width()
# IMU Data_View
w=(cnt+1)%w_size
h=int((cnt+1)/w_size)
imu_Image.set_pixel(w, h, accel_array_zero)
img_buff=imu_Image.resize(view_size,view_size)
view_Image.draw_image(img_buff,100,8)
#imu_Image.pix_to_ai()
if save_flg==1:
view_Image.draw_string(0, 40, "REC", (255,0,0),scale=3)
class_str=str(mode);
view_Image.draw_string(0, 70,class_str, (255,0,0),scale=5)
if cnt%width<width/2:
view_Image.draw_circle(30, 15, 15,(255,0,0),fill=1)
lcd.display(view_Image)
cnt=cnt+1
# IMU Data Save to SD
if cnt>imu_Image.width()*imu_Image.height():
cnt=0
pic_no+=1
if save_flg==1:
cnt_str="{0:04d}".format(pic_no)
mode_str="{0:04d}".format(mode)
fname="cnt_str"+mode_str+"_"+cnt_str+".jpg"
print(fname)
imu_Image.save(fname, quality=99)
if but_a.value() == 0 and but_a_pressed == 0:
but_a_pressed=1
if save_flg==0:
save_flg=1
print("save_start")
elif save_flg==1:
save_flg=0
if but_a.value() == 1 and but_a_pressed == 1:
but_a_pressed=0
if but_b.value() == 0 and but_b_pressed == 0:
but_b_pressed=1
mode+=1
if mode>10:
mode=0
if but_b.value() == 1 and but_b_pressed == 1:
but_b_pressed=0
vany5921 发表于 2019-11-4 17:36
这段代码你测试一下import image
import time
import lcd
多谢!
我测试了一下,可以获得加速度数据了。
对比了一下代码,我的初始化是直接用i2c.writeto_mem来写的,你的代码用了一个bytearry,但不确定是否就是这个的问题。
python和C的区别还是比较大,对于位的操作不太一样,不知道是不是这样原因导致的。
我再试试。 vany5921 发表于 2019-11-4 17:36
这段代码你测试一下import image
import time
import lcd
测试成功了,出问题的代码也找到了,就是这一段:
from pmu import axp192
pmu = axp192()
pmu.enablePMICSleepMode(True)
电源管理模块出的问题。
据网站解释,K210总共3个I2C接口,PMU、摄像头以及其他设备各用了一个,导致如果启用PMU,就没法用MPU6886了。
将其注释掉就可以了。
但不用PMU的话,好像无法正常关机,长按按键变成了重启,也是一个麻烦事。
不知你这边是否有什么好的解决办法?
具体说明可见这个链接:http://community.m5stack.com/topic/1403/m5stickv-firmware_1017-upgrade/24
藏得比较深,在发现是PMU的问题后才搜索到这个问题。
页:
[1]