Accepting variable data stream using SERIN
Hi, new at this so this may be a pretty basic question, I have a BS2 stamp and require data to be input at 19k2 from a PLC, the data stream can be up to 120 bytes long (I do realise that I will ulimately require a BS2p) there is no handshaking and no unique end character apart from a checksum which will obviously vary, embedded within the data is the data length but that will not be availabe until·all the data has been received.·I am aware of special formatter STR ByteArray \L (\E) but this requires either the data length or a unique end character, how can I receive the variable length data with for example:
SERIN 16,16416,[noparse][[/noparse]STR indata\120]
As it stands it requires 120 bytes input before it moves on, I have also tried using the Timeout function but this does not help, maybe I am using it incorrectly? Below is an example which I am using to test but once again, anything less than 22 bytes and it waits for the rest of the data
indata VAR Byte(22)··· 'Array populated by incoming data
counter VAR Byte······
main:
counter = 0
SERIN 16,16416,2000,no_data,[noparse][[/noparse]STR indata\22]
FOR counter = 0 TO·21
·SEROUT 1,16416, [noparse][[/noparse]HEX2 indata(counter)," "] 'Debug
·'SEROUT 1,16416, [noparse][[/noparse]indata(counter)] 'Docklight
NEXT
·SEROUT 1,16416,[noparse][[/noparse]CR]
GOTO main
no_data:
SEROUT 1,16416, [noparse][[/noparse]"No data",CR]
GOTO main
One other question, I ultimately want to use an OEM board, at the moment I have a PIC16C57c microcontroller fitted, if I use a BS2p24 is it just a matter of replacing it with the SX48AC (the speed of 20MHz is the same)
Apologies to everyone if some of these questions are nonsensical
SERIN 16,16416,[noparse][[/noparse]STR indata\120]
As it stands it requires 120 bytes input before it moves on, I have also tried using the Timeout function but this does not help, maybe I am using it incorrectly? Below is an example which I am using to test but once again, anything less than 22 bytes and it waits for the rest of the data
indata VAR Byte(22)··· 'Array populated by incoming data
counter VAR Byte······
main:
counter = 0
SERIN 16,16416,2000,no_data,[noparse][[/noparse]STR indata\22]
FOR counter = 0 TO·21
·SEROUT 1,16416, [noparse][[/noparse]HEX2 indata(counter)," "] 'Debug
·'SEROUT 1,16416, [noparse][[/noparse]indata(counter)] 'Docklight
NEXT
·SEROUT 1,16416,[noparse][[/noparse]CR]
GOTO main
no_data:
SEROUT 1,16416, [noparse][[/noparse]"No data",CR]
GOTO main
One other question, I ultimately want to use an OEM board, at the moment I have a PIC16C57c microcontroller fitted, if I use a BS2p24 is it just a matter of replacing it with the SX48AC (the speed of 20MHz is the same)
Apologies to everyone if some of these questions are nonsensical
Comments
Its more usual (and reliable) to work at 2400 or 4800 with the Stamp if you need to manipulate much data.
The Timeout may seem to not work correctly because it resets whenever any data on the serial port is detected.
As to variable length/no common characters, something will have to give. Suppose a short string arrives. If the PC remains quiet until the next transmisssion, I think you'll just grab enough characters to to fill the string and things will continue. You,of, course, have to figure out where the split is in the data.
What kind of data are you receiving? Its really not common for so much data to be sent with no unique parts. Are there no repeatable spaces, brackets, commas, etc?
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Tom Sisk
http://www.siskconsult.com
·
CC AA 00 00 00 01 00 00 00 01 AA 12 1B 00 CC 09 DB 00
the 12th byte is the length of the string but of course it will be no use until the whole string has been received, what I was wondering was whether there was a way for the stamp to detect data flow/no data flow, alternately Timeout could be set to a value less than the quiet space between data strings if I could set it in the correct configuration
Using an SX48AC is not a drop-in replacement for a Stamp. SX/B is not the same as PBasic although there are a lot of features and syntax that are the same or close which makes conversion easier. You might also consider a Propeller since it very happily handles 19200 Baud with lots of processing power to spare and normally does buffering of the incoming data.
The second question was the start of this topic, how do I detect the end of variable length data when I have no flow control and no unique EOF characters that I can trap, any advice would be much appreciated
I have used the BS2P in the past to capture long strings of data from such devices as GPS modules and other consumer electronics equipment, but I don’t recall ever doing this at 19.2Kbps. Without testing it, I’m not sure if the BS2P can get the data at that rate, but I can answer the question of how to capture the variable length strings.
If you look at the example codes for our PINK module you’ll see the BS2P examples use the SPSTR formatter for serial input. Since they don’t know how long the data will be they assume the maximum length of a variable on the PINK, which is 64 bytes. The SERIN command then uses a short timeout to break from input if nothing is received in that many milliseconds. It is not a perfect solution, but it does work.
Of course, on the PINK the data is being requested, so the timeout is affected by simply waiting for data. You may or may not be able to use this depending on if your PLC is just sending data at random or fixed intervals. If that is the case you may have to use some clever tricks to get the data since the beginning of the data does not contain a fixed header that you can wait for. Take care.
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Chris Savage
Parallax Engineering
Regards and thanks
waitData:
PUT 11,0
SERIN 16,16572,2000,skipnext,[noparse][[/noparse]SPSTR 126]
skipnext:
GET 11,temp
IF temp = 0 THEN GOTO waitData
temp = 0
GET 11, temp1