logo: Troi Serial Plug-in for FileMaker

Troi Serial Plug-in 5.5
for FileMaker Pro 17
USER GUIDE

August 2018







logo: Troi Plug-ins for FileMaker

Troi
Boliviastraat 11
2408 MX Alphen aan den Rijn
The Netherlands

You can visit the Troi web site at: www.troi.com

Troi Serial Plug-in is copyright 1998-2018 of Troi Automatisering. All rights reserved.








Table of Contents


Installing plug-ins

Starting with FileMaker Pro 12 a plug-in can be installed directly from a container field. Installation is therefore very easy: just open the "All Serial Examples.fmp12" example file and the startup script will install the plug-in for you. See also the EasyInstallTroiPlugins.fmp12 example file which contains the actual plug-in and install script.

TIP You can check which plug-ins you have loaded by going to the plug-in preferences: choose Preferences from the Edit menu, and then choose Plug-ins.

You can now open the file "All Serial Examples.fmp12" to see how to use the plug-in's functions. There is also a function and script step reference available.


If you have problems

This user guide tries to give you all the information necessary to use this plug-in. So if you have a problem please read this user guide first. You can also visit our support web page:

            www.troi.com/support

This page contains FAQ's (Frequently Asked Questions), help on registration and much more. If that doesn't help you can get free support by email. Send your questions to support@troi.com with a full explanation of the problem. Also give as much relevant information (version of the plug-in, which platform, version of the operating system, version of FileMaker Pro) as possible. Note that due to spam we have to filter incoming email. It might happen that non-spam email is filtered out too. If you have sent an email and you don't get an answer, try to send another email, slightly differently formulated and include the word "FileMaker" in the body text.

If you find any mistakes in this manual or have a suggestion please let us know. We appreciate your feedback!

TIP You can get more information on returned error codes from the OSErrrs database on our web site. This free FileMaker database lists all error codes for Windows and macOS!


What can this plug-in do?

Troi Serial Plug-in adds serial functions to FileMaker Pro. With this plug-in you can read and write to any serial port that is available on your computer.

NOTE: USB ports are not supported. USB is a bus protocol that can be used from various purposes and devices, like keyboards, hard disks, CD-ROM drives, adaptors, cameras. All these devices need specific drivers. We have currently no plans to create a USB plug-in. Note however that Troi Serial Plug-in is reported to be working with the USB to Serial adapters.


Software requirements

System requirements for macOS

Mac OS X 10.8 (Mountain Lion), OS X 10.9 (Mavericks), OS X 10.10 (Yosemite), OS X 10.11 (El Capitan), macOS Sierra (OS X 10.12), macOS High Sierra (OS X 10.13).

NOTE Troi Serial Plug-in 5.5 will probably run on Mac OS X 10.7 (Lion), but we have not tested this and no longer provide support for this.

System requirements for Windows

Windows 8, Windows 8.1
Windows 10, including Creators Update and Fall Creators Update

FileMaker Pro requirements

FileMaker Pro 13 or FileMaker Pro Advanced 13.
FileMaker Pro 14 or FileMaker Pro Advanced 14.
FileMaker Pro 15 or FileMaker Pro Advanced 15.
FileMaker Pro 16 or FileMaker Pro Advanced 16.
FileMaker Pro Advanced 17.

FileMaker Server requirements

FileMaker Server 13 or FileMaker Server Advanced 13.
FileMaker Server 14 or FileMaker Server Advanced 14
FileMaker Server 15 or FileMaker Server Advanced 15.
FileMaker Server 16 or FileMaker Server Advanced 16.
FileMaker Server 17 or FileMaker Server Advanced 17.

You can use FileMaker Server to serve databases that use functions of Troi Serial Plug-in (client-side): you need to have the plug-in installed at the clients that use these functions.

Troi Serial Plug-in can also be used by FileMaker Server as a server-side plug-in or as a plug-in used by the web publishing engine. More information can be found in the download or on our web site.


