Shop OBEX P1 Docs P2 Docs Learn Events
Questions about Objects and Cogs — Parallax Forums

Questions about Objects and Cogs

TimHTimH Posts: 48
edited 2009-11-18 19:47 in Propeller 1
Hello all.

I'm still working on my first propeller project and making some slow progress. I basically have two standalone routines -
First (main) uses Quadrature Encoder, FullDuplexSerial (for transmit only) and the LCDDEMO Objects
The second uses the FullDuplexSerial (for receive only). Both work alone as expected.

Basically I want to "convert" the second routine into an object that can be called by the first (just like FullDuplexSerial and LCDDEMO). As they both make use of the FullDuplexSerial Object is this a problem?

I want the second Object (lets call it "RecvRS232.spin") to read an RS232 port, waiting for a specific character, perform a simple conversion to the received digits, convert to a long which is then passed back to the First (main) routine. I will not be passing any parameters to the Get_data.spin object - just getting a Long returned from it. The RS232 transmit is for test purposes only.
Attached is the RecvRS232.spin which works what is the best was to change this to an Object.
Excuse some of my ugly code - still new to spin

Thanks for any help or pointers

Tim

Comments

  • Mike GreenMike Green Posts: 23,101
    edited 2009-11-18 05:23
    Yes, it's a problem using the same instance of FullDuplexSerial from two seperate objects. You're also implying that you want to use two separate cogs. Remember that the notion of objects and the notion of using more than one cog for execution are absolutely separate. You can use any number of cogs with only one (main) object and you can have all sorts of objects, all running in the same cog. They're separate concepts.

    First, I would recommend that you change to using Simple_Serial for your serial I/O. You can initialize this for only transmit or only receive or for both. You can have two separate instances, one in the new object for receive-only and one in the main object for transmit-only. It's not buffered, but that shouldn't make any difference in your case.

    For examples of making objects, have a look at the Propeller Education Kit tutorials, then think about how you'd apply the ideas to your own needs and come back with questions.

    Here: www.parallax.com/Portals/0/Downloads/docs/prod/prop/PELabsFunBook-v1.1.pdf

    Post Edited (Mike Green) : 11/18/2009 5:29:45 AM GMT
  • dondedonde Posts: 51
    edited 2009-11-18 05:46
    Excuse me Mike for butting in to your thread with TimH. I'll stand by till you finish up. It's about Objects too. Can I access a Dat block string byte in 1 Object from another? I got 1 response from this forum, but very clear to me.
    Thank you, donde
  • Mike GreenMike Green Posts: 23,101
    edited 2009-11-18 06:55
    @donde - Please do not hijack other threads. It's poor form, just confuses the discussion, and, most importantly, your own topic deserves its own thread.

    The only things you can directly access from outside an object are constants and PUB methods. That's it!

    You can have a method that just returns the address or value of some variable in an object (whether in VAR or DAT areas), but there's no direct access.
  • TimHTimH Posts: 48
    edited 2009-11-18 13:26
    Thanks Mike

    I understand your point about the difference between Cogs and Objects. The reason I want to run the receive serial in its own cog is to speed up execution time. If the external device is only sending data at say 1Hz I don't want the main program just waiting for the next string.
    I will take a look at the Simple_serial object again does it have any disadvantages over using FullDuplexSerial.

    Tim
  • dondedonde Posts: 51
    edited 2009-11-18 15:11
    Mike,
    I'll quit doing what I did.
    donde
  • StefanL38StefanL38 Posts: 2,292
    edited 2009-11-18 17:25
    Hello Tim,

    another aproach could be to use a buffer. There is ONE cog that does all the send and receive to the serial connection.
    All other PUBs just do a write or read of this buffer they do NOT use fullduplexserial DIRECTLY

    Whenever bytes are received this cog writes the bytes to the receive-buffer. Whenever you want to send something
    you write it to a particular place in the send-buffer. This means: let's assume in your code are 4 places where you want to send something
    Now at place 1 you write to bufferbyte 1-5, at place 2 you write to bufferbyte 6-10, place 3 bufferbyte 11-15, place 4 bufferbyte 16-20

    This way nothing gets overwritten as every send has its own space
    The send/receive-cog checks the buffer if something has changed (which needs another backup-buffer) and if something has changed transmits the content of the buffer
    or you transmit the content of the buffer every 0.1 seconds or any timeinterval that suits.

    If you describe the send and receive in detail maybe better suiting soltuions can be found.

    best regards

    Stefan

    Post Edited (StefanL38) : 11/18/2009 5:32:52 PM GMT
  • TimHTimH Posts: 48
    edited 2009-11-18 17:39
    Stefan

    The idea of a buffer sounds interesting. Is a buffer available (in the FullDuplexSerial object) for the receive side as well.· I don't need a buffer on the transmit side - basically I'm generating a control string of about 10 (max) characters and then sending it when ready.· On the receive side I am expecting a similar string but it is only sent once per second or less.· So I don't want to sit waiting for up to 1 second to catch the start of the string.· A receive buffer would solve this for sure - say 10 characters.·
    I've solved this problem in the past using a PIC dedicated to receiving the data and then a simple··interface to another PIC.· Worked fine, but I'm hoping that with the Propeller I can get this done with 1 chip and a more elegant solution.

    Tim
  • StefanL38StefanL38 Posts: 2,292
    edited 2009-11-18 19:47
    Hello Tim,

    if you call fullduplex directly from different cogs you mess up everything. FullDuplexSerial can only work properly if there is a SINGLE cog that calls send or receive methods

    So the reason for the buffer is not buffering "time" the buffer is the place where criss-cross access does not mess up the FullDuplexSerialdriver and combined with DIFFERENT
    places for different calls for sending the only thing that can still happen is, that one status string contains only half of the updated bytes and the nect status-string contains all
    bytes or contains the other half of the bytes that were send. If you write from different cogs to the same place of the buffer this will mess up the buffer but not the FullDuplexSerialdriver

    To speed up things another idea could be to use simple serial with a time out. The disadvantage of simple-Serial is that it is ready to receive only when you have called it.
    If the Rx-line goes high and low driven by the device on the other side and simple_serial is NOT ready to receive (= a call has been done) bits or bytes are lost.

    The advantage of the FullDuplexSerial-driver is that it is ready to receive ALL THE TIME because it is running in its own cog.
    As soon as you call method "Rx" a byte is taken out of the receivebuffer of the FullDuplexSerial-driver
    now if another cog does call method "rx" he might be taking a byte out of the receivebuffer that should belong to the "Rx-es" of the other cog

    example cog 1 wants to receive "ABC" it could happen cog one has executed receiving "A" then comes cog 2 and receives "B" then cog 1 has HUB-access again and receives "C" but the "B" is missing
    or cog 1 wants to send "XYZ" but it might be that HUB-access changes to cog 2 right after the "Tx" of "X" and cog 2 does his own "Tx" with byte "A" then comes cog 1 and does his "YZ" so the buffer
    contains "XAYZ" and the the data is messed up.

    best regards

    Stefan
Sign In or Register to comment.