Configuration¶
Configuration of the AR488 is achieved be editing the AR488_Config.h file. This is a C++ style header file containing various definition statements, also known as ‘define macros’ , starting with keyword #define, that can be used to configure the firmware. The AR488_config.h file must be included in the main AR488 sketch as well as any other module header file (e.g. AR488_Layouts.cpp and AR488_Layouts.h) with an include statement:
#include "AR488_Config.h
A number of these definition statements are contained within an #ifdef .. #endif
construct, some of which may contain additional #else or #elif elements. The presence of
these constructs is necessary and they should not be changed or removed. Only the
definitions within them should be changed as required. Nothing should need to be changed
in any other file.
Firmware version¶
This is in the format:
#define FWVER "AR488 GPIB controller, ver. 0.48.08, 27/01/2020"
This entry should not exceed 47 characters and should not be changed.
Board Selection and serial port configuration¶
The AR488 supports a number of Arduino AVR boards and also a custom GPIO pin layout
which can be defined by the user in the Custom Board Layout section. If a custom GPIO
pin layout is to be used, then following entry must have the comment characters
(preceding //
) removed:
//#define AR488_CUSTOM
Otherwise, the comment characters should remain in place which has the effect of
disabling the definition by designating it as a comment. The compiler ignores comment
statements. Following this is an #ifdef
statement containing several sections
preceded by an #elif
keyword. Each of these is followed by a token that corresponds
to known Arduino definitions for microprocessor types. The structure looks like this:
/*
* Configure the appropriate board/layout section
* below as required
*/
#ifdef AR488_CUSTOM
...
#elif __AVR_Atmega328P__
...
#elif __AVR_Atmega32U4__
...
#elif __AVR_Atmega2560__
...
#endif // Board/layout selection
When the custom layout is selected, all other layouts are ignored. If the custom layout
is not selected, then the section corresponding to the automatically detected Arduino
microprocessor will apply. Each section contains a definition referencing one or more
pre-defined board layouts as well as serial port definitions corresponding to the
features of specific boards. For example here are the definitions for boards based on
the 328p microcontroller which are found within the __AVR_Atmega328P__
section of
the #ifdef
statement:
/* Board/layout selection */
#define AR488_UNO
//#define AR488_NANO
/*** Serial ports ***/
//Select HardwareSerial or SoftwareSerial (default = HardwareSerial) ***/
// The UNO/NANO default hardware port is 'Serial'
// (Comment out #define AR_HW_SERIAL if using SoftwareSerial)
#define AR_HW_SERIAL
#ifdef AR_HW_SERIAL
#define AR_SERIAL_PORT Serial
#else
// Select software serial port
#define AR_SW_SERIAL
#endif
The section contains definitions for two boards, namely the Uno and the Nano. Only ONE of these should be selected by removing the preceding comment characters:
#define AR488_UNO
//#define AR488_NANO
The default entry is AR488_UNO
, which selects the pre-defined template for the
Arduino UNO board in AR488_Hardware.h
. Selecting AR488_NANO
will select the
pre-defined template for the Nano board. In order to compile the sketch for the selected
board, in addition to selecting the template in Config.h
, the correct board must be
selected in the Board Manager within the Arduino IDE (see the Tools | Board:
menu).
Following this are definitions for the serial port:
#define AR_HW_SERIAL
#ifdef AR_HW_SERIAL
#define AR_SERIAL_PORT Serial
#else
// Select software serial port
#define AR_SW_SERIAL
#endif
By default, the most commonly used serial port for a particular board will be enabled.
In the example above, the hardware port named Serial is selected. To switch between the
default hardware port and a SoftwareSerial port, it is necessary only to comment out
#define AR_HW_SERIAL
by preceding the line with //
.
The section for the 32u4 (Micro/Leonardo) is similar, except by default
AR_CDC_SERIAL
is enabled and switching is between the USB CDC
port and the
hardware port Serial1
.
The Mega 2560 has 4 hardware serial ports so either Serial
, Serial1
, Serial2
or Serial3
must be selected. Most likely the default port named Serial will be used
although other options are possible if required. However, please note that the default
GPIO pin layout for the Mega 2560 board (AR488_MEGA2560_D
) uses the pins assigned to
Serial2
for other purposes, so this cannot be used as a serial port with that
particular layout definition. However, it can be used with the E1 and E2 definitions.
For any board, adding the line #define AR_SW_SERIAL
and commenting out the
AR_HW_SERIAL
and/or AR_CDC_SERIAL
definitions will invoke the SoftwareSerial library. When a SoftwareSerial
port is required, then the GPIO pins as well as the baud rate to be used will need to be
configured in the following Software Serial port configuration section.
Where a board has more than one hardware or CDC serial port available, it will be
necessary to correctly specify the Arduino name of the serial port to be used. For the
Uno and Nano this will always be Serial
because those boards have only one UART and
therefore only one hardware serial port. Other boards have more than one serial port
available. For example, on the Pro Micro , enabling the hardware port rather than the
CDC port will automatically select Serial1
instead of Serial
. For the Mega 2560
there are four choices and the correct port name must be chosen by uncommenting the
appropriate line, e.g:
#define AR_SERIAL_PORT Serial1
The remaining choices must be commented out by preceding them with //
.
It should be noted that for any board, only ONE serial port can be used and therefore only one port should be enabled.
It is important to make sure that the correct board is selected in the Arduino IDE Boards Manager (Tools => Board) otherwise the sketch will not compile correctly.
Software Serial port configuration¶
The SoftwareSerial library can be used with any board provided that at least two pins
are available. One of these must be a PWM
enabled GPIO pin which is required to
emulate the transmit (Tx
) output for the serial two wire connection. The receive
(Rx
) pin can be assigned any available GPIO pin.
Enabling SoftwareSerial can be done by removing the comment characters (//
)
preceding the #define AR_SW_SERIAL
entry in the relevant board selection section. In
addition, the pins to be used as well as the board rate will need to be configured in
the Software Serial Support section as follows:
#ifdef AR_SW_SERIAL
#define AR_SW_SERIAL_RX 53
#define AR_SW_SERIAL_TX 51
#define AR_SERIAL_BAUD 57600
#else
#define AR_SERIAL_BAUD 115200
#endif
The appropriate GPIO pin numbers should be specified after the #define
AR_SW_SERIAL_RX
and the #define AR_SW_SERIAL_TX
statements within the #ifdef
AR_SW_SERIAL
clause. The baud rate should be specified here as well after #define
AR_SERIAL_BAUD
. Please note that, when using SoftwareSerial, the maximum baud rate
that can be achieved reliably is 57600 baud.
The hardware/CDC serial port baud rate is specified after the #else
statement. The
default hardware baud rate is 115200, but any valid baud rate can be specified.
Please note also, that when using USB CDC ports, the Arduino board will NOT be reset when a serial connection is made over USB as is the case with Uno and Nano boards. The reset button must be pressed in order to reset the board. The Arduino IDE seems to take care of programming the board automatically but when using the Arduino IDE on Linux, the modemmanager service will need to be disabled as it interferes with serial ports and disrupts the normal operation of the programming process, causing boards to end up in a state where they can no longer be programmed over USB. Boards that have been disabled in this way can be recovered by uploading a bootloader to them using an AVR programmer.
Linux Mint (and probably Ubuntu) will have this service enabled and running in the background by default. This service is not required but may be useful in the event that a serial modem is connected to the PC.
Serial Interrupt Handling¶
All AVR boards support serialEvent.
This was used in previous versions of AR488 but its use is now deprecated. The Arduino
has no hardware interrupt to signal a character being received into the Arduino serial
buffer. The serialEvent function is actually aliased to the serial.available()
function and is executed at the end of every iteration of void loop()
. Non-Arduino
boards (e.g. STM32) may not support serialEvent so for reasons of consistency between
different boards, serialEvent is not used. Instead, a serial event handler is called
at the end of every loop iteration.
When working with programs and scripts (e.g. Python), it should be bourne in mind that the Arduino is only 64 bytes in size. Due to the memory constraints of the Arduino, the additional processing buffer provided by the AR488 program is also limited to only 128 bytes. There is also no handshaking between the PC and the Arduino serial port. Although the Arduino can keep up pretty well, the serial input buffer can easily overflow with loss of characters if data is passed too quickly. This means that a bit of trial and error may be required when working with scripts to establish whether and how much delay is required between commands. A short delay may sometimes be needed to avoid a buffer overflow. The amount of delay will depend on factors such as the interface hardware being used, the time taken for the instrument to respond, as well as the GPIB speed of the instrument being addressed.
Detection of SRQ and ATN pin states¶
Arduino AVR boards support interrupts to detect a change in pin states and this has been
implemented for the UNO, NANO and MEGA boards to improve response. When a supported
board template has been selected, (see the Board Selection and serial port
configuration section) and AR488_CUSTOM
is not in use, then USE_INTERRUPTS
will be defined and certain interrupts activated by default.
Other boards may not support interrupts and interrupts cannot be used with the custom
GPIO pin layout. When AR488_CUSTOM
is defined and in used, USE_INTERRUPTS
will
not get defined and interrupts are not activated. Instead, pin states are detected
during each iteration of the void loop()
function. When a non-AVR or unsupported
board is selected as the compilation target, then USE_INTERRUPTS
should be commented
out and not used.
The section in AR488_Config.h looks as follows:
#ifdef __AVR__
// For supported boards use interrupt handlers
#if defined (AR488_UNO) || defined (AR488_NANO) || defined (AR488_MEGA2560) || defined (AR488_MEGA32U4)
#ifndef AR488_CUSTOM
#define USE_INTERRUPTS
#endif
#endif
#endif
The entry should be preceded by //
to indicate that it has been commented out.
Interrupts are used by default on supported boards because they usually respond faster
than in-loop checking.
Macro support¶
Macros in this context are short sequences of commands that can be used to accomplish a particular task. Controlling an instrument usually requires sequences of commands to be sent to the device to configure it, or to perform a particular task. Sometimes such sequences are performed frequently or repetitively. In those circumstances, it may be more efficient to pre- program the required sequence and then execute it when required using a single command.
The AR488 supports a macro feature which allows user programmed command sequences to be run when the interface starts up, as well as up to 9 user defined command sequences to be executed at runtime.
Macros must be programmed before the sketch is compiled and uploaded to the interface.
Macros can be added to the designated AR488 MACROS SECTION
in the AR488_Config.h
file. Both interface ++
commands and direct instrument commands can be included in
macros. Programming specific instruments is beyond the scope of this manual as commands
will be specific to each instrument or implemented according to the manufacturers choice
of programming language or protocol. However, in general, in order to create macros, a
few simple rules will need to be followed.
Firstly, macros need to be enabled. In the AR488_Config.h
file there are two
definitions under the heading “Enable Macros”:
#define USE_MACROS // Enable the macro feature
#define RUN_STARTUP // Run MACRO_0 (the startup macro)
The #define USE_MACROS
construct enables or disables the macro feature. When this line
is commented out by preceding it with //
then macros are disabled. Removing the
preceding //
will enable the macro feature.
The #define RUN_STARTUP
statement controls whether the start-up macro will run when
the interface is powered up or re-started. The start-up macro is designated MACRO_0
and if #define RUN_STARTUP
is enabled, this macro will run when the interface is
powered on or reset.
When #define USE_MACROS
is disabled, then the start-up macro will not be activated
when the interface is powered up or reset and none of the user macros (1-9) will be
available at runtime.
When enabled, MACRO_0
will run when the interface is powered up or reset but only if
#define RUN_STARTUP
is also enabled. The user macros (1-9) will always be available
and can be executed by the user at runtime by using the ++macro
command. For more
information please see the ++macro
command heading in the Command Reference.
The start-up macro can be used in addition to the interface settings that can be saved
using the ++savecfg
command, to not only to set up the interface, but also to
initialise and configure the instrument for a specific function. In this way, instrument
commands that select function, range and other control features can be sent
automatically as the interface starts up.
Unless steps have been taken to disable the automatic reset that occurs when a USB serial connection is opened to the interface, the start-up macro will run every time that a serial connection is initiated to the interface. On the other hand, disabling reset prevents the Arduino from being programmed via USB, so is not advised unless the intention is to program the Arduino using a suitable AVR programmer.
In the AR488_Config.h
file, sketch, below the help information there is a section
that starts:
/********************************/
/***** AR488 MACROS SECTION *****/
/***** vvvvvvvvvvvvvvvvvvvv *****/
#ifdef USE_MACROS
Macros are defined here. The first macro is the startup macro, an example of which might be defined as follows:
#define MACRO_0 "\
++addr 9\n\
++auto 2\n\
*RST\n\
:func 'volt:ac'
"
/* End of MACRO_0 (Startup macro)*/
All macro commands comprising the macro must be placed after the \
on the first line
and before the final quote on the line before the ending comment. Nothing outside of
these lines, including the quote marks and the \
and after the macro name should be
modified. The final quote mark can be appended to the last command in the sequence if
preferred. It is shown here on a separate line for clarity. Everything between the two
quote marks is a string of characters and must be delimited. The \
character
indicate to the pre-processor that the string continues on the next line.
Each command ends with \n
which is the newline terminator and serves to delimit each
command. The actual sequence shown above is therefore comprised of 4 commands, each
command ending with \n
and then a \
to indicate that the next command is to
follow on the next line. Try to avoid leaving or including any unnecessary spaces.
Each of these commands is either a standard AR488 interface command found in the command
reference, or an instrument specific command. All AR488 interface Prologix style
commands begin with ++
so the first two commands set the GPIB address
to 7 and
auto
to 1. The next two commands are direct instrument commands using the SCPI
protocol, the first of which resets the instrument and the second selects the instrument
AC voltage function.
As shown, each command must be terminated with a \n
(newline) or \r
(carriage
return) delimiter character.
User defined macros that can be run using the ++macro
command follow next, and have
a similar format, e.g:
#define MACRO_2 "\
"
/*<-End of macro 2*/
Once again, the required command sequence must be placed between the two quotes and
after the first /
and be terminated with a \n
or \r
delimiter. Each line
must be wrapped with \
.
There is a slightly shorter method of defining a macro by placing all commands on a single line. For example this:
#define MACRO_1 "++addr 7\n++auto 1\n*RST\n:func 'volt:ac'"
Is exactly the same as this:
#define MACRO_1 "\
++addr 7\n\
++auto 1\n\
*RST\n\
:func 'volt:ac'\
"
The first definition is more condensed and requires no line wrap characters, but it is perhaps easier to see what is going on in the latter example. Either will function just the same and take up the same amount of memory.
The macro definition area provided in the sketch ends with:
#endif
/***** ^^^^^^^^^^^^^^^^^^^^ *****/
/***** AR488 MACROS SECTION *****/
/********************************/
Anything outside of this section does not relate to macros.
Provided that the commands have been specified correctly and the syntax is correct, the sketch should compile and can be uploaded to the Arduino. The start-up macro will run as soon as the upload is completed so the instrument should respond immediately. Please be aware that, unless serial reset has been disabled, it will run again when a USB serial connection is made to the interface. The instrument will probably respond and reconfigure itself again.
Please note that, although AR488 interface ++
commands are verified by the
interface, and will respond accordingly, there is no sanity checking by the interface of
any direct instrument commands. These command sequences are sent directly to the
instrument, which should respond as though the command sequence were typed directly into
the terminal or sent from a suitable instrument control program. Please consult the
instrument user manual for information about the behaviour expected in response to
instrument commands.
Macro sequences can include any number delimiter separated of commands, but any individual command sequence should not exceed 126 characters. This may be particularly relevant to SCPI commands which can be composed of multiple instructions separated by colons.
SN7516x GPIB transceiver support¶
Support for the SN75160 and SN75161 GPIB transceiver integrated circuits can be enabled by uncommenting the following line:
//#define SN7516X
The pins used to control the ICs are defined in the section that follows:
#ifdef SN7516X
#define SN7516X_TE 6
// #define SN75161_DC 13
#endif
Specify the pin to be used for the SN7516X_TE
signal. The above example shows pin 6
being used and this is connected to the talk-enable (TE
) pin on both ICs. The
SN75161
handles the GPIB control signals and in addition to the TE
pin, also has
a direction-control (DC
) pin. This is used to determine controller or device mode
operation. A GPIO pin can be assigned to drive this pin, in which case the
SN75151_DC
definition shown above should be uncommented and an appropriate GPIO pin
number assigned.
Alternatively, since the REN
signal is asserted in controller mode and un-asserted
in device mode, this signal can be used to drive the DC
pin of the SN75161
. In
this case, the SN75161_DC
definition should remain commented out and the GPIO pin
assigned to the REN signal should be connected to both DC
and REN
on the
SN75161
IC. There is one small caveat when using this configuration. The custom
++ren
command, which is used to turn the REN
line on and off, cannot be used and
will just return:
Unavailable.
If a separate GPIO pin is used to control DC then the ++REN command will return the
status of REN
as usual. (See ++ren
in the Custom Commands section of the
`Command Reference`_).
Bluetooth HC05 module Options¶
This section is used to configure Bluetooth HC05 module options and looks like the below:
//#define AR_BT_EN 12 // Bluetooth enable and control pin
#ifdef AR_BT_EN
#define AR_BT_BAUD 115200 // Bluetooth module preferred baud rate
#define AR_BT_NAME "AR488-BT" // Bluetooth device name
#define AR_BT_CODE "488488" // Bluetooth pairing code
#endif
To enable Bluetooth HC05 module auto-configuration, the first line needs to have the
preceding comment characters (//
) removed and a GPIO pin assigned. It is then
necessary to set the configuration parameters, including baud rate, the name that the
device will be identified with and the pairing code. The AR_BT_BAUD
parameter must
not have double quotes around it.
By default, the name is AR488-BT
and the pairing code is 488488
. The HC05 module
only needs connecting to the RX/TX
pins of a serial port and it will be
automatically configured with these parameters on interface start-up.
This feature cannot work with the HC06 module as it does not have management mode or an enable pin implemented. Full details of Bluetooth configuration and wiring are included in the separate AR488 Bluetooth Support supplement.
Debug options¶
The AR488 can send certain debug messages to a serial port which can be helpful when
trying to diagnose a problem. These should not be required or enabled for normal running
of the interface, but if required for debugging, one or more of the following can be
enabled by removing the preceding //
comment characters:
//#define DEBUG1 // getCmd
//#define DEBUG2 // setGpibControls
//#define DEBUG3 // gpibSendData
//#define DEBUG4 // spoll_h
//#define DEBUG5 // attnRequired
//#define DEBUG6 // EEPROM
//#define DEBUG7 // gpibReceiveData
//#define DEBUG8 // ppoll_h
//#define DEBUG9 // bluetooth
By default, debug messages will be sent to the serial port that is used for communication. Where the interface provides additional serial ports or where there are sufficient GPIO pins available to use SoftwareSerial, it is possible to send debug messages to an alternative serial port. This has the advantage that debug messages will no longer interfere with normal interface communications.
The debug messages can be viewed on the alternative debug
port while normal
interface operations are in progress on the communications port.
To enable this feature uncomment the following line in the Debug Options
section in
AR488_Config.h
:
//#define DB_SERIAL_PORT Serial1
Set the serial port to the port that will receive the debug messages. Configure the baud rate, set the serial port type, and if using SoftwareSerial, the GPIO pins to be used, for example:
#define DB_SERIAL_BAUD 57600
#define DB_SW_SERIAL
#ifdef DB_SW_SERIAL
#define DB_SW_SERIAL_RX 53
#define DB_SW_SERIAL_TX 51
#endif
The above will configure a SoftwareSerial port at 57600 baud on GPIO pins 53 and 51. Please note that the maximum advisable speed for a SoftwareSerial port is 57600 baud.
Debug messages do not include messages shown when verbose mode is enabled with the
++verbose
command. When the interface is being directly controlled by another
program, verbose mode should be turned off otherwise verbose messages may interfere with
normal operations.
Custom Board Layout Section¶
The custom board layout section in the Config.h file can be used to create a custom pin layout for the AR488. This can be helpful for non-Arduino boards and where an adjustment to the layout is required in order to accommodate additional hardware. By default, the definition implements the Uno layout:
#define DIO1 A0 /* GPIB 1 */
#define DIO2 A1 /* GPIB 2 */
#define DIO3 A2 /* GPIB 3 */
#define DIO4 A3 /* GPIB 4 */
#define DIO5 A4 /* GPIB 13 */
#define DIO6 A5 /* GPIB 14 */
#define DIO7 4 /* GPIB 15 */
#define DIO8 5 /* GPIB 16 */
#define IFC 8 /* GPIB 9 */
#define NDAC 9 /* GPIB 8 */
#define NRFD 10 /* GPIB 7 */
#define DAV 11 /* GPIB 6 */
#define EOI 12 /* GPIB 5 */
#define SRQ 2 /* GPIB 10 */
#define REN 3 /* GPIB 17 */
#define ATN 7 /* GPIB 11 */
To make use of a custom layout, AR488_CUSTOM
must be selected from the list of
boards at the beginning of the Config.h
file and the pin numbers/designations in the
centre column (shown in bold) should be configured as required.
Please note that on some MCU boards, a number of GPIO pins may not be available as inputs and/ or outputs despite a pad or connector being present. Please check the board documentation. Sometimes such information is revealed only in online forum discussions or blogs.
When AR488_CUSTOM
is defined, interrupts cannot be used to detect pin states and
therefore USE_INTERRUPTS
will not be defined and interrupts will not be activated.
Pin states will be checked on every iteration of void loop()
instead.