Search code examples
pythonsocketstcp

How can I communicate to a device via TCP/IP in Python?


I have an Agilent (Keysight) E4980A LCR meter. If I install the Keysight IO Libraries suite I can connect to the device. This means, at least I have the right LAN (cross-over!) cable. If I send the command send the command *IDN?, I get the response: Agilent Technologies,E4980A,MY46203491,A.06.17

So, that's working fine.

However, I want to address the device from own Python applications (Python 3.7, Windows 10). I started from this instruction and had to find out that you need some "minor" adaptions (i.e. bytes(str,encoding) instead of just a string and print()).

#!/usr/bin/env python
import socket

TCP_IP = '169.254.215.142'
TCP_PORT = 5024
BUFFER_SIZE = 1024
MESSAGE = bytes("*IDN?",'ansi')

s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect((TCP_IP, TCP_PORT))
s.send(MESSAGE)
data = s.recv(BUFFER_SIZE)
s.close()

print("received data:", data)

What is the Port? The E4980A manual says:

A socket is an endpoint for network connection; port 5024 and port 5025 are provided for the sockets for the E4980A/AL. Port 5024 is provided for conversational control using telnet (user interface program for the TELNET protocol) and port 5025 for control from a program.

If I use Port 5025 I get a timeout. If I use Port 5024 and send the command *IDN? or no matter what I send, I get the response:

received data: b'Welcome to E4980A SCPI parser.\r\n\r\nSCPI> '

What am I doing wrong here? Is socket the wrong tool? Am I using the wrong protocol?

There is a similar question, however, using pyvisa and no solution.


Solution

  • After all, the following finally works for me. As Mark Tolonen pointed out, it is necessary to add a lineend character, here "\n". Furthermore, in contrast to the example which I started with, you have to send bytes, where Python's bytes() requires some encoding where it seems to work with ansi, ASCII or utf8.

    Script:

    ### communicate via LAN to Agilent E4980A
    import socket
    
    TCP_IP      = '169.254.215.142'  # or whatever address you'll find on the E4980A screen
    TCP_PORT    = 5025
    BUFFER_SIZE = 1024
    
    def query(cmd):
        s.send(bytes(cmd+"\n",'ansi'))
        return s.recv(BUFFER_SIZE).decode('utf8')
    
    s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    s.settimeout(3.0)
    s.connect((TCP_IP, TCP_PORT))
    
    print(query("*IDN?"))
    
    s.close()
    ### end of script
    

    Result:

    Agilent Technologies,E4980A,MY46203491,A.06.17
    

    Device screen in the browser:

    Enter image description here