PDA

View Full Version : dedicated Cog on serial commn



ALIBE
10-26-2006, 02:39 AM
I am moving one of my serial commn code into a dedicated cog. The code works w/o any problems when run on Cog0. However, when moving to a new Cog, the code seems to be not working. Essentially, the following 2 methods.

Are there any limitations using these on a dedicated cog? What are the alternate methods.· The Baudrate I'm working on is 9600.

thanks in advance



PUB serialIn(pin, Baud, mode, bits) | bitTime, time
{{ Accepts asynchronous byte value on defined pin, at Baud, in mode for #bits
Mode: 0 = Inverted - Normally low Constant: Inv
1 = Non-Inverted - Normally high Constant: NInv }}
dira[pin]~ ' Set up input pin as an input
bitTime := clkfreq / Baud ' Calculate bit time for Baud
waitpeq(mode << pin, |< pin, 0) ' Wait for idle (should be idle)
waitpne(mode << pin, |< pin, 0) ' Now wait for start of start bit
time := cnt ' Wait until middle of start bit
waitcnt(time += bitTime >> 1)
repeat bits ' Sample input at the middle of
waitcnt(time += bitTime) ' each data bit time for #bits
result := ((ina[pin] ^ (1 - mode)) << bits | result) >> 1

PUB serialOut(pin, char, Baud, mode, bits ) | bitTime, time
{{ Send asynchronous character (byte) on defined pin, at Baud, in Mode for #bits
Mode: 0 = Inverted - Normally low Constant: Inv
1 = Non-Inverted - Normally high Constant: NInv }}
outa[pin] := mode ' Set up output pin with the proper
dira[pin]~~ ' idle state and as an output
bitTime := clkfreq / Baud ' Calculate bit time for Baud
char := ((1 << bits | char) << 1) ^ (mode == 0) ' Add start/stop bits & invert if needed
time := cnt
repeat bits + 2 ' Send each bit based on baud rate
outa[Pin] := char
char >>= 1
waitcnt(time += bitTime)
waitcnt(time += bitTime * (bits + 2)) ' Allow a character time for pacing

·



▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
"any small object, accidentally dropped, goes and hides behind a larger object."


ALIBE - Artificial LIfe BEing. In search of building autonoumous land robot
http://ALIBE.crosscity.com/ (http://ALIBE.crosscity.com/)
·

cgracey
10-26-2006, 05:27 AM
Nagi,

I always use FullDuplexSerial. It's on the object exchange within·a zip file I posted which contains many other objects, as well.

The problem with launching your routines into another cog is that you need some buffering structure to handle the data exchanges, since you can't call the serialIn or serialOut when they are already running. FullDuplexSerial does this,·and you could make your own routines work similarly. The way you're heading, you would need to launch TWO cogs - one for in and one for out, since Spin cannot multiplex fast enough to handle concurrent serial I/O. Actually, at 9600 baud, you might be able to do this in Spin, but the code would be complicated to write. I recommend just using FullDuplexSerial, since it takes only one cog, goes both directions, and handles the buffering in and out for you. It couldn't get any simpler to use, I think.

▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔


Chip Gracey
Parallax, Inc.

ALIBE
10-26-2006, 05:30 AM
Chip,
thanks much for the advice and notes. I'll give it a shot right now.

thanks, Nagi

▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
"any small object, accidentally dropped, goes and hides behind a larger object."


ALIBE - Artificial LIfe BEing. In search of building autonoumous land robot
http://ALIBE.crosscity.com/ (http://ALIBE.crosscity.com/)
·

Harley
10-26-2006, 05:36 AM
I'll second Chip's comments. I'm using two FullDuplexSerial 'uarts' and YES they are simple and effective.

At first, one ran marginally until I realized it was communicating with a PIC that was close but not on 38400 baud. So gave the uart the PIC's actual baud value and it was working properly.

Worthwhile looking into.

▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Harley Shanko
h.a.s. designn

ALIBE
10-26-2006, 07:41 AM
A quick update.

As I was playing w/ FullDuplex, I just realized that I had in fact started out with that route a few weeks back. The object is written very well and very well thought of logic flow. And, seems very comprehensive for majority the serial comm needs out there.

However, for my application; There are a couple of the reasons below as to·why I had to back away from using it - **again** just from my application perspective:

a. Asynchronous Rx (meaning, ASM ::Receive runs async on a sep Cog). It then fills that data into the RxBuffer. Although this works great for other applications, for my application, I need the Rx to be Sync.··
·· a.1 So, I can get all bytes in queue, Process the data and Respond back. All happens Sync.
······· Note that ALIBE responds to the command data sent from my homebase command center. Hence Sync Processing. The command center "waits" for the data before sending the next batch of commands

b. a separate Cog is used for the async behavior. I defintely see that this is important for other apps, but, feel an overkill for mine.

So, I thought I must take a simpler approach and then resorted to the above 2 methods.

I made a couple of changes to my codebase.

1. Removed the code to interface w/ LCD in the Cog code dedicated to CommMod
2. Moved that Visualization to a separate Cog
and, that seems to have resolved my problem. I am digging in to see why having LCD in the same Cog would cause the issues. I will post back once I find more.


So, here's the way it is currently laid out

i. Cog 0 - main controller
ii. Cog 1 - CommMod.
····· Receives data Sync,
····· Processes Data,·
····· Responds back w/ Sensory Data and/or,
······Takes onboard overriding actions (such as Turn-left-Right, Move-Slow, Take Camera SnapShot, etc)

