Implementing GSM AT Commands with a Siemens S7-200 PLC RS232 SMS

David Krause15 min read
S7-200SiemensTutorial / 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

Overview

Connecting a programmable logic controller to a GSM modem over RS232 and exchanging AT commands is a well-established pattern for remote alerting, telemetry, and SCADA-over-SMS. The original recommendation of the Siemens SIMATIC S7-200 remains a sound choice: every CPU 22x ships with at least one RS485 port that is freely programmable in Freeport mode, and with a low-cost PC/PPI cable (or an RS485-to-RS232 converter) the controller can drive almost any industrial GSM/GPRS modem.

This reference consolidates the field-proven procedure for:

  • Bringing up a Siemens S7-200 in Freeport mode at 9600 bps, 8N1.
  • Issuing Hayes/3GPP AT+CMGS, AT+CMGR, and AT+CLIP commands to a SIM800/SIM900 or Telit GL865 modem.
  • Decoding SMS text mode (GSM 7-bit) and the unsolicited +CLIP: caller-ID response.
  • Driving a relay output from a received SMS payload or a dialed CallerID.

The same architecture maps directly to the S7-1200 (USS / Freeport via CM 1241), Allen-Bradley MicroLogix 1100/1400 (DF1 half-duplex ASCII), and Unitronics Jazz/Samba (MB/Serial — ASCII protocol), which are summarized in the alternative-platforms section at the end.

Prerequisites

Before commissioning, gather the following hardware and software:

  1. PLC: Siemens S7-200 CPU 224, CPU 224XP, or CPU 226. The CPU 221/222 with a single RS485 port is acceptable but limits you to one half-duplex channel. The CPU 224XP adds a second port (Port 1) that is independent from the programming port (Port 0).
  2. GSM modem: Any 2G/3G modem that exposes a standard Hayes AT interface on a 9-pin D-Sub RS232 port. Field-proven devices include the SIMCom SIM800C, SIM900, Quectel M66, and Telit GL865-DUAL. Confirm that the modem is unlocked and that a working SIM is inserted with PIN disabled (or stored in the modem NVRAM).
  3. Cable: Siemens PC/PPI USB cable (6ES7 901-3DB30-0XA0) with a 9-pin female-to-male RS232 extension, or an industrial RS485-to-RS232 converter such as the Phoenix Contact PSI-MODEM-RS232.
  4. Power supply: 24 VDC at ≥1 A for the S7-200, plus the modem's nominal supply (usually 5–12 VDC at 1–2 A peak during transmit bursts).
  5. Programming software: STEP 7 Micro/WIN V4.0 SP9 (or STEP 7 Micro/WIN SMART if you have migrated to the S7-200 SMART platform).
  6. HyperTerminal, PuTTY, or Docklight: a serial console to validate the GSM modem with the AT command set before any PLC code is written.
  7. Documentation: the 3GPP TS 27.007 AT command set and the Siemens S7-200 System Manual and Communication Manual from the Siemens Industry Online Support portal.
Important: Always bench-test the modem with a PC first. If AT returns OK from PuTTY at 9600 8N1, the same byte stream will work on the PLC. Skipping this step is the single most common cause of "the PLC says nothing back" support tickets.

Hardware Architecture

The S7-200's Port 0 is an RS485 (D+) / (D-) differential port. The internal UART is a standard 16550-compatible design that the firmware re-programs in Freeport mode. Two practical topologies are common:

  1. RS485-to-RS232 converter path (recommended for S7-200, not SMART). A Phoenix Contact PSI-MODEM-RS232/485 or an Advantech ADAM-4520 converts the differential pair to a true RS232 level (TX, RX, RTS, CTS, GND). The PLC's RTS signal in Freeport mode can be used as the modem's Data Terminal Ready on the converter side.
  2. Direct RS232 to CPU 224XP Port 1. The XP/226 variants have a second port that is already RS232, eliminating the converter. This port is bound to the Freeport channel 1 in the SMB30 / SMB130 control byte.
Table 1 — S7-200 port and pin assignment for GSM modem link
S7-200 Port Pin (DB-9) Signal Modem DB-9 Pin Notes
Port 0 (RS485) 3 D+ / TXD 2 (RXD) Through RS485→RS232 converter
Port 0 (RS485) 8 D- / RXD 3 (TXD) Through converter
Shield/Common 5 GND 5 Mandatory for noise immunity
Port 1 (RS232, CPU224XP) 3 TXD 2 (RXD) Direct RS232 cable
Port 1 (RS232, CPU224XP) 2 RXD 3 (TXD) Direct RS232 cable

