S7-1200 ASCII Serial Communication: CM 1241 RS485 Setup Guide

David Krause16 min read
S7-1200SiemensTutorial / How-to
Licensed PE Working through this on a live machine? A Maine-licensed engineer can take it from here — included with IMD hardware, by the hour for everything else. Book an engineer

S7-1200 ASCII Serial Communication with CM 1241 RS485: Complete Engineering Guide

Interfacing an S7-1200 PLC to a third-party temperature controller that exposes only a raw RS485 ASCII protocol (no Modbus, no USS) is one of the most common—and most error-prone—commissioning tasks in compact PLC projects. The SIMATIC S7-1200 family supports this scenario natively through the CM 1241 communication modules and the Point-to-Point (PtP) instruction set built into the S7-1200 CPU firmware. This guide walks through the full engineering cycle: module selection, wiring, TIA Portal hardware configuration, ASCII frame construction, SEND_PTP/RCV_PTP programming, receive buffer parsing, and field verification.

Prerequisites: This article assumes TIA Portal V16 or later, CPU firmware V4.2 or later, and a temperature controller whose ASCII frame format is fully documented (start delimiter, address, command, data, checksum, end delimiter). The CPU must be an S7-1200 with FW ≥ V4.0 to expose the full PtP instruction library.

1. CM 1241 Communication Module Selection

The S7-1200 CPU does not have a native serial port; ASCII traffic must pass through an add-on communication module or communication board. The available variants differ in electrical interface, supported protocols, and physical form factor.

Table 1 — CM 1241 / CB 1241 Module Comparison
Module MLFB / Catalog No. Interface Max Baud Termination Form Factor
CM 1241 RS232 6ES7241-1AH32-0XB0 RS-232C, 9-pin D-sub 115.2 kbit/s N/A Signal Board (left side)
CM 1241 RS422/485 6ES7241-1CH32-0XB0 RS-422/RS-485, 2-wire or 4-wire 115.2 kbit/s Internal DIP switch Signal Board (left side)
CB 1241 RS485 6ES7241-1CH30-1XB0 RS-485, 2-wire only 115.2 kbit/s Internal DIP switch Communication Board (under terminal cover)

For a single temperature controller on a 2-wire RS-485 multidrop bus, the CB 1241 RS485 (6ES7241-1CH30-1XB0) is the lowest-cost solution and is electrically isolated. The CM 1241 RS422/485 (6ES7241-1CH32-0XB0) adds a full RS-422 mode and is preferred when the device supports 4-wire full-duplex ASCII. Both modules support the ASCII point-to-point protocol directly from the CPU firmware; no additional FBs are required.

Important: Only the CM 1241 modules support the USS and Modbus RTU master/slave instructions natively. The CB 1241 RS485 supports ASCII free-port (PtP) operation but does not support USS or Modbus RTU mode in TIA Portal. If you intend to switch protocols later, choose the CM 1241 RS422/485 module.

For full module specifications, refer to the S7-1200 Programmable Controller System Manual.

2. RS-485 Bus Wiring and Termination

RS-485 is a balanced, differential bus. A single shielded twisted pair carries the data, and a third conductor (or the shield) provides the signal common. Correct termination is critical for reliable ASCII communications above 19200 bit/s or on cable runs longer than ~10 m.

  1. Enable internal termination on the CM/CB 1241 by moving the DIP switch labeled TERM to the ON position. The module installs a 120 Ω resistor between the A and B lines.
  2. Match the controller's biasing. If the temperature controller does not provide failsafe bias, externally bias the bus with a 620 Ω pull-up to +5 V on line B and a 620 Ω pull-down to GND on line A.
  3. Use a shielded twisted pair with characteristic impedance of 120 Ω (e.g., Belden 3106A or Alpha 6412). Ground the shield at one end only (typically the PLC cabinet).
  4. Verify polarity. Siemens labels the positive line as T/R+ (also A) and the negative as T/R- (also B). Some controller vendors reverse the labels — always check against the device's datasheet, not its marketing pinout.
  5. Maximum cable length at 115.2 kbit/s is 1000 m (3280 ft). At 19.2 kbit/s it is 1200 m. Total stub length must be < 1/10 of the trunk length to prevent reflections.