Getting started

Using external functions

Troi Serial Plug-in adds new functions to the standard functions that are available in FileMaker Pro. The functions added by a plug-in are called external functions. You can see those extra functions for all plug-ins at the top right of the Specify Calculation box:

External functions in Specify Calculation box

You use special syntax with external functions: FunctionName ( parameter1 ; parameter 2 ) where FunctionName is the name of an external function. A function can have zero or more parameters. Each parameter is separated by a semi-colon. Plug-ins don't work directly after installation. To access a plug-in's function, you need to add the calls to the function in a calculation, for example in a text calculation in Define Fields or in a script in Script Workspace (formaly called ScriptMaker).

Where to add the external functions?

Most of the external functions for this plug-in are intended to be used in a Set Field or Set Variable script step using a calculation. For most functions of this plug-in it makes no sense to add them to a define field calculation, as the functions will have side effects. Only the Serial_AsciiValueToText and Serial_TextToAsciiValue functions have no side effects and can be used in a define field calculation.

Using script steps

Starting with FileMaker 16 plug-ins can also add script steps. You can select these script steps in the script steps pane in Script Workspace, or you can begin typing the script step name, then choose the script step from the list that appears. The script steps significantly expand the possible actions you can perform with FileMaker Pro.

Script steps in the script steps in Script Workspace screenshot of Troi File Plug-in script step

NOTE only steps that perform an action have been added as a script step. Functions that just return information (like for example Serial_GetPortNames) are only available as an external function.

Simple example

We start with a simple example to get you started. Create a new database, with a global text field called gPortNames. Create a new script called "Get Serial Port Names". Delete all steps and then add the following script step:

  Set Field [ gPortNames ; Serial_GetPortNames ( "-Unused" ) ]

This shows the call to the Serial_GetPortNames function. This function has only one parameter, switches, which is currently not used, so "-Unused" is given as value. Performing this script will return all the serial ports that can be found on this computer, separated by returns. On Windows the result will be something like this:
  COM1¶
  COM2¶
  COM3¶
  COM4¶

NOTE Function names, like Serial_GetPortNames, are not case sensitive.

Please take a close look at the included example files, as they provide a great starting point. From there you can move on, using the functions of the plug-in as building blocks. Together they give you great new tools to access serial ports.

You can use globals or variables

With the release of FileMaker Pro 8 and later it is possible to use variables in calculations. Our example files in the download now both use global fields and variables to pass parameters and store the results of a plug-in function.

As this release of Troi Serial is intended for FileMaker Pro 13 and higher, we continue to move the scripts to use variables wherever possible. Note that not all examples are using variables yet.

All plug-in functions work with variables just fine. For example if you have this script steps

  Set Field [ gErrorCode ; Serial_Open ( "-Unused" ; "port1" ) ]

With variables you can alternative use:

  Set Variable [ $ErrorCode ; Serial_Open ( "-Unused" ; "port1" ) ]

The main advantage of variables is that you don't need to define global fields that clutter your database definitions. The variables can stay local to the script.


Steps for working with Troi Serial Plug-in

Below you find an overview of the main steps needed to communicate with a serial port:

1 - Find available ports

Use the function "Serial_GetPortNames" to get the names of all serial ports that are available on the computer and let the end user choose a port.

2 - Open the selected port

Use the function "Serial_Open" to open a port. Optionally use the function "Serial_SetDispatchScript" to specify which script is triggered when data comes in from the serial port.

3 - Communicate with the serial port

Use the functions "Serial_Send" and "Serial_Receive" to send and receive data to and from a serial port. You can use other functions, like "Serial_DataWasReceived", to help you get the data into a FileMaker database.

4 - Close the serial port

At the end of the communication you need to close the serial port.


Specifying the port settings

Default port settings

