LabWindows/CVI

cancel
Showing results for 
Search instead for 
Did you mean: 

problems using comport

Hello,

First the history:
We have an stepping motor unit with serial comunication. The first
version of our comunication programm was DOS-based using "_inp" and
"_outp". It Worked fine!
We ported this Software to windos few years ago unsing the CVI low level
driver functions "inp" and "outp". It worked well with WinNT 4.0 a long
Time. It never worked with win2000 and now we have problems with WinNT
4.0 and fast Computers(maybe a timing problem). Now we try to use the
standard CVI com Functions (ComWrtByte...) and they work. But there is
still a problem: with same baudrate the comunication is about 5 times
slower as the version with "inp" and "outp".

Has anyone an idea how to solve this Problem?.

//***************************************************************************

// InitSer
//***************************************************************************

// Initialising.

//---------------------------------------------------------------------------

// Typ | Parameter |IOR| Bedeutung
//---------------------------------------------------------------------------

// unsigned long | iComNum | I |
//---------------------------------------------------------------------------

// int | RETURN | R | 0 = ok | -1 = Error
//---------------------------------------------------------------------------

int clsComI332::InitSer(long lBaud)
{
WriteLog(LOG_LEVEL_I332,"InitSer(%ld);",lBaud);

#ifdef CVI

int iRet;

iRet = OpenComConfig (iAttrComNo,"", lBaud, 0, 8, 1,30,30);
iRet = SetComTime (iAttrComNo,0.5); // 0.2 Sekunden

return 0;
#else

word BdDiv;

static int ComAdr[4] = {0x3f8, 0x2f8, 0x3e8, 0x2e8};

I332Err = 0; // testweise aus DOS-Version
I332_IFC = 0; // testweise aus DOS-Version

if (iAttrComNo < 1 || iAttrComNo > 2)
{
return (ParErr);
}
I332_IFC=iAttrComNo;

SerPort = ComAdr[iAttrComNo-1];

if (SerPort == 0)
{
return (IFCErr);
}
BdDiv = (word)(115200L / lBaud);

outp(SerPort+3,_inp(SerPort+3) | 0x80);
outp(SerPort+0,(byte) Lo (BdDiv));
outp(SerPort+1,(byte) Hi (BdDiv));
outp(SerPort+3,0x07); // Parameter 1N8

inp (SerPort); // Dummy-Read: Clr Receiver
return (0);
#endif
} // ENDE: Funktion InitSer



//***************************************************************************

// CloseSer
//***************************************************************************

// Zweck:
// close.

//---------------------------------------------------------------------------

// Typ | Parameter |IOR| Bedeutung
//---------------------------------------------------------------------------

// | | |
//---------------------------------------------------------------------------

// int | RETURN | R | 0 = ok | -1 = Error
//---------------------------------------------------------------------------

int clsComI332::CloseSer()
{
WriteLog(LOG_LEVEL_I332,"CloseSer();");
#ifdef CVI
CloseCom (iAttrComNo);
#endif
return 0;
} // ENDE: Funktion CloseSer



//***************************************************************************

// XmtSer
//***************************************************************************

// Comunicate

//---------------------------------------------------------------------------

// Typ | Parameter |IOR| Bedeutung
//---------------------------------------------------------------------------

// char | cCode | I |
//---------------------------------------------------------------------------

// int | RETURN | R | 0 = ok | -1 = Error
//---------------------------------------------------------------------------