GSM AT Command Set Reference (3GPP TS 27.007)

The Hayes command set used by GSM modems is a superset defined in 3GPP TS 27.007. The subset you will use 95 % of the time is:

Table 2 — Core AT commands for PLC ↔ GSM applications
Command Function Example Expected Response
AT Link check AT<CR> OK
ATE0 Disable echo ATE0<CR> OK
AT+CMGF=1 Set SMS text mode (GSM 7-bit) AT+CMGF=1<CR> OK
AT+CMGS="+4917xxxxxxxx" Send SMS, payload follows <SUB> AT+CMGS="+4917..."<CR>Hello<SUB> +CMGS: 1<CR>OK
AT+CMGR=<index> Read stored message AT+CMGR=1<CR> +CMGR: "REC READ","+49...","","25/06/12,10:01:33"<CR>Hello
AT+CMGD=<index> Delete message AT+CMGD=1<CR> OK
AT+CLIP=1 Enable Caller-ID presentation AT+CLIP=1<CR> OK
+CLIP: "+49...",145,... Unsolicited ring indication Parse second field for number
AT+CSQ Signal quality (0–31, 99 = unknown) AT+CSQ<CR> +CSQ: 19,0
AT+CREG? Network registration AT+CREG?<CR> +CREG: 0,1 (home) or 0,5 (roaming)
ATD+49xxxxxxxx; Voice dial (semi-colon suppresses voice path) ATD+49...;<CR> OKNO CARRIER
ATH Hang up ATH<CR> OK

Every line in the table is terminated with carriage return (0x0D); the Ctrl-Z / SUB byte (0x1A) terminates a multi-line SMS payload. Do not append line feed (0x0A); the SIMCom firmware will echo it as a syntax error.

SMS Text Mode vs PDU Mode

The modem can deliver SMS in two encodings:

  • Text mode (AT+CMGF=1) — payloads up to 160 characters using GSM 7-bit default alphabet. Straight ASCII in, ASCII out. Ideal for PLCs because no bit-packing is required. Limited character set: @ £ $ ¥ è é ù ì ò ç ø Å å Δ_ΦΓΛΩΠΨΣΘΞ Æ æ ß É ! " # % & ' ( ) * + , - . / : ; < = > ? ¡ A..Z Ä Ö Ñ Ü § ¿ a..z ä ö ñ ü à.
  • PDU mode (AT+CMGF=0) — every character is encoded in 7-bit packed format, prefixed by service-center address, protocol identifier, and DCS. Required for Unicode (UCS-2) or 8-bit data. The S7-200 can do PDU mode but the parser is non-trivial — see the Siemens Application Note "SMS via S7-200 in PDU Mode".

For a starter build, stay in text mode. If the message body must contain a binary sensor reading, encode it as ASCII hex ("0A2F") inside the text payload, or switch to PDU mode for true binary transport.

S7-200 Freeport Mode Configuration

Freeport is selected with the special marker (SMB2 for Port 0 receive, SMB3 for Port 0 transmit, SMB4 for Port 1 receive, SMB5 for Port 1 transmit) and the protocol selector bits in SMB30 (Port 0) or SMB130 (Port 1). The control byte layout (per the S7-200 System Manual) is:

SMB30 / SMB130 layout (bit 7..0):
  pppd bbbb mm
  p  = protocol:    00 = PPI slave, 01 = Freeport, 10 = PPI master, 11 = reserved
  d  = parity:      0 = even, 1 = no parity
  b  = baud rate:   000=1200 001=2400 010=4800 011=9600 100=19200 101=57600
  m  = char bits:   00=8/c 01=7/c 10=8/c+1 stop 11=8/c+2 stop

Recommended value for GSM modems: SMB30 = 0x09
  0000 1 001 00
        ^  ^^^
        |  ||+-- 8 data bits per char
        |  |+--- 9600 baud
        |  +---- no parity (modems are 8N1)
        +------- Freeport protocol

To enter Freeport at run time use the MBUS_CTRL (Mode switch) instruction or write SMB30 directly from the first scan. The typical ladder pattern is:

  1. First scan: SM0.1 → MOV 16#09 → SMB30.
  2. Initialise the receive buffer length: MOV 200 → VB200 (max receive).
  3. Issue RCV with table pointer VB200 and a 100-ms idle-line timeout.
  4. On RCV completion (B9 done bit), strip the trailing 0x0D 0x0A from VB201..VBn and parse the response string.