A serial port can be configured in a lot of ways. These settings can be set by specifying the settings parameter of Serial_Open. If you don't specify any settings the port is initialized to the following settings: a speed of 9600 baud, no parity, 8 data bits, 1 stop bit, no handshaking. If you want to use this setting, open the port like this:

  Set Field [ gErrorCode ; Serial_Open ( "-Unused" ; "COM2" ) ]


Specifying other port settings

It is recommended that you set the port settings explicitly. Give the settings by concatenating the desired settings keywords. You specify them like this:

  Set Field [ gErrorCode ; Serial_Open ( "-Unused" ;
              "COM2" ; "baud=9600 parity=none data=8 stop=10 flowControl=XOnXOff" ) ]

You can set the speed, the parity, the number of data and stopbits, and the handshaking to use. Note that the order of the keywords and case are ignored. All keywords are optional and should be separated by a space or a return.

Specifying the port speed

The port speed indicates how quickly the data is transported over the serial line. Allowed values for the port speed are:

baud=150 baud=1800 baud=7200 baud=28800 baud=115200
baud=300 baud=2400 baud=9600 baud=38400 baud=230400
baud=600 baud=3600 baud=14400 baud=57600
baud=1200 baud=4800 baud=19200

NOTE Not all speeds may be supported on all serial ports. Check the documentation of the computer and the equipment you want to connect.

You need to specify the same speed that the other equipment is using. Higher port speeds can result in loss of data if the serial cable can't cope with this speed. If this happens try a lower speed.

Specifying the bit format options

Data over a serial port is sent in small packets of 4 to 10 bits. These packets consist of 4-8 data bits, followed by a parity bit and stopbits.

Data bits

You can specify the number of the data bits by adding one of the data size keywords to the switch parameter. The most used value is 8 data bits. Allowed values for the number of data bits are:

data=4 data=5 data=6 data=7 data=8

Parity bits

You can specify the parity bit by adding one of the following keywords to the switch parameter:

parity=none parity=odd parity=even

Stop bits

You can specify the number of stopbits by adding one of the following keywords to the switch parameter:

stop=10 stop=15 stop=20

Here stop=10 means 1 stop bit, stop=15 means 1.5 stopbit and stop=20 means 2 stopbits.


Specifying the handshaking options

Handshaking is a way to ensure that the transfer of data can be stopped temporarily. This is also called (data) flow control. A serial port can use hardware handshaking and software handshaking. For hardware handshaking to work the serial cable must have wires to support it.

Using the Serial_Open function this plug-in allows a basic way to set the handshaking and also an advanced way, which gives more options, but most users probably don't need.

Basic handshaking options

Basic handshaking has 3 keywords:

flowControl=DTRDSR flowControl=RTSCTS flowControl=XOnXOff

You can specify one or more of these flow control keywords. You should specify at least one of these keywords. Try flowControl=DTRDSR as this is mostly supported. flowControl=DTRDSR and flowControl=RTSCTS are hardware handshaking options, for which you need proper cabling. flowControl=XOnXOff is a software based handshake option.

flowControl=DTRDSR means that the signal DTR is used for input flow control and DSR for output flow control.
flowControl=RTSCTS means that the signal RTS is used for input flow control and CTS for output flow control.
flowControl=XOnXOff uses a XOff character (control-S) and a XOn character (control-Q) to stop input and output flow.

IMPORTANT Do not use FlowControl=XOnXOff if you want to transfer binary data, like pictures. This protocol uses two ASCII characters that might also be in the binary data. FlowControl=XOnXOff works fine with normal text.

Example 1

  Set Field [ gErrorCode ; Serial_Open ( "-Unused" ;
            "COM2" ; "baud=9600 parity=none data=8 stop=10 flowControl=DTRDSR" ) ]

This will set the port to use DTR/DSR hardware handshaking.

