Measurement Studio for .NET Languages

cancel
Showing results for 
Search instead for 
Did you mean: 

Controlling Multiple GPIBs in C#

Solved!
Go to solution

Hello everyone,

 

I am currently trying to write some C# code which sends commands to anywhere from 1 to 5 GPIB 488.2's through GPIB-USB-HS adapters. I have my code working for the most part but am running into trouble when sending commands to more than one controller. Below is my method for a calibration cycle on my company's instrument, most of which can be ignored. It simply takes in settings from the GUI and uses the GPIB to send motor commands to a microcontroller.

 

Everything works fine except when I am controlling more than one, it constantly throws the exception: 'System.InvalidOperationException' in NationalInstruments.NI4882.dll due to the inner exception "EndWrite was called before BeginWrite." The problem stems from sending an EndWrite to the first device after sending the first BeginWrite. This throws a flag on the other devices which haven't received their BeginWrite commands (it doesn't happen when I am controlling just one GPIB with the same code)

 

What is the best way to control multiple GPIBs to avoid this error? I am using the NationalInstruments.NI4882.dll in VisualStudio2015 (I implemented the work around to be able to use Measurement Studio 2015 in Visual Studio 2015). I saw something about a function called TriggerList to command multiple GPIB's but have no idea what .dll it is part of. I also am not sure which .dll contains the full function list for the GPIB's such as SENDIFC, ibwait, ibwrt, ect. All I have access to is the board and device class commands. I tried adding other .dll's to my project such as the gpib-32.dll, the visa32.dll, and the ni4882.dll but receive an error stating that they are not valid COM components.

 

To sum up the problems I need help with:

  • What is the best way / function to command multiple GPIB's via C#
  • How do I access the complete GPIB function list as illustrated in this manual: NI-488.2 Function Reference Manual For Windows
  • How do I add the rest of the .dll's such as visa32.dll to my project? (I found a post on the forums describing several various steps to try but was unable to get it working, such as using tlbimp.exe to generate a working .dll)

I would greatly appreciate any help with these issues. I have been stuck for quite some time now. My program does run but occasionally gets tripped up by the exceptions and thus is not suitable for production yet.

 

 

 private void Run_Click(object sender, EventArgs e)
        {
            int nc = Int32.Parse(textBox9.Text); //Read in number of cycles
            long y;
            y = Convert.ToInt64(Convert.ToDouble(textBox8.Text)); //Read in Dwell Time
            cycleTime = (int)y;
            List<string> steps = new List<string>(); // Create list of attenuation steps
            steps.Add(textBox1.Text);
            steps.Add(textBox2.Text);
            steps.Add(textBox3.Text);
            steps.Add(textBox4.Text);
            steps.Add(textBox5.Text);
            steps.Add(textBox6.Text);
            steps.Add(textBox7.Text);
            _worker = new BackgroundWorker();
            _worker.WorkerSupportsCancellation = true;
                    xxx = 1;
            int[] cycles = new int[nc];
            cycles = cycles.Select(i => 5).ToArray();

            if (nc % 1 == 0) 
            {
                if (cycleTime > 1.5)
                {

                    _worker.DoWork += new DoWorkEventHandler((state, args) =>
            {
                do
                {
                    if (_worker.CancellationPending)
                        break;
            
                        foreach (int element in cycles) 
                        {
                        Console.WriteLine(xxx);
                        xxx++;

                            for (int i = 0; i < 7; i++)
                            {

                                if (_worker.CancellationPending)
                                    break;
                                try
                                {

                                    if (checkBox1.Checked)
                                    {
                                        //Device 1:
                                        device.BeginWrite(
                                        ReplaceCommonEscapeSequences(steps[i]),
                                        new AsyncCallback(OnWriteComplete),
                                        null);
                               

                                    }
                                    if (checkBox2.Checked)
                                    {
                                        //Device 2:
                                        device2.BeginWrite(
                                        ReplaceCommonEscapeSequences(steps[i]),
                                        new AsyncCallback(OnWriteComplete),
                                        null);
                                    }
                                    if (checkBox3.Checked)
                                    {
                                        //Device 3:
                                        device3.BeginWrite(
                                        ReplaceCommonEscapeSequences(steps[i]),
                                        new AsyncCallback(OnWriteComplete),
                                        null);
                                    }
                                    if (checkBox4.Checked)
                                    {
                                        //Device 4:
                                        device4.BeginWrite(
                                      ReplaceCommonEscapeSequences(steps[i]),
                                      new AsyncCallback(OnWriteComplete),
                                      null);
                                    }

                                    if (checkBox5.Checked)
                                    {
                                        //Device 5:
                                        device5.BeginWrite(
                                      ReplaceCommonEscapeSequences(steps[i]),
                                      new AsyncCallback(OnWriteComplete),
                                      null);
                                    }

                                    if (xxx > nc)
                                {
                                    stop = false;
                                
                                }

                                    dwellPause = new PauseClass();
                                    dwellPause.Pause(cycleTime * 1000);


                                }
                                catch (Exception ex)
                                {
                                ex.ToString();
                                MessageBox.Show(ex.Message);
                                }
                            }
                            } 

                } while (stop);
            });
                    _worker.RunWorkerAsync();
                    Run.Enabled = false;
                    Stop.Enabled = true;
                    
                }
                else
                {
                    stringReadTextBox.Text = "Error: Dwell Time Too Short!";

                }
            }
            else
            {
                stringReadTextBox.Text = "Error: Number of Cycles Must Be A Whole Number!";
            }
      
            stringReadTextBox.Text = "Cycling For Calibration Is Complete!";
        }

 

