Monday, March 3, 2014

ARDUINO UNO as a USB to GPIB controller - version 6.1


TEK2232 loves Arduino
TEK2232 loves Arduino
Fluke PM2534 loves Arduino
Fluke PM2534 loves Arduino

Disclaimer:
This program is provided as is. It is a hobby work.
It doesn't work correctly. It has not been tested. It can damage your Arduino and the device you connect it to.
Can have unexpected behaviors, can get stuck at any moment, can read and write data to/from the device in ways you might not expect. It can send wrong or erratic commands to the device. Can display data that differ from the actual data the device sent out. Can address GPIB devices
differently from what you might expect.
I have not conducted any speed test; the maximum speed supported is simply unknown.
Is does not follow any official standard. Only a minimum set of the functions included in IEEE-488 is barely emulated.
Hardware limitations: the lack of a GPIB line driver has two major implications: first: your Arduino is directly connected to the device GPIB port without any form of electrical protection of buffering - this can potentially damage your Arduino and/or your device; second: what can happen if you connect more than one GPIB device to the BUS is unpredictable both from an hardware and software point of view. I only experimented with a single GPIB device connected to the BUS.

Creative Commons License
Arduino USB to GPIB firmware by E. Girlando is licensed under a Creative Commons Attribution-NonCommercial-NoDerivatives 4.0 International License.
Permissions beyond the scope of this license may be available at mailto:emanuele_girlando@yahoo.com.

After nights spent coding, this post is about version 6.1 of my USB to GPIB controller software for ARDUINO UNO.
Version 6.1 ??!! Yes, that's it! This is actually version 2 of my software, but because some third party software - actually KE5FX GPIB toolkit -  relies on the content of the output string as issued by the "++ver" command to work properly, I had to force the string "version 6." as part of the" ++ ver" command output. So .. this version has become version 6.1. 

Version 1.0 has been presented in this related post.
Version 1.0 was very crude. Most a beta version to verify the feasibility of this project.
I want to thank you very much all of you that provided me feedbacks.

This release represents a significant step forward toward "++" commands compatibility and software robustness. Still the software is aimed for those of you with test instruments interest at hobby professional level. Do not use it in professional environments.

release notes version 6.1:
  • bug fix especially at command interpreter level ;
  • command syntax is now compatible with the "++" language;
  • for compatibility reasons the controller is now much more silent when executing commands (but see the "++verbose" command below);
  • reads from GPIB are not buffered anymore: char received from GPIb are sent to USB a soon as they are received. This enable this version of the controller to receive bulk binary data;
  • for compatibility reasons the escape char has been changed from "\" to Ascii ESC (0x1B);
  • "++addr" has a new default value of 2;
  • "++eot_char" and "++eot_enable" commands have been implemented with default values of 10 (0xA) and 0 respectively;
  • "++auto" is no more a toggle and is fully compatible now. The new syntax is "++auto [0|1]" and the default is 0;
  • "++eoi" has been implemented with syntax "++eoi [0|1]" and a default value of 1;
  • "++eos" has been implemented with syntax "++eos [0|1|2|3"] and a default value is 1;
  • "++read" is completely unbuffered now. It terminates in front of an EOI signal detect OR an EOS char received from GPIB.  "++read eoi" changes this logic to EOI detection only. This is useful (and works) for binary transfers - e.g. screen dumps. 
  • "++ver" returns " the string "ARDUINO GPIB firmware by E. Girlando Version 6.1 ".
  • "++read_tmo_ms" has been implemented with syntax "++read_tmo-ms [100-9999]" and a default value of 200;
 Two additional proprietary commands (not usually included in the "++" set) have been implemented:
  • "++verbose" this command toggles the controller between  verbose and silent mode. When in verbose mode the controller assumes an human is working on the session: a ">" prompt is issued to the USB side of the session every time the controller is ready to accept a new command and most of the "++" commands now print a useful feedback answers (i.g. the new set value or error messages). This breaks the full "++" compatibility. Do not use verbose mode when trying to use third party software. Default is verbose OFF.
  • "++dcl" sends an unaddressed DCL (Universal Device Clear) command to the GPIB. It is a message to the device rather than to its interface. So it is left to the device how to react on a DCL. Typically it generates a power on reset.
This version of the controller successfully reacts to the Prologic.exe program included in the KE5FX GPIB toolkit. I was not able to test the 7470.exe program as I do not have any instrument compatible with the toolkit (I indeed tryed with my TEK 2232 scope, but it failed...).

