LabVIEW

cancel
Showing results for 
Search instead for 
Did you mean: 

Can a CIN that is in an infinite loop send data to labview without exiting?

I have a C program that continuously queries a motor controller.  Right now that program is in a labview vi as a CIN.  The problem is that the CIN must exit before reporting the controller response to the labview vi.  This means I have to constantly run the CIN which opens, queries and closes the connection each time.  Is it possible to run the loop in the CIN itself so that the response buffer from the controller can be sent to the labview vi without exiting.  Are there variables types that can be passed from the CIN before completing the CIN? 
0 Kudos
Message 1 of 11
(4,257 Views)

Hi amonson,

      I think if you  pre-allocate an array in LabVIEW, and pass the array to your DLL, then update the array in the DLL, a LabVIEW "Monitor-loop" reading the array, will see the updates even while the DLL is executing.

The reason this could work is that arrays are passed to the DLL by reference, so the DLL is updating LabVIEW's memory-space, and if LabVIEW hasn't made a copy of the array for your "Monitor-loop", it'll show you exactly the same memory your DLL is updating!  Sound like a good theory? Smiley Wink

Cheers!

Message Edited by tbd on 09-10-2007 12:33 AM

"Inside every large program is a small program struggling to get out." (attributed to Tony Hoare)
0 Kudos
Message 2 of 11
(4,230 Views)
A CIN (code Interface node) has little to do with calling a DLL (call library function node), so I don't understand the above answer.
 
You might want to check if there is a native LabVIEW driver available for your motor controller? What's the model?

Message Edited by altenbach on 09-09-2007 11:15 PM

0 Kudos
Message 3 of 11
(4,227 Views)

Hi Altenbach,

      As I understood amonson, the essential problem is how to get data out of the CIN - without waiting for it to finish executing.  I think this can be done by passing the CIN a reference.  I always thought the CIN was much like a DLL function - they're both compiled C functions (and can update values by reference) - am I mistaken? Smiley Happy

Cheers.

"Inside every large program is a small program struggling to get out." (attributed to Tony Hoare)
0 Kudos
Message 4 of 11
(4,222 Views)

btw, In this context, reference => "pointer", a memory location, this is how C passes arrays and structures, and how LabVIEW passes arrays when "array data pointer" (the default) is chosen in a DLL's CLF.  I'm sure the CIN gets a pointer when an array is passed-in (so it can update LabVIEWs data), but perhaps there's a more elegant solution. Smiley Tongue

Cheers.

"Inside every large program is a small program struggling to get out." (attributed to Tony Hoare)
0 Kudos
Message 5 of 11
(4,203 Views)
The controller is a Galil DMC4080 motor controller.  I am running Labview under Mandrake Linux.  I can connect and send commands to the controller using a C program.  I modified the C program as a CIN to pass the controller response to the Labview front panel.  Galil has a library of functions used for the controller commands.  LStrPrintf is the command I use to write the data to labview.  Currently I just run this CIN without a while loop and loop it in labview but I recieve an  error message  after  a 1000 executions, see: http://forums.ni.com/ni/board/message?board.id=170&message.id=270220

If interested here is the current code I am using with the infinite loop. 
-----------------------------------------------------------------------------------
#include "extcode.h"
#include "dmclnx.h"
#include "hosttype.h"

MgErr CINProperties(int32 prop, void *data);

MgErr CINRun(LStrHandle IPAddress, LStrHandle Command, LStrHandle Response,
        float64 *ErrorCode);

MgErr CINProperties(int32 prop, void *data)
    {
    switch (prop) {
        case kCINIsReentrant:
            *(Bool32 *)data = TRUE;
            return noErr;
        }
    return mgNotSupported;
    }
MgErr CINRun(LStrHandle IPAddress, LStrHandle Command, LStrHandle Response,
        float64 *ErrorCode)
{
   float          rc = 0;          /* Return code */
   char           buffer[32] = ""; /* Response from controller */
   char           ip[20]=""; /* IP address of controller*/
   char           cmd[20]=""; /* Command to send to controller*/
   HANDLEDMC      hdmc = -1;       /* Handle to controller */
   CONTROLLERINFO controllerinfo;  /* Controller information structure */
 
   memset(&controllerinfo, '\0', sizeof(controllerinfo));
   controllerinfo.cbSize = sizeof(controllerinfo);
   controllerinfo.usModelID = MODEL_2100;
   controllerinfo.fControllerType = ControllerTypeEthernet;
   controllerinfo.ulTimeout = 1000;
   controllerinfo.ulDelay = 5;

   SPrintf(ip,"%H",IPAddress);

   strcpy(controllerinfo.hardwareinfo.socketinfo.szIPAddress, ip);
   controllerinfo.hardwareinfo.socketinfo.fProtocol = EthernetProtocolTCP;
 
   DMCInitLibrary();

   /* Open the connection */
   rc = DMCOpen(&controllerinfo, &hdmc);
   if (rc)
     {
       *ErrorCode = rc;
       return noErr;
     }
      while (1)
        {
          SPrintf(cmd,"%H",Command);
          rc = DMCCommand(hdmc, cmd, buffer, sizeof(buffer));
          if (rc)
            {
              *ErrorCode = rc;
              return noErr;
              break;
            }
          else
            {
              LStrPrintf(Response,buffer);
            }
        }
   rc = DMCClose(hdmc);
   if (rc)
   {
      *ErrorCode = rc;
      return noErr;
   }
   *ErrorCode = rc;
   return noErr;
}