Sending an SMS — Sample Ladder Logic

The following example transmits an alarm SMS whenever input I0.0 is closed. It assumes the modem is configured in text mode (AT+CMGF=1) and that the destination number is stored in V100..V114 as a null-terminated ASCII string.

Network 1  Trigger on rising edge of I0.0
  I0.0            RCV_EN   MOVB   1, VB300   ' Start of message marker
  --||--|P|--------( R_TRIG )--[MOVB 1, VB300]
  Network 2  Copy ASCII number "+4917xxxxxxxx" into VB310..V324
  [BLKMOVB  VB_NUMBER_START VB310  15]
  Network 3  Compose the AT+CMGS command line
  VB300 = 0x41  'A'
  VB301 = 0x54  'T'
  VB302 = 0x2B  '+'
  VB303 = 0x43  'C'
  VB304 = 0x4D  'M'
  VB305 = 0x47  'G'
  VB306 = 0x53  'S'
  VB307 = 0x3D  '='
  VB308 = 0x22  '"'
  ... copy number ...
  VB324 = 0x22  '"'
  VB325 = 0x0D  'CR'
  Network 4  XMT the command
  XMT  VB300  0    ' Transmit buffer starting at VB300 on Port 0
  Network 5  After 200 ms, send the payload and Ctrl-Z
  TON  T37, +200  [XMT VB340 0]   ' "ALARM I0.0 SET\x1A"
  Network 6  On T37 done, set a "Message Sent" flag M10.0
  T37           --( M10.0 )

The two-stage XMT (header first, payload after a small delay) is required because the modem's > prompt is sent only after it has parsed the AT+CMGS="..." line. If you send the payload immediately, the SUB byte will arrive while the modem is still parsing the header and the SMS will be discarded silently.

Receiving an SMS — Parsing the +CMTI Indication

By default the modem does not store received messages in the SIM and only emits a +CMTI: "SM",<index> unsolicited response when AT+CNMI=1,1,0,0,0 has been set. The recommended configuration string is issued once at startup:

AT+CNMI=1,1,0,0,0    ' New message indications → TE (PLC)
AT+CMGF=1             ' Text mode
AT+CLIP=1             ' Enable caller-ID for ringing calls
AT#IND=1              ' SIM900-specific: route state changes to UART

When the RCV instruction in Freeport completes, the buffer contains the unsolicited line, e.g.:

+CMTI: "SM",3\r\n

The S7-200 can extract the index by scanning for the second comma, multiplying nothing — just convert the ASCII byte to a BCD integer. A compact subroutine is:

Network 1  Find the second comma
  FOR  VW500 = VB201 TO VB200+VB202  ' VB202 is the byte count
        |  BMB   VB_in_ptr  1  VB500  ' copy to working buffer
        |  AB==  VB500  44          ' 44 = ASCII comma
        |  ---( NEXT )
  Network 2  Convert the 1- or 2-digit index to a byte
  ATH  VB_in_ptr+1  VB_INDEX       ' ASCII to hex

Then issue AT+CMGR=<index> followed by AT+CMGD=<index> to read and clear the message. The full body returned by +CMGR is on a single line preceded by a header of the form +CMGR: "REC UNREAD","+4917...","","25/06/12,10:01:33" followed by \r\n and the message body. A second \r\nOK\r\n terminates the response.

Caller-ID Detection and Relay Trigger

For applications where a recognised phone number should toggle a relay (e.g. a fleet dispatcher switching a pump on or off), the +CLIP unsolicited response is the simplest hook. The modem emits it after the first ring on every incoming call:

+CLIP: "+4917xxxxxxxx",145,,,,1

The fields are:

  1. Caller number in international format, enclosed in ASCII double quotes.
  2. Type of address: 145 = international, 129 = national.
  3. Caller name (often empty on the GSM network).
  4. Validity (0=valid, 1=restricted, 2=not available).
  5. Subaddress (rare).
  6. SAT (network-provided) type (rare).

Use the ATH command immediately after parsing the number to drop the call. This avoids the modem ever answering and incurring airtime. Hang-up can be issued 200 ms after the first ring is detected by polling the RI pin (ring indicator, DB-9 pin 9) or by counting time after the +CLIP: line.

