Control Using Telnet Server

Other topics about Sample Programs

Overview

This section explains how to control the E5071C by using WinSock API in the Windows environment.

Sample Program in Excel VBA

Opening ctrl_lan.xls in Microsoft Excel displays the screen shown in the figure below.

ctrl_lan.xls

For how to use each element in ctrl_lan.xls, refer to the following description.

  1. Enter the version number of WinSock API in the cell to the right side of "Winsock Version." The version number is obtained by multiplying 256 by the major version and then adding the minor version. For example, when the version of your Winsock API is 1.1, the version number is obtained as follows: 256*1+1=257. Enter the IP address of the E5071C in the cell to the right side of "IP Address." This VBA macro will not work properly without the correct values in these two cells.

  2. In part 2, the sweep range (start and stop points) and the number of measurement points are set. Click Set to execute the setting operation as specified with the setting table, while clicking the button labeled "Query" retrieves the current settings of the E5071C.

  3. Part 3 is dedicated to setting the trigger mode.

  4. Part 4 sets the measurement parameters and data format for trace 1 in channel 1. Click Set to execute the setting operation as specified with the setting table, while clicking the button labeled "Query" retrieves the current settings of the E5071C.

  5. In part 5, click Auto Scale to execute auto scaling for trace 1 in channel 1.

  6. Click Read Trace in part 6 to retrieve the formatted data of trace 1 in channel 1. The data is displayed in tabular and graphical formats.

  7. Click Preset to execute the presetting operation.

Description of operation in VBA macro

This section describes the operation of the VBA macro, focusing on the part related to control with WinSock API.

In order to use WinSock API, you must declare functions and define variables with a definition file of WinSock API, as shown in Definition file of WinSock API.

Definition file of WinSock API

'This is the Winsock API definition file for Visual Basic

 

'Setup the variable type 'hostent' for the WSAStartup command

Type Hostent

h_name As Long

h_aliases As Long

h_addrtype As String * 2

h_length As String * 2

h_addr_list As Long

End Type

Public Const SZHOSTENT = 16

 

'Set the Internet address type to a long integer (32-bit)

Type in_addr

s_addr As Long

End Type

 

'A note to those familiar with the C header file for Winsock

'Visual Basic does not permit a user-defined variable type

'to be used as a return structure. In the case of the

'variable definition below, sin_addr must

'be declared as a long integer rather than the user-defined

'variable type of in_addr.

Type sockaddr_in

sin_family As Integer

sin_port As Integer

sin_addr As Long

sin_zero As String * 8

End Type

 

Public Const WSADESCRIPTION_LEN = 256

Public Const WSASYS_STATUS_LEN = 128

Public Const WSA_DescriptionSize = WSADESCRIPTION_LEN + 1

Public Const WSA_SysStatusSize = WSASYS_STATUS_LEN + 1

 

'Setup the structure for the information returned from

'the WSAStartup() function.

Type WSAData

wVersion As Integer

wHighVersion As Integer

szDescription As String * WSA_DescriptionSize

szSystemStatus As String * WSA_SysStatusSize

iMaxSockets As Integer

iMaxUdpDg As Integer

lpVendorInfo As String * 200

End Type

 

'Define socket return codes

Public Const INVALID_SOCKET = &HFFFF

Public Const SOCKET_ERROR = -1

 

'Define socket types

Public Const SOCK_STREAM = 1 'Stream socket

Public Const SOCK_DGRAM = 2 'Datagram socket

Public Const SOCK_RAW = 3 'Raw data socket

Public Const SOCK_RDM = 4 'Reliable Delivery socket

Public Const SOCK_SEQPACKET = 5 'Sequenced Packet socket

 

'Define address families

Public Const AF_UNSPEC = 0 'unspecified

Public Const AF_UNIX = 1 'local to host (pipes, portals)

Public Const AF_INET = 2 'internetwork: UDP, TCP, etc.

Public Const AF_IMPLINK = 3 'arpanet imp addresses

Public Const AF_PUP = 4 'pup protocols: e.g. BSP

Public Const AF_CHAOS = 5 'mit CHAOS protocols

Public Const AF_NS = 6 'XEROX NS protocols

Public Const AF_ISO = 7 'ISO protocols

Public Const AF_OSI = AF_ISO 'OSI is ISO

Public Const AF_ECMA = 8 'european computer manufacturers

Public Const AF_DATAKIT = 9 'datakit protocols

Public Const AF_CCITT = 10 'CCITT protocols, X.25 etc

