Communicating between two cortex - dual cortex robot


The code linked at the end of this post allows two cortex controllers to be connected using their UART ports. The master cortex (with VEXnet and joystick) controls the slave cortex (no VEXnet) using the example communications protocol.

I’ve posted about serial communications before in the ROBOTC programming tips thread, however, I wanted to show an example that was a little more developed with bi-directional communication between two devices.

For some of the products I work on at my day job I created a simple protocol known as the P3 protocol (when I talk about a “protocol” I’m referring to the rules that need to be followed to allow communication wiki). The name (although having another meaning) was supposed to indicate an enhanced version of an old Sony protocol known as the P2 protocol. This was used for many years in the broadcast industry as a means to control video tape recorders and other similar equipment. The official spec for that would have to be obtained from Sony but I see a summary has been posted here. The P2 protocol has some limitations and is not ideal as a general purpose communications method. The baud rate is slow (38.4k) and the maximum payload data size is only 15 bytes, however, it was an easy protocol to implement and I used custom variations of it for many years.

I decided to port a simplified version of my P3 protocol to ROBOTC on the cortex as a demo. The original plan was to have an application running on a PC controlling the cortex, I did implement that but decided I didn’t want to deal with the cross platform and driver issues involved with publicly releasing it. Plan B uses two cortex controllers connected to each other, one acts as a communications master, the other as a slave.

Serial communication in the context of this post means asynchronous serial communication. This is a means of communication where the clock (a periodic timing signal that determines the speed that data is sent) is not sent from one device to another as a discrete signal. Sometimes the clock is encoded into the data so that a receiving device can exactly recover it, however, in this case it means that as long as both sending and receiving devices know the approximate clock speed (say within 5%) the information can be retrieved from just one data signal. The alternative to asynchronous would be synchronous communication, one flavor of this is used for communications between the cortex and IMEs and is called I2C (inter integrated circuit). Lots of detail on I2C in this old post.

**Example code functionality
The demo only implements commands for motor control and status. A complete implementation would also allow access to the sensor ports and perhaps offload certain processing tasks. The Demo allows the joystick on the master cortex to control four motors on the slave cortex (all 10 are theoretically controlled but only the analog joystick channels are connected to the motors).

**Format of a data packet.
The protocol is not that different from others I have presented in the past. All communication is initiated by the master cortex, it sends a packet of information (several consecutive bytes) to the slave. The slave replies to the master with either an acknowledge (ACK), requested information or an indication that an error has occurred (NAK). Any baud rate can be used but for the example code I am running at 230.4K, pretty much the highest standard rate supported by ROBOTC.


For complete information on the protocol see the document here.

A serial transaction captured by an oscilloscope appears as follows.

Due to the nature of the ROBOTC implementation there will always be a small delay between command and reply, however, this really is not an issue and still easily allows a message to be sent every 10mS (100Hz).

**Connection between host (master) cortex and slave

Demo source code

The source for the p3 library and the demo code (both master and slave) is on github. The ROBOTC implementation limits commands to 128 bytes of data to save memory, this can be increased by modifying the header file if necessary, see the source for more details.


I’d just like to point out I love the captions of “Master” and “Slave”

Well that actually is the correct terminology.

I ported this code to ConVEX and PROS (almost identical code), more or less reverting it back to where it started before moving to ROBOTC. I did not include a full demo project but something that could be added to an existing project perhaps, see the source. Code is the same place as before.

1 Like

Would it be possible to use Y-splits in order to control several cortexes from one?

Please don’t revive such old threads.

To some degree, Y-cables may allow UART communication, but ultimately all signals will be sent to both Cortexes that are not the senders of the message. A more sensible solution would be to just use 1 UART port per Cortex.

I disagree. This was some really interesting information for me that i would probably have never searched for. I learned a lot reading this, and i am glad it got bumped back to the top.

1 Like

If you wanted to communicate with multiple cortexs you have some options.

  1. I2C but would have to write a lot of the basic code yourself because last I checked ROBOTC did not support generic I2C devices.

  2. UART with a single master talking to n slaves. You would need to use a some sort of way to signal each Cortex that it is the cortex you are trying to talk to. The normal technique for something like this is what we call a Chip Select. It involves digital pins between master and slave. The master pulls pins high and the slave sees that it is being talked to so it reads the UART stream.

You could do this simply with up to 12 slave cortexs’ on the master, 1 per digital port. If you wanted to save some digital ports you could also use binary numbers, 6 ports could allow you to communicate with 2^6 additional cortex’s. If you need more than 64 slaves you really should rethink your life. The max would be 2^12 so 4096 slaves.

  1. UART could also be done similar to number 2 but without the Chip Select. You would need to address each UART msg as to who should be receiving it. The overhead on short bursts of msgs would be quite annoying but this system could actually be used to incorporate an infinite amount of cortex’s. Also every cortex would have to read every header of every msg to decide if it needs to act. Creating a header on msgs is really good practice anyway.