Module for MPU9150

Showroom for MicroPython related hardware projects.
Target audience: Users wanting to show off their project!
Turbinenreiter
Posts: 288
Joined: Sun May 04, 2014 8:54 am

Re: Module for MPU9150

Post by Turbinenreiter » Tue Oct 14, 2014 6:46 pm

I haven't seen that behavior yet. This will be nasty to track down.

User avatar
dhylands
Posts: 3821
Joined: Mon Jan 06, 2014 6:08 pm
Location: Peachland, BC, Canada
Contact:

Re: Module for MPU9150

Post by dhylands » Tue Oct 14, 2014 7:00 pm

Lockup on i2c typically happens because somebody is holding the SCL/SDA line low.

You really need to disconnect just the SDA/SCL lines when this happens to figure out which device is at fault.

blmorris
Posts: 348
Joined: Fri May 02, 2014 3:43 pm
Location: Massachusetts, USA

Re: Module for MPU9150

Post by blmorris » Wed Oct 15, 2014 3:18 am

@Turbinenreiter - I took a look at your code (without testing it as I don't have the MPU9150 module) because I was wondering if you might be having a similar problem to one that i encountered a few months ago. While I can't tell if it is the same problem, I did deal with an I2C lockup which gave similar errors, and I don't think the i2c code has changed that much in the last 3 months.
In my project there can be up to four distinct devices on the same i2c bus. The way we initially wrote the device classes, each device instantiation would independently initialize the i2c bus. (I noted that your code puts the i2c bus initialization within the MPU9150 device class.) What we noticed was that the SDA and SCL lines each get pulled low momentarily each time the bus gets initialized, to test that the lines have resistor pull-ups and respond correctly. We found that reinitializing the bus for each device initialization caused intermittent hangups. Our solution was to initialize the i2c bus just once, outside of any device definition, and pass that bus object as a parameter to each device on the bus to avoid multiple initializations.
For example:

Code: Select all

i2c_1 = pyb.I2C(1, pyb.I2C.MASTER)
dev_a = DEV_A_CLASS(i2c_1, …)
dev_b = DEV_B_CLASS(i2c_1, …)
dev_c = DEV_C_CLASS(i2c_1, …)
As far as I can tell, your system does not actually have this multiple device initialization happening, but I wasn't sure so I just wanted to mention the possibility.
-Bryan

User avatar
dhylands
Posts: 3821
Joined: Mon Jan 06, 2014 6:08 pm
Location: Peachland, BC, Canada
Contact:

Re: Module for MPU9150

Post by dhylands » Wed Oct 15, 2014 4:51 am

I think that probably deserves a bug report.

I filed issue: https://github.com/micropython/micropython/issues/908

User avatar
pythoncoder
Posts: 5956
Joined: Fri Jul 18, 2014 8:01 am
Location: UK
Contact:

Re: Module for MPU9150

Post by pythoncoder » Wed Oct 15, 2014 8:17 am

My system has one device only on the I2C bus, and the hangups occur rarely after typically a few thousand successful memory reads. They are associated with I2C timeouts which occur more frequently. If we could understand and fix the timeouts, perhaps the lockouts would go away. It might be instructive if someone with an MPU9150 or other I2C device could perform large numbers of i2c.mem_read() calls to see if timeouts occur.

Regards, Pete
Peter Hinch
Index to my micropython libraries.

Turbinenreiter
Posts: 288
Joined: Sun May 04, 2014 8:54 am

Re: Module for MPU9150

Post by Turbinenreiter » Wed Oct 15, 2014 6:40 pm

@blmorris
I actually initialize the bus twice, once from the MPU9150 module and once from the BMP185 module.

I will have to find a way to check if a bus is already initialized and only create it if not.
Passing in the i2c object is also a possibility, but I kinda don't wanna have to deal with i2c at all, just use the device. However, if I can't find a way to check if a bus was already initialized, I will do it that way.

So ... let's hack globals()! Everybody says not to, but I will just walk through the list and check types. I guess.

User avatar
dhylands
Posts: 3821
Joined: Mon Jan 06, 2014 6:08 pm
Location: Peachland, BC, Canada
Contact:

Re: Module for MPU9150

Post by dhylands » Wed Oct 15, 2014 6:47 pm

What not just create a common module which both of your modules import. And have the common module ensure that the initialization only occurs once?

blmorris
Posts: 348
Joined: Fri May 02, 2014 3:43 pm
Location: Massachusetts, USA

Re: Module for MPU9150

Post by blmorris » Wed Oct 15, 2014 8:16 pm

Turbinenreiter wrote:@blmorris
I actually initialize the bus twice, once from the MPU9150 module and once from the BMP185 module.

I will have to find a way to check if a bus is already initialized and only create it if not.
Passing in the i2c object is also a possibility, but I kinda don't wanna have to deal with i2c at all, just use the device. However, if I can't find a way to check if a bus was already initialized, I will do it that way.
At this point I would guess that your problem isn't multiple i2c inits. If that were the problem, most likely you would see a hang right after the redundant initialization, not thousands of reads later.
I don't imagine that you or @pythoncoder have access to an I2C bus sniffer or a logic analyzer that can decode I2C; they are not yet standard hobbyist tools but this is exactly the situation where they prove their value. Hopefully you can track this down soon so it won't be an issue, but you have me interested in getting an MPU9150, so if I get it before it is resolved I will look into it.
-Bryan

User avatar
dhylands
Posts: 3821
Joined: Mon Jan 06, 2014 6:08 pm
Location: Peachland, BC, Canada
Contact:

Re: Module for MPU9150

Post by dhylands » Wed Oct 15, 2014 8:47 pm

You can now get a 4-channel Logic Pro for $100: https://www.saleae.com/?gclid=Cj0KEQjwt ... ricingTile

Or if you don't mind a clone, you can get a clone of one of the older 8-channel Logic's on eBay. Just search for "8 channel 24MHz logic analyzer" and you can pick one of those up for under $15.

I just bought a 16-channel Logic Pro myself.

User avatar
pythoncoder
Posts: 5956
Joined: Fri Jul 18, 2014 8:01 am
Location: UK
Contact:

Re: Module for MPU9150

Post by pythoncoder » Thu Oct 16, 2014 6:00 pm

Returning to the isuue of timeouts and bus lockups I've done some more testing and it seems that the problems only occur in the presence of hardware interrupts. I have two optical incremental encoders each connected to two pins. All four pins use hardware interrupts, with the total maximum interrup rate being about 500Hz. The errors seem only to occur when the interrupt rate is near to that maximum. My interrupt handlers take about 50uS to run, so the CPU utilisation should be on the order of 50/2000 =2.5%. Here is the handler code:

Code: Select all

    def x_callback(self, line):
        self.forward = self.pin_x.value() ^ self.pin_y.value() ^ self.reverse
        self._pos += 1 if self.forward else -1
        self.tprev = self.tlast
        self.tlast = pyb.micros()
I'm unfamilar with I2C so it's not clear to me why these hardware interrupts should cause problems.

Regards, Pete
Peter Hinch
Index to my micropython libraries.

Post Reply