Public Const AF_SNA = 11 'IBM SNA

Public Const AF_DECnet = 12 'DECnet

Public Const AF_DLI = 13 'Direct data link interface

Public Const AF_LAT = 14 'LAT

Public Const AF_HYLINK = 15 'NSC Hyperchannel

Public Const AF_APPLETALK = 16 'AppleTalk

Public Const AF_NETBIOS = 17 'NetBios-style addresses

Public Const AF_MAX = 18 'Maximum # of address families

 

'Setup sockaddr data type to store Internet addresses

Type sockaddr

sa_family As Integer

sa_data As String * 14

End Type

Public Const SADDRLEN = 16

 

'Declare Socket functions

 

Public Declare Function closesocket Lib "wsock32.dll" (ByVal s As Long) As Long

 

Public Declare Function connect Lib "wsock32.dll" (ByVal s As Long, addr As sockaddr_in, ByVal namelen As Long) As Long

 

Public Declare Function htons Lib "wsock32.dll" (ByVal hostshort As Long) As Integer

 

Public Declare Function inet_addr Lib "wsock32.dll" (ByVal cp As String) As Long

 

Public Declare Function recv Lib "wsock32.dll" (ByVal s As Long, ByVal buf As Any, ByVal buflen As Long, ByVal flags As Long) As Long

 

Public Declare Function recvB Lib "wsock32.dll" Alias "recv" (ByVal s As Long, buf As Any, ByVal buflen As Long, ByVal flags As Long) As Long

 

Public Declare Function send Lib "wsock32.dll" (ByVal s As Long, buf As Any, ByVal buflen As Long, ByVal flags As Long) As Long

 

Public Declare Function socket Lib "wsock32.dll" (ByVal af As Long, ByVal socktype As Long, ByVal protocol As Long) As Long

 

Public Declare Function WSAStartup Lib "wsock32.dll" (ByVal wVersionRequired As Long, lpWSAData As WSAData) As Long

 

Public Declare Function WSACleanup Lib "wsock32.dll" () As Long

 

Public Declare Function WSAUnhookBlockingHook Lib "wsock32.dll" () As Long

 

Public Declare Sub CopyMemory Lib "kernel32" Alias "RtlMoveMemory" (hpvDest As Any, hpvSource As Any, ByVal cbCopy As Long)

 

The basic control flow with WinSock API is shown in the figure below:

Control flow with WinSock API

 

The procedures of each step in Control flow with WinSock API are described below.

Startup

The procedure corresponding to Startup is StartIt. StartIt launches and initializes WinSock API with WSAStartup, whose version is shown in part 1 of ctrl_ lan.xls. The function WSAStartup should always be used when initiating WinSock. This function takes the version number (input) and launching information (output) as its parameters.

StartIt

Sub StartIt()

 

Dim StartUpInfo As WSAData

'Version 1.1 (1*256 + 1) = 257

'version 2.0 (2*256 + 0) = 512

'Get WinSock version

Sheets("Sheet1").Select

Range("C2").Select

version = ActiveCell.FormulaR1C1

'Initialize Winsock DLL

x = WSAStartup(version, StartUpInfo)

 

End Sub

Socket Creation and Connection

The procedure for Socket Creation and Connection is OpenSocket. OpenSocket makes a connection to an instrument associated with the IP address specified with the input parameter Hostname. It uses a socket of the port specified with the input parameter PortNumber. Each functional part of OpenSocket is described below.

In (1), the inet_aadr function of WinSock API is used to convert an IP address delimited by "." to an Internet address.

In (2), a new socket is created with the socket function of WinSock API and its socket descriptor is obtained. If an error occurs, the control returns to the main program with a message. The socket function takes an address family (input), a socket type (input), and a protocol number (input) as its parameters.

In (3), the socket address is specified. Note that htons, which is used for specifying the port number, is a function of WinSock API. This function converts a 2-byte integer from the Windows byte order (little endian) to the network byte order (big endian).

In (4), a connection to the E5071C is made by using the connect function of WinSock API. If an error occurs, the control returns to the main program with a message. The connect function takes a socket descriptor (input), a socket address (input), and the size of the socket address (input) as its parameters.

 

OpenSocket

Function OpenSocket(ByVal Hostname As String, ByVal PortNumber As Intege r) As Integer

Dim I_SocketAddress As sockaddr_in

Dim ipAddress As Long

ipAddress = inet_addr(Hostname) '...........(1)

 

'Create a new socket

