关于M5StickV的SH200Q使用-Arduino中文社区 - Powered by Discuz! Archiver

vany5921 发表于 2019-10-30 15:42

关于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)

xinchen8776 发表于 2019-11-4 09:49

请问LZ在获取芯片ID的时候,有没有出现这样的情况,就是只能读取1次,可以获得正确的ID,后面再读就会收到00啊?我最近在试MPU6886,结果一直出现这个问题。怀疑是初始化的问题,但也查了寄存器,配置上应该没有问题的。
谢谢!

vany5921 发表于 2019-11-4 17:36

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

xinchen8776 发表于 2019-11-11 11:04

vany5921 发表于 2019-11-4 17:36
这段代码你测试一下import image
import time
import lcd


多谢!
我测试了一下,可以获得加速度数据了。
对比了一下代码,我的初始化是直接用i2c.writeto_mem来写的,你的代码用了一个bytearry,但不确定是否就是这个的问题。
python和C的区别还是比较大,对于位的操作不太一样,不知道是不是这样原因导致的。
我再试试。

xinchen8776 发表于 2019-11-14 13:56

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]
查看完整版本: 关于M5StickV的SH200Q使用