I2C Working

C programming, build, interpreter/VM.
Target audience: MicroPython Developers.
Post Reply
User avatar
JonHylands
Posts: 69
Joined: Sun Dec 29, 2013 1:33 am

I2C Working

Post by JonHylands » Sun Mar 02, 2014 1:41 pm

I don't know if anyone has played with the general I2C library, but I have been able to successfully talk to an L3GD20 3-axis gyro using SCL2/SDA2 on my MicroPython board. The mma sensor on the PYBv4 uses its own i2c code, for some reason. I really like how simple it is to use, and how it handles the transitions from writing to reading seamlessly.

- Jon

torwag
Posts: 220
Joined: Fri Dec 13, 2013 9:25 am

Re: I2C Working

Post by torwag » Thu Mar 06, 2014 8:18 pm

Would be glad to see a code snippet. This way we could test the code formatting of the forum too ;)

User avatar
Neon22
Posts: 18
Joined: Fri Feb 28, 2014 11:53 pm

Re: I2C Working

Post by Neon22 » Thu Mar 06, 2014 9:38 pm

There's a set of useful I2C specific functions built on top as a python library here:
https://github.com/Neon22/micropython-I2C

Needs testing on a board...
here's a code snippet for torvag :)

Code: Select all

class I2C_lib(pyb_I2C):
    """ Extend i2c interface
        Existing methods are:
        - start()
        - write(byte)   # send byte
        - read()        # read byte
        - readAndStop()
        - stop()
    """

    def __init__(self, port, dev_addr):
        " nothing more to add "
        #super().__init__(port, dev_addr) # python 3 form
        super(I2C_lib, self).__init__(port, dev_addr) # python 2.7 - not needed
Looks like no syntax highlighting... (I expect we need python and C highlighting)

duncan
Posts: 2
Joined: Sat Aug 09, 2014 1:47 pm

Re: I2C Working

Post by duncan » Sat Aug 09, 2014 2:02 pm

Hello, first time poster, long time admired of micropython! Apologies if this isn't in the appropriate section.

I've also been communicating with the 3-axis L3GD20 unit. The I2C interface has been working like a charm!

Initially I was pulling 6 bytes out (3 axis, higher and lower bytes) from the device.

a = [0]*6
for i in range(0,6):
a = i2c.mem_read(1,device,subaddress+i)

But a much better a less ugly way is:

a = i2c.mem_read(6,device,subaddress) # read in a single call

HOWEVER

As a kickstarter backer I was using the firmware which came installed (sorry didn't note the firmware number...). I wondered if the math.asin function had been added in the most recent firmware so I installed pybv10-2014-08-09-v1.2-84-g590b2ab.dfu. Unfortunately the I2C routine now seemed to be causing me problems, but only when I read multiple bytes in one block and then only *sometimes*.

It turned out cases like this (below) now cause a problem (where they didn't previously before the firmware upgrade). A problematic byte string might be something like:

b'\xff\x8e\xfe}\xfd\x7f'

which has a length of "6" but element 5 can't be reached (index out of range). However if I read each byte in individually, there is no problem. The same byte string in Python 2.7.6 is handled correctly. To my slightly newbish eye it looks like the '}' may be causing an issue with the indexing function in the byte string?

I will roll back to a previously uPy version and see if it fixes itself.

Would be interested in any helpful thoughts and hope this helps someone else!

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

Re: I2C Working

Post by dhylands » Sun Aug 10, 2014 8:46 am

I'd guess that this has something to do with Unicode support and someplace using chars where it should be using bytes.

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

Re: I2C Working

Post by Turbinenreiter » Sun Aug 10, 2014 10:22 am

I see this behavior all the time, some bytes get print as their ASCII equivalents.
I use struct.unpack to get ints from those bytes and it doesn't care about the chars, returns correct numbers nevertheless. So you'd read 2 bytes at once and then unpack it.

i.E.

Code: Select all

ax = struct.unpack('<h',i2c.mem_read(2,device,subaddress))[0]
ay = struct.unpack('<h',i2c.mem_read(2,device,subaddress+2))[0]
az = struct.unpack('<h',i2c.mem_read(2,device,subaddress+4))[0]
ax, ay and az are now integers, made from two bytes.
the '<h' - part defines type. < or > is little or big endian, h is singned and H is unsigned int.

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

Re: I2C Working

Post by dhylands » Mon Aug 11, 2014 3:10 pm


pfalcon
Posts: 1155
Joined: Fri Feb 28, 2014 2:05 pm

Re: I2C Working

Post by pfalcon » Mon Aug 11, 2014 7:38 pm

This bug was fixed in git.
Awesome MicroPython list
Pycopy - A better MicroPython https://github.com/pfalcon/micropython
MicroPython standard library for all ports and forks - https://github.com/pfalcon/micropython-lib
More up to date docs - http://pycopy.readthedocs.io/

norbo
Posts: 4
Joined: Mon May 04, 2015 7:12 am

Re: I2C Working

Post by norbo » Tue May 05, 2015 6:45 am

I have some issues making the I2C work, bassically i get an Oserror: 12 and with another board an oserror: 5 when trying to do I2C comunication with mem_read. iic.scan() delivers [] and hangs up on the other (custom) board after i initialized I2c twice.
Does anyone has an idea? Would be really helpfull.

Post Reply