Page 1 of 1

MPUException: I2C failure when communicating with IMU

Posted: Tue May 01, 2018 9:52 am
by nikhiledutech
Hey,

I am facing problem of " MPUException: I2C failure when communicating with IMU" while i try to plot the yaw, roll, pitch.on UI.

So at start, it works fine. As soon as i make IMU10DOF move faster, it gives me the above mentioned error. When i move it slowly it works but for that the movement should be very slow.

So can anyone help me out ?


Below I have given code of main.py and other .py file i am using to visualize the imu data.
main.py file

Code: Select all

#Interfacing IMU10DOF and displaying Heading, Roll, Pitch  using synchronous method 

from machine import Pin, I2C
from pyb import UART
import utime as time
from mpu9250 import MPU9250
from fusion import Fusion


i2c = I2C(scl = 'PB8', sda ='PB9')
uart = UART(4,115200,timeout=10000)


imu = MPU9250(i2c)



fuse = Fusion()

# Code for external switch
switch = Pin('PE4', Pin.IN, pull=Pin.PULL_UP) # Switch to ground on Y7
def sw():
    return not switch.value()
# Code for Pyboard switch
#sw = pyb.Switch()


# Choose test to run
Calibrate = True
Timing = True

def getmag():                               # Return (x, y, z) tuple (blocking read)
    return imu.mag.xyz

if Calibrate:
    print("Calibrating. Press switch when done.")
    fuse.calibrate(getmag, sw, lambda : pyb.delay(100))
    print(fuse.magbias)

if Timing:
    mag = imu.mag.xyz # Don't include blocking read in time
    accel = imu.accel.xyz # or i2c
    gyro = imu.gyro.xyz
    start = time.ticks_us()  # Measure computation time only
    fuse.update(accel, gyro, mag) # 1.97mS on Pyboard
    t = time.ticks_diff(time.ticks_us(), start)
    uart.write("Update time (uS):", t)

count = 0
while True:
    fuse.update(imu.accel.xyz, imu.gyro.xyz, imu.mag.xyz) # Note blocking mag read
    if count % 50 == 0:
        uart.write("!ANG:{:7.3f},{:7.3f},{:7.3f}\r\n".format(fuse.heading, fuse.pitch, fuse.roll))



    time.sleep_ms(5)
    count += 1





.py file running on PC (Terminal)

Code: Select all

from visual import *
import serial
import string
import math

from time import time

grad2rad = 3.141592 / 180.0

# Check your COM port and baud rate
ser = serial.Serial(port='/dev/ttyUSB0', baudrate=115200, timeout=1)

# Main scene
scene = display(title="9DOF Razor IMU test")
scene.range = (1.2, 1.2, 1.2)
# scene.forward = (0,-1,-0.25)
scene.forward = (1, 0, -0.25)
scene.up = (0, 0, 1)

# Second scene (Roll, Pitch, Yaw)
scene2 = display(title='9DOF Razor IMU test', x=0, y=0, width=500, height=200, center=(0, 0, 0), background=(0, 0, 0))
scene2.range = (1, 1, 1)
scene.width = 500
scene.y = 200

scene2.select()
# Roll, Pitch, Yaw
cil_roll = cylinder(pos=(-0.4, 0, 0), axis=(0.2, 0, 0), radius=0.01, color=color.red)
cil_roll2 = cylinder(pos=(-0.4, 0, 0), axis=(-0.2, 0, 0), radius=0.01, color=color.red)
cil_pitch = cylinder(pos=(0.1, 0, 0), axis=(0.2, 0, 0), radius=0.01, color=color.green)
cil_pitch2 = cylinder(pos=(0.1, 0, 0), axis=(-0.2, 0, 0), radius=0.01, color=color.green)
# cil_course = cylinder(pos=(0.6,0,0),axis=(0.2,0,0),radius=0.01,color=color.blue)
# cil_course2 = cylinder(pos=(0.6,0,0),axis=(-0.2,0,0),radius=0.01,color=color.blue)
arrow_course = arrow(pos=(0.6, 0, 0), color=color.cyan, axis=(-0.2, 0, 0), shaftwidth=0.02, fixedwidth=1)

# Roll,Pitch,Yaw labels
label(pos=(-0.4, 0.3, 0), text="Roll", box=0, opacity=0)
label(pos=(0.1, 0.3, 0), text="Pitch", box=0, opacity=0)
label(pos=(0.55, 0.3, 0), text="Yaw", box=0, opacity=0)
label(pos=(0.6, 0.22, 0), text="N", box=0, opacity=0, color=color.yellow)
label(pos=(0.6, -0.22, 0), text="S", box=0, opacity=0, color=color.yellow)
label(pos=(0.38, 0, 0), text="W", box=0, opacity=0, color=color.yellow)
label(pos=(0.82, 0, 0), text="E", box=0, opacity=0, color=color.yellow)
label(pos=(0.75, 0.15, 0), height=7, text="NE", box=0, color=color.yellow)
label(pos=(0.45, 0.15, 0), height=7, text="NW", box=0, color=color.yellow)
label(pos=(0.75, -0.15, 0), height=7, text="SE", box=0, color=color.yellow)
label(pos=(0.45, -0.15, 0), height=7, text="SW", box=0, color=color.yellow)