3. ASCII Protocol Fundamentals

Unlike Modbus RTU, ASCII (American Standard Code for Information Interchange) is a character-oriented protocol. Each byte in the frame is sent as a 7- or 8-bit ASCII code, prefixed by a start bit and terminated by a stop bit. Frames are bounded by delimiter characters, which makes the protocol tolerant of inter-character gaps but inefficient on the wire (~50% overhead vs. RTU).

Table 2 — Typical Temperature Controller ASCII Frame
Byte Index Field Example (hex) Description
0 Start delimiter 3A (':') Every command/response begins with this character
1 Address (MSB) 30 ASCII '0' = device address 0
2 Address (LSB) 31 ASCII '1' = device address 1
3 Command 52 ASCII 'R' = Read Process Value
4..n-3 Data 31 32 33 2E 35 ('123.5') ASCII numeric payload
n-2 Checksum (high nibble) 34 ASCII '4'
n-1 Checksum (low nibble) 35 (CR) ASCII '5'
n End delimiter 0D 0A CR LF pair

The checksum is typically a 2's-complement sum of all bytes between the start and checksum, expressed as a single ASCII hex byte. Always refer to the controller's manual; some vendors use XOR, some use CRC-8, and a few (incorrectly) use Modbus LRC.

4. Hardware Configuration in TIA Portal

Open TIA Portal, expand Devices & Networks, and add the CPU. The CM/CB 1241 is auto-detected when plugged in (online) or added manually (offline). Configure the module's port as follows:

  1. In the Device View, click the CM 1241 module icon.
  2. Open the Properties > Port Configuration tab.
  3. Set the following parameters for a typical temperature controller:
Table 3 — CM 1241 Port Configuration Parameters
Parameter Value Notes
Protocol ASCII Free-port (PtP) mode
Baud rate 9600 / 19200 / 38400 Match the controller; 9600 is the safe default
Parity None / Even Most ASCII controllers use None-8-1
Data bits 8 ASCII protocol always uses 8 data bits
Stop bits 1 2 if the controller specifies even parity with 8 data bits
Flow control None RS-485 is half-duplex; XON/XOFF is supported but rarely used
End of receive After character timeout (4 ms) Use the timeout method for variable-length ASCII frames
Character timeout 4 ms (or 3.5 char times) Defines inter-frame gap detection

For a full module manual including the protocol field reference, see the S7-1200 Programmable Controller System Manual, chapter 7 "Communication processor and Modbus TCP".

Hardware identifier: TIA Portal assigns a HW identifier (HW-ID) to the CM 1241 port — e.g., 269. This ID is required by every PtP instruction and must be passed through a tag or constant. You can read the HW-ID in the device properties under System constants.

5. SEND_PTP and RCV_PTP Instruction Set

The PtP instruction library lives in the TIA Portal Instructions > Communication > Communication processor > Point-to-Point task card. For S7-1200 firmware V4.0 and later, the relevant FBs are:

Table 4 — Point-to-Point Instructions (S7-1200 CPU FW ≥ V4.0)
Instruction FB Number Purpose Polling Mode
SEND_PTP FB 3 Transmit a buffer via the configured CM 1241 port REQ edge-triggered
RCV_PTP FB 2 Receive bytes into a buffer; triggered by idle-line or character timeout EN = TRUE continuous
RCVREC — Reset the receive buffer (alternative to RCV_PTP EN reset) Conditional call
PTP_CFG — Reconfigure the port at runtime (optional) One-shot on startup
PTP_RST — Reset the physical port and clear all internal state One-shot on fault

