I2C.SLAVE send() no data receive

The official pyboard running MicroPython.
This is the reference design and main target board for MicroPython.
You can buy one at the store.
Target audience: Users with a pyboard.
Post Reply
titchap
Posts: 5
Joined: Thu Sep 10, 2015 6:02 am

I2C.SLAVE send() no data receive

Post by titchap » Thu Aug 18, 2016 1:25 pm

Hello.
After a several tests and after to try the different issues in post viewtopic.php?f=6&t=597&start=10, I come towards you for you help.
I try to communicate in I2C interface with the two pyboard. On in Master and another in Slave, of course.
I use the Pyb.I2C module (no machine.I2C).

I follow the topic (issue) above and I can :
- scan my Slave,
- receive a data from Master to Slave (Master -> Slave),
but when I try to receive a data from Slave to Master (Slave -> Master), i don't recover a good data.

I see in the web several person who post the example for I2C.MASTER implementation but much less for the I2C.SLAVE.
I try the example of code of blmorris post #340 in viewtopic.php?f=6&t=597&start=10.

Code: Select all

#For master 
from pyb import I2C
i2cM = I2C(1, I2C.MASTER)
i2cM.init(I2C.MASTER)
#Launch the receiv commande for the slave and continu with
i2cM.send('ABC', addr=0x42)
#I receive the good 'ABC' in the slave - Ok !
#Launch the send commande for the slave and continu with
i2cM.recv(3, addr=0x42)
#I receive for the master only >> b'\x0c\x00\x00' or b'\x00\x00\x00'

Code: Select all

 For the slave
 from pyb import I2C
i2cS = I2C(1, I2C.SLAVE)
i2cS.init(I2C.SLAVE,addr= 0x42)
i2cS.recv(3,addr=0x42, timeout=-1)
#Launch the send command for the master and continu with
i2cS.send('ABC', timeout=-1)
#Launch the receive commande for the master.
 
I try lot of test with the different address of slave, with the i2c.mem_read() instead of i2c.recv(), with the different baudrate ... i dont know why i can retreive the data only for the master to slave and not for the slave to the master.

For my tests, I use the two pyboard PYBV1.0 and PYLITEv1.0 upgrade with the lasted révision of micropython.
- MicroPython v1.8-66-gcc80c4d on 2016-05-13; PYBv1.0 with STM32F405RG
- MicroPython v1.8.3-8-gaf9889f on 2016-08-12; PYBLITEv1.0 with STM32F411RE

Does someone there an idea ?

User avatar
deshipu
Posts: 1388
Joined: Thu May 28, 2015 5:54 pm

Re: I2C.SLAVE send() no data receive

Post by deshipu » Thu Aug 18, 2016 2:50 pm

I2C communication is usually controlled by the master, so only the master can decide when to send or receive data. The slave should have some kind of a callback that gets called when the master sends or requests data, and any send operations should be only inside that callback -- or at least that's how it always was on other boards and in other languages. I have no experience with slave i2c on PyBoard, so can't really help further.

titchap
Posts: 5
Joined: Thu Sep 10, 2015 6:02 am

Re: I2C.SLAVE send() no data receive

Post by titchap » Thu Aug 18, 2016 3:05 pm

Yes you are right. i understand that and this for that i follow the example and the send slave command launch before the master request. the SCL is provide by the master so the master should receive the nice data prepared by the slave.

I don't understand why is no a good data to receive to master while the example I find in the previous post seems to work for other members.
perhaps is du by i use a pyboard LITE with e pyboard V1 ?

Dont worry, thank you for your response. I appreciate your effort.

PS: Sorry for my english ;-)

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

Re: I2C.SLAVE send() no data receive

Post by pythoncoder » Fri Aug 19, 2016 6:48 am

@titchap tl;dr Unless you've a good reason to use I2C and are fairly experienced I'd recommend using a UART. It's a far easier way to communicate between Pyboards.

@deshipu Callbacks are undoubtedly the way to implement the slave interface but there isn't any documented way to implement these. As far as I can see the Micropython I2C slave interface API is incomplete and you'd have to do it yourself with interrupt handlers.

@titchap The fundamental problem is that I2C is designed to enable a master device to communicate with multiple slaves where the slaves are usually silicon chips. The specification requires the slave to respond fast when the master changes the state of the SCL line. If the slave is a microcontroller a response in a guaranteed maximum time implies an interrupt handler because the master can attempt to communicate at times when the slave may be doing something else.

The Pyboard API only provides blocking calls such as the recv function. Using these is bound to be tricky because you have always to ensure that the slave calls this before the master attempts to communicate. If you lose message synchronisation either the master's transmission will fail (because the slave is doing something else) or the call to recv will block for a long time because the master has failed to transmit.

By contrast the UART API is capable of asynchronous (background) communication. The interface is well proven and easy to use.
Peter Hinch
Index to my micropython libraries.

titchap
Posts: 5
Joined: Thu Sep 10, 2015 6:02 am

Re: I2C.SLAVE send() no data receive

Post by titchap » Fri Aug 19, 2016 7:44 am

Thank you for taking the time to reply. is very friendly.

yes i know UART and I2C protocol and I think your are right, but i dont have possibility of choice. I think the pyboard is just a good issue for implementing in the test hardware for a benchmark of a product. This product use an I2C interface and my requirement is find a mean for test it.

So i just need a little board for make a ADC acquisition and transmit the result by the I2C interface. So I can test if the product is a good battery and a good I2C interface. Just little.
I try to communication over the I2C and i have just a last problem ... transmit the résult after the request Master.
I read the different post and i see the same difficulty but blmorris member give an example for exchange between two pyboard over I2C. viewtopic.php?f=6&t=597
For me, just the received data is not good and i dont know why. It seem is fonctionnal in the post.

I'm understand the API I2C interface is not a good implementation in pyboard and i dont recomment for an new architecture for an important developpement.
After, if is not possible to send a data in SLAVE mode for pyboard, why not remove it from the API ?

I think I fiind someone who are use the I2C SLAVE Mode and tell me this recommandations for reach the send data.

Thank you very much for your time and response.

User avatar
deshipu
Posts: 1388
Joined: Thu May 28, 2015 5:54 pm

Re: I2C.SLAVE send() no data receive

Post by deshipu » Fri Aug 19, 2016 8:15 am

Personally I use a small Pro Mini (Atmega328p) board for doing battery voltage monitoring and also generating servo pwm -- I found it to be much easier to delegate such tasks to a small microcontroller. I run it as an i2c slave, and my MicroPython boards are the masters for it. It works well enough.

User avatar
kamikaze
Posts: 154
Joined: Tue Aug 16, 2016 10:10 am
Location: Latvia
Contact:

Re: I2C.SLAVE send() no data receive

Post by kamikaze » Fri Aug 26, 2016 2:35 pm

just asking... why not CAN?

Post Reply