LabVIEW

cancel
Showing results for 
Search instead for 
Did you mean: 

Parsing data in a package with Labview

I created a sample labview code as follows.
parser-1.png
In the string, 4 samples of 13 bytes come arranged side by side. The same calculations are made for each 4 samples. After these operations are done and after the while loop is stopped, they should be arranged one under the other in a 2D array.
My aim here is to add a sample to the 2D array every 50ms refresh if the change button is pressed and the refresh button is pressed.


I created an example like this, but I feel like I'm using a roundabout method. Is there a shorter way to do this?
________________________________
Every opinion given is worthy of respect. 

0 Kudos
Message 1 of 20
(22,807 Views)

I'm puzzled by your "LabVIEW Code".  You talk about a string containing (I thought) 4 sample of 13 bytes, which I calculate is a 52-byte sample (or at least a sample size divisible by 4).  The example of your input string contains 70 bytes, which is neither equal to 52 nor divisible by 4.

 

It does appear that your 70 characters are made up of 4 arrays of similar appearance (the first column is all 6, the third is all 4, column 2 ranges from 196 to 211, columns 5-7, 11, and 13 are all 0, column 8 is all 250, 9 is all 255, and 10 is all 16.  Furthermore, the final 18 bytes remaining have a very different structure, mostly 0 except for a 62 as byte 53 and a string of bytes from 65 to 70.  [I'm not using "0-indexing" in naming Byte positions -- the first byte I'm calling "Byte 1"].

 

I'm mystified what you are trying to do with the 52 bytes, 4 rows of 13 numbers, that you get (from the beginning of this string).  Once the 2D Array comes into the For loop through the Indexing tunnel, it already is a 1D array of 13, so you don't need to reshape it into a 1D array of 13!  I have no idea why you are torturing yourself (and us) by all the byte-shifting operations that follow.  I suspect that if you described the real format of the data contained in these 52 bytes, we could suggest a Cluster that you could define that would exactly match the actual values contained in those 13 bytes (such a Event, U8; Time, I16, etc.) so you could do the entire conversion by simply type-casting the Array of 52 Bytes into an Array of MyCluster, ending up with an Array of 4 elements containing 4 [Event, Time, etc.] quantities that you could easily (and transparently) process.

 

Bob Schor  

0 Kudos
Message 2 of 20
(22,787 Views)

Here's one possible other method.  The main thing is a tidier way to convert the last 12 of each 13 bytes set to i16.  Here, you flatten the 12 u8's to string then unflatten in "little-endian" mode (to accomplish your byte reversals when building the i16's) to an array of i16.   I did a little other tidying to avoid crossing same-color wires, but mainly left the rest of your code alone.  A few notes and observations below:

 

parser-1 modKP.png

 

1. Your example string has more than 4*13 bytes so you lose all the rest.  Is this intentional?

2. Once you reshape to 4x13, auto-indexing works through the 4 rows in order, no need for the further reshape or for the For Loop termination when i==3.

3. You might want to combine your fields into a typedef'ed cluster containing a combo of i16's and dbl's instead of storing all in a dbl array..  Maybe you should be including your leading u8 'event' designator too?

4. On your GUI, you might want your 'refresh' button to have a "latch when released" mechanical action to avoid the need for some of your boolean logic.  (Right-click for options).   Maybe your 'is changed' button too?

 

 

-Kevin P

ALERT! LabVIEW's subscription-only policy came to an end (finally!). Unfortunately, pricing favors the captured and committed over new adopters -- so tread carefully.
0 Kudos
Message 3 of 20
(22,779 Views)

   and

70 bytes of data in total, but 52 bytes are 4 samples of the data packet sequentially sampled every 50 ms, while 18 bytes of data are normal data that is refreshed only once.
Structure of the packet.
4xEvent,time,X,Y,Z,Voltage,Count,package number,speed,lat,long,device identification code

The data [Event, time, X, Y, Z, Voltage, Count], packet number, speed, lat, long are placed 4 times side by side and added to a packet.
and this data is read from a serial every 200 ms.
Then, after the necessary transformations are made, they will be written constructionworker_1-1704572849736.png to a 2D csv file. 
They will be written below as follows.
At each cycle refresh, 4 samples will be written to the csv file.

Event,time,X,Y,Z,Voltage,Count,package number,speed,lat,long,device identification code
Event,time,X,Y,Z,Voltage,Count,package number,speed,lat,long,device identification code
Event,time,X,Y,Z,Voltage,Count,package number,speed,lat,long,device identification code
Event,time,X,Y,Z,Voltage,Count,package number,speed,lat,long,device identification code



I It's a great kindness to remind me that I forgot a big ''reshape'' there 🙂 

I saw your cluster suggestion, but wouldn't it take more effort to convert from cluster to array again?



Thanks for the method you suggested, it's a little more organized 🙂
-That is right.I forgot to add ''Event''.
-Yes, actually, it can be created in a string-based array instead of an array. In this way, I can print data in double and different data types to the CSV file. But I do not know if these conversions are really needed. Extra time is spent in these functions.
-Boleans are representative.
So normally, if the data comes from the serial, the conditions are met.

0 Kudos
Message 4 of 20
(22,745 Views)

Here's what I might do.

 

altenbach_1-1704600430903.png

 

Same result, less code 😄

 

It would be easy to add your other elements (speed, lat, long, etc.) to the array as needed.

 

Message 5 of 20
(22,712 Views)

   Thanks for your answer.This method is a little more organized

I wanted to ask this question in connection with this topic.
Data from Arduino is sent as packet, but for some reason when reading from serial in labview packet in data sometimes goes to bottom row. This has nothing to do with Arduino code. There was a problem reading data in Labview.
Dropping the bottom row in this way causes errors in the data read. Because I directly convert the read data into a byte array.

What is the cause of this problem and what method can I use to solve it?

constructionworker_3-1704641120061.png

 

 

string.png<<<<< that is true received.

0 Kudos
Message 6 of 20
(22,650 Views)

I don't know your definition of "bottom row", but your use of "bytes at port" is probably misguided since you know exactly how much you are supposed to read with each "packet".

 

We can't really tell much more from a truncated picture of LabVIEW code. Consider attaching your actual VI instead.

 

Maybe start with Tim's presentation and see if you learn something new.

0 Kudos
Message 7 of 20
(22,643 Views)

Now we are getting somewhere.  According to your last two responses, the Arduino sends you a 70 byte packet consisting of the following:  4 13-byte data elements representing a U8 and 6 I16 values, and a "once-every-4" 18 byte data section that includes other numeric and string data which might be package number, speed, latitude, longitude, and a string Device ID Code.

 

@Altenbach is absolutely right that it is difficult for us to make sense of your situation when you (a) send us pictures of your LabVIEW code, and (b) only send "pieces" of the code.  What we'd really like to see is a zipped version of the LabVIEW Project, possibly including the Arduino code, saved in LabVIEW 2018 (which we call can read).

 

So I'm going to make an assumption (which might be entirely wrong!) that the Arduino gathers four 13-byte data packets and transmits them to LabVIEW, along with an 18-byte "supplemental" packet "all at once", ending the transmission with a termination character (I see you have Termination Character enabled on your VISA Serial configuration function).  If you do as @Altenbach suggests and view @crossrulz's Video on the Proper Way to Communicate over Serial (from VIWeek 2020), you'll see you should remove the Bytes at Port call and tell the VISA Read to read 1000 bytes (or, if like me, you prefer binary, ask for 1024 bytes).  If the Arduino is sending out a 70-byte packet + a terminal <LF>, you'll get the data in an optimal fashion.

 

Note that the final "picture" seems to show a string "improperly truncated" because you were "force-reading" 70 bytes at a time the Arduino wasn't sending (who knows why?) -- if you'd only waited for that <LF> (or whatever Termination character you and the Arduino agreed to use), you'd not have this problem!

 

So now you have 70 bytes.  You know that they represent 4 13-byte "XYZ" data elements and 1 "mixed bag + ID code" something.  Sounds like a Cluster to me, with an Array of (it will turn out to be 4) "XYZ-type" data that are a mix of U8, possibly I16 (but more likely ultimately Floats), but definitely 7 distinct numeric quantities that might want to be analyzed as individual elements, followed by a single 18-byte section that is a further mix of numeric and string.  Why not make a Cluster, so you can "break-out" the various pieces that you might want to analyze?

 

Bob Schor

0 Kudos
Message 8 of 20
(22,625 Views)

@Bob_Schor wrote:

If the Arduino is sending out a 70-byte packet + a terminal <LF>, you'll get the data in an optimal fashion.


Since the data is binary, any possible byte is allowed for the bulk data (incl. e.g. <LF>), so a termination character obviously makes no sense because early termination is a real possibility.

0 Kudos
Message 9 of 20
(22,617 Views)

Yes, I want to explain the situation a little more.
The labview code I use is as follows.I explained a little bit about the problem with the way the data comes in the code.


Since the Arduino code is very long, only the packet sending code fragment is as follows.

 

bool sendPkt(uint8_t *data, uint8_t len)
{
  for (int i = 0; i < len; i++)
  {
    radioPort.write(data[i]);
    radioPort.flush();
  }
  radioPort.println();
  radioPort.flush();
  // set flag
  radioFnctn = TXmode;
  TX = true;
  return true;
}
//---------------------- in the library
size_t Print::println(void)
{
	uint8_t buf[2]={'\r', '\n'};
	return write(buf, 2);
}

 

I think the '''\r'', '\n'' used here may be causing a problem because '\n' is used as the termination character of ''VISA Configure serial port'' in the labview.
How can we do this in labview?

 

0 Kudos
Message 10 of 20
(22,581 Views)