The RCV_PTP instruction does not work like a normal polled call. According to the S7-1200 system manual, the FB must be called continuously in a cyclic OB (typically OB1). Internally, RCV_PTP looks for the configured end-of-receive condition (idle line, character timeout, or message count). When that condition is met, the instruction copies the accumulated bytes into the user buffer and sets DONE for one cycle. The next call with a rising edge on ENR (the internal enable receive input) restarts the buffer.

6. Structured Text Implementation

The following example shows a complete polling loop in SCL (Structured Control Language). The PLC requests the process value from device address 01, then parses the ASCII response into a floating-point temperature.

6.1 Data Block Definition

DATA_BLOCK "dbPtPComm"
{ S7_Optimized_Access := 'TRUE' }
VERSION : 0.1
NON_RETAIN
  STRUCT
   bSendReq       : Bool;     // Edge-trigger to send next request
   bTxBusy        : Bool;     // SEND_PTP.BUSY mirror
   bTxDone        : Bool;     // SEND_PTP.DONE mirror
   bTxError       : Bool;     // SEND_PTP.ERROR mirror
   wTxStatus      : Word;     // SEND_PTP.STATUS
   bRxBusy        : Bool;     // RCV_PTP.BUSY mirror
   bRxDone        : Bool;     // RCV_PTP.DONE mirror
   bRxError       : Bool;     // RCV_PTP.ERROR mirror
   wRxStatus      : Word;     // RCV_PTP.STATUS
   rTemperature   : Real;     // Parsed process value in degC
   bParseOK       : Bool;     // TRUE if checksum + format valid
  END_STRUCT;
END_DATA_BLOCK

6.2 Send Request (Polling Logic)

"dbPtPComm".bSendReq := NOT "dbPtPComm".bTxBusy AND NOT "dbPtPComm".bRxBusy;

The bSendReq flag is asserted whenever both the transmit and receive paths are idle. It triggers a new request and falls as soon as SEND_PTP accepts the buffer.

6.3 SEND_PTP Call (OB1)

// Build the ASCII request frame: ':01R' + Checksum + CRLF
// For a controller that uses 2's-complement sum modulo 256:
//   0x3A + 0x30 + 0x31 + 0x52 = 0xF7, 2's-comp = 0x09 -> ASCII '0' '9'
// Transmit buffer = 16#3A 16#30 16#31 16#52 16#30 16#39 16#0D 16#0A

"iSendPTP"(REQ   := "dbPtPComm".bSendReq,
          LADDR := 269,                    // HW identifier of CM 1241 port
          SEND  := P#DB100.DBX0.0 BYTE 8,  // Points to the static frame buffer
          DONE  => "dbPtPComm".bTxDone,
          ERROR => "dbPtPComm".bTxError,
          STATUS=> "dbPtPComm".wTxStatus,
          BUSY  => "dbPtPComm".bTxBusy);

The iSendPTP instance DB is created automatically when the FB is dropped into the program. The SEND parameter is a pointer to the 8-byte transmit buffer in a separate data block (here DB100) that you pre-load once with the frame, including the calculated checksum.

6.4 RCV_PTP Call (OB1, called every cycle)

"iRcvPTP"(EN_R  := TRUE,                    // Continuous receive enable
          LADDR := 269,
          DATA  := P#DB101.DBX0.0 BYTE 64, // 64-byte receive buffer
          LEN   := "iRcvPTP".LEN,           // Actual bytes received
          DONE  => "dbPtPComm".bRxDone,
          ERROR => "dbPtPComm".bRxError,
          STATUS=> "dbPtPComm".wRxStatus,
          BUSY  => "dbPtPComm".bRxBusy);

// Reset the receiver after a successful or failed read
IF "dbPtPComm".bRxDone OR "dbPtPComm".bRxError THEN
   "iRcvPTP".EN_R := FALSE;                // Pulse OFF for one cycle
   // ... and re-arm in the next cycle
END_IF;

DB101 is a 64-byte buffer that the FB fills in with received bytes. After every successful DONE pulse, the buffer length is read out of iRcvPTP.LEN for the parser.

