LabVIEW

cancel
Showing results for 
Search instead for 
Did you mean: 

How to send different types of data periodically over Serial Port?

Solved!
Go to solution

Hello! Everyone

 

I have to send data from LabVIEW to my embedded device over Serial Port.

 

I know how to send data over serial port in LABVIEW, i have done this part already.

 

Now the problem is i have multiple types of data which i need to query from my embedded device, so i want to send query command periodically.

 

So lets say my four Op Codes are as follow, which will send four different types of query command to my embedded device over serial port.

(To be honest only OP_LED and OP_SENSOR is used right now)

 

0, OP_SYNC

1, OP_LED

2, OP_SENSOR

3, OP_FUTURE

 

Basic Packet Structure is as follow:

Header(0x2C), Lengh(Op Code+Data Length), Op_Code (1 Byte), Data Length (n Bytes), Checksum 

 

For OP_LED i need to send the packet as follow:

0x2C 0x02 0x01 0x00 0x2F (Where 0x2F is the XOR Checksum) (Checksum calculation part is done and is present in SUB Vi form)

Here 0x02 is packet length

0x01 is Op Code for OP_LED

 

Similarly

For OP_SENSORi need to send the packet as follow:

0x2C 0x03 0x02 0x00 0x00 0x2D (Where 0x2D is the XOR Checksum) (Checksum calculation part is done and is present in SUB Vi form)

Here 0x03 is packet length

0x02 is Op Code for OP_SENSOR

 

So how can i do this periodically in labview and in such a way that period can be adjusted whenever required.

Is there any thing in LabVIEW to do so.

 

I had done the reception and decoding part and is working properly.

http://forums.ni.com/t5/LabVIEW/Store-data-coming-from-Serial-Port-in-Buffer-and-then-take/m-p/32722...

 

So do i need to implement read and write part in same while loop?

 

 

0 Kudos
Message 1 of 31
(5,263 Views)

Byte packing is always fun.  I have done plenty of these in LabVIEW.  The first thing to do is to get your data into a byte array.  You know the format for each command.  So however you just encode your data however you need to.  Then just use Build Array to add your start byte, opcode, length, and CRC to the data.  Then it is a simple Byte Array To String to write to the serial port with VISA Write.


GCentral
There are only two ways to tell somebody thanks: Kudos and Marked Solutions
Unofficial Forum Rules and Guidelines
"Not that we are sufficient in ourselves to claim anything as coming from us, but our sufficiency is from God" - 2 Corinthians 3:5
Message 2 of 31
(5,256 Views)

@crossrulz wrote:

Byte packing is always fun.  I have done plenty of these in LabVIEW.  The first thing to do is to get your data into a byte array.  You know the format for each command.  So however you just encode your data however you need to.  Then just use Build Array to add your start byte, opcode, length, and CRC to the data.  Then it is a simple Byte Array To String to write to the serial port with VISA Write.


I take a control on front panel which is used to change which Op_Code needs to be send.

 

Then based on the Op_Code selected in front panel, i created packet in case structure which consist of Op Code + Data Bytes.

Then Out of case structure i calculated the XOR Checksum of the OP_Code and Data Bytes.

Then i calculated the length of packed and add it to the data coming from case structure along with header.

Then i combine the checksum and then send it over serial port every 1 sec.

 

Here is the block diagram.

VI.png

 

I try to do everything with the build array but fails to do so, got some errors.

 

Now this works but i do have two problems now.

1) OP_SYNC and OP_FUTURE doesn't have data, but still receive its data on serial port, can i do something here such that i didn't get anything when array is empty in case structure.

2) Selecting which Op Code is to be send is done using front panel control but in real application this task must be automated at some frequency, like OP_LED packet must go out at serial port at 100msec and OP_SENSOR packet must go out at 1000msec, how can i do this.

 

Please suggest.

I am attaching my VI below.

Download All
0 Kudos
Message 3 of 31
(5,232 Views)
Solution
Accepted by topic author xpress_embedo

Don't use Insert into Array if you are putting data into an array at index 0.  Just use Build Array.

 

No need to have the Visa Write be on a wire branch for the VISA reference and error wire going across the top.  Those wires should go THROUGH the VISA Write.

 

