Page 1 of 1
Help extracting information from Serial Port data
Posted: Wed Feb 05, 2014 4:21 am
by aircooled76
Hi Guys,
I have been able to get the serial data into my LiveCode app. Now I need to extract the actual data that I need from the Serial information.
I imagine the way to do this is by manipulating the text and specifying the "char" that I want to take from the string...
The info is from a Basketball Score Controller:
Code: Select all
Ì»Ü19<09T19:09
Ú 0 00Û 0 00Ü19309T19:09
Ì»Ü19<08T19:08
Ú 0 00Û 0 00Ú 1 00A 100
Þ Ü19308T19:08
Ú 2 00A 200
Þ Ì»Ú 3 00A 300
Þ Ü19<07T19:07
Ú 3 00Û 0 00Ú 4 00A 400
Þ Ü19307T19:07
Ú 5 00A 500
Þ Ì»Ú 6 00A 600
Þ Ü19<06T19:06
Ú 7 00A 700
Þ Ú 7 00Û 0 00Ú 8 00A 800
Þ Ü19306T19:06
I can extract the time by putting the following in a read loop:
Code: Select all
read from file "COM14:" until "T"
read from file "COM14:" for 5 char
But doing this I can only extract the one set of data as I don't think I can run multiple read loops from the same Port... any suggestions on how I can do this?
Any loop needs to be pretty fast as the final minute of play the timer counts in 1/10ths of a second...
thanks in advance
Mike
Re: Help extracting information from Serial Port data
Posted: Wed Feb 05, 2014 6:26 am
by dunbarx
Hi,
Very interesting. But you seem to understand exactly what you need to do with the text block.
When you say "multiple read loops from the same port", what do you mean? You can always read more than once. You are not really "looping" when you read, you are just reading. The new data can be appended to the old. I am not sure if the process is fast enough, though.
Where is the score within that text block? Is that what you do not have yet, and must read from another port? In other words, for example, each line that has a colon in it (if that holds true) contains your time, and you can get those times by using the offset function on each line of interest, similar to what you suggested. If all your data is present in the text block, you are already home free. You just extract that data, as you already said, by identifying markers within the text and parsing. You do it fully within LC, which is more than fast enough.
Or am I missing the problem entirely?
Craig Newman
Re: Help extracting information from Serial Port data
Posted: Wed Feb 05, 2014 3:48 pm
by aircooled76
I have tried putting three different functions looking for the different key characters I need to locate... Unfortunately the blocks change depending on when a score is recorded and during the last minute of the game when time goes every 0.1 of a second.
I need to find the 3 characters after "A" and "B" that is the team scores... and the 5 characters after "T" (there will be more variables like shot clock etc later on)
However this seems unreliable and if one function is working the others are not working reliably... (seems to me reading from the same port multiple times is problematic...)
Code: Select all
on readPort1
if the hilite of btn "Port open" = true then
put the label of btn "Port" into thePort
read from file thePort until "A"
read from file thePort for 3 char
if it is not empty then
put it & cr after field "recField"
end if
send readPort1 to me in 5 ticks
end if
end readPort1
on readPort2
if the hilite of btn "Port open" = true then
put the label of btn "Port" into thePort
read from file thePort until "B"
read from file thePort for 3 char
if it is not empty then
put it & cr after field "recField"
end if
send readPort2 to me in 5 ticks
end if
end readPort2
on readPort3
if the hilite of btn "Port open" = true then
put the label of btn "Port" into thePort
read from file thePort until "T"
read from file thePort for 5 char
put it & cr after field "recField"
send readPort3 to me in 5 ticks
end if
end readPort3
I also tried having multiple "if" statements in the same read function
Code: Select all
on readPort
if the hilite of btn "Port open" = true then
if recEOL is empty then resetEOL
put the label of btn "Port" into thePort
read from file thePort until "A"
if it ends with "A" then
read from file thePort for 5 char
if it is not empty then
put it into field "_ScoreA"
end if
else
read from file thePort until "B"
if it ends with "B" then
read from file thePort for 3 char
if it is not empty then
put it into field "_ScoreB"
end if
else
read from file thePort until "T"
if it ends with "T" then
read from file thePort for 5 char
if it is not empty then
put it into field "_time"
end if
end if
end if
end if
end if
send readPort to me in 5 ticks
end readPort
And also multiple or statements...
Code: Select all
read from thePort until "T" or "A" or "B"
Both of these last two only the first if statement works...
Re: Help extracting information from Serial Port data
Posted: Wed Feb 05, 2014 4:42 pm
by aircooled76
OK... I seem to have something working:
Code: Select all
on readPort
if the hilite of btn "Port open" = true then
put the label of btn "Port" into thePort
read from file thePort until CRLF
if it contains "A" then
put offset ("A", it) into myVar
put char myVAR + 1 to myVar + 3 it into field "_ScoreA"
else
if it contains "B" then
put offset ("B", it) into myVar
put char myVAR + 1 to myVar + 3 it into field "_ScoreB"
else
if it contains "T" then
put offset ("T", it) into myVar
put char myVAR + 1 to myVar + 5 it into field "_time"
end if
end if
end if
end if
send readPort to me in 1 ticks
end readPort
However I am quite regularly getting dropped numbers like "18:" instead of "18:06" or blank score numbers... I am reading from the serial port "until CR" when I look at the raw serial data using another program the data stream is intact... just in LiveCode it seems that the final bit of the serial data isn't making it through before the "until CR" cut off.
The frequency of dropouts appears to reduce slightly when the "send readPort to me in 1 ticks" is set to more ticks (but this slows down the response of the whole operation too... but does not totally solve the problem!
Re: Help extracting information from Serial Port data
Posted: Wed Feb 05, 2014 8:23 pm
by dunbarx
HI.
In your latest script, you use the offset function but limit yourself to a certain number of chars after that value. This is dicey, because you may never know how many chars to grab.
But you seem to always want all the chars in the line after where the marker character is found. This is a good thing, and should be exploited. Look up such gadgetry as "lineOffset" and all its ilk. You will fix this soon.
Craig
Re: Help extracting information from Serial Port data
Posted: Thu Feb 06, 2014 4:36 pm
by aircooled76
Hi Craig,
Thank you for your input! The number of characters will always be the same... the time is always TXX:XX or T56.3 The score is always AXXX or B101...
Unfortunately the serial data is not always in the same line structure... I get a time update every 1/2 a second with the lines:
Code: Select all
Ì»Ü19<09T19:09
Ú 0 00Û 0 00Ü19309T19:09
When the timer gets under 1 minute it sends an update every 1/10th of a second on a single lines T52.1 and every whole second a full line as above.
I am not sure how lineoffset will help in this situation... as I am not locating a line but a character in the line... Craig can you tell me a bit more how you see this working?
Re: Help extracting information from Serial Port data
Posted: Thu Feb 06, 2014 6:09 pm
by dunbarx
The idea of the lineOffset was that if you knew the line where the marker was, you could extract all the chars in that line after the offset value: Instead of (pseudoCode):
char (offset + 5), you would: char (offset to the number of chars of that line), using the chunk property of the line instead of an explicit value. Standard stuff.
But this relies on a predictable data structure. Since you mentioned, for example:
"TXX:XX", and then gave an instance of "T52.1". Different lengths, which is why the more robust offset treatment is better. You would then check that extracted portion to see if it contained a colon or a period, and act accordingly
If you think about the idea that you have the ability to pull out any portion of data from the (barely readable) mass you are reading from the port, then you should be able to process as needed with any processing required. So if all you really need is advice on tools to extract those data segments, write back often. Is there any other broad issue you are having trouble with?
Craig
Re: Help extracting information from Serial Port data
Posted: Fri Feb 07, 2014 5:09 am
by aircooled76
Hi Craig,
Thanks again for your help... I understand what you mean... I guess I am having trouble breaking up the lines of the data coming in correctly...
I have been using "read from file thePort until CR" as far as I can see this is the problem as LiveCode (or my serial data) is occasionally putting a CR earlier in the string and breaking my time figures when using the previous code I posted (eg I get 18: instead of 18:51) or totally blank fields when the CR comes in even earlier.
"read from file thePort until eol" that reads until the end of each line.... however when the timer goes under 60... each line includes 10 1/10ths of a seconds data... So I need to split it more frequently than just "eol"
I have also tried until "CRLF", "LF" and "numToChar(13)" Any other suggestions on how to do this.... My code extracts the data correctly... but because of the extra "CR"s that come into LiveCode it breaks the data get...
thanks again for any assistance
Re: Help extracting information from Serial Port data
Posted: Fri Feb 07, 2014 5:39 am
by dunbarx
Hi.
Someone else will have more experience with this sort of thing, where data brought in over these strange portals contains undocumented aliens. Perhaps some setting might tighten the imported data.
Anyone? We cannot have this. Carriage returns rampaging....
Craig
Re: Help extracting information from Serial Port data
Posted: Fri Feb 07, 2014 3:47 pm
by aircooled76
Anyone? We cannot have this. Carriage returns rampaging....
I agree... well said Craig!
Re: Help extracting information from Serial Port data
Posted: Fri Feb 07, 2014 4:47 pm
by Thierry
aircooled76 wrote:
However I am quite regularly getting dropped numbers like "18:" instead of "18:06" or blank score numbers... I am reading from the serial port "until CR" when I look at the raw serial data using another program the data stream is intact... just in LiveCode it seems that the final bit of the serial data isn't making it through before the "until CR" cut off.
Hi,
If I had to do the job, I would save the data stream from your "another program" as a binary file.
Then dump the Hexadecimal of this file and get precisely the format of each message you receive.
May be there are some no-printable-ascii values ? or extra CR ?
Then a second test with LC could be (pseudo-code) :
in a loop:
read .. for 1 in 1 milliseconds
if IT is not empty then put IT after myrawdatas
then again, save myrawdatas as a binary file, and do a hex dump and hunt the details...
My 2 cents,
All the best,
Thierry
Re: Help extracting information from Serial Port data
Posted: Wed Mar 26, 2014 4:46 pm
by aircooled76
I am back trying to slay this dragon of a serial problem...
I am starting to think it is a LiveCode bug / fault...
Using RS232 DataLogger
http://www.eltima.com/products/rs232-data-logger/
I get really clean serial data:
Code: Select all
Ú22 00A12200
Þ Ú23 00A12300
Þ Û 41 00B 4100
Þ Û 42 00B 4200
Þ Ü2049T20.9
Ü2048T20.8
Ü2047T20.7
Ü2046T20.6
Ü2045T20.5
Ü2044T20.4
Ü2043T20.3
Ü2042T20.2
Ü2041T20.1
Ü2040T20.0
Ü1949T19.9
Ü1948T19.8
Ü1947T19.7
Ü1946T19.6
Ü1945T19.5
Ü1944T19.4
Ü1943T19.3
Ü1942T19.2
Ü1941T19.1
Ü1940T19.0
Ü1849T18.9
Ü1848T18.8
Ü1847T18.7
Ü1846T18.6
Ü1845T18.5
Ü1844T18.4
Ü1843T18.3
Ü1842T18.2
Ü1841T18.1
Ü1840T18.0
Ü1749T17.9
Ü1748T17.8
Ü1747T17.7
Ü1746T17.6
Ü1745T17.5
Ü1744T17.4
Ú24 00A12400
Þ Ü1743T17.3
Ü1742T17.2
Ü1741T17.1
Ü1740T17.0
Ü1649T16.9
Ü1648T16.8
Ü1647T16.7
Ü1646T16.6
Ü1645T16.5
Û 43 00B 4300
Þ Ü1644T16.4
Ü1643T16.3
Ü1642T16.2
Ü1641T16.1
Ü1640T16.0
Ü1549T15.9
Ü1548T15.8
Ü1547T15.7
Ü1546T15.6
Ü1545T15.5
Ü1544T15.4
Ü1543T15.3
Ü1542T15.2
Ü1541T15.1
Ü1540T15.0
Ü1449T14.9
Ü1448T14.8
Ü1447T14.7
Using livecode stack
http://www.troz.net/rev/stacks/SerialTest.rev That I have been using for testing I get:
Code: Select all
Ü11<55T11:55
Ü11355T11:55
Ü11<54T11:54
Ü11354T11:54
Ü11<53T11:53
Ü11353T11:53
Ü11<52T11:5
2
Ü11352T11:52
Ü11<51T11:51
Ü11351T11:51
Ü11<50T11:50
Ü11350T11:50
Ü11<49T11:49
Ü11349T11:49
Ü11<48T11:48
Ü11348T11:48
Ú
As you can see it is all over the shop...
Any ideas how I can narrow this down or get the problem fixed...
Re: Help extracting information from Serial Port data
Posted: Thu Apr 03, 2014 3:50 pm
by aircooled76
Hi Guys,
Still looking for a solution for this... any wiser heads than me can see if this is a bug or something I am doing?
If I can't fix this I will have to look for other Program language to use and potentially leave the livecode family
Mike
Re: Help extracting information from Serial Port data
Posted: Mon Jan 05, 2015 9:01 pm
by n.allan
Bit late for this post but it came up in a google search.
I have had luck in the past reading binary data from serial ports but I never rely on livecodes buitl in "read from file unti crlf" or any of that jazz. My approach was to constantly read fro the port "until empty" and put the data "after" a buffer variable. something like this.
Code: Select all
local tBuffer -- a buffer to hold any serial data
on readPort tPort
if tPort is not among the lines of the openFiles then exit readPort -- stops the loop if the port is not open
read from file tPort until empty -- read all data on port regardless
put it after tBuffer -- self explanitory
if char -1 of tBuffer is lf then send "gotData" && tBuffer to this stack -- send a message to the stack along with the data gathered if the last char is linefeed
put empty into tBuffer -- clear the buffer variable so data does not build up
send "readPort" && tPort to me in 1 tick -- repeat quickly (maybe need milliseconds depending on the baud rate of the data)
end readPort
on gotData tData
--process tData here
end gotData
so basically, read ALL data from the port, put it after a variable, check the last char for a "terminator" (usually crlf on serial data) if the terminator is there, send a message to the stack with the data then flush the buffer.
note that the gotData message may receive more than one line of data if you are reading the port slower than the dat strings are coming in.
FINAL NOTE: as of livecode 7 serial data does not seem to be working at all so use an older version for testing.