Verification Checklist

  1. Send AT from PuTTY directly wired to the modem. Verify OK.
  2. Send AT+CPIN? — confirm +CPIN: READY (SIM is unlocked).
  3. Send AT+CREG? — confirm +CREG: 0,1 or 0,5 (registered).
  4. Send AT+CSQ — confirm signal ≥ 10 (≈ -83 dBm). Re-locate the antenna if lower.
  5. Send AT+CMGF=1 and AT+CMGS="+49xxxxxxxx"<CR>Hello<SUB>. Confirm the SMS reaches the destination handset.
  6. Connect the modem to the S7-200 with the wiring in Table 1. Power up. Place a scope on Port 0 / Port 1 TXD — confirm the byte stream is identical to step 5.
  7. Trigger I0.0 on the PLC. Confirm an SMS is sent within 2 s of the rising edge.
  8. Dial the SIM number from a test handset. Confirm the relay Q0.0 closes for 1 s on a recognised caller, and stays released for any unknown number.

Troubleshooting Matrix

Table 3 — Common failure modes and remedies
Symptom Likely Cause Diagnostic Remedy
No reply to AT Baud rate or parity mismatch Try 2400, 4800, 9600, 19200 8N1 Re-issue XMT with correct SMB30 value
Modem returns ERROR Command syntax wrong (extra \n, missing ;) Compare byte stream with PuTTY Strip 0x0A, use 0x0D only
Modem returns +CMS ERROR: 512 SIM PIN required Send AT+CPIN="1234" from PuTTY Disable PIN or store PIN in modem NVRAM
SMS not delivered Network rejects service centre address AT+CSCA? Set correct SCA with AT+CSCA="+491710760000"
Garbled characters in received SMS Baud rate wrong, parity enabled Oscilloscope on RXD Set SMB30 parity to none (d=1)
RCV never completes Idle-line timeout too short, or RCV on wrong port Force RCV with breakpoint Increase SMB88 (start char) and SMB89 (end char) or set SMB94 timeout ≥ 100 ms
Caller-ID not detected AT+CLIP=1 not saved Send AT+CLIP=1;&W Save profile with &W for power-cycle persistence
Relay chatters on incoming ring Modem auto-answers before ATH arrives Check ATS0? Set ATS0=0 (no auto-answer)

Alternative PLC Platforms

The same AT-command architecture can be deployed on other small PLC families. The most common alternates are summarised below.

Table 4 — PLC platforms supporting GSM AT-command serial ASCII
Manufacturer / Family Serial Port Protocol Instruction Notes
Siemens S7-1200 + CM 1241 RS232 / RS485 Send_Config / Receive_Config, free ASCII via Send_P2P Use TIA Portal V15+, RS232 module 6ES7241-1AH32
Siemens LOGO! 8 + AM2 AQ RS485 Network project text messages via LOGO! CMR (cloud relay) No direct AT command; use CMR module
Allen-Bradley MicroLogix 1100/1400 RS232 (Channel 0) DF1 half-duplex ASCII, ASCI instruction Set channel 0 to ASCII, then ASCI to write the AT line
Unitronics Jazz / Samba RS232 / RS485 MB/Serial — user-defined ASCII protocol Use SEND with binary ASCII buffer; configure port as User-defined protocol
Schneider Electric M221 / M241 RS485 (SL1), optional RS232 with TM200USB EXCH instruction (free ASCII) EcoStruxure Machine Expert — Basic / Expert
Wago PFC200 + 750-652 RS232 / RS485 e!COCKPIT / Codesys 3.5 — custom serial library Use SerialLineCtrl + raw socket

For the Allen-Bradley MicroLogix 1100/1400, the channel configuration is performed in RSLogix 500 under Channel Configuration → Channel 0 → Driver = ASCII (9600, 8, None, 1). The ASCI instruction then writes a string of bytes directly to the modem; the ARD and ABL instructions read the response. The same diagnostic discipline (PuTTY first, then PLC) applies.

