Talking to other MicroPython or WiPy boards

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.
betabrain
Posts: 5
Joined: Wed Aug 17, 2016 12:55 pm

Talking to other MicroPython or WiPy boards

Post by betabrain » Thu Sep 15, 2016 6:07 pm

Hello,

Has anyone any experience, advice, or opinions about connecting multiple micropython and/or wipy boards? The aim is to separate concerns and distribute load. Ideally the connection could be extended to more than two boards and reuse existing library code for all hw interaction.

- Are there existing projects that do something like this?
- Which IO tech/connectors are best suited?
- Are there any relevant constraints, e.g. necessity to use interrupts which would limit the complexity of the 'networking stack'?

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

Re: Talking to other MicroPython or WiPy boards

Post by deshipu » Thu Sep 15, 2016 9:06 pm

I have a project where I used a PyBoard (now replaced with an OpenMV board) as a robot's brain, and a second microcontroller (ATmega328p) for generating the PWM signal for all the 18 servos. It's quite easy to make the two boards communicate over the I2C protocol, with one of them being the master, and possibly multiple boards being slaves. If you only need to connect two boards, then you could also use UART. If you need higher speeds, then probably SPI is the way to go. You can also have multiple devices on the same SPI bus, with additional "chip select" pins for each device.

There was no particular complexity necessary in my case, but if you need some real-time signaling, you might indeed add an "interrupt" pin that lets the master know that there is something to read from the slave.

As for connectors, I just use simple dupont cables with female plugs.

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

Re: Talking to other MicroPython or WiPy boards

Post by dhylands » Fri Sep 16, 2016 6:15 am

You can do multidrop serial as well.

I've implemented the bioloid protocol, which uses a single wire (plus ground) to connect multiple devices together. The UART uses 1 Mbit speed.

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

Re: Talking to other MicroPython or WiPy boards

Post by pythoncoder » Fri Sep 16, 2016 7:02 am

My preference would be to use UARTs over I2C because the UART drivers work asynchronously. In particular received characters are buffered. This means that the sender can send data even if the receiver happens to be doing something else at the time. The data will be buffered by the receiver so nothing is lost. All you need to do is define the buffer size. This can be taken further with automatic flow control, but in most applications this isn't necessary.

As I understand it I2C slave mode requires that the receiver is trying to receive at the time when the transmitter is sending. This could be problematic, depending on the application.
Peter Hinch
Index to my micropython libraries.

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

Re: Talking to other MicroPython or WiPy boards

Post by deshipu » Fri Sep 16, 2016 7:32 am

pythoncoder wrote: As I understand it I2C slave mode requires that the receiver is trying to receive at the time when the transmitter is sending. This could be problematic, depending on the application.
For that reason, the platforms that have hardware i2c slave support often have them implemented with a buffer (usually 32 bytes long), that gets filled by the hardware (or by an interrupt in the i2c-handling library).

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

Re: Talking to other MicroPython or WiPy boards

Post by pythoncoder » Fri Sep 16, 2016 8:09 am

deshipu wrote:...For that reason, the platforms that have hardware i2c slave support often have them implemented with a buffer (usually 32 bytes long), that gets filled by the hardware (or by an interrupt in the i2c-handling library).
I2C is intended for situations where the slaves are silicon chips (the giveaway is in the name "Inter-Integrated Circuit"). These are assumed permanently to be ready to communicate. With an unbuffered, blocking, software slave you really need to assign another pair of wires to protocol. Master asserts "I want to transmit", slave asserts "OK, go ahead" and enters blocking read. But even that is only a partial solution: in general the master might want to read or write, adding a further level of protocol.

In your opinion would a buffered, interrupt driven asynchronous slave mode be feasible on the Pyboard?

Or is the exercise pointless? UARTs aren't perfect, but their issues have been understood for decades...
Peter Hinch
Index to my micropython libraries.

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

Re: Talking to other MicroPython or WiPy boards

Post by deshipu » Fri Sep 16, 2016 8:36 am

UART has exactly the same problem with having to be always ready to receive, and it's solved the same way -- with a buffer.

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

Re: Talking to other MicroPython or WiPy boards

Post by deshipu » Fri Sep 16, 2016 8:46 am

In fact, I2C has an advantage over 2-wire UART here: when the buffers get filled, the slave can hold down the SCL line to tell the master to wait for it to process it (this is called clock stretching), while all UART can do is either discard the data from the buffer or ignore the incoming data.

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

Re: Talking to other MicroPython or WiPy boards

Post by pythoncoder » Fri Sep 16, 2016 4:26 pm

The overflow problem can be fixed with flow control - albeit at the expense of two extra wires. This does work with the Pyboard driver. An alternative is <ctrl>S <ctrl>Q flow control which avoids the need for extra wires and only works if using a half-duplex protocol. I don't think this has been implemented on the Pyboard.

I appreciate that I2C slave mode could be implemented in an asynchronous fashion using interrupts and buffering and that clock stretching can be used to implement flow control. But my understanding is that the existing Pyboard slave mode driver doesn't actually do this. Rather it implements synchronous (blocking) methods which are harder to use effectively.

If I'm right on this my advice remains that, with current Pyboard driver implementations, UARTs are easier to use.
Peter Hinch
Index to my micropython libraries.

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

Re: Talking to other MicroPython or WiPy boards

Post by dhylands » Fri Sep 16, 2016 4:34 pm

I've implemented I2C slaves on the AVR (fully interrupt driven). I've also implemented I2C bootloader for the AVR. And as @deshipu suggests, the fact that you can stretch the clock does allow for certain types of "synchronous" operations. IIRC, according to smbus you're allowed to stretch for upto 35 msec, which means that you could even implement I2C callbacks in python.

SPI is a bit more unforgiving.

Post Reply