The full project documentation updated to version 6.1 follows.
----

ARDUINO UNO as a USB to GPIB controller 

Documentation of Version 6.1

Introduction 

This project is aimed to provide a cheap and quick GPIB solution for those that need to gain control over a single instrument and interact with it (e.g. to dumo screen shots or calibrate instruments that can be calibrated via GPIB only -- HP6632A Power Supply being a good example).

I supposed that cheap adapters were available on the market to interface GPIB instruments with a PC. I was wrong. The only feasible solution is to go with a Prologix USB to GPIB converter, still it would have cost me more than 100 EUR .
Other solutions (open or proprietary) required buying or building hardware.

On the other end I had an Arduino UNO floating around on my bench waiting for a problem to solve other than blinking leds or writing "hello world" on an LCD..

So I decided to face the challenge of writing down a sketch and have the Arduino play the adapter role I was looking for.
To make a long story short.. (I supposed that GPIB was simple at least as much RS-232 is, .. and it is not! I was wrong again!) after reading a lot of IEEE-488 documentation, I got a decent implementation of a GPIB controller out of my Arduino UNO. This post is dedicated to describe the project.


Code availability

In some of the feedbacks post in the HP or TEK Yahoo discussion groups I have been accused of not having published the source code. Here it is. Enjoy it! BUT: I am interested in test&meas instruments. I am not interested in developing open source projects. I wrote this program just because it happens I am an ICT professional and consequently I have some educational reminiscence of  programming.

Because of the hard effort I put into the project, I kindly request you to donate a couple of bucks if you find this program useful for your hobby or research.



  Download GPIB6.1.ino (dropbox link).
donations are not for a "product" or a "product functionality", .. they represent a light payback for what you have learned reading a content and possibly getting some free software to play with... which have cost some effort to the editor to be developed.

Below you'll find the program documentation describing the implemented functionalities, limitations, commands syntax and hardware required (close to null.., just a bunch of wires and a plug).

----
This program allows to have the Arduino UNO to implement a GPIB controller. The objective was to have a way to get control of test instruments by the ability to send and receive commands to/from such devices via GPIB using a terminal emulator o an appropriate script.

Despite the disclaimer I can say that the objective has been successfully met; with this program uploaded to an Arduino UNO I can now establish sessions with my hobby  instruments and interact with them the way they allow to (see instrument manual).
Most of the version 1 limitations are still here. Actual limitations are:

- the program operates in controller mode only; it is not (yet) able to behave like a device.
- two important GPIB pins are not managed: REN and SRQ;
- Serial poll is not implemented.
- subaddressing is not implemented.
- ++read [char] not implemented (useful?!);
- ++rst, ++lon, ++savecfg, ++spoll, ++srq, ++status, ++help are not implemented;

Hardware set up instructions:

The hardware needed is simple: just a bunch of wires from the GPIB plug to Arduino pins. Here is the pin mapping:

GPIB-Arduino fixture
GPIB-Arduino fixture
  A0   GPIB 1
  A1   GPIB 2

  A2   GPIB 3 
  A3   GPIB 4
  A4   GPIB 13
  A5   GPIB 14
  4    GPIB 15
  5    GPIB 16
  12   GPIB 5
  11   GPIB 6
  10   GPIB 7
  9    GPIB 8
  8    GPIB 9
  7    GPIB 11




NOTE:
 GPIB pins 10, 17-24 goto GND, but (!!):
  •  GPIB pin 17 (REN) has to be implemented ..stay ready to reroute it differently in the future;
  •  GPIB pin 10 (SRQ) has to be implemented ..stay ready to reroute it differently in the future;
  •  GPIB pin 12 should be connected to the cable shield (not used here - I left it n/c).
Build the the shield the way you want. Nothing is simpler provided you have a minimum electronic construction skills.
For testing I preferred the "flying" shield visible in the pictures but the actual construction is your choice.
The male GPIB connector was realized sacrificing a CENTRONICS 32pins male connector out of a PC parallel printer cable. I have just cut it leaving 12 positions out of the original 16.

Get it working

Get the GPIB6.1.ino sketch compile it and upload it to the Arduino.
If you want/need to see a bunch of debugging output, just uncomment the two #defines directives on top of the source file.