char clsComI332::XmtSer(char cCode)
{
#ifdef CVI
int iRet;

ComWrtByte (iAttrComNo, (int)cCode & 0xFF); //Write
iRet = ComRdByte (iAttrComNo); //Read
return (char)(iRet & 0xFF);
#else
clock_t tTimeOut, tDuration;

tDuration = CLOCKS_PER_SEC ; // Sekunde reicht
//* 20; // * 1 -> 1 Sekunde

if (I332Err != 0)
{
//
TL_MessagePopup("MotorCtrl",GetRS232ErrorString(I332Err),TL_ERR_CAT_INIT,TL_ERR_MOD_MOT_SMU2,TL_ERR_PRIO_NONE);

return (0);
}
tTimeOut = clock() + tDuration;

while ((_inp(SerPort+5) & 0x40) == 0)
{
if (clock() > tTimeOut)
{
I332Err = TimeOutErr;
//
TL_MessagePopup("MotorCtrl",GetRS232ErrorString(I332Err),TL_ERR_CAT_INIT,TL_ERR_MOD_MOT_SMU2,TL_ERR_PRIO_NONE);

return (0);
}
}
outp(SerPort,cCode);

tTimeOut = clock() + tDuration;

while ((_inp(SerPort+5) & 0x01) == 0)
{
if (clock() > tTimeOut)
{
I332Err = TimeOutErr;
//
TL_MessagePopup("MotorCtrl",GetRS232ErrorString(I332Err),TL_ERR_CAT_INIT,TL_ERR_MOD_MOT_SMU2,TL_ERR_PRIO_NONE);

return (0);
}
}
return (_inp(SerPort));
#endif
} // ENDE: Funktion XmtSer
0 Kudos
Message 1 of 5
(3,591 Views)
We use the CVI library in an VC++ project.

Babak Pourat schrieb:

