Interfacing a second Micro to the RC

Does anyone out there (rbayer, wildstang…) have some code samples to post on how they passed information back and forth between their custom micro and the Robot Controller. Looking at different Micros such as the HC11 (12) and other and wondering if any of them are better or worse at talking with the RC.

Any help would be great

I used a stamp2 as my “coprocessor” this year.

It worked out ok but there were difficulties.

The main thing had to do with the Programming port from the Stamp2 on the RC echoing back any character that I sent it.

This was a MAJOR pain in the rear.

The only way I could get it to work was to use the programming port as my RC -> CO-Processor path and to use the digital input port on the RC as my CO-Processor -> RC path.

Once I figured this out, I still was not out of the woods because I discovered that in the worst case conditions there is a 3 data packet delay from the data being put onto the digital input port and the Master CPU on the RC passing the data to the Stamp2 on the RC.

I spoke to Innovation First folks about this a bit and they were not very helpful to be honest.

In any case, here is the scheme that I developed that worked for me.

#1
I would send out a data request or other command (for example, zero all counters or give me CG position data) by asking for one of 16 “addresses” via the programming port of the RC stamp2.

#2
4 pins of the digital input port were then devoted to the address of the data that was put on the port (this limited me to 12 bits of data per transfer, but it was a reliable handshake method).

#3
The RC Stamp2 would only request a new address after the address it got back from the digital input port matched the address it had requested.

This worked pretty well.

Note that the coprocessor Stamp2 had some counter circuits and a latch/shift register in order to do the fast work of keeping track of wheel positions (a Stamp2 is not really capable of keeping track of left and right wheel positions at the same time yet alone communicate with another Stamp2 via serial data while doing it – the counters did all the time critical work and the Stamp2 just read the counters at its leisure).

I hope that Innovation First comes up with a better system next year, but if they don’t, I would use the system we had this year again without hesistation.

Joe J.

P.S. The only thing I would do is improve some of my routines on the co-processor Stamp2 to do more stuff. I had plans to have the co-processor keep track of CG velocity (direction and speed) and to compute a “virtual Yaw Rate sensor” as well as a few other things but never got around to it. In the end, all I needed from the co-processor was distance the CG moved since reset and angular orientation relative to orientation at reset. Not too sexy but enough to get to the stack in sub 3 second times.

*Originally posted by Joe Johnson *
**The main thing had to do with the Programming port from the Stamp2 on the RC echoing back any character that I sent it.

This was a MAJOR pain in the rear.**

Isn’t that the truth. It took us a few days to figure that one out. We managed to get a pure serial link working between the RC and our microcontroller (HC08) by having the RC issue a ‘request’ (a 1 byte command) that the uC would respond to with a 1 byte response. We had 3 pieces of data to pass back (X, Y coordinates and our orientation) that were each a byte. Initially we tried a single request byte to which the uC would respond with all 3 bytes but ran into a big problem with that: the BASIC Stamp is barely capable of 9600 bps. Even after adding delays into our uC between each byte the RC still wasn’t always capable of keeping up with it. So we settled on 1 request byte for each byte of data we returned (ugly, painful, and slow but it worked). Also the other problem we ran into is if you try to SERIN multiple bytes in the same statement, the timeout parameter only works if NO bytes are received. For example, if you’re trying to SERIN 3 bytes but only end up reading in 2 bytes, the SERIN command will NOT time out, and eventually the RC will reset the BASIC Stamp. This causes a mess during autonomous.

To solve the “echo” problem, we created command bytes that were reserved (i.e. only the RC could send them - before the uC sends out a byte, it ensures that the byte doesn’t match any of the command bytes). This way, the interrupt service routine on our microcontroller can safely assume that any byte that’s not a command byte is an echo and discard it. We do this by checking the outgoing byte in our SendByte routine on the uC and rounding down any value that matches a command byte (also we have no sequential commad bytes).

Here’s the relevant RC code:


'==========================================
'========= InputData Subroutine ===========
'== Inputs:  none
'== Outputs: s_curr_pos_x - current X position
'==          s_curr_pos_y - current y position
'==          s_curr_orient - current orientation
'== Modifys: tmp1, tmp2, tmp3
'== Purpose: get current position data from CC
'==========================================
InputData:

