low level Monitor command


Gammatech

Recommended Posts

Hello,

Is there a way to position where the 'Monitor - Serial' Pop up appears? I would like to use the facility so that if there is a serial problem the user can bring up this screen as a diagnostic aid but I would prefer it in the position that I pop up all my other user screens, ie roughly the bottom left quarter of the full screen. I have noticed that if the Monitor - Serial screen is re-positioned by dragging the top blue bar of the monitor screen the next time it is called it pops up where it last was. I have tried passing the coordinates I want into the Device.LAP.Monitor() call such as Device.LAP.Monitor(left,right,top,bottom) without any success. As it seems to "remember" where it was last this implies that the coordinates are stored somewhere.

Martin

Link to comment
Share on other sites

  • 2 weeks later...

OK.

I'll have to go back to one of my original thoughts where my popup page (bottom left corner where I want it) has a table component with the channel reading that holds my serial message (RawMsg) This channel has a history of 300 and as the messages come in every second that will give me the last 5 minutes viewable by using the vertical scroll bar. As the the table is being updated every second it is rather difficult to resolve any one value from the raw serial string (there are 24 comma separated elements) I therefore need a "Pause button" for the display (the channel is still being updated every second)

My other thought was to have 10 to 15 Variable value components aligned vertcally so they appear to be a table. The top Variable Value component has RawMsg[0] as its expression and 0 as its caption. The successive variable value components have RawMsg[1] with 1 as its caption and so on down to the bottom of the group of variable value components. I would still need a "Pause Button" but here I may be able to increment the indexes used each second so that a particular RawMsg[n] stays at the same vertical position in the grop.

Any suggestions for the "pause button" sequence or any other ideas of how to create such a display?

I've just thought of a problem. My serial protocol just looks for the carriage return at the end of the line and then reads until the next carriage return and passes the resultant string back to the main program. If there is a problem with the communications unless it is very slight my protocol is not going to find carriage returns to trigger it. I could really do with sending each character at the port. As my valid serial message has a three letter header followed by 22 values (numerical ASCII) followed by a three letter footer (with LF CR after) I might be better to do the framing in the main program.

Martin

Link to comment
Share on other sites

  • 3 weeks later...

Hi,

Following on from my realization that, as I was capturing a serial string that ends in Line feed, any major corruption (such as wrong baud rate etc) would probably not give me any characters at all to show in a monitor screen.

The device protocol I use was 'helped' (virtually created) by your "Matt" way back in time before this forum even existed. The on receive is simply:

If(StrIn == Chr(10))
  MeasReady = 1
  DataIn = ReadUntil(10)
  Local.Channel.AddValue(StrDevice,0,"Input",0,DataIn)
EndIf

The OnLoad, OnSend, & OnUnload are all empty while the Poll is as provided standard. (I don't use it as my remote device spews out a serial string of 24 comma separated fields once every second)

My auto run initialisation routine declares DataIn as a string but nothing for StrDevice

The problem is I just don't understand how the data gets into my application! I can see how the above OnReceive code works but not how it gets into the channel that it ends up in.

All my channels are Device type LAP (Which is the device name in the quick configuration)

They are all set to have I/O type blank and ascending channel numbers (0 to 162 at present)

There is one channel called 'Input' (that must be a left over from some long forgotten test) with Device Type 'Test', I/O Type 'A to D', Channel number 38, Timing 2 and all the rest at the default except that in the Quick Note/Special/OPC column there is a small grey box with three dots in it. Left clicking on this grey box causes a pop up entitled "Take Bulk Data"

The channel called "Input" has a slowly varying sine wave whilst my channel "RawMsg" has the correct string as received from my remote serial equipment. There are plenty of places in my main continuously running loop where some part of the latest value of the string is accessed and processed but I can't find anywhere any code that gets the received string into RawMsg. RawMsg is numbered channel 0

If I am to create some alternative to your monitor screen then I need to get each character as it comes in, recognize the return/linefeed pair and load up my channel RawMsg with the resultant string. That way gross corruption to the serial stream would be recognizable as random characters and hopefully correctable.

My message string that is placed somehow in channel RawMsg is always less than 150 characters in length so if it is greater than this without a Cr/Lf pair I simply abandon it any processing of it.

I would appreciate any light you can shed on this along with suggested code to read the incoming data character by character and form it into a string for storage.

Best Regards

Martin

Link to comment
Share on other sites

This line:

Local.Channel.AddValue(StrDevice,0,"Input",0,DataIn)

stuffs the value into the channel. Which channel is determined by the parameters. In this case, its whatever device the protocol is assigned to (because of "strDevice"), D# 0, I/O Type "Input", channel #0.

The best and easiest way to read character by character is outside a protocol. In fact, I rarely recommend OnReceive anymore and instead suggest something more like this anyway:

global string message
while(1)
   try
	  message += device.mydevice.read(1)
   catch()
	  delay(0.05)
   endcatch
endwhile

This reads one character at a time, waiting if it needs to for that character, and adds it to the end of a global variable called message.

Link to comment
Share on other sites

Hi,

So assuming my device is called "LPU" would I just select the Null protocol and have my new continuously running loop include the line:

Message += Device.LPU.Read(1)

At the moment I have the flag called MeasReady that is set each time a complete message (ending in LF/CR) is received and reset when the message has been processed. I have a large continuously running loop that does the processing if MeasReady is set and then resets MeasReady. If MeasReady is not set then there is no processing to do. In my new small additional continuously running loop if I check each character as it comes in and set MeasReady when CR is detected then it should all run as now:

Private ThisChar
while(1)
   try
	  ThisChar = Device.LPU.read(1)
	  Message += ThisChar
	  If(ThisChar == Chr(13))
		 MeasReady = 1
		 RawMsg.AddValue(Message)
	  EndIf
   catch()
	  delay(0.05)
   endcatch
endwhile

When I reset MeasReady I can empty the global string 'Message'.

Is it ok to stuff the global string 'Message' into my channel RawMsg as above? I assume I can't actually build the string in the latest element of RawMsg

As always thanks for all the help,

Martin

Link to comment
Share on other sites

You can't modify a value once its in the channel, so you have to build it in your global. Truthfully, I wouldn't do your processing outside this loop. You are going to have synchronization problems. Put the processing right in the if() or have the if() call another sequence as a function to do that processing. DAQFactory will buffer the characters while its busy doing that processing. Then do message = "" afterwards. Also, use a private instead of a global...

Link to comment
Share on other sites

Archived

This topic is now archived and is closed to further replies.