Get any terminal emulator and manage to have it working with the FTDI RS232/USB converter (nothing to do under linux; install the FTDI driver in Windows: it cames for free with the Arduino IDE. I have successfully used the serial display provided by the arduino IDE, putty under Linux and HyperTerminal under (virtual) Windows XP.
You probably have to set the some serial communication parameters.
The default serial speed is 115200 bps.
Other serial parameters are: Data_bits=8, Stop_bits=1, Parity=None, Flow_control=None.
I successfully also interacted with the controller using cat, tail -f, echo, .. linux commands redirected to the FTDI serial device (/dev/ttyACM0 in my case). To do that you have to play a little with the stty command. For sure you need to set -hupcl so that the DTR 232 signal is not deasserted while disconnecting from the device. It can also be useful to defeat the "reboot on connection" feature of the Arduino. Google about these topics before doing it! You can make your arduino impossible to reprogram.
The controller is silent at startup. To test it send a "++ver" command and the Arduino should reply with "ARDUINO GPIB firmware by E. Girlando Version 6.1".
If you plan to interact directly with your instrument, please issue the command "++verbose". This will make your controller much more friendly (see below).

Principle of operations

Everything received from the USB is passed to GPIB (126 char max).
Characters from the USB are fetched in line by line and buffered. The software support for both CR, LF and CRLF line termination.
Once the line termination char is encountered in the USB input stream the entire buffer gets parsed. If you need to include CR or LF in the input stream to be sent to your instrument you must rely on the help of the linux serial device driver using ^V in front of ^M or ^J to defeat their default behaviour of terminating the command shell lines.. (see stty man page). Still the ^V mechanism is not enough. ^V prevents the linux driver from sending out your line in the middle of your editing, but still the received CR or LF are interpreted as end of line by the Arduino. To avoid this an escape mechanism has been implemented. The escape char is "ESC" or 0x1B. So to send CR to the GPIB BUS you need to type "ESC^V^M" and similarly for LF. To send a single "ESC" you must escape it with "ESC" so you need to type "ESC" two times. You can terminate the input line with "\" so that the following CR or LF will be escaped. If you insert unescaped CR or LF in the stream (e.g typing "^V^M" with no preceding "ESC") the line is split in two parts: everything preceding the CR or LF is passed on for processing; everything following the CR or LF is simply discarded.
I don't know of any way to send CR or LF or ESC ascii char from the Arduino IDE serial monitor. Testing for all this stuff has been conducted via putty.
WARNING: if you use buffered I/O on the sender side, and you often do, be aware that sending more than 64 chars per line can lead to serial buffer overflow as the Arduino sketch cannot keep pace with the burst of characters coming in @115200bps. Yet, the program detects this situation, issues a "Serial buffer overflow - line discarded. Try setting non buffered I/O" error message and discards the line entirely. As the error message suggests, you can switch your sender (terminal emulator) to unbuffered I/O so that it sends out one char at a time. If you are typing at a keyboard the problem is solved (unless you are typing at the speed of light); if the data comes from some kind of script, care must be taken to send small chunks of data introducing delays to allow for the program to eat them.
Line starting with "++" are assumed to be commands directed to the controller and are parsed as such. Nothing beginning with "++" can be sent to instruments.
Conversely everything not starting with "++" is transparently sent to the addressed instrument over the GPIB BUS.

Implemented commands:

NOTE: the command interpreter is very raw: I remember from high school that they have to be programmed in a certain way, but I don't really remember how; so I did my best. Misspelled commands will (better: should) generate a Syntax error message. As soon as a non existent command code or a Syntax error is detected the line is discarded entirely. After a valid command has been recognized, any additional characters following it (if any) is discarded.

++addr [address] 
Fully compatible with the "++" de facto standard, but subaddressing is not implemented (SADs are syntactically accepted but ignored).
++ver
just displays a version string of the controller.
++auto
Fully compatible with the "++" de facto standard.
But what is automode? Ok, you have to know that GPIB devices do not work the way we are used to with modern devices. When you send a command they process it and if any output is generated they put it to an instrnal buffer waiting to be addressed to speak. The final result is that just to get the identification string out of a device you have to send the request command (e.g "id?") and then issue the command "++read" to the controller. Automode ON just makes this for you: for every string sent to GPIB, the controller issues an implicit "++read" to the addressed device. This gives you the impression to have the device immediately react in front of the string you sent it. Beautiful! ...however a hidden trap is around: some GPIB device gets upset if asked to speak when it has nothing to say and with automode ON this can happen very often (I have an instrument that lights the error annunciator on the front panel when this situation occurs, but yet it continues working as nothing happened).
For this reason automode is blocked if you just send an empty string pressing CR or NL. Automode is also suppressed with "++" commands.
++clr
Fully compatible with the "++" de facto standard.
++eoi
Fully compatible with the "++" de facto standard.
++eos
Fully compatible with the "++" de facto standard.
++eot_enable
Fully compatible with the "++" de facto standard.
++eot_char
Fully compatible with the "++" de facto standard.
++ifc
Fully compatible with the "++" de facto standard.
++llo
Fully compatible with the "++" de facto standard.
++loc
Fully compatible with the "++" de facto standard.
++mode
the command is syntactically fully compatible with the "++" de facto standard, but the only mode implemented is CONTROLLER; so the command is provided for compatibility only and it is inoperative.

++read
Fully compatible with the "++" de facto standard, but ++read [char] is not implemented.
++read_tmo_ms
Fully compatible with the "++" de facto standard.
++trg
is implemented for the addressed device only; it doesn't accept PADs or SADs paramenters.

++rst, ++lon, ++savecfg, ++spoll, ++srq, ++status, ++help are not implemented.

Two additional proprietary commands (not usually included in the "++" set) have been implemented:
++verbose
This command toggles the controller between  verbose and silent mode. When in verbose mode the controller assumes an human is working on the session: a ">" prompt is issued to the USB side of the session every time the controller is ready to accept a new command and most of the "++" commands now print a useful feedback answers (i.g. the new set value or error messages).
This breaks the full "++" compatibility. Do not use verbose mode when trying to use third party software. Default is verbose OFF.
This is very useful to see timeout errors otherwise hidden..
++dcl
Sends an unaddressed DCL (Universal Device Clear) command to the GPIB. It is a message to the instrument rather than to its interface. So it is left to the instrument how to react on a DCL. Typically it generates a power on reset. See your instrument documentation.

Feedbacks

This version can be successfully used to interact with your instruments, but is still imperfect. Please post feedbacks and comments below this post.
In addiction to bug fixing, I am interested in sharing experiences in using third party software especially for dumping plots down from instruments. I have a TEK2232 and an HP853 I am interested in producing plots from.


Future development

I am going to improve it by bug fixing and keep the documentation deep and updated and working on Version 6.2 that will wide the project scope up to:
  • settings save/restore,
  • serial poll support (if not too difficult),
  • improve ++trg compatibility,
  • porting to different Arduino platforms.

Conclusions

Enjoy your GPIB controller and please do not forget to donate some buck just to recognize the effort I made to develop and document this project.
Thank you!
Emanuele.



  Download GPIB6.1.ino (dropboxlink).
donations are not for a "product" or a "product functionality", .. they represent a light payback for what you have learned reading a content and possibly getting some free software to play with... which have cost some effort to the editor to be developed. 

Creative Commons License
Arduino USB to GPIB firmware by E. Girlando is licensed under a Creative Commons Attribution-NonCommercial-NoDerivatives 4.0 International License.
Permissions beyond the scope of this license may be available at mailto:emanuele_girlando@yahoo.com.

54 comments:

  1. Hello Emanuele! Such a great instructional guide! I've followed your guide and in just a few hours was talking to GPIB devices. I did get the controller to work with three devices, and believe that it can work with even more than three devices. Very nice! Thank you for sharing your code & how-to.

    ReplyDelete
  2. Hi Emanuele! A great project! But, does it also provide me to read from an instrument? I need to get data from a counter, just frequencies...

    Thanks for your reply

    ReplyDelete
    Replies
    1. This is exactly what the project was related to...
      Remember that, in order to read values out of a GPIB instrument, usually requires a two steps procedure: first you to send it an inquiry command and then read the result.
      Please, read the programming section of the instrument manual.. ciao.

      Delete
  3. Hi Emanule I want to try using a different Arduino platform, but I have read that in version 6.2 it can. My question is when version 6.2 comes out.
    Sincerely,
    Frank

    ReplyDelete
    Replies
    1. Frank,unfortunately (or fortunately, depending on the point of view), I am currently very busy at work and I have no time left for developing the project now.
      Still I am interested in developing cross arduino platform compatibility, line drivers and the missing commands, especially the serial poll.
      When? I actually don't know. May be in Q2 or Q3 this year.
      Thank you very much for your interest in my project.
      Sincerely.
      Emanuele

      Delete
  4. Hi Emanuele!

    Your work here is valuable and very much appreciated. I'd like to add a little fix: My current-meter device sends data very fast and so I always missed the first few chars. Solution lies in the beginning of read_h function: NRFD needs to be pulled LOW as soon as possible. I added pinMode and digitalWrite in the beginning of the function and now it just works fine.

    Sincerely,
    Florian

    ReplyDelete
  5. Thank you Florian!
    I would incorporate your fix in the next release.
    Bye.
    Emanuele.

    ReplyDelete
  6. The project works very well. Thank you.

    ReplyDelete
  7. Hi I have an Stabilock 4040 with a GPIB connection for a printer. It sends ASCII to the printer. Can I use this interface too to get my print data out and rout it to a Laser printer in some way ? ??

    ReplyDelete
  8. I had to google to know what a Stabilock 4040 is..
    Reading the manual (Cap5) it seems you can send commands to the rig and get data out of it as in any GPIB compatible test equip.
    Will it work with the Arduino? Who knows. I do not see any reason for it not to work.. Give it a try and let us know.
    Ciao.
    Ciao.
    Emanuele.

    ReplyDelete
  9. Hi Emanuele

    could it be so that with direct connection to GPIB bus arduino will not be able to read HIGH level if instrument uses IEEE488 drivers SN75161BN/SN75160BN? At least I was not able to get it working. As soon as I attach arduino to Kaithley 2306, each line drops from 3V to 1.95V and arduino is not able to get HIGH signal.. just ordered same drivers to use at arduino side, hope that it will help, if so, probably it would be good idea to include such drivers in next version.

    Sincerely,
    Arnis

    ReplyDelete
    Replies
    1. Arnis,
      what lines are you speaking about? All? Some?
      In what GPIB state your instrument is in?

      I assume all instruments have GPIB line driver in them (otherwise how could they declare to be in IEEE-488 compliance..? ).
      So I don't think it is a driver/no-driver problem (provided you connect a single instrument!).

      Have you double checked your cabling? Ground returns?
      Have you a different instrument to experiment with?

      Emanuele.

      Delete
  10. Hi Emanuele
    finally found the problem - it wasn't driver fault, it was fact that I was trying it with Arduino Micro (32u4) with different pin mapping and I didn't notice a part with bitwise operations in the code. Now it's working and I have to donate from next salary :))

    Arnis

    ReplyDelete
    Replies
    1. Great to know!!
      Thank you for sharing the solution.
      Enjoy your project.
      Emanuele.

      Delete
  11. please explain how I can connect it to the GND that did not understand very well

    ReplyDelete
  12. GND NOTE explanation:
    connect pin 10 and all the pins from 17 to 24 to the Arduino GND pin (I've used the one between pin13 and Aref); but pin 17 and 10 may need to be rerouted to an Arduino i/o pin in the future to implement REN and SRQ. So keep them in a way that you can easily reroute them in the future.
    Pin 12 is the chassis ground. I left it not connected but you can connect it to the chassis GND of you instrument by the cable shield leaving it n/c on the Arduino side (to avoid forming a ground loop).
    This solution is for sure NOT in line with the GPIB electrical standard, but for point2point short connections it works.
    Emanuele.

    ReplyDelete
  13. Thank you for making this very nice project, Emanuele. It works fine for me when I use a terminal program such as HyperTerm or RealTerm to communicate with it.

    I did test your project with KE5FX's HP7470A Emulator and also with KE5FX's GPIB Configurator and it does not work with either one.

    Neither the KE5FX configurator nor the KE5FX emulator recognize any reply from the Arduino. KE5FX's software sends "++ver" to the Arduino but the Arduino does not respond. When I use a terminal program to communicate with the Arduino, it responds appropriately with the version. I don't know why the Arduino does not respond to this message from KE5FX's software.

    I do have an HP 8563E that works with KE5FX's software when used with a National Instruments interface, so I can do further tests if that would be helpful.

    Thanks again!

    ReplyDelete
  14. Im very new to programming and arduino. Tried compiling the code but it says "
    'DDRD' was not declared in this scope".

    :(

    ReplyDelete
  15. The software was developed on UNO. You have to be sure to use a compatible 328's ports hardware or you have to rewrite the relevant code - get_dab() and set_dab() bitwise operations.
    The source still contains the original hardware independent, not bitwise, not optimize code for those two functions. You can try to switch between the two.
    Ciao Emanuele

    ReplyDelete
  16. Graaaaaaandeeeee !!! guarda, sorry se ti scrivo in italiano MA sono troooppo contento di aver trovato questo sito ... (:-)
    Te la faccio breve per non disturbare troppo :
    1) ho appena comprato un HP3457A e ho scoperto DOPO che i 7.5 digit promessi ce l'ha MA solo se li leggi con hpib ... (:-(
    2) a questo punto lungi da me comprare un interfaccia gpib-usb che mi costerebbe più dello strumento ...
    3) decido di vedere un pò cosa offre la rete per il DIY e .... trovo te !!!
    GRANDE !!! appena mi arriva lo strumento comincio un pò a vedere come va (p.s. sono già Arduino-dipendente da tempo ... (:-))

    Quindi GRAZIE ancora e .. last but not least, sono a Torino anch'io e ...lavoro nell'Istituto che misura ... e se sei un torinese docg non devo neanche dirti il suo nome ... (;-) = se vuoi passare dai ns. uffici/laboratori sarai ben accetto (a patto che tu non sia già nel ns. hinterland !!!)

    ReplyDelete
  17. FS, thank you for your interest.
    ...scrivimi su emanuele_girlando@yahoo.com così ti posso rispondere personalmente.
    Emanuele.

    ReplyDelete
  18. Hi, Very interesting project!
    Can I send SCPI commands using this implementation?
    I'm sure I'm missing something simple. I do understand how to read line but I'm unsure how to actually write the command..

    ReplyDelete
    Replies
    1. To send commands to instruments just type them in your terminal (or IDE serial) following the instrument syntax. That's all.
      Good luck.
      Emanuele.

      Delete
    2. Great, Thanks! So.. assuming I have a device on address 18, I should:
      1. Upload the Arduino firmeware.
      2. Open a serial monitor.
      3. Set the address with command "++adder [18]"
      4. Send the SCPI command "*IDN?"
      5. Send "++read"
      6. Happily see my device answer?

      Will try that out tomorrow
      Thanks!


      Delete
    3. YES Sir!
      But see also the ++auto section of the documentation.
      Ciao

      Delete
    4. Thanks!
      Wired it all up - so far it seems to be working fine from Arduino console. Trying not to push the unbuffered interface - I'm able to control 2 units simultaneusly. SCPI commands work as expected.
      From what I noticed - I'm having trouble accessing the serial port from putty/Mobaxterm. The command line seems to be unresponsive.
      I'll try writing a python wrapper and report.

      Delete
  19. Grat job mate!
    I wrote a very simple python3 object to abstract the device initialization (print version string, verbose-on), and also the operations "++addr", "++read", "++read eoi" and generic "write text". I prefer to avoid the implicit auto-mode. So far seems to work properly.

    I might add some series resistors (100-470 Ohm) on the I/O lines to limit the max current through them, but if you're only driving one device it prob. don't matter much.
    Cheers!

    ReplyDelete
  20. Thanks for your great job, Emanuele. To work with KE5FX GPIB Configurator it´s nessesary to connect CTS on GND and open DTR. Remove the 100n capacitor to reset on the ARDUINO board. With this mods the GPIB Configurator can find the GPIB interface (but it´s no more able to reprogram the board, use jumper) This works with FTDI FT232, also with CH340!
    But now there is the next problem. With my HP8595E the HP7470A Plotter Emulator shows an empty grid with some parameters like RES BW, VBW, SWP but no beam, no date, no time. 1006 bytes received from instrument. Any idea?

    ReplyDelete
  21. Great Job Emanuele!!!

    I added some functionality to your code to handle SRQ and to measure temperature with a LM35 sensor.

    //jxl - append to pin defines
    #define SRQ 2 /* GPIB 10 : Service Request - Arduino PORTD bit 2 */
    #define LM35 A7 /* LM35 temp sensor - Arduino A7 */

    ...

    // jxl - append to controller state variables
    boolean srqmode = false;
    volatile int8_t srqflag = 0;

    ...

    //jxl - insert in setup()
    analogReference (INTERNAL); // 1.1V
    pinMode(SRQ, INPUT_PULLUP );

    ...

    // jxl - insert in do while loop in getUSBline() to check for SRQ interrupt
    if (srqflag)
    {
    if (verbose)
    {
    Serial.print ("SRQ "); Serial.println (srqflag);
    }
    else
    {
    Serial.println ("SRQ");
    }
    srqflag = 0;
    }

    ...
    // jxl - add to cmds[]
    { "temp", temp_h }, // jxl
    { "srq", srq_h }, // jxl
    { "srqmode", srqmode_h }, // jxl

    ...

    // jxl - append to command handlers
    // jxl
    void srq_h()
    {
    byte srq;

    if (LOW == digitalRead(SRQ))
    srq = 1;
    else
    srq = 0;

    Serial.println (srq, DEC);
    }
    void srq_handler ()
    {
    for (uint8_t i = 5; i > 0; i--)
    {
    if ((PIND & 0x04) == 0) srqflag += 1;
    }

    // there is a ~100ns glitch on the SRQ line during the databus transition - simultaneous switching noise ???
    if (srqflag < 2) srqflag = 0;
    }
    void srqmode_h()
    {
    char *param, *pend;
    int temp;

    if ( (param=strtok(NULL, " \t")) )
    {
    temp = strtol(param, &pend, 10);
    if (*pend != NULL)
    {
    if (verbose) Serial.println(F("Syntax error."));
    return;
    }
    if (temp < 0 || temp > 1)
    {
    if (verbose) Serial.println(F("srqmode: valid range is [0|1]."));
    return;
    }
    srqmode = temp ? true : false;
    if (srqmode)
    {
    attachInterrupt (0, srq_handler, FALLING);
    }
    else
    {
    detachInterrupt (0);
    }
    if (!verbose) return;
    }
    Serial.println(srqmode);
    }
    void temp_h()
    {
    uint32_t TempReading;
    float Temp;

    // let analog reference stabalize (needs >40 conversions to stabilize)
    for (uint8_t i = 0; i < 100; i++)
    {
    TempReading += analogRead(LM35);
    }
    TempReading = 0;
    for (uint16_t i = 0; i < 500; i++)
    {
    TempReading += analogRead(LM35);
    }
    Temp = (float) TempReading * 1.1 / 1024.0 / 5.0; // temperature in C

    Serial.println (Temp, 3);
    }

    ...

    With these changes as implemented using an Arduino Pro-mini the following features are added:
    ++srq : prints "1" if SRQ is active
    ++srqmode 1 : enables controller to print "SRQ" everytime SRQ goes active
    ++temp : prints temperature in Celsius


    -JXL

    ReplyDelete
  22. Thank you for kindly posting this project!
    Question: If I have 2 GPIB instruments to read, do I have to build 2 UNO converters or can one handle both instruments, somehow?
    JH

    ReplyDelete
  23. The solution doesn't include GPIB line drivers. So, thus the GPIB is a BUS logically designed to connect multiple devices, in this solution the direct connections to Arduino's I/O pins to the BUS can lead to electrical overhead to the Arduino should multiple devices being connected. So I recommend using it as a point to point solution (Arduino<->instrument).
    Said that the first comment to this article - dated December 29, 2014 at 2:48 AM - states one guy has been successful in connecting three GPIB devices. If you want give it a try that's is all at your risk! I personally haven't tried that, but in case of need I would......

    ReplyDelete
  24. I am not able to download the .ino file. The .hex file downloads though not the .ino file. Any ideas? I'd like to try with the latest version and use the old code as reference to compare if needed to upgrade the coding for more functionality if needed before I donate though will donate if works since this looks like the most cost effective option I've found and I do have like you a Arduino Uno lying around not ever used. If you prefer I donate first, I can do that also. Please advise. Thanks in advance for your time.

    ReplyDelete
  25. Sorry. Drobox link changed I don't know why...
    It has been fixed now and should work.
    Emanuele.

    ReplyDelete
  26. Hello, Is this possible to use it as a GPIB emulator/virtual device to test the programs?
    We are trying to develop a VNA-GPIB interfCING program and we need to emulate the GPIB to test the program which is far from the instrument.
    Thanks.

    ReplyDelete
    Replies
    1. well...,
      you have the source code. It should be possible to tweak the high level reading and writing GPIB routines (gpibTalk() and gpibReceive()) to return some value without actually interact with the BUS..

      Delete
  27. I cannot access the source *.ino file :-(

    Is it available in a zip file (or some other archive) ??

    ReplyDelete
  28. I've just successfully downloaded it...
    dx click -> save link as..

    ReplyDelete
  29. in your source pin 8 and 9 are exchanged in comment:
    #define NDAC 9 /* GPIB 8 : Not Data Accepted - Arduino PORTB bit 0 */
    #define IFC 8 /* GPIB 9 : Interface Clear - Arduino PORTB bit 1 */

    ReplyDelete
  30. I don't think so...
    ARDUINO digital pin 9 (named NDAC in the program) has to be connected to GPIB pin 8 namely No Data ACcepted.
    ARDUINO digital pin 8 (named IFC in the program) has to be connected to GPIB pin 9 namely Interface Clear.

    ReplyDelete
  31. Dear Emanuele, I wanted to congratulate you on a great job!!
    Perhaps you can point me in the right direction with this: I have a HP 34401A which is capable of 1000 readings per second through the GPIB but I'm lucky if I get 1 reading every second... do you know how I can improve this? Grazie!

    ReplyDelete
  32. Dear Emanuele, first of all, great job!
    I'm writing you because I have a HP 34401A which should do 1000 reagings per second (allegedly :P) but I hardly obtain more than 1 per second... do you know what could be the reason? Will it make a difference if I change the DigitalWrite with direct port manipulation? Grazie!

    ReplyDelete
  33. I don't really think it is the arduino slowing down your data exchange.. The time it takes for the Arduino to "++read" is orders of magnitude lower than 1 second!
    I would check the control lines to see what is going on.

    ReplyDelete
  34. I am interested in creating a shield for this.
    Is there enough user interest to make it worth my while?

    ReplyDelete
  35. Have a look at the Pageviews counter..

    ReplyDelete
  36. Its Nice to see you are still helping us to learn how to use this development. I am trying to communicate with a FLUKE 8508A. (Sorry my bad English).

    ReplyDelete
  37. Emanuele,

    Great software! This is the lowest cost GPIB adapter that I've found. Much less expensive than my Prologix adapter.

    I provide some open source instrument control software designed to work with a Prologix adapter.

    https://mesterhome.com/gpibsw/index.html

    Users of your Arduino based GPIB adapter are having problems connecting to instruments using my software. I built a copy of your Arduino adapter so that I could test it and compare it to my Prologix adapter.

    I found a few differences from your Arduino adapter and my Prologix adapter.

    First, my program sends sequences of instrument commands followed by Prologix commands. A typical sequence is "S++read eoi". My Prologix adapter had no problems with this. Your Arduino adapter would miss the ++read eoi command. I found that a time delay between instrument data and prologix commands would correct the problem.

    After looking at your code, I saw "flush_serial();" in line 168. I found that this code is what was causing the lost data. I changed line 168 to: "if (verbose) flush_serial();". This corrected the problem without adding a time delay to my code. I assume that "flush_serial();" is only needed for Verbose mode.

    Next, I was having problems with extra text being returned by your Arduino adapter when escaped binary characters were sent or . It appears that some debug code was left active in line 230. "if (isesc) { Serial.println("CR or LF inserted");goto loadchar; }". I disabled this and enabled line 229 "if (isesc) goto loadchar; ". This corrected the extra text problem.

    After these changes to your code, my software now runs correctly with my Prologix adapter and with your Arduino adapter.

    ReplyDelete
  38. Luke,
    thank you very much for you post.
    I fully agree with your points and I have already modified the software on this blog.
    I have not introduced a new version for those minor changes: it still is 6.1.
    Thank you very much.
    Emanuele.

    ReplyDelete
  39. Hi everyone,
    I've made this interface and it works well with HP 34401A multimeter... unfortunately something is not good with HP6632A PSU, I can send command to PSU and it react to it, but I can't receive anything from PSU, on "++verbose" mode interface write "gpibRead: timeout waiting DAV".
    I've try this PSU with other GPIB interface (Agilent E5810A) and communication works fine on both side.
    Anyone can help?
    Regards
    socha6

    ReplyDelete
  40. Hi Emanuele,

    Thank you for your great work.
    I designed a board for this as I don't want to use an arduino board:
    https://pakahuszar.blogspot.com/2019/04/gp-ib.html
    https://pakahuszar.blogspot.com/2019/04/gp-ib-2.html
    Can you please tell me, how can I further develop and share the source code of the device?
    Thank you,
    Zoltan

    ReplyDelete
  41. Thanks so much for your project. I am interfacing it with a Fluke 8505A multimeter. I also intend to add an RS232 Shield to the Arduino on a MEGA 2560 connected to serial port 3 for communication with a DOS computer.

    My question is: you refer several times in you documentation to "the de-facto standard". Exactly what standard is that, please?

    Thank you

    ReplyDelete
  42. Is there anyway to show that to any software that I have a real GPIB adaptor Arduino gives a (in device manager) com port, software looks for a GPIB device need a virtual GPIB device to COM port converter, help! like virtual network card and sound cards etc a virtual GPIB adaptor to fool the software and forward data to Arduino com port

    ReplyDelete