![]() Troi Serial Plug-in 8.0 |
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:
|
|
|
Stop bits
You can specify the number of stopbits by adding one of the following keywords to the switch parameter:
|
|
|
Here stop=10 means 1 stop bit, stop=15 means 1.5 stopbit and stop=20 means 2 stopbits.
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:
keyword | meaning |
inputControl=XOnXOff | use XOnXOff for input handshaking |
outputControl=XOnXOff | use XOnXOff for output handshaking |
inputControl=RTS | use RTS for input handshaking |
outputControl=CTS | use CTS for output handshaking |
inputControl=DTR | use DTR for input handshaking |
outputControl=DSR | use DSR for output handshaking |
DTR=enabled | set DTR signal permanent to high |
DTR=disabled | set DTR signal permanent to low |
RTS=enabled | set RTS signal permanent to high |
RTS=disabled | set 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.
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. Version 5.5 and later 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_SetDispatchScript | tell the plug-in which (Dispatch) script to trigger when data is received |
Serial_DataWasReceived | returns 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 and later:
Serial_RestoreSituation |
TIP See the example file Terminal.fmp12 for a working example.
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.
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".
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 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.
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.
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:
gPortName | global text field, to hold the port name |
gErrorCode | global text field, to hold the error code in |
weight | number 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.
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 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.