Serial Com with buffers
Rsadeika
Posts: 3,837
Is anybody working on a program like FullDuplexSerial that would have TX/RX buffers? I am thinking that the buffer sizes could be assigned at initialization of the Com program, and would allow for different buffer sizes for the different Com programs that you would start.
I would like to have a scenario where, lets say, you have, in the RX buffer, the string - "Turn on LED 16". I would like to be able to take that string, that is in the RX buffer, evaluate it, and do a corresponding action. I will be running at least three com programs, which will have their own buffer size assignments. Any ideas?
Thanks
Ray
I would like to have a scenario where, lets say, you have, in the RX buffer, the string - "Turn on LED 16". I would like to be able to take that string, that is in the RX buffer, evaluate it, and do a corresponding action. I will be running at least three com programs, which will have their own buffer size assignments. Any ideas?
Thanks
Ray
Comments
VAR
byte rx_buffer[noparse][[/noparse]16]
byte tx_buffer[noparse][[/noparse]16]
This must be the small buffer everyone is referring too. I also found the methods where these are being used. Do I surmise that at all times these arrays are filled with bytes, up to sixteen of them? Of course there would have to be a stream of bytes coming in.
There is also a method, PUB rx : rxbyte. I realize that this pulls one byte at a time, so where would it be best to handle a string of bytes, within the FullDuplexSerial method, or within the object that is calling it? In the example - "Turn on LED 16", I have to deal with fourteen bytes, can I just access the rx_buffer[noparse]/noparse, and get it there? Or is their a better way of doing it?
What you're wanting to do seems very simple on the surface but is complex -- you're trying to get the Propeller to do natural language processing. What about case? What about the LED on pin 15? What if the user enters "Turn LED 16 on" (order of words is different). These things are tough. You can simplify them, though, by creating a shortcut command syntax. For example:
L 16 1
could be used to turn the LED ("L" command) on P16 on (1). This simplifies your parsing of the incoming stream. After you see the letter command you can jump to a routine that handles it. In the case of the LED command it is expecting two decimal values: the pin number and the state (1 or 0).
What is the start of a command, the end?
What happens is the prop is started after the otherside or the other way round?
A common approach is the start/end to be the newline. The app initializes by calling rx and discards until it receives a newline, then the main loop calls rx and puts the char into an app buffer until it gets a newline. Then it processes the command in the app buffer, then it loops back to calling rx and putting the char in the app buffer.
With this approach you miss the 1st line but you dont try to process partial commands. If the otherside is also a program it sends "I", newline (init command) until the prop sends a "O", "K", newline response then the 2 sides are in sync.
This way the serial port rx buffer is not the buffer the app is using, its used by the serial port to buffer when the app is busy and chars are arriving. The app buffer is used by the app to process commands.
I have attached an example - GPS processing. GetNMEAline is the main processing routine, its calling rxcheck, it has 2 states - waiting for start of line - discarding until it sees a $ which is GPS start. Wait for end of lilne - receive char put in buffer, if end of line call ProcesNMEALine and then go to wait for startof line, otherwise stay waiting for end of line.
ProcessNMEALine looks at the gps buffer and works out the commands to process.
rxcheck is used rather than rx so it doesn't wait, if it doesn't receive a char it can go and do something else
Post Edited (Timmoore) : 8/22/2009 7:24:34 PM GMT
This is going to be tough, but if you really want to give it a go then you should have a look at Mike Green's Femto BASIC interpreter for ideas on parsing strings and working with them.
This way, you get char by char from the serial until you see a CR/LF. That's the signal to stop reading and start processing the string. After that, start reading again ... and so on and so on.
To change the buffer size, you also have to modify the PASM. It's all not commented. Neither in SPIN, nor in PASM. It's not enough just to change the buffer size. If you want to handle and RvBuffer and an TxBuffer of different sizes, you have to modify the PASM even more. See comments.
Nick
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Never use force, just go for a bigger hammer!
The DIY Digital-Readout for mills, lathes etc.:
YADRO
take a look at that
best regards
Stefan
Yes, the phrases will be terminated with a CR/LF. I am also developing a terminal program, written in freeBASIC, which will handle the other end of the conversation. So, my first objective is to have my terminal program on my PC converse with a Propeller demo board using BlueTooth as the conduit. Hence the phrase "Turn on LED16".
So far what I have is, on my terminal program, I press the letter 'a' to turn on/off LED 16, and 's' to turn on/off LED 17, I will add a CR/LF to this. And the Demo board does the actual work of completing the instruction. Maybe I will add in a response from the demo board side, "On a coffee break, will be back in 15", just to lighten things up a bit.
http://obex.parallax.com/objects/397/
Everything you need. Read·the documentation·for the receiving functions and you will understand.·Much smaller than fullduplex serial also.
...
Use the attached file for string processing.
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Nyamekye,
Post Edited (Kye) : 8/23/2009 3:41:38 AM GMT
Its does exactly what is asked.
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Nyamekye,
At this point I am trying to show Proof Of Concept (POC), and I need to go at it in the most proficient manner as possible. Later, I can think about making algorithms more efficient, by converting them to asm. I am also involved with my PC terminal program, which is eating up a lot of time, but is necessary because it will be designed to work with the Propeller, specifically my Propeller object code.
At this point I would like to mention the other serial program, the one that uses one cog for multiple UART instances, may be a good solution, but ... It lacks some clear documentation, and some examples, as to how it should be used. That alone stopped me in my tracks. So, I have looked at most of the objects that are available, and each one has their own little niche that it fills, but does not fill my niche. I guess my POC will be a little longer to achieve, I will probably have to come up with my own serial object.
Thanks
Ray
Here I thought I would have to get into the asm code, to my delight, the problem was solved in quick order. Now, I will look at your stringEngine object to see what you got going there.
Thanks
Ray
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
--Steve
Propeller Tools
@Rsadeika - my driver does not save you a cog. It still uses one every time you call uartEngine to start the driver. You will need X# versions of the driver each all with their own pins configured to different pins.
In that sense my driver is no better than FDS, however you will find mine uses less code space, has much larger buffers, and is much faster if you peform a raw speed test.
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Nyamekye,
Thanks
Ray
interpreting a SPIN-command needs time to load the SPIN-token, fetch parameters, branch to the underlying assembler-routine, and execute the assembler-routines
and all of this takes time.
As a maximum speed-test how fast SPIn is executed you can code a small loop simply toggling an IO-pin low-high-low.... and measure the frequency
or if you would like to measure execution-time of other commands
at 19200 baud the high-time of a bit is long enough to be reliably detected it as high when coding in spin
above this baudrate you will miss some of the bits
best regards
Stefan
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
--Steve
Propeller Tools
I have the receiveCheck method. It lets you peek at the last entered character into the receiver buffer. Good for looking for line feeds or carriage returns. You aren't sopposed to do string processing on stuff within the serial driver's com buffers.
That would be very bad. Instead you transfer the string to the string engine's buffers. There, you can do all the string manipulation you want.
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Nyamekye,
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
--Steve
Propeller Tools
Using the propeller architecture however, your program should use one cog to only poll that buffer and nothing else waiting for input. Another cog should be used to run other parts of the program.
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Nyamekye,