> Hello,
>
> First the history:
> We have an stepping motor unit with serial comunication. The first
> version of our comunication programm was DOS-based using "_inp" and
> "_outp". It Worked fine!
> We ported this Software to windos few years ago unsing the CVI low level
> driver functions "inp" and "outp". It worked well with WinNT 4.0 a long
> Time. It never worked with win2000 and now we have problems with WinNT
> 4.0 and fast Computers(maybe a timing problem). Now we try to use the
> standard CVI com Functions (ComWrtByte...) and they work. But there is
> still a problem: with same baudrate the comunication is about 5 times
> slower as the version with "inp" and "outp".
>
> Has anyone an idea how to solve this Problem?.
>
> //***************************************************************************
>
> // InitSer
> //***************************************************************************
>
> // Initialising.
>
> //---------------------------------------------------------------------------
>
> // Typ | Parameter |IOR| Bedeutung
> //---------------------------------------------------------------------------
>
> // unsigned long | iComNum | I |
> //---------------------------------------------------------------------------
>
> // int | RETURN | R | 0 = ok | -1 = Error
> //---------------------------------------------------------------------------
>
> int clsComI332::InitSer(long lBaud)
> {
> WriteLog(LOG_LEVEL_I332,"InitSer(%ld);",lBaud);
>
> #ifdef CVI
>
> int iRet;
>
> iRet = OpenComConfig (iAttrComNo,"", lBaud, 0, 8, 1,30,30);
> iRet = SetComTime (iAttrComNo,0.5); // 0.2 Sekunden
>
> return 0;
> #else
>
> word BdDiv;
>
> static int ComAdr[4] = {0x3f8, 0x2f8, 0x3e8, 0x2e8};
>
> I332Err = 0; // testweise aus DOS-Version
> I332_IFC = 0; // testweise aus DOS-Version
>
> if (iAttrComNo < 1 || iAttrComNo > 2)
> {
> return (ParErr);
> }
> I332_IFC=iAttrComNo;
>
> SerPort = ComAdr[iAttrComNo-1];
>
> if (SerPort == 0)
> {
> return (IFCErr);
> }
> BdDiv = (word)(115200L / lBaud);
>
> outp(SerPort+3,_inp(SerPort+3) | 0x80);
> outp(SerPort+0,(byte) Lo (BdDiv));
> outp(SerPort+1,(byte) Hi (BdDiv));
> outp(SerPort+3,0x07); // Parameter 1N8
>
> inp (SerPort); // Dummy-Read: Clr Receiver
> return (0);
> #endif
> } // ENDE: Funktion InitSer
>
> //***************************************************************************
>
> // CloseSer
> //***************************************************************************
>
> // Zweck:
> // close.
>
> //---------------------------------------------------------------------------
>
> // Typ | Parameter |IOR| Bedeutung
> //---------------------------------------------------------------------------
>
> // | | |
> //---------------------------------------------------------------------------
>
> // int | RETURN | R | 0 = ok | -1 = Error
> //---------------------------------------------------------------------------
>
> int clsComI332::CloseSer()
> {
> WriteLog(LOG_LEVEL_I332,"CloseSer();");
> #ifdef CVI
> CloseCom (iAttrComNo);
> #endif
> return 0;
> } // ENDE: Funktion CloseSer
>
> //***************************************************************************
>
> // XmtSer
> //***************************************************************************
>
> // Comunicate
>
> //---------------------------------------------------------------------------
>
> // Typ | Parameter |IOR| Bedeutung
> //---------------------------------------------------------------------------
>
> // char | cCode | I |
> //---------------------------------------------------------------------------
>
> // int | RETURN | R | 0 = ok | -1 = Error
> //---------------------------------------------------------------------------
>
> char clsComI332::XmtSer(char cCode)
> {
> #ifdef CVI
> int iRet;
>
> ComWrtByte (iAttrComNo, (int)cCode & 0xFF); //Write
> iRet = ComRdByte (iAttrComNo); //Read
> return (char)(iRet & 0xFF);
> #else
> clock_t tTimeOut, tDuration;
>
> tDuration = CLOCKS_PER_SEC ; // Sekunde reicht
> //* 20; // * 1 -> 1 Sekunde
>
> if (I332Err != 0)
> {
> //
> TL_MessagePopup("MotorCtrl",GetRS232ErrorString(I332Err),TL_ERR_CAT_INIT,TL_ERR_MOD_MOT_SMU2,TL_ERR_PRIO_NONE);
>
> return (0);
> }
> tTimeOut = clock() + tDuration;
>
> while ((_inp(SerPort+5) & 0x40) == 0)
> {
> if (clock() > tTimeOut)
> {
> I332Err = TimeOutErr;
> //
> TL_MessagePopup("MotorCtrl",GetRS232ErrorString(I332Err),TL_ERR_CAT_INIT,TL_ERR_MOD_MOT_SMU2,TL_ERR_PRIO_NONE);
>
> return (0);
> }
> }
> outp(SerPort,cCode);
>
> tTimeOut = clock() + tDuration;
>
> while ((_inp(SerPort+5) & 0x01) == 0)
> {
> if (clock() > tTimeOut)
> {
> I332Err = TimeOutErr;
> //
> TL_MessagePopup("MotorCtrl",GetRS232ErrorString(I332Err),TL_ERR_CAT_INIT,TL_ERR_MOD_MOT_SMU2,TL_ERR_PRIO_NONE);
>
> return (0);
> }
> }
> return (_inp(SerPort));
> #endif
> } // ENDE: Funktion XmtSer
0 Kudos
Message 2 of 5
(3,591 Views)
The ComWrt in CVI is an asynchronous command. This means that it runs on a separate thread. Thus, your main thread would continue to execute while on second thread the serial communication would occur. The time delays come from the Windows management of the threads. The threads compete for CPU time. There are several ways to improve the communication delay. One way is to increase the computer speed. With a faster CPU, your system should be able to respond faster. Another way is to reduce the number of threads that are running (close other applications). In addition, you could upgrade to CVI version 5.5.1. In the newer version of Labwindows the function ComWrt has an option to be run in synchronous mode. It means that the thread will wait until the communication
is complete.


Buddy Curtis
Applications Engineer
National Instruments
Joji
Message 3 of 5
(3,591 Views)
Buddy Curtis schrieb:

> In addition, you could upgrade to CVI version 5.5.1. In
> the newer version of Labwindows the function ComWrt has an option to
> be run in synchronous mode. It means that the thread will wait until
> the communication is complete.

Where can I find this option?

Babak
0 Kudos
Message 4 of 5
(3,591 Views)
If you have LabWindows/CVI 5.5.1, you can specify a negative value for the Output Queue Size when calling OpenComConfig(). This makes write operations synchronous -- when ComWrt() or ComWrtByte() return, they have completed their output operations. I would recommend this as well as switching from ComWrtByte() to ComWrt(). To upgrade online to CVI 5.5.1, go to http://www.ni.com/upgrade and select upgrade to Measurement Studio 1.0.1.
Joji
0 Kudos
Message 5 of 5
(3,591 Views)