Here is the example from Keysight, what I am after is starting the socket and leaving it open for 5 IP addresses. The issue I am having is I open and close the socket ever time I write a line and the instrument does not like this. I have slightly overcome this by writing classes that have multiple lines that I can pass vaiables through, but there are still issues. I modified a project years ago that had this built in, but for the life of me I do not know what is is called and my searches are leading me down the wrong path. I should be able to make a class that starts the socket, then write lines to the socket.
////////////////////////////////////////////////////////////////////////////////
// © Keysight Technologies 2016
//
// You have a royalty-free right to use, modify, reproduce and distribute
// the Sample Application Files (and/or any modified version) in any way
// you find useful, provided that you agree that Keysight Technologies has no
// warranty, obligations or liability for any Sample Application Files.
//
////////////////////////////////////////////////////////////////////////////////
using System;
using System.Collections.Generic;
using System.Text;
using Ivi.Visa;
using Ivi.Visa.FormattedIO;
namespace Socket_Example
{
class Program
{
static void Main(string[] args)
{
// Change this variable to the address of your instrument
string VISA_ADDRESS = "Your instrument's VISA address goes here!";
// Create a connection (session) to the TCP/IP socket on the instrument.
// Change VISA_ADDRESS to a SOCKET address, e.g. "TCPIP::169.254.104.59::5025::SOCKET"
IMessageBasedSession session = GlobalResourceManager.Open(VISA_ADDRESS) as IMessageBasedSession;
// The first thing you should do with a SOCKET connection is enable the Termination Character. Otherwise all of your read's will fail
session.TerminationCharacterEnabled = true;
// We can find out details of the connection
ITcpipSocketSession socket = session as ITcpipSocketSession;
Console.WriteLine("IP: {0}\r\nHostname: {1}\r\nPort: {2}\r\n",
socket.Address,
socket.HostName,
socket.Port);
// Send the *IDN? and read the response as strings
MessageBasedFormattedIO formattedIO = new MessageBasedFormattedIO(session);
formattedIO.WriteLine("*IDN?");
string idnResponse = formattedIO.ReadLine();
Console.WriteLine("*IDN? returned: {0}", idnResponse);
// Close the connection to the instrument
session.Dispose();
Console.WriteLine("Press any key to exit...");
Console.ReadKey();
}
}
}
Phillip SmilskiPosted Apr 9, 2024, 5:40 PM
So the solution came down to declaring the socket oustide the main class "IMessageBasedSession session;" and then making a new instance in side the main class. That way the socket is left open and the other classes could access the socket without making a new instance. I also had to do the same in the form for accesing the class and keeping the same IP going. Below are snippets:
using Ivi.Visa;
using Ivi.Visa.FormattedIO;
using System;
using System.Windows.Forms;
using System.IO;
namespace Refresh
{
internal class SessionClass
{
IMessageBasedSession session;
MessageBasedFormattedIO formattedIO;
public SessionClass(string strIP)
{
try
{
//Start the socket
string VISA_ADDRESS = "TCPIP::" + strIP + "::5025::SOCKET";
session = GlobalResourceManager.Open(VISA_ADDRESS) as IMessageBasedSession;
session.TerminationCharacterEnabled = true;
formattedIO = new MessageBasedFormattedIO(session);
}
catch (Exception ex)
{
MessageBox.Show("Unable to start connection to " + strIP + ". Make sure the equipment is on and the address is correct. \n Error code follows:\n" + ex, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
public bool SendSCPIandGetResponse(string strSendMe, out string strOut)
{
strOut = "";
try
{
formattedIO.WriteLine(strSendMe);
strOut = formattedIO.ReadLine();
return false;
}
catch (Exception err)
{
if (err.HResult == -2146233088)
{
MessageBox.Show("Check to see if the Spectrum Analyzer is ON and the IP address for the Spectrum Analyzer is correct. Fault from SendSCPIandGetResponse", "Device not found", MessageBoxButtons.OK, MessageBoxIcon.Error);
return true;
}
else
{
MessageBox.Show(err.Message.ToString());
return true;
}
}
}
public bool SendSCPI(string strSendMe)
{
try
{
formattedIO.WriteLine(strSendMe);
return false;
}
catch (Exception err)
{
if (err.HResult == -2146233088)
{
MessageBox.Show("Check to see if the Spectrum Analyzer is ON and the IP address for the Spectrum Analyzer is correct. Fault from SendSCPI", "Device not found", MessageBoxButtons.OK, MessageBoxIcon.Error);
// Closes the program.
return true;
}
else
{
MessageBox.Show(err.Message.ToString());
// Closes the program.
return true;
}
}
}
public void Close()
{
session.Dispose();
}
}
using System;
using System.ComponentModel;
using System.Linq;
using System.Windows.Forms;
using System.Xml;
namespace Refresh
{
public partial class SpecAnControls : Form
{
TestClass testClass = new TestClass();
//start SessionClass reference at form level and create new instance later to pass variable
SessionClass SessionClass;
//Create a new instance of XML document to use through the form
XmlDocument doc = new XmlDocument();
//SpecAnControls is the "main form" for this form.
public SpecAnControls(string strSA_internal_name, string strIP_use)
{
//see if SpecAn communicates and if it does not disable the controls.
bool blnContinue = Poll_SA_Class();
if (blnContinue == true)
{
SessionClass = new SessionClass(strIP_use);
}
}
}
}
Phillip SmilskiPosted Mar 26, 2024, 8:59 PM
So my thing did not work, please help.
Phillip SmilskiPosted Mar 25, 2024, 9:21 PM
Thank you both for your help, I think the biggest problem is I do not know how to ask this properly. I will try to clarify and please forgive me. Also when typing this up, I think I got close
Curently I have the main form using one IP and then 4 buttons that call the same child form and passes the IP address to each form upon button click. Each form will control the IP address, so I lead you on the wrong direction (sorry again).
What I want to do is have class like calls that I can use with the form controls like:
using System;
using System.Windows.Forms;
namespace MyApplication
{
public partial class Form1 : Form
{
mySessions mySession = new mySessions;
public Main(string strIP)
{
InitializeComponent();
mySession.start(strIP);
}
private void button1_Click(object sender, EventArgs e)
{
mySession.write(strMessage);
}
private void button2_Click(object sender, EventArgs e)
{
mySession.read(strMessage, strResponse);
}
private void closeButtonPressed(string[] args)
{
mySession.close();
}
and structure the class like:
using System;
using System.Collections.Generic;
using System.Text;
using Ivi.Visa;
using Ivi.Visa.FormattedIO;
namespace MyApplication
{
class mySessions
{
static void start(string strIP)
{
// Change this variable to the address of your instrument
string VISA_ADDRESS = "TCPIP::" + strIP + ":::5025::SOCKET";
// Create a connection (session) to the TCP/IP socket on the instrument.
IMessageBasedSession session = GlobalResourceManager.Open(VISA_ADDRESS) as IMessageBasedSession;
session.TerminationCharacterEnabled = true;
}
static void write(string strMessage)
{
// Send the cmd
MessageBasedFormattedIO formattedIO = new MessageBasedFormattedIO(session);
formattedIO.WriteLine(strMessage);
}
static void read(string strMessage, string strResponse)
{
// Send the cmd and read the response as strings
MessageBasedFormattedIO formattedIO = new MessageBasedFormattedIO(session);
formattedIO.WriteLine(strMessage);
string strResponse= formattedIO.ReadLine();
}
static void close()
{
// Close the connection to the instrument
session.Dispose();
}
}
}
Tuhin PaulPosted Mar 25, 2024, 11:09 AM
instrumentAddressesarray to include your actual IP addresses.*IDN?command with your desired instrument commands within the loop.Tuhin PaulPosted Mar 25, 2024, 11:08 AM
This example opens and closes the socket connection for each instrument communication. This isn't ideal for your scenario where you want to keep the connection open for multiple commands.
Amit MohantyPosted Mar 25, 2024, 5:35 AM
To keep a socket open and continuously write to it without closing it after each write, you can keep the socket open within a loop.