L1 = label(pos=(-0.4, 0.22, 0), text="-", box=0, opacity=0)
L2 = label(pos=(0.1, 0.22, 0), text="-", box=0, opacity=0)
L3 = label(pos=(0.7, 0.3, 0), text="-", box=0, opacity=0)

# Main scene objects
scene.select()
# Reference axis (x,y,z)
arrow(color=color.green, axis=(1, 0, 0), shaftwidth=0.02, fixedwidth=1)
arrow(color=color.green, axis=(0, -1, 0), shaftwidth=0.02, fixedwidth=1)
arrow(color=color.green, axis=(0, 0, -1), shaftwidth=0.02, fixedwidth=1)
# labels
label(pos=(0, 0, 0.8), text="9DOF Razor IMU test", box=0, opacity=0)
label(pos=(1, 0, 0), text="X", box=0, opacity=0)
label(pos=(0, -1, 0), text="Y", box=0, opacity=0)
label(pos=(0, 0, -1), text="Z", box=0, opacity=0)
# IMU object
platform = box(length=1, height=0.05, width=1, color=color.red)
p_line = box(length=1, height=0.08, width=0.1, color=color.yellow)
plat_arrow = arrow(color=color.green, axis=(1, 0, 0), shaftwidth=0.06, fixedwidth=1)

# f = open("Serial"+str(time())+".txt", 'w')

roll = 0
pitch = 0
yaw = 0

while 1:
    line = ser.readline()
    # line = "!ANG:100,50,100"
    line = line.replace("!ANG:", "")  # Delete "!ANG:"
    print line
    # f.write(line)                     # Write to the output log file
    words = string.split(line, ",")  # Fields split
    if len(words) > 2:
        try:
            roll = float(words[0]) * grad2rad
            pitch = float(words[1]) * grad2rad
            yaw = float(words[2]) * grad2rad
        except:
            print "Invalid line"

        axis = (cos(pitch) * cos(yaw), -cos(pitch) * sin(yaw), sin(pitch))
        up = (sin(roll) * sin(yaw) + cos(roll) * sin(pitch) * cos(yaw),
              sin(roll) * cos(yaw) - cos(roll) * sin(pitch) * sin(yaw), -cos(roll) * cos(pitch))
        platform.axis = axis
        platform.up = up
        platform.length = 1.0
        platform.width = 0.65
        plat_arrow.axis = axis
        plat_arrow.up = up
        plat_arrow.length = 0.8
        p_line.axis = axis
        p_line.up = up
        cil_roll.axis = (0.2 * cos(roll), 0.2 * sin(roll), 0)
        cil_roll2.axis = (-0.2 * cos(roll), -0.2 * sin(roll), 0)
        cil_pitch.axis = (0.2 * cos(pitch), 0.2 * sin(pitch), 0)
        cil_pitch2.axis = (-0.2 * cos(pitch), -0.2 * sin(pitch), 0)
        arrow_course.axis = (0.2 * sin(yaw), 0.2 * cos(yaw), 0)
        L1.text = str(float(words[0]))
        L2.text = str(float(words[1]))
        L3.text = str(float(words[2]))
        rate(100)
ser.close
# f.close


Re: MPUException: I2C failure when communicating with IMU

Posted: Tue May 01, 2018 10:12 am
by pythoncoder
This is a bit of a shot in the dark but I suggest you try pyb.I2C and try using a hardware I2C interface. I've never seen this error in my testing, but I haven't tried rapid motion with a software I2C instance.

Re: MPUException: I2C failure when communicating with IMU

Posted: Tue May 01, 2018 11:02 am
by nikhiledutech
Okay. Sorry but there was issue with relemate cable. :oops:

But whats problem is , when i see the Output on UI it gives me following problem: Northeast becomes North West. Same lies with south and east-west Direction.


Can you tell me where i have gone wrong.

Re: MPUException: I2C failure when communicating with IMU

Posted: Thu May 03, 2018 4:28 am
by pythoncoder
Assuming you've not gone wrong with the coordinate system it's almost certainly an issue with magnetometer calibration. Mags are very sensitive devices. Indoors they can be problematic due to stray magnetic fields. I'd take the unit outdoors, go through the calibration routine as described in the docs, and try again.