Doesn't your checksum require all the bytes up through the data?  Righ now you are only putting the checksum on the data bytes and forgetting about the opcode and length bytes.

 

Your not sending the opcode for Opsync or Opfuture.  You are just sending empty arrays.  Meanwhile for the other two, you put the opcode into the data array.  Just wire your original opcode wire into the Build Array.  Get the data element out of those case structures that is supposed to represent the opcode.

 


@xpress_embedo wrote:

Now this works but i do have two problems now.

1) OP_SYNC and OP_FUTURE doesn't have data, but still receive its data on serial port, can i do something here such that i didn't get anything when array is empty in case structure.

I don't understand this statement.  Maybe my answer above will fix whatever question you have here.

 

 

 

2) Selecting which Op Code is to be send is done using front panel control but in real application this task must be automated at some frequency, like OP_LED packet must go out at serial port at 100msec and OP_SENSOR packet must go out at 1000msec, how can i do this.

Now you are getting into a little bit more of an architecture.  I would encapsulate the code that is inside the while loop as a subVI.  Then with your program's main while loop, use two Elapsed Time Express VI's, one set for 100 msec, the other for 1000 msec.  When an express VI is true, have it execute the subVI with one set of commands waiting for the response.  When the other Express VI is true, have it execute the subVI with the other set of commands.



 

Does the device respond with anything when you send these commands?  You are only sending data.  I don't see any VISA Read to be able to get any data back.

Message 4 of 31
(5,222 Views)

@RavensFan wrote:

Don't use Insert into Array if you are putting data into an array at index 0.  Just use Build Array.

 

I modified the block diagram and here it is updated block diagram with both previous one and using build array only, but why it contains to many red marks. Good thing is that it is working fine.

VI.png

 

 

No need to have the Visa Write be on a wire branch for the VISA reference and error wire going across the top.  Those wires should go THROUGH the VISA Write.

Okay, so what i understand is that, connect VISA Reference and error to Write Block and then to Close block, no need to go directly.

Like this

VI.png

 

Doesn't your checksum require all the bytes up through the data?  Righ now you are only putting the checksum on the data bytes and forgetting about the opcode and length bytes.

Yes you are right checksum should be of whole packet, but there is some problem due to which i had to take checksum of Op Code and Data Bytes only. Will correct it in future right now i just want to complete this task.

 

Your not sending the opcode for Opsync or Opfuture.  You are just sending empty arrays.  Meanwhile for the other two, you put the opcode into the data array.  Just wire your original opcode wire into the Build Array.  Get the data element out of those case structures that is supposed to represent the opcode.

Actually i want something like , that if array is empty then don't send packet, but i think there is noo need for that, i will simply discard this packet when received at my device.

 


@xpress_embedo wrote:

Now this works but i do have two problems now.

1) OP_SYNC and OP_FUTURE doesn't have data, but still receive its data on serial port, can i do something here such that i didn't get anything when array is empty in case structure.

I don't understand this statement.  Maybe my answer above will fix whatever question you have here.

Yes Its fixed now thanks

 

 

 

2) Selecting which Op Code is to be send is done using front panel control but in real application this task must be automated at some frequency, like OP_LED packet must go out at serial port at 100msec and OP_SENSOR packet must go out at 1000msec, how can i do this.

Now you are getting into a little bit more of an architecture.  I would encapsulate the code that is inside the while loop as a subVI.  Then with your program's main while loop, use two Elapsed Time Express VI's, one set for 100 msec, the other for 1000 msec.  When an express VI is true, have it execute the subVI with one set of commands waiting for the response.  When the other Express VI is true, have it execute the subVI with the other set of commands.

 

Creating a SUB VI looks a good idea, This is what i am looking for Elapsed Time Express, i will now study how can i use this in my VI as i am new.



 

Does the device respond with anything when you send these commands?  You are only sending data.  I don't see any VISA Read to be able to get any data back.

Yes Device will also receive the same packet with information, right now i am sending the query packet only and my device will respond with response, which part is already done and i have to integrate both VI's

And that part is here, and you help me lot in creating that VI, thanks

http://forums.ni.com/t5/LabVIEW/Store-data-coming-from-Serial-Port-in-Buffer-and-then-take/td-p/3266...


 

