Measurement Studio for VC++

cancel
Showing results for 
Search instead for 
Did you mean: 

Serial Communication with EventHandler in Visual C++

I would like to use the "CNiVisaSerialAnyCharReceivedEvent", but I have problems with the InstallEventHandler()-function.
 
Can someone give me an easy sample code ?
 
 
Thanks a lot.
0 Kudos
Message 1 of 7
(5,497 Views)

Can you describe the problem you're running into? The documentation for the CNiVisaSession::InstallEventHandler includes a pretty good code example of how to hook up your event handler code. The method has three overloads, depending on what kind of event handler you want to install.

0 Kudos
Message 2 of 7
(5,487 Views)

Dear Glenn,

I would like the callback handler function to be a member function of the same class as the CNiVisaSession object in the following way:

class MyDialog: public CDialog

{

     .......

     CNiVisaSesion *m_Session;

     ViStatus MyEventHandler( CNiVisaEvent& event );

     .....

}

 

My online-documentation looks like this:

m_Session->InstallEventHandler( VisaEvent..., OnEvent, eventID);

 

If I try this, I get the compiler error C2664.

 

Meanwhile I found a solution in the discussion forum (year 2001), which looks like this

m_Session->InstallEventHandler( VisaEvent..., *this, OnVisaEventHandler( MyDialog, MyEventHandler )  )

 

With this the compilation runs without failure, but I cannot find any hint in the documentation to do it like this.

 

New problem:

If I run the program I get the Visa Exceptin   

 

0 Kudos
Message 3 of 7
(5,480 Views)

Dear Glenn,

I would like the callback handler function to be a member function of the same class as the CNiVisaSession object in the following way:

class MyDialog: public CDialog

{

     .......

     CNiVisaSesion *m_Session;

     ViStatus MyEventHandler( CNiVisaEvent& event );

     .....

}

 

My online-documentation looks like this:

     m_Session->InstallEventHandler( VisaEvent..., OnEvent, eventID);

 

If I try this, I get the compiler error C2664.

 

Meanwhile I found a solution in the discussion forum (year 2001), which looks like this

     m_Session->InstallEventHandler( VisaEvent..., *this, OnVisaEventHandler( MyDialog, MyEventHandler )  )

 

With this the compilation runs without failure, but I cannot find any hint in the documentation to do it like this.

 

New problem:

If I run the program, I get the Visa Exception Error "BFFF0028 ( a handler was not installed )"

 

Can you help me ?

 

Hannes  

0 Kudos
Message 4 of 7
(5,478 Views)

The Visa Exception Error "...handler not installed" exists no longer, if I put the EnableEvent(...) after the InstallEventHandler(...) in that way:

m_Session->InstallEventHandler( VisaEventSerialAnyCharReceived, *

this, OnVisaEventHandler(CDialogEmpfangen, OnByteEmpfangen), eventId );

m_Session->EnableEvent( VisaEventSerialAnyCharReceived, VisaHandler );

First I put the EnableEvent(...) before the InstallEventHandler(...) and I got the error.

But now I get new runtime errors !!!

I think the best would be, if anyone could give me a small code example which includes completely the following functionality:

Everytime if a new byte is received from the serial input (RS232), the EventHandler is triggered. In that function, the byte is transferred to a variable m_cZeichen like this:

ViStatus CDialogEmpfangen::OnByteEmpfangen( CNiVisaEvent& event )

{
     m_Session->Read( &m_cZeichen, 1 );

     return VisaSuccess;

}

 

Thanks a lot, if you can help me !

0 Kudos
Message 5 of 7
(5,477 Views)
Hannes,
 
I created a simple Dialog class with the following methods in it:
 

void

CVisaSerialEventHandlerDlg::OnBnClickedButton1()

{

CNiVisaEventHandlerId eventId;

_session->InstallEventHandler(VisaEventSerialAnyCharReceived, *

this, OnVisaEventHandler(CVisaSerialEventHandlerDlg, OnByteReceived), eventId);

_session->EnableEvent(VisaEventSerialAnyCharReceived, VisaHandler);

_session->Write(

"*IDN?\n");

}

ViStatus CVisaSerialEventHandlerDlg::OnByteReceived(CNiVisaEvent& event)

{

CNiString string;

uInt32 count;

_session->GetAttribute(VisaSerialBytesAvailable, count);

_session->Read(string, count);

return VI_SUCCESS;

}

This ran without any errors. I would need to see a larger amount of your code to figure out why you're having problems. Please not the following from the NI-VISA help reference for the ASRL_CHAR event:

"Notification that at least one data byte has been received. Each data character will not necessarily result in an event notification. In other words, if multiple data bytes arrive at once, you may get only one event. After receiving this event, you should query the serial port for the number of bytes available via the VI_ATTR_ASRL_AVAIL_NUM attribute." That's why I'm using the VisaSerialBytesAvailable to determine the number of bytes to read back.

0 Kudos
Message 6 of 7
(5,458 Views)

Hallo Glenn,

thank you very much for your code example and your willingness to deal with my problems.

Meanwhile I "killed the runtime errors" and I can read serial data with the event handler.
With the new incoming data I would like to update the data of my Dialog controls (bargraphs etc.) inside of the event handler, but it doesn't work (new runtime errors). Can you imagine why ?
To overcome this problem, I update the controls by timer event (every some seconds) inside of the timer response (not ideal, but enough in the moment).

The serial data are coming continuously without any handshake. So I found out with my tests, that the "AnyCharReceivedEvent" is not ideal for that. The event handler should only be triggered after for example 1200 Bytes were received into the serial input buffer (in real time with 9600 Baud). The receiving process should work in the background. During the time, which is necessary for the 1200 Bytes, the program should be able to react to user input. After the bytes are inside the buffer, they heve to be processed to get new data for the Dialog controls. During this time, the user need not make any inputs.
I think "asynchronously read()" would be the appropriate mechanism for that. Do you agree ?
Do you have experience with serial asynchronously communication ?
If yes, could you give me some hints please (and / or some code example), how to get it work ?

I made some tests with setting the buffer size of the serial communication buffer:

     m_Session->SetBufferSize( VisaSerialInputBuffer, (uInt32)4096 );

Because of my tests I think, that the real buffer size is totally different to my setting value (I tried out different values).
Can you imagine why ?
Is something wrong with that code ?

 

Thank you for your help

Hannes

0 Kudos
Message 7 of 7
(5,438 Views)