'request X
Serout 16, CC_OUTBAUD, [CC_CMD_REQ_X_POS]
Serin 16, CC_INBAUD, 5, InputDataNoData, [tmp1]
'request Y
Serout 16, CC_OUTBAUD, [CC_CMD_REQ_Y_POS]
Serin 16, CC_INBAUD, 5, InputDataNoData, [tmp2]
'request theta
Serout 16, CC_OUTBAUD, [CC_CMD_REQ_THETA]
Serin 16, CC_INBAUD, 5, InputDataNoData, [tmp3]

GET s_waypoint, waypoint
if(waypoint__idx = DEFAULT_WAYPOINT_IDX) then
   'The RC has just reset, we must ask the CC for what waypoint we were at before the reset.
   '  On powerup the CC will default the index to 0, so powerup will work fine.
   Serout 16, CC_OUTBAUD, [CC_CMD_REQ_WAYPOINT]
   Serin 16, CC_INBAUD, 5, WaypointManagerDone, [tmp3]
   waypoint__idx = tmp3
endif
  
'If we reset in the middle of auton mode, then we won't be able to figure out the autonomous
'  program number so it will be INVALID.  In this case, ask the CC for that info
if((waypoint__prog_side & WAYPOINT_PROG_ONLY_MASK) = AUTO_LIST_INVALID) then
   Serout 16, CC_OUTBAUD, [CC_CMD_REQ_PROG_SIDE]
   Serin 16, CC_INBAUD, 5, WaypointManagerDone, [tmp3]
   waypoint__prog_side = tmp3
endif

PUT s_waypoint, waypoint

'debug "x ", DEC tmp1, " y ", DEC tmp2, " t ", DEC tmp3, CR

'X,Y,Theta of Zero means the CC has reset and doesn't know where it is.  We will
'  feed it with the last known data (or in a powerup case, the data for the our start
'  position on the field.
if ((tmp1 = 0) AND (tmp2 = 0) AND (tmp3 = 0)) then
   GET s_curr_pos_x, tmp1
   GET s_curr_pos_y, tmp2
   GET s_curr_orient, tmp3
   Serout 16, CC_OUTBAUD, [CC_CMD_SET_POSITION, tmp1, tmp2, tmp3]
   
else
   PUT s_curr_pos_x, tmp1
   PUT s_curr_pos_y, tmp2
   PUT s_curr_orient, tmp3
endif

goto InputDataEnd

InputDataNoData:
'NO CUSTOM CIRCUIT!!!
'Toggle 7
'debug "Serin timeout", CR
nvr_2_3_auton_bits__auton_stop = 1
GET s_target_orient, tmp1  'No custom circuit so set the curr theta to target to prevent theta correction
PUT s_curr_orient, tmp1

InputDataEnd:

return 'from InputData

A decent portion of this routine is dedicated to ‘disaster recovery’. As we mentioned on CD before, at one point we were having major problems with our RC and/or custom circuit resetting due to static electricity discharge. To handle that and other reset problems, we built in some code that keeps key autonomous information redundant between the RC and the CC. If the RC were to reset, it wouldn’t know which waypoint it was heading towards. If the CC reset, it woudln’t know where it was anymore (it would think it was back at the starting point). So, we store the waypoint in the CC and the position in the RC for redundancy. This way, if the custom circuit resets, the RC can detect that and initialize it with the robot’s current position on the field. If the RC resets, the CC will feed it the correct waypoint. It’s a pretty neat feature that we added sometime after the Midwest regional I believe. Luckily we never made much use of it in competition (because it still slows everything down when the RC resets!)

Well hopefully this gives you something to noodle over. Let us know if we can provide more info or help!

This year, our team (alpine robotics) used the HC11 in a custom circuit designed to monitor the position of the translational drive wheels. We did our communication to the RC through the programming port, and the interfacing was relatively straightforward.
To correct the echo byte, we just programmed the HC11 to discard the first input that it recieved after sending the output, and we had no problems. Our biggest problem was that the RC is slow, so that the RC would not be able to receive data in time. This was fixed with a delay in the HC11 program.
We also had other minor problems due to wiring. Once we forgot to cross pins two and three, which are transmit and recieve. When the custom board is connected to a serial port of a computer, these pins are crossed inside the computer’s wiring, but when the custom circuit is connected to the RC, you must cross them yourself. Also, for some reason that I forget at the moment, we had to connect pin 4 to ground as well as 5.
I still have all our resources, including the PCB schematic, the assembly program, and I think our PBASIC program is on the white pages. Contact me if you want any of those things.

-Bobby Sakurai