socketId = socket(AF_INET, SOCK_STREAM, 0) '

If socketId = SOCKET_ERROR Then '

MsgBox ("ERROR: socket = " + Str$(socketId)) '...........(2)

OpenSocket = COMMAND_ERROR '

Exit Function '

End If '

 

'Open a connection to a server

 

I_SocketAddress.sin_family = AF_INET '

I_SocketAddress.sin_port = htons(PortNumber) '...........(3)

I_SocketAddress.sin_addr = ipAddress '

I_SocketAddress.sin_zero = String$(8, 0) '

 

x = connect(socketId, I_SocketAddress, Len(I_SocketAddress)) '

If socketId = SOCKET_ERROR Then '

MsgBox ("ERROR: connect = " + Str$(x)) '..(4)

OpenSocket = COMMAND_ERROR '

Exit Function '

End If '

 

OpenSocket = socketId

 

End Function

Communication

The procedure corresponding to Communication is SendCommand. SendCommand transmits a message (SCPI command) specified with the input parameter "command" to the E5071C using the send function of WinSock API. The send function takes a socket descriptor (input), a message to be transmitted (input), message length (input) and a flag (input) as its parameters.

SendCommand

Function SendCommand(ByVal command As String) As Integer

 

Dim strSend As String

strSend = command + vbCrLf

count = send(socketId, ByVal strSend, Len(strSend), 0)

If count = SOCKET_ERROR Then

MsgBox ("ERROR: send = " + Str$(count))

SendCommand = COMMAND_ERROR

Exit Function

End If

SendCommand = NO_ERROR

 

End Function

The procedure corresponding to the Receiving part of communication is RecvAscii and other functions. RecvAscii receives a message in ASCII format and stores it in the dataBuf output parameter. Maximum length of the message is specified with the maxLength input parameter. Each functional part of RecvAscii is described below.

In (1), a message (a response to a query for a SCPI command) is received from the E5071C as a series of characters using the recv function of WinSock API. If an error occurs, the control returns to the main program with a message. The recv function takes a socket descriptor (input), a message to be received (input), message length (input) and a flag (input) as its parameters.

In (2), it is determined whether each received character is LF (ASCII code: 10). When it is LF, receiving is terminated by adding NULL (ASCII code: 0) to the end of the dataBuf string and the control returns to the main program.

In (3), the number of the last characters that were read out is added to the count value for checking the number of received characters, and the characters are appended to the end of the dataBuf string.

RecvAscii

Function RecvAscii(dataBuf As String, ByVal maxLength As Integer) As Integer

 

Dim c As String * 1

Dim length As Integer

dataBuf = ""

While length < maxLength

DoEvents

count = recv(socketId, c, 1, 0) '

If count < 1 Then '

RecvAscii = RECV_ERROR '............(1)

dataBuf = Chr$(0) '

Exit Function '

End If '

If c = Chr$(10) Then '

dataBuf = dataBuf + Chr$(0) '............(2)

RecvAscii = NO_ERROR '

Exit Function '

End If '

length = length + count '............(3)

dataBuf = dataBuf + c '

Wend

RecvAscii = RECV_ERROR

End Function

 

Disconnection

The procedure corresponding to Disconnection is CloseConnection. CloseConnection disconnects communication and removes a socket using the closesocket function of WinSock API. The closesocket function takes a socket descriptor (input) as its parameter.

c

Sub CloseConnection()

 

x = closesocket(socketId)

If x = SOCKET_ERROR Then

MsgBox ("ERROR: closesocket = " + Str$(x))

Exit Sub

End If

 

End Sub

End

The procedure corresponding to End is EndIt. EndIt disconnects WinSock API using the WSACleanup function of WinSock API. The function WSACleanup should always be used when terminating WinSock.

EndIt

Sub EndIt()

 

'Shutdown Winsock DLL

x = WSACleanup()

 

End Sub

 

Example of control

The E5071C can be controlled by executing the above procedures in order, following the control flow in Control flow with WinSock API. This is demonstrated by the procedure autoscale (a procedure that is executed when the Auto Scale button is clicked) as described in autoscale.

autoscale

Sub autoscale()

'

' auto scaling

'

Call StartIt

Call get_hostname

x = OpenSocket(Hostname$, ScpiPort)

x = SendCommand(":DISP:WIND1:TRAC1:Y:AUTO")

Call CloseConnection

Call EndIt

End Sub

When you execute more than one command by connecting and disconnecting a socket for every command, the sequence of execution may change.