I was wondering if anyone has some working sample code for multi-byte reads from the I2C bus?
I'm using the mp-esp8266-firmware-v02.bin
Code: Select all
#4 ets_task(40100278, 3, 3fff4658, 4)
MicroPython v1.6-336-g6f5af76-dirty on 2016-03-16; ESP module with ESP8266
Type "help()" for more information.
The time is set properly via an RPi (hwclock -w), and with a battery in place, I have confirmed it is working properly when moving from the RPi to the ESP8266 and back.
When I try read all the by registers at once in MicroPython, only the first byte appears to have valid data (and seems to properly increment with seconds). Note that I write a zero to register 0 before reading. Without it, I seem to get garbage data. (Is that really needed?)
Code: Select all
>>> from machine import Pin, I2C
>>> i2c = I2C(scl=Pin(5), sda=Pin(4), freq=100000)
>>> buf=array.array('H')
>>> buf.append(0)
>>> print(buf)
array('H', [0])
>>> i2c.writeto(0x68,buf)
>>> print(i2c.readfrom(0x68, 7) )
b'\x14\xff\xff\xff\xff\xff\xff'
>>> print(i2c.readfrom(0x68, 7) )
b'\x01\xff\xff\xff\xff\xff\xff'
>>> print(i2c.readfrom(0x68, 7) )
b'\x03\xff\xff\xff\xff\xff\xff'
>>> print(i2c.readfrom(0x68, 7) )
b'\x93\xff\xff\xff\xff\xff\xff'
>>> print(i2c.readfrom(0x68, 7) )
b'\xfa\xff\xff\xff\xff\xff\xff'
>>> print(i2c.readfrom(0x68, 7) )
I was able to get something somewhat working, by reading a single byte at a time with this hack:
Code: Select all
class DS1307():
def __init__(self, addr=0x68):
self._addr = addr
self._i2c = I2C(scl=Pin(5), sda=Pin(4), freq=100000)
def _readbyte(self):
return self._i2c.readfrom(self._addr, 1)
def _readbyte_nostop(self):
return self._i2c.readfrom(self._addr, 1, stop=False)
def readbuf_nostop(self, numbytes):
# it seems only one byte is actually returned! (the remainders are 0xff)
# we will assume this is an incomplete implementation
self._write(0,0) # we need to send a zero to start reading
buf = [0x0] * numbytes # char array
for i in range(0, numbytes-2):
buf[i] = self._readbyte_nostop()
print(i, hex(ord((buf[i]))))
buf[i + 1] = self._readbyte() # final read includes stop
print(i + 1,hex(ord((buf[i+1]))))
return (buf)
has anyone had any luck with multi-byte I2C? or perhaps can spot what I'm doing wrong? Thanks