Questions about Objects and Cogs
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
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
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
Thank you, donde
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.
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
I'll quit doing what I did.
donde
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
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
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