Field-Proven Caveats

  1. 3G/4G sunset — many European carriers have switched off 2G GSM. Confirm the chosen modem band with the local operator before commissioning. SIM800/SIM900 (2G) will not register on a 3G-only or LTE-only network. Use the SIM7000 (LTE Cat-M / NB-IoT) or Quectel BG95 (LTE Cat-M1) for modern deployments, but verify that the AT command set for SMS still follows 3GPP TS 27.007 (it does on both).
  2. Antenna placement — a ¼-wave whip antenna inside a metal cabinet will detune. Use a remote SMA antenna on the cabinet roof with a ≤ 3 m RG174 pigtail.
  3. EMC — the GSM transmit burst draws 1.5–2 A peak at 5 V, causing a 4 V sag on a marginal supply. Fit a 1000 µF bulk capacitor at the modem input and a ferrite bead on the supply line.
  4. Carrier latency — SMS delivery can take 5–30 s. Do not use SMS for safety-critical interlocks. Use a polled GPRS or MQTT-over-MQTT-S link on LTE-M for that.
  5. Power-on default profile — issue AT&W at the end of the init sequence to store CMGF=1, CLIP=1, CNMI=1,1,0,0,0 into the modem's user profile. The PLC will not need to re-send the init after every modem reset.
  6. Watchdog the modem — every 60 s issue AT+CREG? from the PLC. If the response is +CREG: 0,0 (not searching) for more than 30 s, power-cycle the modem via a relay output. This is the single most useful 30 lines of ladder you will ever add.

Safety and Standards

Modems and PLCs in industrial cabinets must comply with the EMC Directive 2014/30/EU and the Low-Voltage Directive 2014/35/EU in the EU, and FCC Part 15 / Part 22 / Part 24 in the USA. Use a modem that carries an R&TTE or RED CE mark, and document the conformity in the technical file. The AT command set itself is a 3GPP normative specification, not a regulatory requirement, but the SMS service centre address format follows ITU-T E.164.

When deploying in hazardous areas (ATEX/IECEx Zone 1 or Zone 2), the GSM modem must be installed in an Ex-certified enclosure and the antenna routed through a certified RF feedthrough. The PLC and modem power supply must be SELV or PELV as defined in IEC 61131-2.

FAQ

What is the minimum S7-200 CPU for GSM SMS via AT commands?

The CPU 222 (6ES7 212-1AB23-0XB0) is sufficient for text-mode SMS. It has 6 digital inputs and 4 digital outputs, an RS485 port, and 2 KB of program memory. For PDU mode, use the CPU 224 (12 KB program memory) to leave headroom for the parser.

Do I need an RS485-to-RS232 converter, or can I wire RS485 directly to the modem?

You must convert. A standard GSM modem's DB-9 port is RS232 (±12 V). The S7-200 Port 0 is RS485 (differential 5 V). A converter such as the Phoenix Contact PSI-MODEM-RS232/485 or the Advantech ADAM-4520 is required, or use the S7-200 CPU 224XP / 226 Port 1 which is true RS232.

What is the correct Freeport configuration for 9600 8N1 on Port 0?

Write 16#09 to SMB30. The bits resolve to: Freeport protocol, no parity, 9600 baud, 8 data bits per character. On Port 1 of the CPU 224XP/226, write the same value to SMB130. Confirm the modem's UART is configured identically — most SIMCom and Quectel parts default to 115200 8N1, so issue AT+IPR=9600 first and store with &W.

Why does my modem return OK to AT but ERROR to AT+CMGS?

Almost always a missing <CR> (0x0D) on the command, or the destination number lacks the international prefix (+). Some operators also reject short numbers (less than 7 digits). Capture the exact byte stream with PuTTY and compare it with the working pattern shown in this article.

How do I send binary sensor data in an SMS without leaving text mode?

Encode the value as 4-character ASCII hexadecimal, e.g. 0A2F for the integer 0x0A2F. The receiving parser converts the two-byte ASCII hex back to the integer. If you need 32-bit floating-point data, use IEEE-754 hex ("41C80000" for 25.0) and parse on the host side.

Can I use the S7-200 to dial a phone number and route voice to a speaker?

No. The S7-200 has no audio codec or DTMF generator. The modem's audio lines (SPK+, SPK-, MIC+, MIC-) must be wired to a separate analogue audio amplifier. The PLC can issue ATD+49xxxxxxxx; to place the call and ATH to hang up, but voice path handling is external.

What replaces the S7-200 in a new design?

The direct successor is the S7-200 SMART (CPU SR20/ST20 and above), which retains the same RS485 port plus an additional RS485/RS232 selectable port. Programming is with STEP 7 Micro/WIN SMART. The freeport equivalent is the Send_Config and Receive_Config instructions on the RS485 module, with identical AT command strings.

Back to blog