Linking two controllers together - the how? part

There has been lots of talk about the new controllers’ i/o functions and, more specifically, ways of linking the edu controller to the main controller.

Being kinda inexpierienced when it comes to these types of things, could some of you guys explain how this would work? Specifically details about synchronizing the two codes. When do you read in (serin?) info and when do you output info? What are the steps to synchronize the two? Say that you’d use the serial port… is there any special data/packet formatting that you have to do?

I (and I’m sure a lot of other programmers too scared to say it) basically have no idea where we would start with something like this. Anyone care to go over the concepts?

What talk?!

Well, one good example is the Digital I/O. Lets say you have some extra sensors attached to the eduBot RC, the Gyro for example. For those who havent, check out StangPS, the auto system that Wildstang developed. You can see their explanation here:

http://www2.wildstang.org/2003/video/StangPS/

Lets say your Main RC, or MRC, as I’ll say, is connected by it’s last 2 digital i/o pins, 15 + 16, to the eduRC, or ERC. I’m just giving this as a rough example, not a hard fact of how to do it all. The MRC gets the signal from the competition controller that the user mode has been turned to Auto mode. It’s auto program is to do the following:

-Ping the ERC
-Receive a small array of Data from the eduRC
-Output that Data to the PWM outputs.
-Loop until Auto mode is turned off

Lets look at Step 1.

Ping the ERC:
The MRC sends out a “1” or on signal through both its Digital pins. The ERC, while calculating, treats this form of signal as a signal to send the data.

Send the Data:
The ERC Stops what it’s doing, and sends data out to the MRC. It could probably send in binary form. If pin 15 is activated, it represents a “1”, and pin 16 represents a “0”. At the same time, the MRC is receving the data and assigning it to a chunk of memory. When the ERC is done, it will send an on signal through both pins. This Would represent an “EOF” of some sorts, because it would be impossible to have both 0 and 1 at the same time in a binary “string”.

Sort and Output data:
The MRC would check back to that memory location, convert the “string” to integers, assign them to individal values, and output them the the PWMs.

Why would you do this?
Well, there are several reasons. First off, you would have a clean slate using the ERC’s memory to hold all of your Auto Mode data. This would free up lots of room on the MRC for whatever you need. Also, the ERC would be doing the sensor input and calculations for auto mode, and the MRC would only be outputting that data. That leaves more room for program space on the MRC as well. The ERC would be treated as it’s own auto mode device. This can clear things up sometimes when your defining parts of your robot. All your auto sensors branch to the ERC, and can continue to be read during user mode.
Also, for speed. By the time the MRC put the string in memory into variables, and outputs it to the PWM’s, the ERC has calculated the next batch of data, and can send it. If you only used the MRC, you’d have to calculate, then send, but you could do both at once with connecting the two controllers.

My example isn’t perfect. In reality, you would probably need 3 pins for it to work correctly. Why?
If your program loops are not exactly synced, this is what happens:

SENDS ERC:1
RECEIVES MRC:1
RECEIVES MRC:1
SENDS ERC: 0
RECEIVES MRC:0

So thus:
The ERC tried to send this data:
10
but the MRC got this:
110
Why did the MRC get an extra 1? Because it looped it input routine around 2 times before the ERC had the next bit ready.
A way to get around this would use 3 pins.
One that Represents a 1, one that represents a 0, and one that acts as a go-between, or I’ll call it the “GB” bit.
When the ERC receives the “All Go” signal from MRC, it pings back one “All go signal”, and if it gets another back, it begins sending data.
First, it activates it’s GB pin. This tells the MRC to wait for the next value before it adds anything more to the string.
Then it begins sending the data as normal, with a GB signal in between each bit value. At the end, it pings back an all go signal. The mrc pings one back if it received everything fine, and the ERC trots on its merry little way.

This way, even though it might be a tad slower, it is absolutely stable data that you are receiving.
Anyway, I’ll post more on this later, but I’m glad someone brought it up.

I have thought of this possibility. I thought you ment there was talk of that being the standard, required configuration.

My guess is that FIRST will expect team to use the Serial TTL ports as a standard, and IFI will probably include code for interfacing through those pins in the default code. The only problem is that the TTL port is slower than if you used a digital i/o configuration. As usual, if you do it yourself, it’s worth the effort.

*Originally posted by SuperDanman *
When do you read in (serin?) info and when do you output info? What are the steps to synchronize the two?

If the new processor in the RC is even remotely decent, it should provide an interrupt when a byte is received by the serial port. Also, if you’re transmitting data, it should provide an interrupt when the transmit buffer is empty. I haven’t checked the spec sheet on it yet, but I’d be very surprised if this wasn’t true.

The way we set up our StangPS last year, the RC was in control of the serial link and would send out a “request” byte to our custom circuit’s microcontroller. Our custom controller was just running a loop of code that read various sensors and constantly recalculated its position. When a request byte came in from the RC, it generated an interrupt which caused our microcontroller to jump to the interrupt code where we took care of responding to the request byte. After the interrupt handler was done, it would resume the main loop of checking sensors & updating its position.

**Say that you’d use the serial port… is there any special data/packet formatting that you have to do?
**
This would be entirely up to you. I’d recommend you design some sort of protocol that the two use to talk to each other. Again, in our example, the “protocol” was merely a single byte sent from the RC to the custom circuit that requested a certain type of data. When the custom circuit received it, it responded with a predermined number of bytes which the RC was waiting for with a serin statement.

