Instrument | Working features |
Keysight Technologies AWG 33612A | (discover+scpi+screenshot) |
Keysight Technologies DMM 34461A | (discover+scpi+screenshot) |
Keysight Technologies MSO-X 3024T | (discover+scpi+screenshot) |
Rigol Technologies DS1104Z | (discover+scpi+screenshot) |
Rigol Technologies DS2302 | (discover+scpi+screenshot) |
Rigol Technologies DG4062 | (discover+scpi+screenshot) |
Rigol Technologies DG4102 | (discover+scpi+screenshot) |
Rigol Technologies DG4162 | (discover+scpi+screenshot) |
Rigol Technologies DP831 | (discover+scpi+screenshot) |
Rigol Technologies DP832 | (discover+scpi+screenshot) |
Rigol Technologies DM3068 | (discover+scpi+screenshot) |
Rigol Technologies DSA815 | (discover+scpi+screenshot) |
Rigol Technologies MSO2302A | (discover+scpi+screenshot) |
Rigol Technologies DP832 | (discover+scpi+screenshot) |
Rohde & Schwarz HMC 8012 | (discover+scpi+screenshot) |
Rohde & Schwarz HMC 8043 | (discover+scpi+screenshot) |
Rohde & Schwarz HMO 1202 | (discover+scpi+screenshot) |
Rohde & Schwarz HMO 3054 | (scpi+screenshot) |
Rohde & Schwarz RTB 2004 | (discover+scpi+screenshot) |
Siglent Technologies SDG1032X | (discover+scpi+screenshot) |
Siglent Technologies SDG2122X | (discover+scpi+screenshot) |
Siglent Technologies SDG6052 | (discover+scpi+screenshot) |
Siglent Technologies SDS1202X-E | (discover+scpi+screenshot) |
Siglent Technologies SDS1204X-E | (discover+scpi+screenshot) |
Siglent Technologies SDS2304X | (discover+scpi+screenshot) |
Siglent Technologies SDM3045X | (discover+scpi+screenshot) |
Siglent Technologies SDM3055 | (discover+scpi+screenshot) |
Siglent Technologies SDM3065X | (discover+scpi+screenshot) |
Siglent Technologies SPD3303X-E | (scpi) |
Siglent Technologies SSA3032X | (discover+scpi+screenshot) |
sudo apt-get install git automake autogen autoconf libtool libreadline-dev libc-dev-bin libc6-dev libavahi-core-dev libavahi-common-dev libavahi-client-dev libxml2-dev liblua5.2-dev
mkdir lxi && cd lxi
git clone [url]https://github.com/lxi-tools/liblxi[/url] && cd liblxi
./autogen.sh
./configure --prefix=$HOME/opt/lxi
make install
cd ..
git clone [url]https://github.com/lxi-tools/lxi-tools[/url] && cd lxi-tools
./autogen.sh
./configure --prefix=$HOME/opt/lxi LDFLAGS=-L$HOME/opt/lxi/lib
make CFLAGS=-I$HOME/opt/lxi/include install
cd ..
export PATH=$HOME/opt/lxi/bin:$PATH
I've opened an issue for lxi-tools. Perhaps I'm messing things up when compiling
do you have plans for python bindings?
Might be a stupid question, but what's the difference between LXI and VXI11?
Usage: lxi [--version] [--help] <command> [<args>]
-v, --version Display version
-h, --help Display help
Commands:
discover [<options>] Search for LXI devices
scpi [<options>] <scpi-command> Send SCPI command
screenshot [<options>] <filename> Capture screenshot to file
Discover options:
-t, --timeout <seconds> Timeout (default: 3)
Scpi options:
-a, --address <ip> Device IP address
-t, --timeout <seconds> Timeout (default: 3)
-x, --dump-hex Print response in hexadecimal
-f, --dump-file <filename> Save response to file
-i, --interactive Enter interactive mode
-s, --script <filename> Run script file
Screenshot options:
-a, --address <ip> Device IP address
-t, --timeout <seconds> Timeout (default: 3)
-m, --model <name> Name of device model (model/family)
-l, --list List supported device models
EXAMPLES
Send SCPI command to LXI device:
lxi scpi -a 192.168.0.42 "*IDN?"
Capture screenshot from LXI device with specific model/family:
lxi screenshot -a 192.168.0.42 -m rigol-1000z my-screenshot.png
rogeorge@debian80:~$ lxi scpi -a 192.168.1.3 *IDN?
RIGOL TECHNOLOGIES,DS1104Z,DS1ZA16*,00.04.04.SP3
rogeorge@debian80:~$ lxi scpi -a 192.168.1.4 *IDN?
RIGOL TECHNOLOGIES,DP832,DP8C16*,00.01.11
rogeorge@debian80:~$ lxi scpi -a 192.168.1.5 *IDN?
Rigol Technologies,DG4102,DG4E17*,00.01.12
rogeorge@debian80:~$ lxi discover
Searching for LXI devices - please wait...
Broadcasting on interface lo
Broadcasting on interface eth0
No devices found
rogeorge@debian80:~$ ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
inet 127.0.0.1/8 scope host lo
valid_lft forever preferred_lft forever
inet6 ::1/128 scope host
valid_lft forever preferred_lft forever
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000
link/ether 00:0c:29:*:*:* brd ff:ff:ff:ff:ff:ff
inet 192.168.146.134/24 brd 192.168.146.255 scope global dynamic eth0
valid_lft 1711sec preferred_lft 1711sec
inet6 fe80::20c:*:*:*/64 scope link
valid_lft forever preferred_lft forever
rogeorge@debian80:~$
I noticed that running "lxi discover" does not find any instrument when running on a Debian 8.0 installed in a VMware machine that is running under Windows 10, but sending SCPI commands to specified addresses works just fine.
- The Debian 8 VMware machine is set to use "NAT: Used to share the host's IP address".
$ lxi screenshot --list
Name Description
keysight-iv2000x Keysight InfiniVision 2000 X series oscilloscopes (experimental)
rigol Rigol 1000z/2000/4000 series oscilloscopes
rs-hmo1000 Rohde & Schwarz HMO 1000 series oscilloscopes (experimental)
tektronix-2000 Tektronix MSO/DPO 2000 series oscilloscopes (experimental)
lxi screenshot --adress 192.168.0.40 --model rigol screenhot.png
Saved PNG screenshot image to screenhot.png
- AFAIK all Rigol oscilloscopes use the same SCPI command for a screenshot. Why it was necessary in the code to separate them by 1000/2000/4000 models?
- Also, since lxi-tools allows running a SCPI text file, why not just defining a text SCPI file for each instrument, so the user can add its own instrument any time?
- A thing that I noticed when capturing screenshots with my software was that I was lazy enough to write a small script to increment the file name, so I made the code to put a timestamp in the filename. That was useful because once a command it's typed in the terminal, it's very easy to repeat it by simply "up arrow" and "enter", and the previous screenshot files will not be overwritten.
- I can add screnshots for the Rigol DG4000 DDS signal generators if you want, and for the Rigol DP832 power source. Should I make a pull request, or just tell you here the SCPI commands after manually testing them on my instruments?
lxi scpi --raw --address 192.168.0.42 "*IDN?"
RIGOL TECHNOLOGIES,DS1104Z,DS1ZA1234567890,00.04.04.SP3
- I can add screnshots for the Rigol DG4000 DDS signal generators if you want, and for the Rigol DP832 power source. Should I make a pull request, or just tell you here the SCPI commands after manually testing them on my instruments?
FYI
liblxi fails in ./configure because it can't find ifaddrs.h on Solaris 10 u8
lxi-tools fails in ./configure because it can't find libreadline even though liibreadline is in /app/lib and /app/lib is in LD_LIBRARY_PATH
FWIW I have 397 executables in /app/bin, all of which were compiled from source.
Back during the workstation wars I built a large system for SunOS, AIX, IRIX, CLIX, Ultrix and HP-UX with only two #ifdefs in the code. One for byte sex and the other for FORTRAN record length. The only build dependency was the presence of Gnu make on all systems. We now have autotools just to make code portable across linux distros.
Congratulations on recreating the major mistakes of the last 70 years.
Did you ever hear of POSIX? RMS coined the name and the concept. If you write to the C and POSIX standards your code will run easily almost anywhere. That was why that 500,000+ line mixture of C, FORTRAN, lex and yacc ran on all those different systems. The package was a port from VMS and I insisted on conformance to standards. It was in regular use for almost 20 years with no support at all for probably 10 years. There were no bugs left. We had fewer than a dozen user submitted bugs the first year of deployment and it went down from there. Every build included a large test suite. When we wrote a module, we wrote tests for it and ran it on all the supported platforms. It makes you very sensitive to where the standards say that behavior is "undefined" or "implementation dependent". So you don't do stupid stuff.
The readline check fails because autotools is semantically and conceptually broken. It is *supposed* to look in all the directories in LD_LIBRARY_PATH. I don't try to fix broken machine generated code. I wasted an entire week trying to get Octave to work once because they botched the autotools setup. Never mind that R compiled just fine. I've compiled a lot of code that uses Gnu readline. Ken Thompson wrote early versions of Unix in fewer lines than a configure script!
The consequence is simply that I shall write my own software rather than contribute to yours. A command line LXI interface is just an example program from "Advanced Programming in the Unix Environment" by Stevens and Rago decorated with some LXI details. It can also be done in python or perl, though I don't care much for either.
There's a Dilbert cartoon on the cover of Stevens and Rago that's very relevant. The interchange in the last frame is "You're one of those condescending Unix users." "Here's a nickel, kid. Get yourself a better computer."
I'm a professional SW engineer and I'm a big fan of POSIX and I use it extensively in most software that I write. However, for some applications, part of the software rely on system level features which are not covered by any of the available POSIX standards. In case of liblxi I'm relying on specific interfaces that allows me to discover and manage all available network interfaces to be used in the lxi discover feature. No such interfaces are available via POSIX. Hence I write that part of the code specifically for GNU/Linux systems because it is the most popular platform out there in the *nix world.
int lxi_discover(struct lxi_info_t *info, int timeout)
{
struct sockaddr_in *broadcast_addr;
struct ifaddrs *ifap;
int status;
// Go through available broadcast addresses
if (getifaddrs(&ifap) == 0)
{
struct ifaddrs *ifap_p = ifap;
while (ifap_p)
{
if ((ifap_p->ifa_addr) && (ifap_p->ifa_addr->sa_family == AF_INET))
{
broadcast_addr = (struct sockaddr_in *) ifap_p->ifa_broadaddr;
// Notify current broadcast address and network interface via callback
if (info->broadcast != NULL)
info->broadcast(inet_ntoa(broadcast_addr->sin_addr), ifap_p->ifa_name);
// Find LXI devices via broadcast address
status = discover_devices(broadcast_addr, info, timeout);
}
ifap_p = ifap_p->ifa_next;
}
freeifaddrs(ifap);
}
return LXI_OK;
9964 NAME
19965 SYNOPSIS
19966 #include <net/if.h>
if_nameindex — return all network interface names and indexes
struct if_nameindex *if_nameindex(void);
19967
19968 DESCRIPTION
19969 The if_nameindex( ) function shall return an array of if_nameindex structures, one structure per
19970 interface. The end of the array is indicated by a structure with an if_index field of zero and an
19971 if_name field of NULL.
19972 Applications should call if_freenameindex( ) to release the memory that may be dynamically
19973 allocated by this function, after they have finished using it.
19974 RETURN VALUE
19975 An array of structures identifying local interfaces. A NULL pointer is returned upon an error,
19976 with errno set to indicate the error.
19977 ERRORS
19978 The if_nameindex( ) function may fail if:
[ENOBUFS]
19979
Insufficient resources are available to complete the function.
19980 EXAMPLES
19981 None.
19982 APPLICATION USAGE
19983 None.
19984 RATIONALE
19985 None.
19986 FUTURE DIRECTIONS
19987 None.
19988 SEE ALSO
19989 getsockopt ( ), if_freenameindex( ), if_indextoname( ), if_nametoindex( ), setsockopt ( ), the Base
19990 Definitions volume of IEEE Std 1003.1-2001, <net/if.h>
cd ~
mkdir lxi-tools
cd lxi-tools/
git clone https://github.com/lxi/liblxi
cd liblxi/
su
apt-get update
apt-get install automake
apt-get install autogen autoconf libtool
./autogen.sh
./configure
make
make install
cd ..
git clone https://github.com/lxi/lxi-tools
cd lxi-tools/
./autogen.sh
apt-get install libreadline-dev
./configure
make
make install
exit
cd ..
# not required any more ???
# export LD_LIBRARY_PATH="$LD_LIBRARY_PATH:/usr/local/lib"
lxi
rogeorge@debian80:~/lxi-tools$ lxi
Usage: lxi [--version] [--help] <command> [<args>]
-v, --version Display version
-h, --help Display help
Commands:
discover [<options>] Search for LXI devices
scpi [<options>] <scpi-command> Send SCPI command
screenshot [<options>] [<filename>] Capture screenshot
Discover options:
-t, --timeout <seconds> Timeout (default: 3)
Scpi options:
-a, --address <ip> Device IP address
-t, --timeout <seconds> Timeout (default: 3)
-x, --dump-hex Print response in hexadecimal
-f, --dump-file <filename> Save response to file
-i, --interactive Enter interactive mode
-s, --script <filename> Run script file
-r, --raw Use raw/TCP
-p, --raw-port <port> Use raw/TCP port (default: 5555)
Screenshot options:
-a, --address <ip> Device IP address
-t, --timeout <seconds> Timeout (default: 15)
-m, --model <name> Name of model
-l, --list List supported models
rogeorge@debian80:~/lxi-tools$
Passedrogeorge@debian80:~/lxi-tools$ lxi --version
lxi v1.6
rogeorge@debian80:~/lxi-tools$ lxi -v
lxi v1.6
rogeorge@debian80:~/lxi-tools$ lxi -h
Usage: lxi [--version] [--help] <command> [<args>]
-v, --version Display version
-h, --help Display help
Commands:
discover [<options>] Search for LXI devices
scpi [<options>] <scpi-command> Send SCPI command
screenshot [<options>] [<filename>] Capture screenshot
Discover options:
-t, --timeout <seconds> Timeout (default: 3000)
Scpi options:
-a, --address <ip> Device IP address
-t, --timeout <seconds> Timeout (default: 3000)
-x, --dump-hex Print response in hexadecimal
-f, --dump-file <filename> Save response to file
-i, --interactive Enter interactive mode
-s, --script <filename> Run script file
-r, --raw Use raw/TCP
-p, --raw-port <port> Use raw/TCP port (default: 5555)
Screenshot options:
-a, --address <ip> Device IP address
-t, --timeout <seconds> Timeout (default: 15000)
-m, --model <name> Name of model
-l, --list List supported models
rogeorge@debian80:~/lxi-tools$ lxi --help
Usage: lxi [--version] [--help] <command> [<args>]
-v, --version Display version
-h, --help Display help
Commands:
discover [<options>] Search for LXI devices
scpi [<options>] <scpi-command> Send SCPI command
screenshot [<options>] [<filename>] Capture screenshot
Discover options:
-t, --timeout <seconds> Timeout (default: 3000)
Scpi options:
-a, --address <ip> Device IP address
-t, --timeout <seconds> Timeout (default: 3000)
-x, --dump-hex Print response in hexadecimal
-f, --dump-file <filename> Save response to file
-i, --interactive Enter interactive mode
-s, --script <filename> Run script file
-r, --raw Use raw/TCP
-p, --raw-port <port> Use raw/TCP port (default: 5555)
Screenshot options:
-a, --address <ip> Device IP address
-t, --timeout <seconds> Timeout (default: 15000)
-m, --model <name> Name of model
-l, --list List supported models
rogeorge@debian80:~/lxi-tools$
Failed - Cosmeticrogeorge@debian80:~/lxi-tools$ lxi discover
Searching for LXI devices - please wait...
Broadcasting on interface lo
Broadcasting on interface eth0
Found "RIGOL TECHNOLOGIES,DS1104Z,DS1ZA16*,00.04.04.SP3" on address 192.168.1.3
Found "Rigol Technologies,DG4102,DG4E17*,00.01.12
4.SP3" on address 192.168.1.5
Found "RIGOL TECHNOLOGIES,DP832,DP8C16*,00.01.11
4.SP3" on address 192.168.1.4
Found 3 devices
rogeorge@debian80:~/lxi-tools$
Failed - Major inconveniencerogeorge@debian80:~/lxi-tools$ lxi scpi -a 192.168.1.5 *IDN?
Rigol Technologies,DG4102,DG4E17*,00.01.12
rogeorge@debian80:~/lxi-tools$ lxi scpi -a 192.168.1.4 *IDN?
RIGOL TECHNOLOGIES,DP832,DP8C16*,00.01.11
rogeorge@debian80:~/lxi-tools$
rogeorge@debian80:~/lxi-tools$ lxi discovery
Error: No IP address specified
rogeorge@debian80:~/lxi-tools$
Failed - Minor inconvenienceI hate seeing unportable code that could trivially have been written to be portable to any Unix system. I've had to fix far too much of it.