0 Kudos
Message 1 of 31
(4,571 Views)

Hello hwalke


I was seeing the code thank you very much for upload it.

 

Let verify internally what the driver is doing on the background, Do you have the I/O Trace?

 

http://zone.ni.com/reference/en-XX/help/370404J-01/nise/nispy/

 

Let use that in order to debug the code.

 

Regards

0 Kudos
Message 2 of 31
(4,518 Views)

Yes I have it

0 Kudos
Message 3 of 31
(4,504 Views)

I am randomly getting time outs when controlling one GPIB as well. I am able to connect but then receive a timeout giving the command. I ran trace and it sent the command perfectly fine the first couple times. Then I halted my program and started it again - this time the timeout errors starting occurring again with no changes in setup or code. Here is the trace:

0 Kudos
Message 4 of 31
(4,503 Views)

I currently am able to control 1 out of 2 GPIB's connected. When I send them a command, device 2 is able to carry out the command but device 1 times out. I think it may be an interface clearing issue but am not sure how to fix it. Creating a board class and implementing board.SendInterfaceClear() at the start of the code has no effect. I know it must be something a long these lines but am still stuck. I noticed that if I unplug device 1 and only keep device 2, the boardID for device 2 still remains as 1 - the computer seems to permanently save the boardID in the registry. I think the interface may have gotten mixed up with how to ID device 1. How can I reset this?

0 Kudos
Message 5 of 31
(4,482 Views)

I am able to run the code now if I just always remember to set each GPIB to its permanent boardID of 1, 2, ect even if it is the only actively plugged in GPIB. 

 

Someone please comment me a solution to reset boardID's

0 Kudos
Message 6 of 31
(4,470 Views)

Hello,

 

I would try to reset the GPIB board after you are receiving the GPIB timeout error to reset the ID. There is information in the KB below to help. 

 

LINK:

Reinitialize GPIB Board when an Error Occurs

http://digital.ni.com/public.nsf/allkb/62BB94BB841025F586256B2900634D86

 

Are you initially setting the board ID, or is it automatically assigned? I thought that the board ID may have been set in firmware. 

 

Spencer | NI

0 Kudos
Message 7 of 31
(4,462 Views)

The boardID's are being automatically set when plugged into my computer - the first one plugged in was assigned 0, the second plugged in was assigned 1, the third was 2, and so forth. These ID numbers remain when everything is unplugged and only one is plugged back in. How do I access the functions such as SendIFC? When I reference the NationalInstruments.NI4882.dll in my code, it does not contain all of the functions listed in the reference manual - it only contains very few. The device class is missing all of the Send IFC, ibcmd, ibwait, ibnotify, ect commands in .NET, it only contains very basic ones such as BeginRead, Write, and so forth - there is no SendIFC. Only the board class has an interace clear command - SendInterfaceClear(); I have been trying to access the full function list for weeks with no luck. Please help! 

0 Kudos
Message 8 of 31
(4,454 Views)

I tried referencing the NIVisa4882.dll in my .NET project  in order to find the missing functions and I receive an error stating that it is not a valid assembly or COM reference.

0 Kudos
Message 9 of 31
(4,453 Views)

Hello,

 

I know you mentioned using a work around to be able to use MS 2015 with VS 2015. What is that workaround? Were you aware that the support for MS uses the previous version of VS (Using MS 2015 with Microsoft VS 2015)?

-Being unaware of your workaround I would be interested to see if the functions are accessible within VS 2013.

 

Otherwise what version of the NI 488.2 driver do you have installed?

LINK: NI 488.2 16.0.0 Driver

 

Spencer | NI

0 Kudos
Message 10 of 31
(4,448 Views)