edwardewilliams Posted October 21, 2008 Share Posted October 21, 2008 We use the following custom sequence to poll remote serial device over telemetry links. The link is established elswhere in DF and the Device Number (dn) is passed to this function. function PollLogger(dn) ispolling = 1 try private string datain = "junk" private string chan private ch private val private count = 0 while (1) try purge() write(chr(13)) delay(2) write(chr(13)) delay(2) write(chr(13)) delay(3) read(3) purge() if (resetpulse[dn]) //sitenum or dn? write("ch,p1"+chr(13)) delay(3) purge() write("pm=3"+chr(13)) delay(3) purge() resetpulse[dn] = 0//sitenum or dn? endif write("cr,a"+chr(13)) break catch() ? strLastError endcatch count++ if (count > 3) return endif delay(10) endwhile while (1) try datain = readuntil(10) // read a line: BV: 12.831310 chan = right(parse(datain,0,":"),2) val = strtodouble(parse(datain,1,":")) if (val == NaN()) val = 0 endif if (chan == "BV") ch = 0 else ch = strtodouble(mid(chan,1,10)) endif chan = left(chan,1) switch case (chan == "B") Channel.AddValue(strDevice,dn,"BatteryVoltage",0,val) case (chan == "S") Channel.AddValue(strDevice,dn,"SDISensor",ch,val) case (chan == "A") Channel.AddValue(strDevice,dn,"AnalogInput",ch,val) case (chan == "P") Channel.AddValue(strDevice,dn,"PulseInput",ch,val) endcase catch() ? "PollLogger: " + strLastError timepolled[dn] = systime() return endcatch endwhile catch() ? strLastError endcatch timepolled[dn] = systime() This has worked well for us in the past, but recently we've started having a problem where the last value read and placed in the "DATAIN" string will continue to parse over and over and over again - about every 8 seconds or so. Setting the timeout for the remote device to a shorter time solves the problem (the sequence relies on comm timeout to move on out of the read/parse loop) but then we have a problem where some of the devices may not connect since sometimes, depending on the device, it can take 10-15 seconds to obtain a connect - if device timeout is set shorter than that to avoid this problem, then we never connect in the first place. Thoughts as to how to make this more predictable? We can't have a "hard out" from the read/parse loop since depending on the device, we get a different number and combination of channels and channel types with no "end of data" character or similar termination sequence available. Link to comment Share on other sites More sharing options...
AzeoTech Posted October 22, 2008 Share Posted October 22, 2008 I'm assuming of course, that your device isn't actually sending the same string over and over again. The monitor would tell you this. I'm also assuming you don't have an ignore("all") or similar somewhere. I'd try two things first: 1) put a breakpoint in and walk through the code. If you have this in a protocol, you'll have to move it to a sequence to walk through it. Put a using("device.myserial") in front so you don't have to expand all the readuntil() and other serial functions. Or, if you don't want to do that, add a bunch of ? statements so you can trace what is happening. 2) Put datain = "" just before the readuntil(10). This will ensure that the previous reading doesn't get carried forward. Link to comment Share on other sites More sharing options...
edwardewilliams Posted October 22, 2008 Author Share Posted October 22, 2008 Sorry, I should have clarified. The parsing loop exectues properly for each of the inbound reading as they come and get placed in to the "DATAIN" string. (no, the remote device isn't sending the same stirng over and over) Say for instance I'm reading five channels, they all get read and properly parsed. Then, the remote device gets done sending and while we're waiting for the timeout to occur in order to cause the while loop to error out and the function to exit, the last reading (the fifth channel in my example, for instance) just continually re-parses. In other words, the parsing loop just re-executes on whatever the last string was that was placed in to "DATAIN" In the copy of this I have running on my machine, I've added a number of "?" statements and they show that the parsing loop simply keeps repeating, re-parsing that last piece of data and creating new entries on the associated channel over and over until manually stopped. It's as if the connection isn't timing out or the function isn't seeing the timeout.... ? We did, however, have an "ingnore("all")" call in the startup routine...... I'll see how it works now. Link to comment Share on other sites More sharing options...
AzeoTech Posted October 23, 2008 Share Posted October 23, 2008 ignore("all") only affects the current thread, so if your startup routine did beginseq() it won't affect the sequence started. However, if a sequence has ignore("all") and then calls another as a function I believe it will also ignore all errors. The easy workaround if you don't want to chase it down is simply this: datain = "junk" datain = readuntil(10) // read a line: BV: 12.831310 if (datain == "junk") throw() endif Link to comment Share on other sites More sharing options...
edwardewilliams Posted October 23, 2008 Author Share Posted October 23, 2008 Thanks for the tips. If the issue happened all the time, it would be easier to find - but it's intermittent and hard to predict, so the "quick fix" is needed for the moment. Appreciate the help, as always. Link to comment Share on other sites More sharing options...
Recommended Posts
Archived
This topic is now archived and is closed to further replies.