Instrument Control (GPIB, Serial, VISA, IVI)

cancel
Showing results for 
Search instead for 
Did you mean: 

automatic serial poll

I need to use autopolling so my instrument can call back and tell me when it has finished a measurement.  I had code to do this that worked fine, but it now seems to have stopped working.  Not being sure what all I might of changed, I've contructed the following simple example (in VB.NET) to demonstrate the problem.  When I run this, the dataReady function never gets called.  I've run a concurrent session of the interactive control tool so I can do manual serial polls, and found that the instrument is indeed issuing a service request, but this is somehow not causing dataReady to get called.  It seems like automatically serial polling isn't happening, but the board properties form in MAX shows that autopolling is supposedly enabled.  I have tried restarting the intrument, my computer, and running the repair on the NI .NET libraries and NI-488.2 2.4 drivers from the installer.  I'm at a complete loss as to what is wrong.  Any suggestions would be much appreciated.

Weirdly, I've found that if I let the program complete and the waitOne call timeout, when I run the program again, the dataReady function is called as soon as I call Notify and before the measurement is even started.

-Alex

Imports NationalInstruments.NI4882
Imports System.Threading

Module Module1
    Sub Main()
        Dim dataReadyD As New NotifyCallback(AddressOf dataReady)
        Dim lock As New AutoResetEvent(False)

        Dim analyser As New Device(0, 17)
        analyser.Write("*CLS")
        analyser.Notify(GpibStatusFlags.DeviceServiceRequest, dataReadyD, lock)
        analyser.Write("*ESE 1")     'Enable reporting of operation complete in standard event status
        analyser.Write("*SRE 32")    'Trigger SRQ when a standard event status event occurs
        analyser.Write(":PAGE:SCON:SING")    'Trigger measurement
        analyser.Write("*OPC")       'Raise operation complete event in standard event status register
        'when measurement completes
        lock.WaitOne(100000, False)
    End Sub

    Private Sub dataReady(ByVal sender As Object, ByVal notifyData As NotifyData)
        Dim theDevice As Device = CType(sender, Device)
        theDevice.SerialPoll()
        Dim theLock As AutoResetEvent = CType(notifyData.UserData, AutoResetEvent)
        theLock.Set()
    End Sub
End Module
0 Kudos
Message 1 of 7
(5,672 Views)
I have an explanation for part of the behavior described above.  When the application is run again after timing out the operation complete service request is still pending.  After the Notify method is called, the next write action to the device causes the system to realize a service request has been issued and call the dataReady function.  So, it sounds like my hypothesis about this being a failure of autopolling is correct.  Unless action is being taken with the device, the system never notices that a service request has been issued.

I've now tried completely uninstalling all NI software, rebooting, reinstalling, and rebooting again.  Didn't make any difference.  Does anybody know percisely how the autopolling system works and what might disrupt its operation?
0 Kudos
Message 2 of 7
(5,647 Views)
Hi zap_path,

I have tried to replicate the problem you are seeing, but have not been able to generate the same issues that you are having.  Some questions which may help narrow down the source of the problem are:

1. Is this instrument (PAD 17) the only instrument on the bus, or are there others?

2. Is the GPIB driver used in any location in your program other than Module1.Main() and the callback?

3. Have you tried this program as you have posted it?  Try creating a program with nothing more than a button which calls Module1.Main

4. Which version of Visual Basic are you using?

Jason Smith
Applications Engineer
National Instruments

----------------------------------

You can see the exact code I executed below.  As I mentioned above, my application is a single button which calls Module1.Main

Module Module1
    Sub Main()
        Dim dataReadyD As New NotifyCallback(AddressOf dataReady)
        Dim lock As New AutoResetEvent(False)

        Dim analyser As New Device(0, 2)
        analyser.Notify(GpibStatusFlags.DeviceServiceRequest, dataReadyD, lock)
        analyser.Write("*SRE 16")    'Trigger SRQ when data is ready
        analyser.Write("*IDN?")    'Trigger measurement
        lock.WaitOne(100000, False)
    End Sub

    Private Sub dataReady(ByVal sender As Object, ByVal notifyData As NotifyData)
        Dim result As String

        Dim theDevice As Device = CType(sender, Device)
        theDevice.SerialPoll()
        result = theDevice.ReadString()
        MsgBox(result)

        Dim theLock As AutoResetEvent = CType(notifyData.UserData, AutoResetEvent)
        theLock.Set()
    End Sub
End Module


0 Kudos
Message 3 of 7
(5,630 Views)
Thanks for your help.  I actually seem to have resolved the problem altough the explanation for the behavior is still a mystery.  The solution was to restart the instrument, but I'm still confused because:
-I tried this already, and it didn't work before.
-The instrument must have been sending the service request because I could see it had in the other NI GPIB tools.  From this I had concluded it must have been an issue with the computer and not the instument.

In case you have any thoughts, I've responded to your questions below.  Hopefully, it just won't happen again.

1)  There are 9 instruments on the bus (10 including the computer).  I've checked that they all have unique addresses.
2)  The code I posted here was the entire program.  It was a console application, so no windows form with a go button was needed.
3)  My test code was posted here without modification.  Now that the instrument has been restarted, your program works fine as well.
4)  I am using Visual Studio/Visual Basic 2005.  I know this version is intended for use with .NET 2.0 whereas the NI GPIB library is intended for use with .NET 1.1.  I'm not sure of the implications of this.

Thanks again for your help,

-zap_path
0 Kudos
Message 4 of 7
(5,596 Views)
One thought is that it was taking more than 10s for the device to request service. That could have been because the instrument was in a bad state, but since you were only waiting 10s, that could have been the problem....
0 Kudos
Message 5 of 7
(5,579 Views)
I actually waited 100 seconds (not 10) for timeout.  The device is supposed to request service after the measurement is complete, and since the instrument shows the progress of the measurement on its own screen, it is clear when it has finished.  Like I said, it appeared that the device was requesting service just as it was supposed to, but the computer was not hearing its plea.  This is probably difficult to diagnose since no one (including me now) can reproduce the problem.
0 Kudos
Message 6 of 7
(5,567 Views)

hello

I have excactly the same problem! Same code, just in c#.
Unfortunately a device restart isn't a solution for me (and my customers).
Can anybody help me with this problem?

 

 

 

 

Here's my sourcecode:

 


public partial class Form1 : Form {

    public Form1() {
     
      InitializeComponent();

     

      if (device != null) {
        device.Dispose();
        device = null;
      }
      device = new Device(0, 1);


      device.Reset();
      Thread.Sleep(1000);
      device.Clear();
      device.write("*CLS");

      device.write("*idn?");
      string idn = this.read();

 

    // -> device.write( Commands );


      Callback = new NotifyCallback(SRQ_Notify);
      device.Notify(GpibStatusFlags.DeviceServiceRequest, Callback, "test");


    // -> device.write( Start );


    }


    private Device _device = null;
    private Device device {
      get {
        return _device;
      }
      set {
        _device = value;
      }
    }


    NotifyCallback Callback = null;

 


  private void SRQ_Notify(object sender, NotifyData e) {

      SerialPollFlags SRQ_Return = device.SerialPoll();

      if (0 != (SRQ_Return & SerialPollFlags.RequestingService)) {


 
        byte[] res = this.read_bytes();
        int sec = BitConverter.ToInt32(res, 7);
 
        if (sec  == 0) {
 
       // -> device.write( Stop )

        }

      }


        e.SetReenableMask(GpibStatusFlags.DeviceServiceRequest);


    }

}

0 Kudos
Message 7 of 7
(4,501 Views)