PyB-to-PyB using I2C?
-
- Posts: 68
- Joined: Sat May 03, 2014 11:31 pm
Re: PyB-to-PyB using I2C?
At some point all of these leave the strictly lower level and need to address what the user is trying to do, and the consequences of, say, a corrupt block/packet of data. In previous projects, the data was real-time and was sent at a rate of 100 hz. It was important to reliably detect that a packet was bad, but then the consumer had to live with that until a new set of data showed up in msec. A little bit like a Kalman filter, in a way. If the data is terribly important, and an acknowledge/request for repeat is needed, that is different. On my project I used a combination of a Fletcher checksum and a so-called horizontal parity check. This was because it was computationally simple! I never saw it allow a bad block of data through. However, this chip has a hardware CRC genereator, which should be even better, if it could be used to protect a block or packet. But you are right, it needs a way to signal how long a block of data is going to be- or have begin and end flags of some kind... It should be malleable so that it can implemented in different ways for diffreent uses, I guess.
-Gordon
-Gordon
-
- Posts: 68
- Joined: Sat May 03, 2014 11:31 pm
Re: PyB-to-PyB using I2C?
At some point all of these leave the strictly lower level and need to address what the user is trying to do, and the consequences of, say, a corrupt block/packet of data. In a previous project, the data was real-time and was sent at a rate of 100 hz. It was important to reliably detect that a packet was bad, but then the consumer had to live with that until a new set of data showed up in 10 msec. A little bit like a Kalman filter, in a way. If the data is terribly important, and an acknowledge/request for repeat is needed, that is different. On my project I used a combination of a Fletcher checksum and a so-called horizontal parity check. This was because it was computationally simple! I never saw it allow a bad block of data through. However, this chip has a hardware CRC genereator, which should be even better, if it could be used to protect a block or packet. But you are right, it needs a way to signal how long a block of data is going to be- or have begin and end flags of some kind... It should be malleable so that it can implemented in different ways for different uses, I guess.
-Gordon
-Gordon
Re: PyB-to-PyB using I2C?
My experience with i2c slaves is using the smbus protocol with a slave running on an ATMega128.
smbus limits the packet size to 255 bytes.
The smbus protocol has something called Block Read and Write which allow variable sized packets, but the packet size is part of the message.
For non-smbus transfer, my understanding is that the NAK at the end terminates the packet.
So I would expect the slave to do a recv for whatever its max is, and it may get less data.
I don't know exactly what the HAL supports.
smbus limits the packet size to 255 bytes.
The smbus protocol has something called Block Read and Write which allow variable sized packets, but the packet size is part of the message.
For non-smbus transfer, my understanding is that the NAK at the end terminates the packet.
So I would expect the slave to do a recv for whatever its max is, and it may get less data.
I don't know exactly what the HAL supports.
-
- Posts: 68
- Joined: Sat May 03, 2014 11:31 pm
Re: PyB-to-PyB using I2C?
I tested the following slave code, and it works as expected:
Gives the following on the VCP, when you send '123' on the master:
.
.
b'123'
.
.
.
.
The try/except is necessary because the timeout function actually throws an "OSerror: 116".
I will have to extend this in some fashion, I am still thinking it through. Maybe if I want to send 16 bytes, it is done in two stages- first send '0x10' and then send the actual block of data.
Code: Select all
i2cS = I2C(2, I2C.SLAVE) # create and init as a slave
i2cS.init(I2C.SLAVE, addr = 0x55) # init as a slave
print("Slave")
while True:
data = []
try:
data = i2cS.recv(3, timeout=100) # 100 msec
except:
pass
if data != []:
print(data)
else:
print('.')
.
.
b'123'
.
.
.
.
The try/except is necessary because the timeout function actually throws an "OSerror: 116".
I will have to extend this in some fashion, I am still thinking it through. Maybe if I want to send 16 bytes, it is done in two stages- first send '0x10' and then send the actual block of data.
-
- Posts: 35
- Joined: Wed Mar 11, 2015 7:48 pm
Re: PyB-to-PyB using I2C?
I'd like to do some testing with this and the asyncio library to see if we can get an asynchronous I2c socket. Has anybody tried this?
Re: PyB-to-PyB using I2C?
Reporting similar issues.
I can not get the I2C SLAVE talking back to I2C MASTER.
However, both devices do work with a designated I2C slave digital potentiometer flawlessly.
and master:
after hard reset:
1) run slave code
2) run master code
the following happens:
Can anybody explain or replicate?
I can not get the I2C SLAVE talking back to I2C MASTER.
However, both devices do work with a designated I2C slave digital potentiometer flawlessly.
Code: Select all
############## SLAVE device ###########
import pyb
from pyb import I2C
from pyb import Pin
pyb.freq(168000000)
i2c = pyb.I2C(2, I2C.SLAVE, addr=0x42)
while True:
data = []
try:
data = i2c.recv(3, timeout=200) # 100 msec
except:
pass
if data != []:
print(data)
else:
pass
and master:
Code: Select all
import pyb
from pyb import I2C
pyb.freq(168000000)
#i2c = I2C(2, I2C.MASTER, baudrate=400000)
i2c = I2C(2, I2C.MASTER)
i2c.scan()
i2c.send('abc',addr=0x42,timeout=100000)
#i2c.send('abc',addr=0x42)
1) run slave code
2) run master code
the following happens:
MASTER can not see the SLAVE 0x42 on I2C.>>> i2c.scan()
[66]
>>> i2c.send('abc',addr=0x42,timeout=100000)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
OSError: 116
>>> i2c.send('abc',addr=0x42,timeout=100000)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
OSError: 16
>>> i2c.scan()
[]
Can anybody explain or replicate?
Re: PyB-to-PyB using I2C?
Found the only solution that works, but the code is definitely buggy.
Follow the previous post for code setup
If you change slave to receive less than 3 chars,
IOSError: 16 and the I2C interface is fried until hard reset.
The reset must be then performed also on MASTER.
Why is i2c.scan() on MASTER empty, even when SLAVE is ready?
Follow the previous post for code setup
### MASTER:
>>> i2c.scan()
[]
### SLAVE:
>>> i2c
I2C(2, I2C.SLAVE, addr=0x42)
>>> i2c.recv(3, addr=0x00, timeout=122000)
###MASTER:
>>> i2c.send('abc',addr=0x42,timeout=100000)
###SLAVE:
b'def'
If you change slave to receive less than 3 chars,
IOSError: 16 and the I2C interface is fried until hard reset.
The reset must be then performed also on MASTER.
Why is i2c.scan() on MASTER empty, even when SLAVE is ready?
- pythoncoder
- Posts: 5956
- Joined: Fri Jul 18, 2014 8:01 am
- Location: UK
- Contact:
Re: PyB-to-PyB using I2C?
I2C master mode has had a lot of testing on the Pyboard with different devices and data lengths. My guess is that slave mode has been less used and the bug probably lies there.
Peter Hinch
Index to my micropython libraries.
Index to my micropython libraries.
Re: PyB-to-PyB using I2C?
Hi guys
Just wondering whether there's been any further development of the board to board I2C?
Personally, I'm using ESP8266.
My goal is to use 2 devices to monitor each other to improve up time.
Thanks
Just wondering whether there's been any further development of the board to board I2C?
Personally, I'm using ESP8266.
My goal is to use 2 devices to monitor each other to improve up time.
Thanks
Re: PyB-to-PyB using I2C?
As far as I am aware, the 8266 does not support I2C client mode.