LabVIEW

cancel
Showing results for 
Search instead for 
Did you mean: 

Reading data from serial port using c++

I am interfacing with a C+ program file over an rs-232 connection i.e generating a DLL file and calling that function from labview.

The function work fine with the visual c++ 6.0 but whenever I am calling that function from labview it is giving me the following error.

“An exception occurred within the external code called by a Call Library Node. This might have corrupted LabVIEW’s memory. Save any work to a new location and restart Labview.”



I am attaching the code for your convenience.

#include "extcode.h"
#include "stdafx.h"

#define STRICT
#include
#include
#include
#include
#include
#include



extern "C"{
_declspec(dllexport) unsigned char read_Sensor(unsigned char read_data[], unsigned long read_length, unsigned long byte_transfered);
}

_declspec(dllexport) unsigned char read_Sensor(unsigned char read_data[],
unsigned long read_length, unsigned long byte_transfered)
{

HANDLE hPort = NULL;
DCB PortDCB;
COMMTIMEOUTS comTimeOut;
bool read_status = false;
DWORD dwCommModemStatus;

unsigned char error = 0;
unsigned long temp = 0;
unsigned char Byte[10];

if (hPort == NULL)
hPort = CreateFile("COM1",
GENERIC_READ|GENERIC_WRITE,
0, NULL, OPEN_EXISTING,0,NULL);
if(hPort == INVALID_HANDLE_VALUE)
{
error = 1;
return error;
}
else
{


PortDCB.DCBlength = sizeof (DCB);

// Get the default port setting information.
GetCommState (hPort, &PortDCB);

// Change the DCB structure settings.
PortDCB.BaudRate = 9600;//19200; // Current baud //19200 FOR CATTLE TAG
PortDCB.fBinary = TRUE; // Binary mode; no EOF check
PortDCB.fParity = TRUE; // Enable parity checking
PortDCB.fDtrControl = DTR_CONTROL_ENABLE;

PortDCB.fRtsControl = RTS_CONTROL_TOGGLE;
// error
PortDCB.ByteSize = 8; // Number of bits/byte, 4-8
PortDCB.Parity = NOPARITY; // 0-4=no,odd,even,mark,space
PortDCB.StopBits = ONESTOPBIT; // 0,1,2 = 1, 1.5, 2

// Configure the port according to the specifications of the DCB
// structure.
SetCommState (hPort, &PortDCB);

GetCommTimeouts (hPort, &comTimeOut);
// Specify time-out between charactor for receiving.
comTimeOut.ReadIntervalTimeout = 3;
// Specify value that is multiplied
// by the requested number of bytes to be read.
comTimeOut.ReadTotalTimeoutMultiplier = 3;
// Specify value is added to the product of the
// ReadTotalTimeoutMultiplier member
comTimeOut.ReadTotalTimeoutConstant = 3;
// Specify value that is multiplied
// by the requested number of bytes to be sent.
comTimeOut.WriteTotalTimeoutMultiplier = 0;
// Specify value is added to the product of the
// WriteTotalTimeoutMultiplier member
comTimeOut.WriteTotalTimeoutConstant = 0;
// set the time-out parameter into device control.
// Set the timeout parameters for all read and write operations
// on the port.
SetCommTimeouts (hPort, &comTimeOut);

SetCommMask (hPort, EV_RXCHAR);

while(1)//temp {
WaitCommEvent (hPort, &dwCommModemStatus, NULL);
SetCommMask (hPort, EV_RXCHAR );
if (dwCommModemStatus & EV_RXCHAR)
{
if( !ReadFile(hPort, &Byte, 1, &byte_transfered, NULL) )
{
error = 2;
read_status = false;
break;
}

if (byte_transfered == 1)
{
read_data[temp] = Byte[0];
temp++;

if (temp>read_length) break;
}
}
}
}




CloseHandle(hPort);
return error;



}
0 Kudos
Message 1 of 4
(5,136 Views)
tanjina,

How are you calling your dll in LabVIEW? Are you running it in the UI thread or as reentrant? I would suggest reentrant and see if that fixes your exception error.

Do this by double clicking on the library node and selecting reentrant from the pull-down.

-Brett
0 Kudos
Message 2 of 4
(5,108 Views)
I suspect the culprit to be the first parameter to your function actually. Calling another function requires the caller to allocate any buffer with a big enough size for the function to write something into. Allocate that array by using Initialize Array with U8 as type and the correct number as size. Pass this size also as read_length. While your code doesn't make use of this I think the third parameter to your function is either wrong or unnecessary.

As you use it now it is really nothing more than a local stack variable which you could declare inside the fucntion just as well. On the other hand what you probably want to do is have a function prototype like:

extern "C" _declspec(dllexport) unsigned char read_Sensor(unsigned *char read_data, unsigned long read_length, unsigned long *byte_transfered);

But you will have to do some modifications in your C code to support that parameter correctly.

That all said, doing the same in LabVIEW using VISA functions would have been done with about two VISA nodes, no DLL headaches and probably already long ago working.

Rolf Kalbermatter
Rolf Kalbermatter  My Blog
DEMO, Electronic and Mechanical Support department, room 36.LB00.390
Message 3 of 4
(5,085 Views)
I suspect the culprit to be the first parameter to your function actually. Calling another function requires the caller to allocate any buffer with a big enough size for the function to write something into. Allocate that array by using Initialize Array with U8 as type and the correct number as size. Pass this size also as read_length. While your code doesn't make use of this I think the third parameter to your function is either wrong or unnecessary.

As you use it now it is really nothing more than a local stack variable which you could declare inside the fucntion just as well. On the other hand what you probably want to do is have a function prototype like:

extern "C" _declspec(dllexport) unsigned char read_Sensor(unsigned *char read_data, unsigned long read_length, unsigned long *byte_transfered);

But you will have to do some modifications in your C code to support that parameter correctly.

That all said, doing the same in LabVIEW using VISA functions would have been done with about two VISA nodes, no DLL headaches and probably already long ago working.

Rolf Kalbermatter
Rolf Kalbermatter  My Blog
DEMO, Electronic and Mechanical Support department, room 36.LB00.390
Message 4 of 4
(5,084 Views)