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.
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 » Sat Sep 17, 2016 8:23 am

Perhaps we should consider actual needs. In the Pyboard to Pyboard case I'd argue it's a solved problem: we have solid reliable UART drivers and five UARTs. However some platforms are short of UARTs, notably the ESP8266, where there are only 1.5 UARTs and both are subject to assorted random messages from the OS. A proper, asynchronous I2C or SPI slave interface would be useful here.

I wrote a bit-banged full duplex asynchronous driver which can exchange arbitrary Python objects between any pair of MicroPython platforms. So long as you can control four GPIO pins at each end it should work. But its aim to be as hardware independent as possible means it is slow - about 3Kbps. https://github.com/peterhinch/Micropyth ... ter/syncom.

A fast native solution would be good.
Peter Hinch
Index to my micropython libraries.

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

Re: Talking to other MicroPython or WiPy boards

Post by kamikaze » Mon Sep 19, 2016 10:25 pm

just get another PyBoard and use CAN bus like many vehicles do?

User avatar
dbc
Posts: 89
Joined: Fri Aug 28, 2015 11:02 pm
Location: Sunnyvale, CA

Re: Talking to other MicroPython or WiPy boards

Post by dbc » Tue Sep 20, 2016 3:34 am

kamikaze wrote:just get another PyBoard and use CAN bus like many vehicles do?
Indeed. A few months back, before I got distracted by other aspects of life, I worked through the CAN tutorials and was able to get two PyBoards to blink each other's LEDs over the CAN bus.

The prototype just has a couple of TI CAN XCVRs connected appropriately. With any luck, I should be able to find my notes, but it was actually very easy to get going using the CAN API on the PyBoard, so its likely my notes won't add much to the tutorials/docs.

[img]
IMG_2691_sm.jpg
IMG_2691_sm.jpg (67.62 KiB) Viewed 7492 times
[/img]

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 » Tue Sep 20, 2016 5:53 am

@dbc Interesting, that had never occurred to me. To someone ignorant of CAN, what advantages does this have over simply using a UART?
Peter Hinch
Index to my micropython libraries.

User avatar
kfricke
Posts: 342
Joined: Mon May 05, 2014 9:13 am
Location: Germany

Re: Talking to other MicroPython or WiPy boards

Post by kfricke » Tue Sep 20, 2016 9:36 am

"CAN is a multi master serial bus..."
Sorry for pulling the Wikipedia bat out, but the architecture is quite interesting: https://en.wikipedia.org/wiki/CAN_bus#Architecture

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

Re: Talking to other MicroPython or WiPy boards

Post by kamikaze » Tue Sep 20, 2016 11:19 am

To get CAN bus working you'll actually need a CAN bus transceiver like MCP2562 or TCAN337 (because PyBoard has only CAN bus controller).
In a week or so I'll get my brand new PCBs for two interconnected CAN nodes with possibility to connect them to "outer" CAN bus. (tired of breadboard wiring mess). I'm doing my car project so knowing how to work with CAN is very valuable for your possible projects.

More info

User avatar
dbc
Posts: 89
Joined: Fri Aug 28, 2015 11:02 pm
Location: Sunnyvale, CA

Re: Talking to other MicroPython or WiPy boards

Post by dbc » Tue Sep 20, 2016 3:42 pm

pythoncoder wrote:@dbc Interesting, that had never occurred to me. To someone ignorant of CAN, what advantages does this have over simply using a UART?
Well, there are plusses and minuses.

A multi-drop bus with RS-485 is relatively easy to get going if the UART peripheral supports "9-bit mode" -- that is using the 9th bit as an address flag. Usually this is done as a 1-master, N-slaves. After address resolution, non-addressed nodes can mute the UART and therefore don't have to handle an interrupt per character. Hardware usually un-mutes when another address byte is detected. Note that in this kind of system, addressing is per node, and you have 256 addresses to work with. Now, if you look at the ST parts, their 9-bit UART mode is particularly obtuse. I want to find some engineer at ST and slap them. It supports hardware addressing and mute, but they only match on 4 (!) address bits. Golly, I guess with all the other stuff on the chip, having those 4 extra bit latches in the peripheral that it would take to match on 8 bit addresses was just too expensive. There are ways around that, but it involves some rather tricky interrupt handlers to do software muting and so forth -- it's been a while since I looked at it.