0 Kudos
Message 5 of 31
(5,212 Views)

@xpress_embedo wrote:

@RavensFan wrote:

Don't use Insert into Array if you are putting data into an array at index 0.  Just use Build Array.

 

I modified the block diagram and here it is updated block diagram with both previous one and using build array only, but why it contains to many red marks. Good thing is that it is working fine.

VI.png

 The red marks are called coercion dots.  It is telling you the datatypes don't line up and some need to be coerced to another datatype.  That datatype will be the one that can best represent the most numbers.  Because array size gives an I32, all the U8's get coerced to an I32 when going into the array.  Then because you are displaying that into a U8 array indicator, they all get coerced back.

 

Attached is a cleaner form of that code.

 

Message 6 of 31
(5,198 Views)

Thanks for that help.

 

But now i am confused.

I created sub vi and then using elasped time express vi to schedule when packet is going to be send.

 

VI.png

 

Am i doing it in right way as it is creating confusion in my mind.

Like where do i place serial write, whether it is outside the case structure or inside the case structure, if i place it inside the case structure then i have to provide some data in False case as well, which will trigger some packet on serial port.

Please suggest what could be the best possible way to implement this.

 

Another question, which is just for knowledge though it is not impacting anything.

1) Why my SUB VI borders are light in color.

2) How to align the input and output terminal.

0 Kudos
Message 7 of 31
(5,177 Views)

@xpress_embedo wrote:

Like where do i place serial write, whether it is outside the case structure or inside the case structure, if i place it inside the case structure then i have to provide some data in False case as well, which will trigger some packet on serial port.


Yes, put the VISA Write inside of the case structure.  You just wire the VISA Resource straight through in the false case.

 

 


@xpress_embedo wrote:

Another question, which is just for knowledge though it is not impacting anything.

1) Why my SUB VI borders are light in color.

2) How to align the input and output terminal.


1. That usually happens when you change the connector pane of the subVI.

2. That is completely based on the connector pane and where you wire up the controls.


GCentral
There are only two ways to tell somebody thanks: Kudos and Marked Solutions
Unofficial Forum Rules and Guidelines
"Not that we are sufficient in ourselves to claim anything as coming from us, but our sufficiency is from God" - 2 Corinthians 3:5
Message 8 of 31
(5,169 Views)

@xpress_embedo wrote:

Thanks for that help.

 

But now i am confused.

I created sub vi and then using elasped time express vi to schedule when packet is going to be send.

 

VI.png

 

Am i doing it in right way as it is creating confusion in my mind.

Like where do i place serial write, whether it is outside the case structure or inside the case structure, if i place it inside the case structure then i have to provide some data in False case as well, which will trigger some packet on serial port.

Please suggest what could be the best possible way to implement this.

 

Another question, which is just for knowledge though it is not impacting anything.

1) Why my SUB VI borders are light in color.

2) How to align the input and output terminal.


This is a study in how to ignore data flow principles.  😉 Just because "VISA Close" is to the right of your loop doesn't make it execute after the loop.  Because it isn't wired to execute after the loop - or after anything, actually - it will execute whenever it wants - and probably before you want it to.  Your elapsed time express VIs are not wired to execute after anything, so either one may fire first.  Similarly, the two cases aren't wired somehow together, so either one may execute first.  Similarly, that means any of the "VISA Write" nodes may execute first - definitely NOT what you had in mind.

 

A more subtle gotcha is that if "Select Opcode Data" isn't set to execute re-entrantly, one instance will have to wait until the other has completed before it can execute.  In the vast majority of cases, this isn't a problem, but if the VI takes a while to execute, it may unnecessarily slow down the application or it may mess up timing.

Bill
CLD
(Mid-Level minion.)
My support system ensures that I don't look totally incompetent.
Proud to say that I've progressed beyond knowing just enough to be dangerous. I now know enough to know that I have no clue about anything at all.
Humble author of the CLAD Nugget.
Message 9 of 31
(5,167 Views)

Put the Byte Array to String and VISA Write inside your subVI.  Everything about how to formulate a message and the actual writing of the message should be encapsulated in the subVI.

 

(Why'd you change Enable Termination Character from False to True?)

Message 10 of 31
(5,154 Views)