7. Parsing the ASCII Response into a REAL

Most temperature controllers return the value as a decimal ASCII string. The parser must:

  1. Validate the start delimiter (0x3A).
  2. Validate the address byte matches the device being polled.
  3. Compute the checksum and compare against the trailing two ASCII hex bytes.
  4. Extract the numeric payload (skip non-numeric characters).
  5. Convert the ASCII string to a 32-bit float.

The S7-1200 system library provides a string-to-real conversion String_TO_REAL() in the Conversion Operations group. Use it together with CHARS_TO_STRING() from the String + Char group to slice the buffer.

// Example parser: extract the 5 ASCII chars at offset 4..8 and convert to REAL
IF "dbPtPComm".bRxDone AND "dbPtPComm".bRxError = FALSE THEN
   "tmpStr" := CHARS_TO_STRING(IN := P#DB101.DBX4.0 BYTE 5);
   "dbPtPComm".rTemperature := STRING_TO_REAL("tmpStr");
   "dbPtPComm".bParseOK := TRUE;
ELSE
   "dbPtPComm".bParseOK := FALSE;
END_IF;
STRING_TO_REAL quirks: The function expects a decimal point. North American controllers transmit '.', European controllers transmit ',' depending on the country. The S7-1200 firmware treats ',' as a non-numeric character and returns 0.0. If the device is European, write a small loop that replaces ',' with '.' before calling STRING_TO_REAL, or normalize at the controller configuration level.

8. Common Error Codes and Recovery

SEND_PTP and RCV_PTP return a 16-bit STATUS word. The most common values for ASCII mode are listed below. For the complete list, refer to the S7-1200 System Manual Appendix B.

Table 5 — SEND_PTP / RCV_PTP STATUS Codes (ASCII Mode)
STATUS (hex) Meaning Root Cause Remediation
0000 No error — —
7000 No active job REQ not set Verify trigger logic
7001 Job accepted, executing — Wait for DONE/ERROR
7002 Job rejected, internal busy Previous job not yet finished Hold REQ until BUSY rises
8085 Bad LADDR / HW-ID Wrong hardware identifier Check System Constants > HW identifier
8090 Pointer invalid SEND or DATA pointer length 0 or wrong area Verify P# pointer syntax
80A0 Hardware fault / port not ready CM 1241 missing, faulty, or not in run Check module diagnostic LEDs
80A8 Frame sent but no acknowledgment Wiring, address, or baud mismatch Loopback test, swap A/B, verify baud
80B0 Parity / framing error Different parity/stop bits on PLC and device Re-check port configuration on both sides
80B1 Overrun CPU cycle time too slow to drain the buffer Increase OB1 priority, use a smaller buffer, or shorten the cycle
80B2 Buffer overflow Receive buffer too small for incoming frame Increase DATA pointer length

9. Loopback Test Procedure

Before connecting the temperature controller, validate the PLC hardware and software path with a hardware loopback. This catches 80% of "I can't read anything" faults before they reach the field.

  1. Wire pin 2 (T/R+) to pin 7 (T/R-) and pin 1 (T/R-) to pin 8 (T/R+) on the CM 1241 9-pin connector — i.e., cross A↔B and short the receive pair. Or use a DB9 gender-changer wired as a loopback.
  2. Set the TERM DIP switch to ON so the bus is terminated.
  3. Configure the port for 8N1 9600.
  4. Send a known 8-byte string ("TESTDATA") from a small SCL program. Trigger a one-shot SEND_PTP, then enable RCV_PTP.
  5. Watch the watch table: iRcvPTP.DONE must pulse, STATUS = 0, and the receive buffer at DB101 must contain 54 45 53 54 44 41 54 41.
  6. If the loopback fails, the issue is hardware (module, cable, DIP switch) or TIA Portal configuration (protocol field set incorrectly). Re-check the device configuration.

10. Field Commissioning Checklist

Table 6 — ASCII RS-485 Commissioning Checklist
# Check Pass Criteria
1 CM/CB 1241 is firmly seated; CPU recognizes it Module visible in online > accessible nodes
2 Port configured for ASCII, correct baud and frame Matches controller datasheet exactly
3 DIP switch TERM = ON at both ends 120 Ω measured between A and B
4 Polarity A↔B consistent PLC T/R+ to controller A+
5 Loopback test on the field cable (controller disconnected) RCV_PTP returns sent bytes
6 Controller echo test (enable controller's continuous broadcast) RCV_PTP receives unsolicited frames
7 Request/response cycle bTxDone and bRxDone alternate, rTemperature updates
8 Checksum validation bParseOK stays TRUE over 1 hour
9 Long-run soak test (≥ 24 h) No STATUS errors, no resets

11. Diagnostic Tools and Watch Tables

Create a watch table with the following tags during commissioning:

// Watch table tags
"dbPtPComm".bSendReq        BOOL   // Trigger to send
"dbPtPComm".bTxBusy         BOOL   // SEND_PTP BUSY
"dbPtPComm".bTxDone         BOOL   // SEND_PTP DONE (one-shot)
"dbPtPComm".wTxStatus       WORD   // SEND_PTP STATUS
"dbPtPComm".bRxBusy         BOOL   // RCV_PTP BUSY
"dbPtPComm".bRxDone         BOOL   // RCV_PTP DONE
"dbPtPComm".wRxStatus       WORD   // RCV_PTP STATUS
"dbPtPComm".bParseOK        BOOL   // Parser success flag
"dbPtPComm".rTemperature    REAL   // Parsed temperature in degC
"iRcvPTP".LEN               INT    // Bytes actually received

For the receive buffer, create an "observe all" array view in DB101. The S7-1200 CPU stores received bytes sequentially beginning at byte 0. Capture a few hundred milliseconds of buffer activity with a trace; if the buffer shows garbage, the baud or parity is wrong; if the buffer is empty, the controller never received the request — check wiring and address.

12. Multi-Device Bus and Polling Cycle

RS-485 supports up to 32 unit loads (1 UL ≈ 12 kΩ) per bus. For a multi-device bus, address each controller in turn and add a fixed inter-frame delay (≥ 3.5 character times) so that the device can release the bus. A simple sequencer is sufficient:

// State machine: 0=Idle, 1=Sending, 2=Awaiting response, 3=Parsing
CASE "dbPollState".iState OF
   0:  // Idle: select next device, build request
       IF NOT "dbPtPComm".bTxBusy AND NOT "dbPtPComm".bRxBusy THEN
          "dbPollState".iAddr := "dbPollState".iAddr + 1;
          IF "dbPollState".iAddr > 8 THEN "dbPollState".iAddr := 1; END_IF;
          // Build frame for "dbPollState".iAddr into DB100
          "dbPtPComm".bSendReq := TRUE;
          "dbPollState".iState := 1;
       END_IF;
   1:  // Wait for SEND_PTP DONE
       IF "dbPtPComm".bTxDone THEN
          "dbPtPComm".bSendReq := FALSE;
          "dbPollState".iState := 2;
          "dbPollState".tRcvTimeout(IN := FALSE); // preset 100 ms
          "dbPollState".tRcvTimeout(IN := TRUE, PT := T#100ms);
       END_IF;
   2:  // Wait for RCV_PTP DONE or timeout
       IF "dbPtPComm".bRxDone THEN
          "dbPollState".iState := 3;
       ELSIF "dbPollState".tRcvTimeout.Q THEN
          "dbPollState".iState := 3; // skip this device, go to next
       END_IF;
   3:  // Parse and return to Idle
       // Parser runs in OB1 every cycle; just move on
       "dbPollState".iState := 0;
END_CASE;

Adjust the inter-request delay (state 0 dwell) to allow the controller to update its value register; 200–500 ms is typical for slow thermal loops.

13. Performance, Timing, and Cycle Budget

At 9600 bit/s, one ASCII character (10 bits including start/stop) is 1.04 ms. A 16-byte request and 24-byte response round-trip is therefore ≈ 41 ms of wire time. With the CPU cycle overhead (typically 5–10 ms at OB1 priority 1) and the RCV_PTP reset pulse (one cycle), a single poll takes ~50 ms. Polling 8 devices on one bus costs 8 × 50 ms = 400 ms, which is well within the 1 s refresh rate required by most temperature control loops.

If the cycle is too long, increase the baud to 38400 or 57600 — most modern temperature controllers support these rates. Avoid going above 38400 on long cable runs without proper termination and biasing.

14. Migration to Modbus RTU

Many new temperature controllers now expose a Modbus RTU interface. If the controller is dual-protocol, switching the CM 1241 from ASCII to Modbus RTU master is straightforward: change the protocol in the port configuration and replace the SEND_PTP/RCV_PTP calls with the standard MB_MASTER instruction. The same buffer logic and parser code can be reused with minimal changes. Refer to the S7-1200 System Manual, Modbus section for the full instruction set and STATUS codes.

15. Frequently Asked Questions

What is the difference between ASCII and Modbus RTU mode on a CM 1241?

ASCII mode uses a character-oriented frame with start and end delimiters (typically ':' and CRLF) and 7- or 8-bit data. Modbus RTU uses a time-silent bus with no delimiters and packs the entire frame as 8-bit binary. RTU is more efficient on the wire (~50% less overhead) but requires tight inter-frame timing. The CM 1241 supports both modes on the same hardware; you change modes by editing the port configuration in TIA Portal.

Why is my RCV_PTP STATUS returning 0x80A8 after I send a request?

STATUS 0x80A8 means the frame was sent but the receiver did not see a valid response. Common causes are A/B polarity swap, baud rate mismatch, address mismatch (the controller ignores requests not addressed to it), or a broken cable. Verify polarity with a multimeter, run a loopback test on the field cable, and confirm the controller's address in its configuration menu.

How do I compute the ASCII checksum for a temperature controller request?

The most common method is the 2's-complement sum of all bytes between the start delimiter and the checksum position. For example, for the frame ':01R', the sum of 0x3A, 0x30, 0x31, 0x52 is 0xF7, the 2's complement is 0x09, and the checksum is the ASCII characters '0' and '9' (0x30 0x39). Always check the controller manual — some vendors use XOR or CRC-8.

Can I use a CB 1241 RS485 module for ASCII communication?

Yes, the CB 1241 RS485 (6ES7241-1CH30-1XB0) supports the ASCII PtP protocol. However, it does not support USS or Modbus RTU mode and has only 2-wire half-duplex. For a single temperature controller on a 2-wire bus it is the most cost-effective solution. For future protocol migration, choose the CM 1241 RS422/485 (6ES7241-1CH32-0XB0) instead.

How do I convert an ASCII numeric string from a temperature controller into a REAL tag?

Use the S7-1200 standard conversion function STRING_TO_REAL from the Conversion Operations group. First slice the relevant bytes from the receive buffer with CHARS_TO_STRING(IN := P#DBxxx.DBXoffset.0 BYTE length), then call the conversion. If the controller uses ',' as the decimal separator, replace it with '.' in a small loop before conversion, because STRING_TO_REAL expects a '.'.

Why does my receive buffer contain garbage characters at higher baud rates?

Garbage on the wire at 38400 bit/s and above is almost always a termination or biasing problem. Enable the CM 1241 internal 120 Ω termination (DIP switch TERM = ON), and if the controller does not bias the bus, add external 620 Ω pull-up/pull-down resistors. Also check that the cable is shielded twisted pair and that the shield is grounded at one end only. Re-measure the bus with an oscilloscope — a clean RS-485 signal should show a 1.5 V to 5 V differential swing, not collapsing to ground between characters.

Back to blog