Example 2

  Set Field [ gErrorCode ; Serial_Open ( "-Unused" ; "COM2" ;
           "baud=9600 parity=none data=8 stop=10 flowControl=DTRDSR flowControl=RTSCTS
            flowControl=XOnXOff" ) ]

This will set the port to use all 3 types of handshaking in parallel.

Advanced handshaking options

Advanced handshaking options allows you more control over the serial port settings. It enables you to set the handshaking of the output and input separately.

With advanced handshaking you can use the following keywords:

keywordmeaning
inputControl=XOnXOffuse XOnXOff for input handshaking
outputControl=XOnXOffuse XOnXOff for output handshaking
inputControl=RTSuse RTS for input handshaking
outputControl=CTSuse CTS for output handshaking
inputControl=DTRuse DTR for input handshaking
outputControl=DSRuse DSR for output handshaking
DTR=enabledset DTR signal permanent to high
DTR=disabledset DTR signal permanent to low
RTS=enabledset RTS signal permanent to high
RTS=disabledset RTS signal permanent to low

Below you find how the basic handshaking keywords relate to the advanced handshaking keywords:

basic keyword=the same as 2 advanced keywords
flowControl=XOnXOff=inputControl=XOnXOff outputControl=XOnXOff
flowControl=RTSCTS=inputControl=RTS outputControl=CTS
flowControl=DTRDSR=inputControl=DTR outputControl=DSR

The other advanced keywords don't have an equivalent.

NOTE You can mix the basic handshaking keywords with the advanced handshaking keywords, as long as this is sensible.

Example 1

If you want to use DTR handshaking for input flow control and CTS for output flow control use the following settings to open COM1:

  Set Field [ gErrorCode ; Serial_Open ( "-Unused" ; "COM1" ;
        "baud=9600 parity=none data=8 stop=10 outputControl=CTS inputControl=DTR" ) ]

Example 2

If you want to enable the DTR signal and use XOnXOff input flow control use the following settings to open COM1:

  Set Field [ gErrorCode ; Serial_Open ( "-Unused" ; "COM1" ;
            "baud=9600 parity=none data=8 stop=10 DTR=enabled inputControl=XOnXOff" ) ]

Example 3

  Set Variable [ $ErrorCode ; Serial_Open ( "-Unused" ; "COM2" ;
            "baud=9600 data=7 parity=odd stop=20 flowControl=XOnXOff " &
            "outputControl=CTS inputControl=DTR" ) ]

This shows that XOnXOff is used for input and output flow control and also DTR handshaking for input flow control and CTS for output flow control.


Receiving data via script triggering

The Plug-in API for FileMaker Pro 7 and later has an official way to trigger scripts (or dispatch scripts). It is possible on all platforms to trigger scripts by filename and script name. The 5.5 version of the Serial Plug-in implements this triggering. Other ways of triggering are no longer needed.

Functions to implement Dispatch Scripting

The following external functions help in achieving the receiving of data via the Dispatch Script.

Serial_SetDispatchScripttell the plug-in which (Dispatch) script to trigger when data is received
Serial_DataWasReceivedreturns the name of the port when data was received on an open port

The following function is no longer needed, and is no longer present in Troi Serial Plug-in 5.5:

Serial-RestoreSituation

TIP See the example file Terminal.fmp12 for a working example.


Dispatch Scripting using script name

This method will trigger a script when data is received on one of the open ports. Usually you set the dispatch script once after you have opened the serial port(s).

Example "Set Dispatch Script with name"

Below you find a sample Set Dispatch Script:

  Set Field [ gErrorCode ; Serial_SetDispatchScript ( "-Unused" ; "" ;
                  Get ( FileName ) ; "Process Data Received" ) ]
  If [ Left ( gErrorCode ; 2 ) = "$$" ]
        Beep
        Show Message [ An error occurred while setting the dispatch script ]
        Halt Script
  End If

This tells the plug-in to trigger the script Process Data Received whenever incoming data from (one of) the serial port(s) is available. In the script Process Data Received you can retrieve the incoming data, and store it, and do any other processing.

Dispatch Scripting for a specific port

This plug-in can also trigger different scripts for different open ports. This is done with the Serial_Open function. This is how this can be done:

Example Dispatch Script for specific port

Below you find a sample Dispatch Script:

  Set Variable [ $ErrorCode ; Serial_Open ( "-Unused" ;
                  gPortName1 ; "baud=19200 parity=none" ; Get ( FileName ) ;
                  "Process Data Received for 1st Port" ) ]
  If [ Left ( $ErrorCode ; 2 ) = "$$" ]
        Beep
        Show Message [ "An error occurred while opening the port." ]
        Halt Script
  End If

This script will open the port gPortName1 and will trigger script "Process Data Received for 1st Port" when data comes in on this port. If both triggering with Serial_Open and also with Serial_SetDispatchScript has been specified the trigger script specified with Serial_Open takes precedence.

Example Process Data Received script

Below you find a sample "Process Data Received" script, which gets the data from the plug-in into the field mesReceived.

  Enter Browse Mode []
  Set Field [ gTempResultReceived ; Serial_Receive ("-Unused" ;  gPortName ) ]
  Set Field [ mesReceived ; mesReceived & gTempResultReceived ]

Example "Set Dispatch Script" script

Below you find a sample "Set Dispatch Script" script:

  Set Field [ gErrorCode ;  Serial_SetDispatchScript ( "-Unused" ;
                                    Get ( FileName ) & "MyTriggerScript" ) ]
  If [ Left ( gErrorCode ; 2 ) = "$$" ]
        Beep
        Show Message [ An error occurred while setting the dispatch script ]
        Halt Script
  End If

Example Start Receiving script

Below you find a sample "Start Receiving" script:

  Perform Script [ Sub-scripts ; "Open Serial Port" ]
  Perform Script [ Sub-scripts ; "Set Dispatch Script" ]

When you want to begin receiving perform the "Start receiving script".


Script triggering on a match string

The Serial plug-in can look for a special match string that has to arrive at the input buffer before it triggers a script. When you specify the dispatch script, you can add the waitstring parameter.

The script step below will set open a port with a dispatch script Process Data Received, which is only triggered after the string OK is received in the input buffer.

  Set Field [ gErrorCode ; Serial_SetDispatchScript ( "-Unused" ;
                  Get (FileName ) &
                  "Process Data Received" &
                  "OK" ) ]

The script step below will set a dispatch script Process Data Received , which is only triggered after a CR (carriage return) character, followed by a LF (linefeed) character is received. These are the ASCII characters 0x0D and 0x0A respectively (see the ASCII Table in the ASCII.fmp12 file in the download).

Using the Serial_AsciiValueToText function we set the waitstring like this:

  Set Field [ gErrorCode ; Serial_SetDispatchScript ( "-Unused" ;
                  Get ( FileName ) &
                  "Process Data Received" &
                  Serial_AsciiValueToText ( "-Unused" ; "OxOD Ox0A" ) ]

There is no longer a length limitation on the waitstring.


Getting the last match string

It is also possible to get the last string of text that matches the match string. You specify this in the Serial_Receive function.

You need to have this script step:

  Set Field [ gResult ; Serial_Receive ( "-GetLastMatch" ; "COM1" ; ]

Example

We assume, like the example above, to be waiting for match "<CR><LF>" and this data comes in:

  12345<CR><LF>
  434343<CR><LF>
  5678<CR><LF>
  12

If we now run the Serial_Receive script step this data is received in the gResult field:

  5678<CR><LF>

All earlier data is discarded.


Controlling input from the serial port

The function "Serial_Control" controls the serial port. With this function you can suspend or resume the incoming data. This command is very useful for devices that send out continuous data, like an electronic weighing scale.

NOTE The buffer will be emptied when the port is suspended. So when you give the resume command only the data received after this command will be received.

NOTE You can continue to send data to the serial port.

Example 1

  Set Field [ gResult ; Serial_Control ( "-Suspend" ; "Modem port" ) ]

This will suspend the incoming stream of data from the Modem port.

  Set Field [ gResult ; Serial_Control ( "-Resume" ; "Modem port" ) ]

This will resume the previously suspended incoming stream of data from the Modem port.

Example 2

Say you have an electronic weighing scale that sends data to the serial port continuously. The data is in this form:

  1200 kg net CR LF 
  1199 kg net CR LF 
  1200 kg net CR LF 
  1200 kg net CR LF
  etc.

You are only interested in this data when you are actually weighing something. So the best way to handle this is to open the serial port and then suspend this port. When you want to measure something you send a resume command, and gather a full line of data, then suspend the port again.

You need to define these fields:

gPortNameglobal text field, to hold the port name
gErrorCodeglobal text field, to hold the error code in
weightnumber field, to store the weight

When starting up the database you issue these commands in a startup script:

  Set Field [ gPortName ; "COM2" ]
  Set Field[ gErrorCode ; Serial_Open ( "-Unused" ; gPortName ; "baud=19200" ) ]
  If [ gErrorCode = 0 ]
        Set Field [ gErrorCode ; Serial_Control ( "-Suspend" ; gPortName ) ]
  End If

This will open the port and then wait till further notice.
When the user of the database presses a button you start this Measure Now script:

  Set Field [ gTempResultReceived ; "" ]
  Set Field [ gTempBuffer ; "" ]
  Set Field [ gNumber ; 10 ]
  # ...Resume the incoming data...
  Set Field [ gErrorCode ; Serial_Control ( "-Resume" ; gPortName ) ]
  If [ gErrorCode = 0 ] 
  	Loop
        Set Field [ gTempResultReceived ; Serial_Receive ( "-Unused" ;  gPortName ) ]
        Set Field [ gTempBuffer ; gTempBuffer & gTempResultReceived ]
        Exit Loop If [PatternCount ( gTempBuffer ; "¶" ) >= 2 or gErrorCode <> 0 ]
        Pause/Resume Script [ 0:00:01 ]
        Set Field [ gNumber ; gNumber - 1 ]
        If [ gNumber = 0 ]
                Set Field [ gErrorCode ; -1 ]
        End If
  	End Loop
    Set Field [ gNumber ; Serial_Control ( "-Suspend" ; gPortName ) ]
  End If
  Perform Script [ Sub-scripts ; Store Measure Results ]

The Measure Now script resets the buffers, then resumes the incoming data. Inside the loop the data is received until there are 2 returns in the buffer, which means a complete line was received. The script then suspends the port again and then the script Store Measure Results is called to store the results in a record.

To prevent this looping forever when no data is received we also use a counter, gNumber. It starts at 10 and is lowered every time through the loop. After 10x the script gives up and an error code of -1 is set, to get out of the loop.

Here is the Store Measure Results script:

  If [ gErrorCode = 0 and PatternCount ( gTempBuffer ; "¶" ) >= 2 ]
  	New Record/Request
    #...Cut off at the end of the line...
    Set Field [ gTempBuffer ; Left ( gTempBuffer ;
    	Position ( gTempBuffer ; "¶" ; Length ( gTempBuffer ) ; -1 ) - 1 ) ]
    #...Copy one line from the end...
    Set Field [ Weight ; Middle ( gTempBuffer ;
        Position ( gTempBuffer ; "¶" ; Length ( gTempBuffer ) ; -1 ) + 1 ;
        Length ( gTempBuffer ) ) ]
  Else
  	Beep
    Show Message [ An error occurred! ]
  End If
  Go to Field []

This script will create a new record and find the last line in the buffer, and store it in the field Weight.


Function and script step reference

For a description of all External Functions and External Script Steps added by Troi Serial Plug-in please see the separate Reference.fmp12 file. For each function and script step you will find:

  • the correct syntax
  • the parameters/options to be used
  • the returned result
  • special considerations
  • an example usage

The same information is also available as online help on Troi's web site.

You can easily consult the online help directly from FileMaker, by clicking the Help button (the small question mark button) next to the function description in the functions pane or the script step description in the script steps pane.