Communications
Protocol
Introduction
Device
Driver
Message Protocol
Calculating
the Checksum
Example
Messages
Example
using LabVIEW(TM)
INTRODUCTION
A communications protocol defines the way you
encode commands and data
for transmission and reception.
The protocol we use for our standard temperature
controllers is unique
to our controllers, and our custom built temperature controllers will
sometimes
be assigned new, custom protocols based on the requirements of the
application.
Our communications protocols apply to all our computer compatible
temperature
controllers regardless of the method of communications (RS-485, RS-232,
GPIB, etc.)
The communications protocol is the same for all
our standard controllers
(Models 5C7-361, 5C7-362, 5C7-366, 5C7-371, 5C7-378, etc.)
Since the 5C7-362 and 5C7-378 is RS-232 it has no
real need for a device
address. This is true for any of our controllers that use RS-232 serial
communications instead of the RS-485. The default address is 1 (one)
but
0 (zero) can be used also.
DEVICE DRIVER
MESSAGE PROTOCOL
All communications to the controller follow the
pattern of
-
(start-of-message)
-
(device number)
-
(command)
-
(value)
-
(calculated checksum for this message)
-
(end-of-message).
All communications from the controller follow the pattern of
-
(start-of-message)
-
(value)
-
(calculated checksum for this message)
-
(end-of-message).
The following example is for controllers with a display precision of
0.1
degrees. If you have a controller with a display precision of 0.01
degrees,
the programming is similar, accept that you multiply the temperature by
100 instead of by 10 when setting or reading that value. See the
appropriate
command set documentation provided on diskette or CDROM with your
controller
for more specific information.
To send the Set Temperature of 100.0 Deg.F to
address 1 (controller
device address number 1):
1. First, the Fixed Decimal
Set Temp of 100.0
is multiplied by 10 (changing it into an integer value of 1000) to
prepare
to send.
2. Then we convert 1000 to hex,
which is 3e8. We are actually
going to send the characters "3", "e" and "8" as the value...
Send: (stx)011c000003e8b5(etx)
3. (stx) = "*" (2a hex), and
(etx) = carriage return
(0d hex), and so the above is
"*" (the start of message character)
"01" (the device number)
"1c" (the command - set the temperature)
"000003e8" (the temperature)
"b5" (a checksum for the message being sent)
Carriage Return (the end-of-message character for the computer's
message).
Receive: (stx)000003e8c0(ack)
4. (stx) = "*" (2a hex), and
(ack) = "^" (5e hex),
and so the above is
"*" (the start of message character)
"000003e8" (the temperature again)
"c0" (a checksum for the message being recieved)
"^" (the end-of message character for device's message)
Negative arguments are in two's complement. They begin with an "f" instead of a "0" (zero).
For example, using "ffffe360" as a temperature reading returned in the reply we can translate it into a decimal value as follows.
Hex e360 in binary is...
1111 1111 1111 1111 1110 0011 0110 0000
and the two's complement is...
0000 0000 0000 0000 0001 1100 1001 1111
which in hex is...
1c9f
We add one when using two's complement...
1c9f + 0001 = 1ca0
We can convert that to decimal and treat it as a negative value...
-7328
And divide by whatever multiplier is appropriate for the controller you are using...
-7328 / 100 = -73.28 degrees
Your programming language might do that automatically when converting a hexadecimal number to a decimal number if it sees a hexadecimal value beginning with an "f".
You can also subtract the argument from hexadecimal
100000000. Hex
100000000 - ffffe360 = 1ca0, which is also what we calculated above.
Or, convert the argument to decimal and do a subtraction in decimal. In this case we can change the order of the subtraction in order to get a negative result. Hex ffffe360 in decimal is 4294959968. Hex
100000000 in decimal is
4294967296. 4294959968 -
4294967296 = -7328.
The method you use depends on the programming language you are using.
CALCULATING THE CHECKSUM
The checksum is obtained by adding up the ascii
values of each character
that forms the main body of the RS422 string - the address, command,
and
value (or argument) - and then dividing by 256. The remainder is the
checksum.
Convert it to lower case hex.
In the message shown above, (stx)011c000003e8b5(etx),
the "b5" represents the checksum. You total the ascii
values
of all the characters shown below in green...
(stx)011c000003e8b5(etx)
"0" in ascii
decimal is 48.
"1" in ascii decimal is 49.
"3" in ascii decimal is 51.
"8" in ascii decimal is 56.
"c" in ascii decimal is 99.
"e" in ascii decimal is 101.
1) Add up the ascii values...
48+49+49+99+48+48+48+48+48+51+101+56=693
2) Determine 693 MOD
256...
693/256=
2.70703125
which rounds down to 2.
693-(256*
2)=181
3) Convert to hex value and then the value to
lower case text...
181 DECIMAL = B5 HEX which in lower case is "b5"
So we send the string, "b5" for the checksum.
The message string you construct may be a command
to set one of the
controllers operating parameters. Or, your string might be a request
for
some value (such as the current temperature).
You send your own string to the controller and
then always get a reply
from the same controller. The reply from the controller does not
include
the device address. Since the reply does not contain the device
address,
the checksum in the reply is based only on the characters that
represent
the command and the value.
Below is BASIC language code which is used to send
a string out through
the communications port.
' Construct the
Main part of the RS422
string.
' [The Device
Address + The Command
+ The Value]
' [These are passed to
this Visual Basic procedure
as iAddr, iCmd, and iVal.]
' [The integer values
become lower case hexadecimal
using 'LCase'.]
' [The integer values
become 2 characters
and 2 characters and 8 characters.]
' [Note: The code
'Right$("0" & Hex(X),
2)' makes X a 2 character hexadecimal string.]
M$ = LCase( _
Right$("0" & Hex(iAddr),
2) _
& Right$("0" &
Hex(iCmd), 2) _
& Right$("00000000"
& Hex(iVal), 8) _
)
' Add the characters of
the above.
' (I will determine the
checksum when I send
the it.)
cs% = 0
For i% = 1 To Len(M$)
cs% =
cs% + Asc(Mid(M$,
i%, 1))
Next i%
' Send it.
' [Sending the
Start-of-Text character,
the part constructed above, the checksum, and the End-of-Text
character.]
' [I use the Mod
function to obtain the checksum
value]
COMPort.Send(LCase(
_
MSG_STX _
& M$ _
& Right$("0"
& Hex(cs% Mod 256), 2) _
& MSG_ETX _
))
The modulus, or remainder, operator of the BASIC programming language,
as used above, divides number1 by number2 and returns only the
remainder
as the result. For example, in the following expression, A (which
is the result) equals 5.
A = 19 Mod 7
EXAMPLE MESSAGES
|
|
|
MESSAGES EXCHANGED
WITH A 5C7-361
CONTROLLER
WITH DEVICE ADDRESS OF
'01'. |
|
|
|
|
|
Function
Description |
Sent |
Reply |
|
ETX = Carriage
Return . |
ACK is the ^ |
|
|
|
Set Controller to 25 C. (x 10 = 250) |
*011c000000fadc |
*000000fae7^ |
Read Back Actual (desired) Set Point 25 C. |
*01030000000044 |
*000000fae7^ |
Read Actual Temperature (Sensor Input1)
(/10=100C) |
*01010000000042 |
*000003e8c0^ |
Set controller address from 99 to address #1 |
*632a000000017d |
*0000000181^ |
Turn controlller #1 ON |
*012d0000000178 |
*0000000181^ |
Turn controlller #1 OFF |
*012d0000000077 |
*0000000080^ |
Fixed set value of Controller #1 to 30C (x
10 = 300) |
*011c0000012cab |
*0000012cb6^ |
Set Proportional bandwidth to 5 (x 10 = 50) |
*011d000000327b |
*0000003285^ |
Set Integral reset to 0.5 (x 100 = 50) |
*011e000000327c |
*0000003285^ |
Set derivative rate to 0.1 (x 100 = 10) |
*011f0000000aa9 |
*0000000ab1^ |
Set input 1 offset to 0.2 (x 10 = 2) |
*0126000000024b |
*0000000282^ |
Set heat side multiplier to 1.0 (x 100 =
100) |
*010c000000647e |
*000000648a^ |
Set control deadband to 3 (x 10 = 30) |
*01250000001e7e |
*0000001eb6^ |
Set PWM out put time base to slow time base
(675HZ) |
*01300000000044 |
*0000000080^ |
Set PWM out put time base to fast time base
(2700HZ) |
*01300000000145 |
*0000000181^ |
Set control type to PID control |
*012b0000000176 |
*0000000181^ |
Set control mode to heat WP1+, WP2- |
*012c0000000076 |
*0000000080^ |
Set control mode to heat WP1-, WP2+ |
*012c0000000177 |
*0000000181^ |
Set alarm type to fixed value alarrm |
*0128000000024d |
*0000000282^ |
Set display unit in degree F |
*01320000000046 |
*0000000080^ |
Set display unit in degree C |
*01320000000147 |
*0000000181^ |
Set alarm latch OFF |
*012f0000000079 |
*0000000080^ |
Set alarm latch ON |
*012f000000017a |
*0000000181^ |
|
|
|
EXAMPLE USING LABVIEW™
The program below reads the temperature 10 times
in 10 seconds in LabView
without a device driver. The panel shows a temperature of 25.00 (degC)
which was room temperature when the program was run.
The front panel shows the temperature. At the
bottom it shows any error,
and for each read it shows how many characters went out in the command
string and how many characters were received in the reply, and it shows
the reply string.
Click here for
Panel,
Diagram and vi.