iii. Cog 2 - Visualization
··· Essentially displays critical data onboard on the LCD (or may be TV on board eventually)

iv. Cog 3 - Sensory Devices
··· Gathers data from all level 1 input devices

v. Cog 4 - Output Devices (not visualization and those that are not controlled by Cog 1)
··· Servos, Motors, Camera, etc

I still need to test and make sure all of this integration and synchronization works hand-in-hand.


But, who knows, i this all does not shake well, I may reconsider and switch to FullDuplex and see where that goes. I am completely open to ideas, comments, criticism, etc. All, welcome.

thanks again Chip and Harley

I'll keep this forum posted.

▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
"any small object, accidentally dropped, goes and hides behind a larger object."


ALIBE - Artificial LIfe BEing. In search of building autonoumous land robot
http://ALIBE.crosscity.com/ (http://ALIBE.crosscity.com/)


Post Edited (ALIBE) : 10/25/2006 11:46:17 PM GMT

acantostega
10-26-2006, 09:03 AM
I'll post more info later on my award winning robot (really!), but here's how I laid out the cogs (note I don'e rely on order)
0: startup (cog launches), then Behavior Arbiter / main loop
2 cogs w/ two FullDuplexSerial, one for CMUcam, one for a serial LCD (which was overkill for the LCD, since I could've used a simpleSerial object (9600 bauds), but this worked better)
one cog for flashing IR detection
3 other cogs, each running a "behavior", with the corresponding sensing and acting
1 cog for servo32 objects moving some servos

ALIBE
10-26-2006, 09:09 AM
acantostega, would be very interested in seeing the info. Looks like you're a big fan of FullDuplex - good to know.

▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
"any small object, accidentally dropped, goes and hides behind a larger object."


ALIBE - Artificial LIfe BEing. In search of building autonoumous land robot
http://ALIBE.crosscity.com/ (http://ALIBE.crosscity.com/)
·

Mike Green
10-26-2006, 09:29 AM
Asynchronous here (FullDuplexSerial or Simple_Serial) refers to the timing of the bits in the characters being transferred. Each character has a start bit (0) which provides the timing for the character. Each character can occur asynchronously in relationship with other characters. Synchronous, in the same context, refers to bit timing and requires that either the transmitting end or receiving end supply a separate clock line.

I think (correct me if I'm wrong) that you're referring to how the received data is processed, that the application receives some kind of command, processes it, and replies to it before looking for the next command. You can certainly use FullDuplexSerial with this (and the receive buffer) because it's the sender and receiver that are working synchronously, not the actual serial transfer of the data.

As you mentioned, all you have to do is wait for the entire command to be received before acting on it and transmitting a reply.

ALIBE
10-26-2006, 10:03 AM
Mike,
thanks for taking the time to read thru my notes. Yes, you're understanding of my defn async vs sync is correct. Pardon my ignorance - the author of FD, Mike and rest of the folks in this thread, I am trying to identify what is it that I will get w/ FullDuplex that I'm not getting w/ the above 2 routines. I am not able to clearly tell what I'm not getting by not going the FD route.

I'm sure I'm not understanding something. "Not knowing the unknown" :)

▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
"any small object, accidentally dropped, goes and hides behind a larger object."


ALIBE - Artificial LIfe BEing. In search of building autonoumous land robot
http://ALIBE.crosscity.com/ (http://ALIBE.crosscity.com/)
·

Mike Green
10-26-2006, 10:50 AM
You may not need the FD serial object and what you have may work just fine. One advantage of using it is that you can do some processing while the reply is being transmitted and, if your processing takes a little too long, you won't miss the next command coming in because it's being buffered. It doesn't look like you're short of cogs, so that's not an issue. It may be that the best reason for using the FD serial object is simply that it's already a nice package, self contained and you can just use it as is even if you don't need some of its features. If, for some reason, you need to do more in your CommMod, you already would have reserve capability.
Mike

ALIBE
10-26-2006, 12:10 PM
Mike, thanks - ok - that helps my understanding. If and when my CommMod overgrows her needs, I will keep FD in mind.

another ?n based on your note, "...that it's already a nice package...".
code occupies room, if I understand the prop arch correctly, I take it that "all" code whether used or not is loaded into mem. Correct? There's no on demad code loading in the prop arch?

am I correct in that understanding.

▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
"any small object, accidentally dropped, goes and hides behind a larger object."


ALIBE - Artificial LIfe BEing. In search of building autonoumous land robot
http://ALIBE.crosscity.com/ (http://ALIBE.crosscity.com/)
·

Mike Green
10-26-2006, 12:27 PM
Actually, the SPIN compiler removes unreferenced methods. If no part of your program calls a particular routine in an object, that routine is not included in the binary program. It's not really "on demand" loading since it's not based on dynamic needs at run-time. The compiler makes a sweep over your program starting with the main routine and notes (marks) what routines are called anywhere in the main routine. It then looks at all the routines that are called and does the same analysis. The compiler only includes the routines that are marked in the final binary program. That way, there's no space penalty for parts of an object that are never referenced. Does that help?

ALIBE
10-26-2006, 09:09 PM
Yes, that helps - thanks for clarifying

▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
"any small object, accidentally dropped, goes and hides behind a larger object."


ALIBE - Artificial LIfe BEing. In search of building autonoumous land robot
http://ALIBE.crosscity.com/ (http://ALIBE.crosscity.com/)
·