HELP: I need to read a value from a SERIAL PORT?


DaviD_H

Recommended Posts

Hi

I am develop an application to read some parameter on a doppler radar.

On of this parameter is the speed with its given by the radar to te PC by RS232.

When I see the data in DAQF's com monitor I see a long sequence similar to:

RX: +0008 Km/h 001 001 0010 0000

The data I need to read to put it on a variable display is +0008 Km/h

How can I do it?

Thanks a lot

Link to comment
Share on other sites

I'm assuming that your device just streams data without being polled. Is there any sort of end of line delimiter like a carriage return? I'm going to assume that the end of your Rx line has a 13 there.

1) create a channel to put the data into. Call it whatever you want (I'll call it "speed"), device type "Test", I/O type "A to D" with a Timing of 0.

2) next create a sequence: I'm assuming your device name attached to the serial port (with protocol of NULL) is "mydevice"

device.mydevice.purge()
private string datain
while(1)
   try	
	  datain = device.mydevice.readuntil(13)
	  datain.time = systime()
	  speed.addvalue(strtodouble(left(datain,5)))
   catch()
	  delay(0.2)
   endcatch
endwhile

3) run the sequence

If the line you posted is actually the line, it changes just a little. I'm going to use the K in Km/h as the delimiter. This means that no where else in the line can there be a K:

device.mydevice.purge()
private string datain
while(1)
   try	
	  datain = device.mydevice.readuntil(75) // 75 is ascii code for K
	  datain.time = systime()
	  speed.addvalue(strtodouble(right(datain,6)))
   catch()
	  delay(0.2)
   endcatch
endwhile

Link to comment
Share on other sites

Hi

I have attached a screen capture of my soft. I am trying to show the speed value in a variable value box called "VALUE".

In the COM viever you can see the 3 typical messages that the external device send automatically to us.

Satrting from the top:

1st line- a normal speed message with the device internal counter status

3rd line- an info message without speed

5th line- a speed mesage with an alarm status in the device.

As you can see, I thing that the delimiter must be "+" if is possible.

I have tryied to do with your sequence:

device.mydevice.purge()
private string datain
while(1)
   try	
	  datain = device.mydevice.readuntil(75) // 75 is ascii code for K
	  datain.time = systime()
	  speed.addvalue(strtodouble(right(datain,6)))
   catch()
	  delay(0.2)
   endcatch
endwhile

But firs I get in screen VALUE= NaN V and last VALUE= 124 V.

I think it could happens because a conversion error.

Any suggestion?

THANKS

post-1274-1248079402_thumb.jpg

Link to comment
Share on other sites

Actually, it appears that your lines do, in fact, have a carriage return / line feed at the end. So you should use this as the line delimiter. The NaN issue is because your are trying to parse the Counter Status line as a number and "Counter" obvious isn't a number.

Now that I see the traffic (and for anyone else who posts, please always include the monitor as it makes it much easier for us to see what your device is doing), your script should look like this:

device.mydevice.purge()
private string datain
while(1)
   try	
	  datain = device.mydevice.readuntil(10) 
	  datain.time = systime()
	  if (strtodouble(right(datain,6)) != NaN())
		 speed.addvalue(strtodouble(right(datain,6)))
	  endif
   catch()
	  delay(0.2)
   endcatch
endwhile

Link to comment
Share on other sites

Hi

I have finally get it. This is my code:

private string velocidad
private string contadores


device.COM1.Purge()
while (1)
   try	  
	  // read a line:
	  velocidad= device.COM1.readuntil(104) //read until "h" in km/h

	  contadores= device.com1.ReadUntil(13) // read until the first end of line
	  contadores= device.com1.ReadUntil(10) // read until the last end of line and the space too
	  velocidad.time = systime()

	  speed.AddValue((right(velocidad,8)))  // I pick 8 char before the h

   catch()
   delay (0.2)
   endcatch
endwhile

Another question.

How can I create an hyperterminal with DAQFactory?

I mean, I want to read all the data received throught RS232 each time and be able to send data too.

Anyway, must I have to insert a delay every time I send or receive data to not loose any data?

Thanks

Link to comment
Share on other sites

The comm monitor is essentially hyperterminal, but better because it shows all control characters.

There actually is no delay in the loop. The delay is inside the catch() statement and is just there so that if you have an error inside the try block you don't have an infinite loop that hangs your system. During normal, non-error, operation, the delay never executes.

Link to comment
Share on other sites

  • 1 year later...

Hi

In the serial data in the attached picture what is the correct parsing to get the watts figure. This is the 00000 number after <ch1><watts>00000.

I have not had any success so far working out how to handle the mid string. The values shown are for testing but didn't work, keep getting a NaN.

Thanks for the assistance

Rx: <msg><src>CC128-v1.18</src><dsb>00001</dsb><time>16:24:44</time><tmpr>24.9</tmpr>

<sensor>0</sensor><id>02335</id><type>1</type><ch1><watts>00000</watts></ch1></msg>1310

post-6481-1287210529_thumb.jpg

Link to comment
Share on other sites

You can't use mid() because its in XML format. mid() only works when you have fixed field lengths. In this case you have to find identifiers (<watts>) to locate the desired value. In most cases, you should always think about whether you can use the parse() function to do what you want, and in this case you can. Doing:

parse(datain, -1, ">")

where datain equals that long string, gives you an array that looks something like this:

{"<sensor", "0</sensor", "<id", "02335</id", "<type", "1</type", "<ch1", "<watts", "00000</watts", "</ch1", "</msg", "1310"}

You can see that the number you desire is right after the one labelled "<watts", so you can use the search() function to find it, then use the next index. Something like this:

private string data = parse(datain, -1, "&gt;")
private loc = search(data == "&lt;watts")
if (loc != -1)  // it will == -1 if not found
   return strToDouble(data[loc+1])
endif
return NaN()

First, doing parse() splits the string based on the specified value, namely ">". Passing -1 returns an array of strings parsed by that value. The delimiter (">") is stripped, thus the reason the string ends up being "<watts" and not "<watts>". Second, when you do strToDouble() on a string, it reads through the string until it finds the first invalid character and processes what it got so far. So even though the value after "<watts" is "00000</watts", the strToDouble() will just ignore everything from the < onwards. I could, technically, just parse that value by "<" and it would separate it into just the 00000. Its unnecessary in this case, but would be necessary if, for example, you were actually trying to extract a string value instead of a number.

Link to comment
Share on other sites

Archived

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