Strange result with serial data in TCPSocket

I am using an ethernet to RS485 adapter to get serial data from a meter. My first attempt garbaged the data with the first byte returned from the meter being the last byte reported by Xojo. The partial code below was in the SendMsg method that I added to a TCPSocket subclass. [code]

me.write msg
TicksExpire = Ticks + Ticks2Wait
While Ticks < Ticks2Wait and me.MeterReply = “”
if me.LookAhead.len >= Bytes2Get then
me.MeterReply = me.ReadAll
end if
app.DoEvents
Wend
[/code]
I fixed the problem with the code below:[code]

me.write msg
TicksExpire = Ticks + Ticks2Wait
While Ticks < Ticks2Wait
While me.MeterReply = “”
if me.LookAhead.len >= Bytes2Get then
me.MeterReply = me.ReadAll
end if
app.DoEvents
Wend
if me.MeterReply <> “” Then Exit
Wend
[/code]

I post this with the hope that it will save someone a few of the many hours I fought this problem. Another helpful hint: the NET485 adapter from GridConnect is easier to set up than any similar device I have tried.

don’t do those loops. Use DataAvailable event and wait for the data.

Could using .len instead of .lenB be causing you trouble? .Len() could treat the bytes as unicode characters, depending on the string encoding. .LenB() should be faster and more reliable.

Is this a console app? If not, then using app.DoEvents is a no-no. This will cause issues later on in non-console apps.

Use the DataAvailable event like Christian said. Example code from one of my working projects (oSerial is a simple SerialPort):

[code] dim sSerialBuffer1 as string
while oSerial.BytesAvailable > 0

dim s as string = oSerial.ReadAll
sSerialBuffer1 = sSerialBuffer1 + s
oSerial.poll

wend

//Now process sSerialBuffer1

[/code]

One thing that might happen is that your end of message may not have occurred yet even though BytesAvailable = 0. You’ll have to keep track of the data you’ve received and if you have a partial message you need to keep it around for the next DataAvailable event. It’s also possible that you could get two messages back to back so you need to know what separates messages.

Serial comms is a bear. It took me a while to get it working.

[quote]don’t do those loops. Use DataAvailable event and wait for the data.[/quote]I used the DataAvailable event at first, but had a hard time getting it to work with the timeout. I cannot just wait for the data because it might not come if there is a problem with the meter or the network. I also cannot start to read the next meter until I know the reply has come back from the current one. Somehow, I have to pause the main thread until the network is ready to send the next reading.

This is a console app that runs as a Windows service.

It could still cause problems the way you are using it. Poll the socket instead of using DoEvents.

You’ll need to start a timer outside of the DataAvailable event. If the meter has a problem you’ll never get ANY data, right? That would imply that this is the wrong place to check for a timeout.

You need to work with the events and create some internal modes. Mode: Sending Request. Mode: Waiting for Response/Data In this 2nd mode have a timer running and when it times out it’s failed to respond and then move on to the next one.