LabVIEW

cancel
Showing results for 
Search instead for 
Did you mean: 

Connecting multiple call library function nodes

Solved!
Go to solution

Piezo Control.jpg

 

 

First off, I apologize if some of these questions are fairly basic. For my job, I've been teaching myself LabVIEW (using one of the books) for the past two months, in addition to a semesters course of C++ software development. I've poured through some examples from the book and have searched on these forums + google search, but I've found confusing and conflicting information on how to handle C string data.

 

I have attached a picture of the block diagram, the actual VI, and a manual describing the .dll file I'm calling. My actual application is more complicated than what I've built here (I installed a free trial at home, since I can't bring files from my laboratory computers due to them not having internet access... IT has to install everything for us, but that's a side story!), but deals with execution outside this, as I'd have the VI wrapped around an event strucutre that executes based on which front-panel button a user presses, additional pop-up messages to the user, etc.

 

Ultimately, I'm setting up a program that alllows a user to press one button that sends a bunch of instructions to an instrument, where the given commands were compiled by the instrument company into a couple of .dll files. The instrument itself will hold on to some of the function specifications, so there isn't much need to worry about outputting the string parameters somewhere to be stored, and there is no receiving data from the instrument: it simply dispenses liquid loads based on what paramters I pass to it. Given the same issues of internet connection, I have to wait a few weeks for my IT team to install a .dll file decompiler on the computer that has LabVIEW installed, so that hopefully I could directly import the header file into the import wizard. I've been working off of their manual without even being able to look into the .dll file (that maybe has more documentation), and they don't have the most detailed documentation on their data types (though maybe these data types are common knowledge and I'm simply missing something). I've went ahead and copied + pasted some of their function prototypes + example code from pages 16-17 of the provided pdf (looks to me like a C calling convention):

 

' DLL Functions to talk to the PiezoElectronics

Public Declare Function bfx_piezo_OpenPort Lib "bfx_piezocontrol.dll" (ByVal portname As String) As Integer

Public Declare Function bfx_piezo_ClosePort Lib "bfx_piezocontrol.dll" () As Integer

Public Declare Function bfx_piezo_ConfigurePiezo Lib "bfx_piezocontrol.dll" (ByVal Capacity As Double, ByVal VoltagePerStroke As Double) As Integer

Public Declare Function bfx_piezo_SetupPiezo Lib "bfx_piezocontrol.dll" (ByVal StrokeLength As Double, ByVal DownStrokeVelocity As Double, ByVal HoldTime As Integer, ByVal UpStrokeVelocity As Double, ByRef LoadTime As Double,  ByRef LoadCurrent As Double, ByRef UnloadTime As Double,  ByRef UnloadCurrent As Double) As Integer

 

 

' Search for the electronics

rc = bfx_autodetect_SearchPiezo(False, PiezoElectronicsPort, PiezoElectronicsDev)

If rc = 0 Then MsgBox("No electronics could be detected", MsgBoxStyle.Critical) ' Error message LogLabel.Text = "No electronics could be detected"

   Else

       Action.Enabled = True '

      Device found -> enable Button LogLabel.Text = "Piezoelectronics found on Port " & PiezoElectronicsPort

      rc = bfx_piezo_OpenPort(PiezoElectronicsDev) ' Establish the communication

      If rc = 0 Then LogLabel.Text = "Opened Electronics"

   End If

End Sub

 

 

Private Sub Action_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Action.Click

Dim rc As Integer ' To store the dll's return code

Dim LoadTime, LoadCurrent, UnloadTime, UnloadCurrent As Double ' To store the values returned by the dll

 

rc = bfx_piezo_ConfigurePiezo(PiezoCapacity, PiezoVoltagePerStroke) ' Tell the dll the dispenser physics

If rc = 0 Then LogLabel.Text = "Configured dispenser" ' Setup dispensing parameters

 

rc = bfx_piezo_SetupPiezo(Stroke, DownStroke, HoldTime, UpStroke, LoadTime,  LoadCurrent, UnloadTime, UnloadCurrent) rc += bfx_piezo_Repeat(Repetitions, RepeatDelay)

If rc = 0 Then LogLabel.Text = "Setup dispensing parameters"

 

 

 

The only four functions of inerest to me are search piezo, open port, configure piezo, and setup piezo, as can be seen on my block diagram. My questions only concern the openport and setup piezo functions and how I built the call library function nodes, since these would also answer how to set up the other two. Upon VI execution, the error code I get is 1517, with the setup function highlighted, leading me to believe I have this function set up incorrectly (and potentially openport, explained in the next paragraph).

 

The open port function has two string parameters that are passed by reference, and the configure function takes one of these strings as a call by value. Can I simply wire the two together as I have done, or is it necessary to do something along the lines of adding a GetValueAtPointer sub-VI to first dereference the string pointer, and then pass the actual string along to the second node?

 

For specifying data types in the call library function nodes, I have all of the strings as C strings, doubles as doubles, return numerics as signed 32 integers (every function returns a long numeric I believe for debugging purposes), boolean as a signed 16-bit integer (after I forced my boolean constant into an integer), and one of my numbers in the setup function as an unsigned integer, as I was told in an email from the instrument manufacturer. Should I specify the call by value numbers as constants, or not, since they're not explicitly defined as constants in the provided code? Since they were not specified as long, am I right to assume signed 16-bit integer for the pass by value numerics? Is the boolean an 8-bit or 16-bit, and signed? If the function has a numeric paramter as call by value, I assume that by wiring in a numeric constant, that this value is passed along to the function?

 

Again, I apoligize if these questions are overly simplistic (as well as a lot of them), due to my limited programming experience and possibly scanty documentation from the company upon inspection. I welcome any comments about the VI as well, if I did anything simply illegal/bad practice.

 

Thank you for your time!

0 Kudos
Message 1 of 6
(3,637 Views)
Solution
Accepted by nprice2012

First of all, I am really not familiar with C/C++ dlls, but I remember something the DLL should include standard C functions in order to properly be accessed from LabVIEW. I do not know if this is the situation here, but lets see some others will enlight this part.

 

Second, whenever I have the chance to use simple serial commands directly, I go that way and I create my own LabVIEW VIs. As I see in the attached pdf doc, it is possible to command the hardware via serial without using the DLL (from page 18). If those functions fulfil your needs, I would really program the VIs via VISA, your life will be much easier...

 

edit: http://www.ni.com/tutorial/3702/en/

Message 2 of 6
(3,618 Views)

The DLL does contain exported functions but was probably written in Visual Basic .Net. As such it has a few specific details that make it less trivial to interface to LabVIEW. First, a String in Visual Basic is a Unicode string, while LabVIEW uses ASCII strings. So that won't work directly. Second, a Boolean in VB is platform dependent, it used to be 16 bits in VB6 but MS doesn't really document the exact storage in newer VB versions. Also note that Integer in modern VB versions is actually a 32 bit integer value.

 

Considering these complications I would definitely second Blokk's recommendation to go directly with the serial port communication. The protocol looks trivial enough so that implementing it in a few VIs is actually more efficient, even for someone with lots of experience with the Call Library Node. Extra bonus is that you will not get crashes or hard to understand error codes from the Call Library Node.

Rolf Kalbermatter
My Blog
Message 3 of 6
(3,599 Views)

I understand y'alls points. Luckily, the PipeJet does have a RS-232 port I can use for serial communications. I'm assuming this must be used instead of its USB connection (if this is considered serial), or will the VISA commands work either way, as long as the resource has the PORT location the instrument is connected to?

 

I looked at the handy Instrument Assistant that allows opening and writing multiple commands. Does placing indicivial opening, write, read, etc. commands on the block diagram have any realy advantage over using this Instrument Assistant, other than that we can cleary see what's going on?

 

Thanks again!

0 Kudos
Message 4 of 6
(3,553 Views)

I looked at the handy Instrument Assistant that allows opening and writing multiple commands. Does placing indicivial opening, write, read, etc. commands on the block diagram have any realy advantage over using this Instrument Assistant, other than that we can cleary see what's going on?

 

It is ok to test the hardware using this Express VI (Instrument Assistant), but for often better to use proper low level VISA calls (Open, Write, Read, Close, etc.). The Express VI always opens and closes communication with your hardware. There are cases when this is not a problem, but for example if you want to use a While loop and repeatedly perform a command, this can cause delays (Opening the communication takes usually more time than normal operation commands).

 

To avoid such drawbacks, I would recommend you to use low level VISA functions. For simple manual command testing you can just use the VISA Interactive Control from MAX (Measurement and Automation Explorer).

 

About the code: since you need to perform sequences, I would use some form of State Machine (maybe queued state machine, since you have predefined sequences). If you use a State Machine, you have full control over your task: even during a sequence is executing, you can abort, measure time, etc...

Message 5 of 6
(3,547 Views)

@nprice2012 wrote:

I understand y'alls points. Luckily, the PipeJet does have a RS-232 port I can use for serial communications. I'm assuming this must be used instead of its USB connection (if this is considered serial), or will the VISA commands work either way, as long as the resource has the PORT location the instrument is connected to? 

 


Unfortunately, the answer will be: it depends! An USB device CAN be implemented in a way that it will announce itself as a Virtual COM port to a computer. In that case VISA will simply see it as a normal COM port. But you mentioning that the instrument also has an RS-232 port build in makes me seriously wonder. Why would they do that if the USB port can work as a virtual COM port too?

 

So there is a good chance that the USB port uses a different protocol, either based on for instance the USB HMI class (normally used for mouse, keyboards, joysticks, etc) or an entirely porprietary protocol. While VISA can access such devices through the USB Raw interface it is a very tedious exercise to write a driver for that and requires a fully documented protocol description, which is in most cases already the KO criteria, since very few manufacturers are willing and able to document their low level data protocols.

Rolf Kalbermatter
My Blog
Message 6 of 6
(3,541 Views)