Another thing to consider is the cost of RS-485 drivers. In my experience, you can find delicate RS-485 transceivers, or expensive RS-485 transceivers. Robust, inexpensive RS-485 transceivers seem to be scarce. On the other hand, since CAN is an automotive standard, CAN transceivers are pretty much universally robust and low cost, because you don't get automotive design wins without both. One of my friends has done a lot of work on a multi-drop bus where he uses the UART in RS-485 mode, but via CAN transceivers. This has worked very well for him, with one quirk. Since with a CAN transceiver the sender gets a local hardware echo of everything sent, each node will hear the address byte of it's own transmission, which it needs to throw away. Muting takes care of the data after that. This works great with Atmel ATMega parts, as their UART has very nice RS-485 support.

On the topic of transceivers, RS-485 is a differential bus. CAN is very often mistaken for a differential bus, but it is not. CAN collision detection works by having every node synchronize the start of their frames, and a transmitting controller listens to the echo of the sent message ID. Any node that sends a '1' and receives an echoed '0' in the message ID immediately backs off. By the end of the message ID, one node is transmitting in the clear. In order to get that collision detection to work, all nodes must have a common ground -- or at least "common-ish" -- CAN is designed to tolerate a modest amount of ground reference skew.

So, on to message ID's. RS-485 is node-addressed. CAN is publish/subscribe, with the proviso that only one node may publish any given message ID, otherwise collision detection fails. So it is easy to do multi-cast.

There are various protocols built on top of CAN, some with whole books about them, so CAN protocol stacks can get complex, but don't have to. A CAN message payload is 0 to 8 bytes. The CAN controller provides only a low-level interface so if you want to send longer messages, or have a connected protocol, you have to build a protocol on top of the 8 byte limitation. Where CAN is great is if you have short messages and don't stream. The hard part is coming up with a sensible assignment of message IDs.

So... you like robots, I like robots, so let's talk robots. A CAN protocol for a robot might do something like:

Code: Select all

ID=all-0 -- E-stop
ID=<0000><small number>, payload=<opcode> -- high priority commands
ID=<0010><motor ident>, payload=<desired speed> -- motor controls
ID=<0100><sensor id> , payload = <sensor data> -- high priority sensors
ID=<0110><sensor id>, payload = <sensor data> -- lower priority sensors
etc...
So on a CAN bus, the sensors just spit out data when they have it, and other nodes that are interested can snag the message as it goes by. For actuators, the situation is a little different. If multiple nodes want to send messages to a particular actuator, you need to work a sender identification into the message ID some how so that only one of them wins the bus. Note that the message ID determines which node wins, so it implicitly sets the priority. Something like the protocol above is simple as long as you can keep the payload at 8 bytes or less.

My little prototype in the picture above is from when my daughter and I were working on a robot with (on paper, anyway) seven nodes on the CAN bus. Alas, she is now getting the Freshman Engineering experience 3 time-zones away, so I'm back to solo robot development.

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 » Tue Sep 20, 2016 7:02 pm

Thanks for that detailed description. I never realised the STM 9 bit mode was so dumb. What was the designer thinking?

The CAN transceivers must be pretty robust to cope with the automotive environment which is pretty tough electrically and environmentally. I hadn't considered for general use but maybe I should, at least in multi-drop situations. For an 8 bit point to point interface I still think UARTs are the easiest.
Peter Hinch
Index to my micropython libraries.

User avatar
dbc
Posts: 89
Joined: Fri Aug 28, 2015 11:02 pm
Location: Sunnyvale, CA

Re: Talking to other MicroPython or WiPy boards

Post by dbc » Tue Sep 20, 2016 9:03 pm

Yes, for just two PyBoards, a UART link is much simpler. It is multi-drop where CAN gets interesting.

Post Reply