0 Kudos
Message 6 of 11
(4,183 Views)

Hi amonson,

      If I understand, you're passing a LabVIEW String to the CIN (passed by reference).  I believe this means LabVIEW needs to allocate the memory for the string that your CIN will write to.  What's the length of the string you're passing to the CIN, and is it long enough to accommodate any message the CIN might try to copy to it?

Cheers.

"Inside every large program is a small program struggling to get out." (attributed to Tony Hoare)
0 Kudos
Message 7 of 11
(4,171 Views)
Yes.  I am passing the IPAddress (14 characters) and Command (variable length string) from labview to the CIN.  When the CIN completes it passes the Response(variable length string) to Labview.  I would like to pass the response to labview without the need to exit the CIN.  It would also be great if I could incorporate a stop button in the vi that when pressed would cause the CIN to break the loop.  Is it possible to have the CIN scan the labview variables.  
0 Kudos
Message 8 of 11
(4,156 Views)

Hi amonson,


> I would like to pass the response to labview without the need to exit the CIN.

> It would also be great if I could incorporate a stop button in the vi that when pressed would cause the CIN to break the loop.


I'm sure you can do this, but I've only had experience with C and DLLs - so you'll have to have patience. Smiley Wink

When you define the CIN, can you choose to pass a pointer-to-value for a numeric Input?  If so, then to stop your CIN, pass in a numeric, by pointer, then have your CIN watch that input for a specific value.  Set the value of the control in LabVIEW and the CIN should see it change.

I'd use the same technique to update a string, though I'm not sure how CINs see string-inputs, for instance, does LabVIEW send a pointer to a "String" structure with length-bytes first?  To keep it simple, I'd pass the CIN an array of (32) U8, and have the CIN populate it like a char[32].  In LabVIEW, poll the array of U8 for changes and write new contents to the FP.  You may need to truncate the [U8]/string at a null character. Smiley Wink

Cheers!

P.S. If you pass in an array of 32 U8s, make sure your Response is limited to 32 characters. (it looks like sizeof(buffer) will work assuming the declaration "char buffer[32]".)

Message Edited by tbd on 09-10-2007 04:30 PM

"Inside every large program is a small program struggling to get out." (attributed to Tony Hoare)
0 Kudos
Message 9 of 11
(4,148 Views)
Hi amonson,
   Here's CINRun with an additional parameter "ExitFlag" a char pointer.  I don't know how to make this show-up as an input parameter - is that defined in extcode.h?  Anyway, if you write to ExitFlag in LabVIEW, any non-zero value should stop the CIN.  There was a lot of room for simplifying this function - couldn't help myself - hope you don't mind. Smiley Tongue
 
 
MgErr CINRun(LStrHandle IPAddress, LStrHandle Command, LStrHandle Response,
        float64 *ErrorCode, unsigned char *ExitFlag)
{
   float          rc = 0;          /* Return code */
   char           buffer[32] = ""; /* Response from controller */
   char           ip[20]=""; /* IP address of controller*/
   char           cmd[20]=""; /* Command to send to controller*/
   HANDLEDMC      hdmc = -1;       /* Handle to controller */
   CONTROLLERINFO controllerinfo;  /* Controller information structure */
 
   memset(&controllerinfo, '\0', sizeof(controllerinfo));
   controllerinfo.cbSize = sizeof(controllerinfo);
   controllerinfo.usModelID = MODEL_2100;
   controllerinfo.fControllerType = ControllerTypeEthernet;
   controllerinfo.ulTimeout = 1000;
   controllerinfo.ulDelay = 5;
   SPrintf(ip,"%H",IPAddress);
   strcpy(controllerinfo.hardwareinfo.socketinfo.szIPAddress, ip);
   controllerinfo.hardwareinfo.socketinfo.fProtocol = EthernetProtocolTCP;
 
   DMCInitLibrary();
   /* Open the connection */
   rc = DMCOpen(&controllerinfo, &hdmc);
   *ExitFlag = 0;
   while ((rc == 0) && (*ExitFlag == 0))
   {
      SPrintf(cmd,"%H",Command);
      rc = DMCCommand(hdmc, cmd, buffer, sizeof(buffer));
      if (rc)
         break; // just exits loop
 
      LStrPrintf(Response,buffer);
   }
 
   if (rc == 0)
      rc = DMCClose(hdmc);
 
   *ErrorCode = rc;
   return noErr;
}
// Cheers!

Message Edited by tbd on 09-11-2007 12:53 AM

"Inside every large program is a small program struggling to get out." (attributed to Tony Hoare)
0 Kudos
Message 10 of 11
(4,125 Views)