Communications Protocol

Device Driver
Message Protocol
Calculating the Checksum
Example Messages
Example using LabVIEW(TM)

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.



All communications to the controller follow the pattern of

  1. (start-of-message)
  2. (device number)
  3. (command)
  4. (value)
  5. (calculated checksum for this message)
  6. (end-of-message).
All communications from the controller follow the pattern of
  1. (start-of-message)
  2. (value)
  3. (calculated checksum for this message)
  4. (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...


    We add one when using two's complement...

    1c9f + 0001 = 1ca0

    We can convert that to decimal and treat it as a negative value...


    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.

    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...


    "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...

    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



    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^


    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.

    Contact McShane

    LabVIEW is a Trademark of National Instruments,

    Updated: Saturday, August 17, 2002
    DC Load Temperature Controllers for TEC, peltier modules, fans, or resistive heaters, etc. Proportional & On/Off control.

    Descriptive Indexes and Searches

    SKU  Volts(v)  Amperes(A)  °C
    5C7-195 1-28v 10A -40-150°

    5R7-001 0-36v 25A -50-300°
    5R7-002 0-36v 25A -50-300°

    5R7-388 0-36v 25A -200-400°

    5C7-582 9-36v 28A+ -50-300°

    5R7-570 3-28v 12.5A -20-150°

    5R7-350 0-24v 7.5A -20-100°
    5R7-347 0-24v 7.5A 0-120°