Issue with I2C while writing and reading from buffer

Discussion and questions about boards that can run MicroPython but don't have a dedicated forum.
Target audience: Everyone interested in running MicroPython on other hardware.
Post Reply
nikhiledutech
Posts: 118
Joined: Wed Dec 27, 2017 8:52 am

Issue with I2C while writing and reading from buffer

Post by nikhiledutech » Fri May 18, 2018 12:55 pm

Hey,

I am currently interfacing, I2C with Stm32f407disc board. problem here is when i use bytearray to read small length of data it works fine. But when i increase the bytearray size, and try to read it gives me garbage data.


Here goes my code to send array data of 6 elements. This program works fine and give me the following result, given below.

from pyb import I2C, UART
import utime as time

#I2C Initialisation
i2c = I2C(1,I2C.MASTER, baudrate = 100000) #master mode

#Buffer to transmit and Recieve data
Tx_buf = bytearray(5) #array of 7bytes
Rx_buf = bytearray(5) #array of 7 bytes

#Uart Initialisaion
uart = UART(4, 9600)


#Temp list to hold Read bytearray
temp = [0] * len(Rx_buf)



#Main Function
def main():
for x in range (5):
Tx_buf[x] = x #Sequence number stored in array

#Write Tx_Buf array to slave address 80
#@param ( Data or Data buffer, Addr, mem_addr, timeout, address size )
i2c.mem_write(Tx_buf, 80, 1, timeout = 5000, addr_size = 8)
time.sleep_ms(100) #Delay to write to EEPROM


#Recieve data into Recieve Buffer
#@param (No of bytes/buff, Addr, mem_addr, timeout, address size )
i2c.mem_read(Rx_buf, 80, 1, timeout = 5000, addr_size = 8)


uart.write("Read Array : {} \r\n".format(Rx_buf)) #Transmiting Read byte on UART4


main()
Result

Read Array : bytearray(b'\x00\x01\x02\x03\x04')

Now if i increase the size of the transmitted array,

Tx_buf = bytearray(100) #array of 7bytes
Rx_buf = bytearray(100) #array of 7 bytes
It gives the garbage data given below.
bytearray(b'`abcTUVWXYZ[\\]^\x0e\x0f\x10\x11\x12\x13\x04\x05\x06\x07\x08\t\n\x0b\x0c\r\x06\x07\x08\t\n\x0b\x0c\r\x0e\x0f\x10\x11\x12\x13\x04\x050233456869:;<=>?\x0e\x0f\x10\x11\x12\x13\x04\x05\x06\x07\x08\t\n\x0b\x0c\rPQRSTUVWXYZ[\\]^_`bdcd')
can anyone suggest how to write 256 bytes and read 256 byte of data ?

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

Re: Issue with I2C while writing and reading from buffer

Post by pythoncoder » Fri May 18, 2018 2:54 pm

I take it that the "garbage" is the contents of Rx_buf rather than data read from the UART. So am I right in saying the issue is with reading and writing the EEPROM not with the UART? So we can forget the UART for the moment.

If so you need to determine if the fault occurs on reading or writing; this may involve a degree of low cunning. It seems evident that the data being read back isn't random garbage: it looks very much like data which has been written on previous tests, as it contains long sequences of incrementing values. Try zeroing 256 bytes but then reading back several small sets of data from different addresses to see if the write was successful. If it was, try writing values from 0 to 255 to addresses 0-255 and again reading back small sets.
Peter Hinch

nikhiledutech
Posts: 118
Joined: Wed Dec 27, 2017 8:52 am

Re: Issue with I2C while writing and reading from buffer

Post by nikhiledutech » Mon May 21, 2018 5:23 am

Hello,
So as per your advice i wrote 0 to 256 byte of data . It worked fine . I also read the same in 256 bytes of buffer.

for x in range (255):
i2c.mem_write(0x00 , 80, 1 + x, timeout = 5000, addr_size = 8)
time.sleep_ms(100) #Delay to write to EEPROM



i2c.mem_read(Rx_buf, 80, 1, timeout = 5000, addr_size = 8)

for val in range(len(Rx_buf)):
temp[val] = Rx_buf[val] #Temp list holding the read data

print(Rx_buf)
I read data from different locations.

Rx_buf1 = bytearray(5)
i2c.mem_read(Rx_buf1, 80, 50, timeout = 5000, addr_size = 8)
print(Rx_buf1)

It read zero values from 50-55th mem address . I also printed out the whole 256 byte after reading it into buffer. It print out zero.


But problem occurs when i try to write incrementing data, In read, it throws up garbage value after 8-9 successful read cycles. The previous write cycles was of 0x00.


Below is the code and result which i get after writing 0-15 at address 1-15.

for x in range (255):
i2c.mem_write(0x00 , 80, 1 + x, timeout = 5000, addr_size = 8)
time.sleep_ms(100) #Delay to write to EEPROM

for x in range (255):
i2c.mem_write(0x00 + x , 80, 1 + x, timeout = 5000, addr_size = 8)
time.sleep_ms(100) #Delay to write to EEPROM

i2c.mem_read(Rx_buf1, 80, 1, timeout = 5000, addr_size = 8)
print(Rx_buf1)
Result: bytearray(b'\x00\x01\x02\x03\x04\x05\x06\x07\x08\t\n\x0b\x0c\r\x0e')


So how to solve this issue ?

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

Re: Issue with I2C while writing and reading from buffer

Post by pythoncoder » Mon May 21, 2018 6:22 am

That looks correct. I think you may be misunderstanding the way Python displays bytes and bytearray objects. Where an element can be represented as an ASCII character it will be, so 0x09 is shown as \t (the tab character) and 0x0a displays as \n (newline).

Code: Select all

>>> a = bytearray(b'\x00\x01\x02\x03\x04\x05\x06\x07\x08\t\n\x0b\x0c\r\x0e')
>>> for x in a:
...     print(hex(x))
... 
0x0
0x1
0x2
0x3
0x4
0x5
0x6
0x7
0x8
0x9
0xa
0xb
0xc
0xd
0xe
>>> 
Peter Hinch

nikhiledutech
Posts: 118
Joined: Wed Dec 27, 2017 8:52 am

Re: Issue with I2C while writing and reading from buffer

Post by nikhiledutech » Tue May 22, 2018 6:24 am

okay got it. thanks Sir.

Still there is slight problem. I have read correctly 255 bytes out of 256. But the last byte should be FF and its reading 0xF.

Why So ?

0xF8 - 0xFF : ['0xf8', '0xf9', '0xfa', '0xfb', '0xfc', '0xfd', '0xfe', '0xf']

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

Re: Issue with I2C while writing and reading from buffer

Post by pythoncoder » Tue May 22, 2018 7:44 am

I think you need to read up on the Python range keyword. Or experiment with it...
Peter Hinch

Post Reply