Thursday, September 29, 2016

Use Prologix USB-GPIB with Python (or any other language)

Prologix This USB to GPIB adapter by Prologix is cheap and pretty neat. It uses an FTDI chip to interface with USB, so the device shows up as a COM port when connected to a computer. The FTDI driver is available on Windows, Linux and Mac OS, so most users can use these devices without worrying about finding drivers.

The programming is relatively easy, as long as you can communicate through COM port. Since it is a virtual COM port over USB, the Baud rate can be set very high. The command strings are sent through the virtual COM port, buffered, then sent over GPIB. Therefore, a command string has been written to the COM port does not mean it has reached the slave on the bus. This asynchronous nature can cause some unexpected behavior. For example, if we send *IDN? to an equipment on the bus, Pyserial write function returns as soon as this string is in the buffer of COM port. If we start to read from the bus right away, the equipment does not understand why it is set to TALK. To avoid this problem, a short delay should be inserted between writing to the equipment and reading from it.

Some queries may take time to complete because the slave needs to collect data samples, process the data, ... Consequently, the query may timeout and return empty or partial information. Increasing timeout may help the situation but with side effects. This is because there are two timeouts - GPIB timeout and COM (serial) port timeout. In addition, longer timeout will delay many normal operations. This problem can be easily solved by increase the delay mentioned above without touching timeouts. The GPIB slave cannot send the response until it is set to TALK, therefore no information will be lost if we do not start the read. In the sample code linked below, the delay can be simply controlled for each query, so it is trivial to adapt to different use cases.

One feature of the adapter often causes problems is read-after-write. This is set by writing "++auto 1" to COM port. Although it is convenient in theory, some instruments report error when being set to TALK by some commands that do not require an answer. Therefore, it is recommended to disable this feature and read explicitly by "++read eoi" command.

A simple class written in Python can be found at 
https://bitbucket.org/qiang_self/prol_gpib/src The code has been tested on Windows 7 with Python 2.7.11 and 3.5.2.

Thursday, February 11, 2016

Easy way to run python script in Conda activated environments in Windows

Conda is a great tool to setup python and various packages/languages. It provides easy method to switch between environments, e.g., one can easily switch between python 2.7 and python 3.5 without resorting tedious hacks and tricks. However, when using it in Microsoft Windows, it is not as convenient as one wishes for.

In Windows, there are multiple ways to run a python script.
  1. You can set the path to python.exe in your PATH variable, then type "python path_to_your_script". Although you don't have to type the path to your python installation, you have to type the path to your script every time. You can use the script in the same directory as your command line environment, but this is an inconvenient restriction.
  2. In addition to setting the path to python.exe in PATH variable, one can also set the path to your scripts in PATH variable. Some distributions of python works well and you simply need to type "your_script_name" and Windows will call python.exe to run it. This did not work for me at least on Anaconda2-2.5.0-Windows-x86_64. I had to manually associate files with .py extension with python.exe installed by Anaconda. While this did work, there is a new problem - it always uses the root environment. In my case, the root environment is python 2.7. I installed python 3.5 through Conda and named it py35. After "activate py35", and run python.exe --version, it shows python 3.5. However, when I run my script, it still shows python 2.7. This is because when I type the name of the script, Windows loads the python.exe file (version 2.7 in this case) that I associated earlier. 
In order to take advantage of Conda's capability of switching environment, I tried a a slightly different approach. I created a file called run_python.bat and saved it in the same directory as my python scripts. You can save it anywhere as you like, just make sure to add the path to it in your PATH variable. Inside this file, there is only one line - @python.exe  %* Then I associated .py extension with this new batch file. Note that I did not put the path to python.exe in the batch file. It is intentional. Without an absolute path specified, Windows searches for it. As Conda switches the environment, the python.exe found by Windows will be different, which serves my purpose perfectly. By default, when you associate an file extension with a program, there is an entry created in Windows registry. Run regedit.exe, search for an entry called "run_python.bat" after you have associated the .py extension with it. There should be "shell:open:command" for this entry. The default value for command is "path_to_your_directory\run_python.bat" "%1", change it to "path_to_your_directory\run_python.bat" "%1" %* so that the arguments can be passed to your python script properly.

That's it. A simple trick that worked for me.