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, andAT+CLIPcommands 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:
- 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).
- 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).
- 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.
- 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).
- 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).
- HyperTerminal, PuTTY, or Docklight: a serial console to validate the GSM modem with the AT command set before any PLC code is written.
- 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.
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:
- 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.
- 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.
| 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:
| 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> |
OK → NO 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:
- First scan:
SM0.1→ MOV16#09→ SMB30. - Initialise the receive buffer length:
MOV 200→ VB200 (max receive). - Issue
RCVwith table pointer VB200 and a 100-ms idle-line timeout. - On
RCVcompletion (B9 done bit), strip the trailing0x0D 0x0Afrom 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:
- Caller number in international format, enclosed in ASCII double quotes.
- Type of address: 145 = international, 129 = national.
- Caller name (often empty on the GSM network).
- Validity (0=valid, 1=restricted, 2=not available).
- Subaddress (rare).
- 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
- Send
ATfrom PuTTY directly wired to the modem. VerifyOK. - Send
AT+CPIN?— confirm+CPIN: READY(SIM is unlocked). - Send
AT+CREG?— confirm+CREG: 0,1or0,5(registered). - Send
AT+CSQ— confirm signal ≥ 10 (≈ -83 dBm). Re-locate the antenna if lower. - Send
AT+CMGF=1andAT+CMGS="+49xxxxxxxx"<CR>Hello<SUB>. Confirm the SMS reaches the destination handset. - 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.
- Trigger I0.0 on the PLC. Confirm an SMS is sent within 2 s of the rising edge.
- 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
| 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.
| 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
- 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).
- 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.
- 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.
- 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.
-
Power-on default profile — issue
AT&Wat the end of the init sequence to storeCMGF=1,CLIP=1,CNMI=1,1,0,0,0into the modem's user profile. The PLC will not need to re-send the init after every modem reset. -
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.