Author |
Message |
Phil23 Guru
 Joined: 27/03/2016 Location: AustraliaPosts: 1667 |
Posted: 10:17pm 31 Aug 2016 |
Copy link to clipboard |
 Print this post |
|
Hi All,
Does this seem a valid approach when I have different sized data frames coming from different devices & want to ensure I suck the Coms buffer dry each time.
Each device is polled by a Master, so only one Slave will reply at a time.
Haven't tried it; thinking while out....
Position & length of pause in the loop?
Beginning or end? Length?
Do While or is Loop Until more appropriate.
Thanks
Phil.
[Code]
Open "Com1:9600,,RecComs,140" as #1
Sub RecComs
Local HdrLoc as integer
Local HdrFnd As String
Local BufLen As Integer
BufLen=0
DO WHILE BufLen<> LOC(#1)
PAUSE 10
BufLen=LOC(#1)
LOOP
Print "Buffer Length=",Loc(#1)
DataStr=INPUT$(LOC(#1),#1) 'then suck everything in the buffer out and stick it in D$....
HdrLoc=Instr(DataStr,"##Data")
If HdrLoc<>0 Then HdrFnd=Mid$(DataStr,HdrLoc,8)
Print "Header Location",HdrLoc ',Instr(DataStr,"##HpData")
Print "Header Found", HdrFnd
Print DataStr 'and print that data on the screen.
Print "==========================================="
..
..
Select Case HdrFnd
..
..
End Select
End if
End Sub
[/code] |
|
MicroBlocks
 Guru
 Joined: 12/05/2012 Location: ThailandPosts: 2209 |
Posted: 10:32pm 31 Aug 2016 |
Copy link to clipboard |
 Print this post |
|
[code]
HdrLoc=Instr(DataStr,"##Data")
If HdrLoc<>0 Then HdrFnd=Mid$(DataStr,HdrLoc,8)
[/code]
This could already fail when there is not enough data available.
I think using an interrupt would be easier to use together with a rather large buffer for the com port (depending on how quick data arrives and is processed)
You would then append data to the end of a buffer$ in the interrupt routine.
In the main loop you check the buffer$ if it contains the start of header AND the end of header.
You could then read the complete header and parse its values.
You then chop of the header from the buffer$ with a MID$(buffer$,HeaderPosition+HeaderLength) and retrieve the data with a LEFT$buffers$,DataLength). DataLength would be one of the values in the header. You then chop of the data also to keep the buffer$ as small as possible.
A header could be:
[code]
<SOH><Type><Length><EOH>
[/code]
followed directly by data
[code]
<SOT>This is the data<EOT>
[/code]
Another much easier way is to first make sure there is enough data with LOC() and then use an INPUT$ to read a line of data from the com port. If your data 'records' end with a CR/LF then that is all you need.
Microblocks. Build with logic. |
|
Phil23 Guru
 Joined: 27/03/2016 Location: AustraliaPosts: 1667 |
Posted: 12:23am 01 Sep 2016 |
Copy link to clipboard |
 Print this post |
|
Thanks MB,
What I'm using at the moment is working, but the data is sent as frames,
about 140 to 160 bytes from each device.
It's four HC-12's all sitting on the same channel.
The Master Requests the data from a slave & it responds with it's data.
The 2 slaves can't overlap in their transmissions the way the polling is made.
It's the 4th device that has the twist, as it's a receive only monitor.
So it's buffer with contain both the request sent to the slave, as well as the slaves response for the master.
That's why I'm searching for the data header in the string.
At the moment the interrupt is triggered at 140 bytes, but to make sure everything is in the buffer before I read it I have a pause in place of about 50ms to allow extra characters to arrive.
I'd rather not have the pause just fixed; Don't like pauses a lot....
Cheers. |
|
Grogster
 Admin Group
 Joined: 31/12/2012 Location: New ZealandPosts: 9589 |
Posted: 12:28am 01 Sep 2016 |
Copy link to clipboard |
 Print this post |
|
[Quote=Phil23]Open "Com1:9600,,RecComs,140" as #1[/Quote]
@ MicroBlocks - the above line of code in Phil's example IS an interrupt - it will loop to RecComs when there is 140 bytes or more in the serial port buffer. Therefore, the code won't fail in the sub, as there will be at least 140 bytes in the buffer at the point the sub is called. Provided of coarse that 140 bytes satisfies the data manipulation routines..... Smoke makes things work. When the smoke gets out, it stops! |
|
MicroBlocks
 Guru
 Joined: 12/05/2012 Location: ThailandPosts: 2209 |
Posted: 01:24am 01 Sep 2016 |
Copy link to clipboard |
 Print this post |
|
Nothing guarantees that the data is exactly what you expect it to be. Well, Murphy's law actually guarantees it is not like you expected. :)
The ##Header could be at the end of the 140 bytes that is read. And the data in the next block of 140 bytes, which will be available later in the next interrupt.
You need to put everything in a buffer and then 'find' the header and make sure there is enough after the header to proceed.
Microblocks. Build with logic. |
|
Grogster
 Admin Group
 Joined: 31/12/2012 Location: New ZealandPosts: 9589 |
Posted: 01:30am 01 Sep 2016 |
Copy link to clipboard |
 Print this post |
|
Good point.
I especially like your Murphy's Law comment! Smoke makes things work. When the smoke gets out, it stops! |
|
Phil23 Guru
 Joined: 27/03/2016 Location: AustraliaPosts: 1667 |
Posted: 09:55am 01 Sep 2016 |
Copy link to clipboard |
 Print this post |
|
The ##Data Header is unusual at the beginning of the buffer on the Main unit, but moves to either 11 or 21 on the monitor only MM.
I get a different case if I take one slave off line, as the monitor receives 2 requests on it's buffer, but only one is followed by a response.
Trying to accommodate that situation, units not responding.
That's why I search for the headers position.
The data is all sent in a burst, so since the 140 triggers the routine I want to make sure I've got the whole lot before moving on.
Noticed its less of an issue on the 28 pin than the E64 as the speed of the 100 can have it processing before the last 10 or 20 characters are received.
The processing below the sub ensures the data is valid.
Phil. |
|
Phil23 Guru
 Joined: 27/03/2016 Location: AustraliaPosts: 1667 |
Posted: 09:57am 01 Sep 2016 |
Copy link to clipboard |
 Print this post |
|
So back to the primary question,
is the DO WHILE a valid way to check that the buffer is not growing once the Com interrupt is triggered.
|
|