*Originally posted by Sachiel7 *
**My example isn’t perfect. In reality, you would probably need 3 pins for it to work correctly. Why?
If your program loops are not exactly synced, this is what happens:

SENDS ERC:1
RECEIVES MRC:1
RECEIVES MRC:1
SENDS ERC: 0
RECEIVES MRC:0

So thus:
The ERC tried to send this data:
10
but the MRC got this:
110
Why did the MRC get an extra 1? Because it looped it input routine around 2 times before the ERC had the next bit ready.
A way to get around this would use 3 pins.
One that Represents a 1, one that represents a 0, and one that acts as a go-between, or I’ll call it the “GB” bit.
When the ERC receives the “All Go” signal from MRC, it pings back one “All go signal”, and if it gets another back, it begins sending data.
First, it activates it’s GB pin. This tells the MRC to wait for the next value before it adds anything more to the string.
Then it begins sending the data as normal, with a GB signal in between each bit value. At the end, it pings back an all go signal. The mrc pings one back if it received everything fine, and the ERC trots on its merry little way.

This way, even though it might be a tad slower, it is absolutely stable data that you are receiving.
Anyway, I’ll post more on this later, but I’m glad someone brought it up. **

You could also have one line be a data line and another be a clock line. So it would look like this (to send 10010):


Line 1 1111000000001111100000
Line 2 0011110000111100001111
Result   1   0   0   1   0

So whenever the clock line toggles, the data would be considered new. I also came up with another way of doing it:


Line 1 01110111011101110111000
Line 2 00100000000000100000010
Result     1   0   0   1   0

This way, whenever Line 2 turns on, the receiver resets a variable. If Line 1 turns on while Line 2 is on, it sets the bit to 1. When Line 2 turns off, it stores/processes it. Once the nybble/byte/word/double/long/whatever length message is done, the EDU turns Line 2 on, telling the receiver to execute it or do whatever. The EDU could also pause between bits, waiting for the receiver to turn on one of the lines as a feedback signal. Two signals could mean start and next, so the receiver setting Line 1 high tells the sender to measure the data, then the sender sets Line 2 high. Then the receiver sets Line 1 low, the sender sets Line 2 low, and begins to send data. Between bits, the receiver would set Line 2 high to ask for the next bit, and the sender would start sending on Line 1. By making the communication two ways, this allows for the receiver to ask for data while it is doing mindless work, and not receive it when it is busy.

Since the EDU RC has a RF link built into it, I dont think FIRST will let you use them on your competition bot.

What channel would it try to receive and transmit on? (dont forget, the RC does transmit data back to the operator interface)

getting all your needed inputs into the RC on the pins provided is part of the challenge.

*Originally posted by Dave Flowerday *
This would be entirely up to you. I’d recommend you design some sort of protocol that the two use to talk to each other. Again, in our example, the “protocol” was merely a single byte sent from the RC to the custom circuit that requested a certain type of data. When the custom circuit received it, it responded with a predermined number of bytes which the RC was waiting for with a serin statement.

To my knowledge there is no way to have an interrupt when a byte is received. Don’t worry there is a way around this. You use a seperate general purpose IO line and set that up as an interrupt. On the transmitting side, whenever you finish sending a frame, you raise the line and trigger the interrupt.

*Originally posted by KenWittlief *
**Since the EDU RC has a RF link built into it, I dont think FIRST will let you use them on your competition bot.

What channel would it try to receive and transmit on? (dont forget, the RC does transmit data back to the operator interface)

getting all your needed inputs into the RC on the pins provided is part of the challenge. **

It’s entirely possible that they have engineered the new control system in such a way that if those mysterious R/C PWM IN lines are in use, that the radio is disabled(or some other means of detecting both devices in use)…

*Originally posted by Rickertsen2 *
**To my knowledge there is no way to have an interrupt when a byte is received. Don’t worry there is a way around this. You use a seperate general purpose IO line and set that up as an interrupt. On the transmitting side, whenever you finish sending a frame, you raise the line and trigger the interrupt. **

Please see the PIC 18F8520 datasheet, page 94 (of the PDF, page 92 of the document itself), bits 3-5.

As I said, any microcontroller worth its salt provides interrupts when bytes are transmitted/received. Regardless, even if it didn’t you’d simply need to poll the receive buffer status to see when it’s full, and then go and read in the data that was received. No need to use an external signalling line (good thing too, since you wouldn’t be able to do that with anything off-the-shelf that speaks RS232).

This isn’t hard to do, and better yet if InnovationFirst allows access to the Serial Port Interface (SPI) module on the 18f8520 all you have to do is load the byte and tell the controller to transmit.

It looks like the others have covered the basics of doing the software version of SPI so I won’t cover it again.

This will be fun. I think a PS2 controller is going to be hooked up.

*Originally posted by Dave Flowerday *
**Please see the PIC 18F8520 datasheet, page 94 (of the PDF, page 92 of the document itself), bits 3-5.

As I said, any microcontroller worth its salt provides interrupts when bytes are transmitted/received. Regardless, even if it didn’t you’d simply need to poll the receive buffer status to see when it’s full, and then go and read in the data that was received. No need to use an external signalling line (good thing too, since you wouldn’t be able to do that with anything off-the-shelf that speaks RS232). **

IF the 18Fxx20 is llike some of its great uncles, it may even have a serial interface in hardware. Interrupt-on-change by pin is a recurring theme in the 16F/Cxx line, so there is the likihood of an automatic serial service routine.

I2C is another possibility.