Talking to other MicroPython or WiPy boards
Talking to other MicroPython or WiPy boards
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'?
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'?
Re: Talking to other MicroPython or WiPy boards
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.
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.
Re: Talking to other MicroPython or WiPy boards
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.
I've implemented the bioloid protocol, which uses a single wire (plus ground) to connect multiple devices together. The UART uses 1 Mbit speed.
- pythoncoder
- Posts: 5956
- Joined: Fri Jul 18, 2014 8:01 am
- Location: UK
- Contact:
Re: Talking to other MicroPython or WiPy boards
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.
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.
Index to my micropython libraries.
Re: Talking to other MicroPython or WiPy boards
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).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.
- pythoncoder
- Posts: 5956
- Joined: Fri Jul 18, 2014 8:01 am
- Location: UK
- Contact:
Re: Talking to other MicroPython or WiPy boards
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.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).
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.
Index to my micropython libraries.
Re: Talking to other MicroPython or WiPy boards
UART has exactly the same problem with having to be always ready to receive, and it's solved the same way -- with a buffer.
Re: Talking to other MicroPython or WiPy boards
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.
- pythoncoder
- Posts: 5956
- Joined: Fri Jul 18, 2014 8:01 am
- Location: UK
- Contact:
Re: Talking to other MicroPython or WiPy boards
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.
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.
Index to my micropython libraries.
Re: Talking to other MicroPython or WiPy boards
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.
SPI is a bit more unforgiving.