Overview
Receiving NMEA 0183 GPS sentences on a Siemens CP341 communication module connected to an S7-300 PLC (CPU 315-2DP) is a common field requirement for time synchronization, fleet tracking, and position logging. When the receive path is built around FB7 (P_RCV_RK) with the ASCII driver and <CR>/<LF> as message terminators, an intermittent symptom appears in which the first 13 bytes of the leading $GPRMC sentence are truncated, while the trailing payload and the eleven subsequent sentences arrive intact.
This article documents the hardware, the FB7 parameterization, the NDR/ERROR diagnostics that must be observed, and the deterministic root-cause path that eliminates the dropped leading bytes. It also covers a parallel architecture using twelve DBs indexed by a counter, and a comparison path that uses an ET200S 1SI with FB2.
Problem Details
| Attribute | Value |
|---|---|
| PLC | Siemens S7-300, CPU 315-2DP (6ES7 315-2AFxx) |
| Comms module | CP341 (6ES7 341-1AH0x-0AE0) – RS232 variant |
| GPS receiver | Garmin eTrex, NMEA 0183, 4800 bps, 8N1 |
| Receive block | FB7 (P_RCV_RK) from Siemens example zXX21_01_PtP_Com_CP34X |
| Driver | ASCII driver (loadable), <CR>+<LF> end-of-message delimiter |
| Observed fault | First 13 bytes of $GPRMC truncated; remaining payload and sentences 2–12 received correctly |
| Spurious symptom | UTC time hhmmss lost from $GPRMC; still present in $GPGLL
|
Hardware and Software Configuration
Refer to the CP 341 Point-to-Point Communication manual (PDF) for the canonical parameter list. The key fields that govern this case are:
| Parameter | Setting | Notes |
|---|---|---|
| Protocol | ASCII | Loadable driver from the CP341 parameter assignment in STEP 7 HW Config |
| Baud rate | 4800 bit/s | Default NMEA 0183 rate |
| Data bits / parity / stop | 8 / None / 1 | NMEA 0183 default framing |
| End-of-message delimiter |
<CR> + <LF> (0x0D 0x0A) |
Required by NMEA 0183 sentence structure |
| Receive buffer | Up to 1024 bytes | CP341 internal ring buffer |
| Flow control | None / RTS-CTS optional | GPS receivers are DCE-like; XON/XOFF not used |
The FB7 (P_RCV_RK) interface, as shipped in the Siemens sample project zXX21_01_PtP_Com_CP34X, supplies the receive interface to the CPU. Relevant FB7 inputs for the diagnostic path:
-
EN– enable; cyclically TRUE in OB1. -
REQ– request new receive job. -
R– reset of the receive job. -
LADDR– I/O base address of the CP341 (e.g., 256). -
DB_NO– destination data block for the received frame. -
DBB_NO– byte offset inside the destination DB. -
L_TYP– frame length storage location. -
L_NO– word offset of frame length inside the DB.
Relevant outputs:
-
NDR(DB45.DBX 0.4) – new data received, single-cycle TRUE. -
ERROR/STATUS– diagnostic flags. Both must be evaluated every cycle.
Root Cause Analysis
The repeatable loss of the leading 13 bytes of $GPRMC is not a CP341 silicon defect; it is a synchronization mismatch between the start of the GPS burst and the first CP341 receive job triggered by FB7. Three plausible contributors must be distinguished before a fix is selected.
Candidate 1: FB7 issued before any character has arrived
If FB7 is started in OB1 with a fixed-cycle rate (e.g., OB1 scan time of ~10 ms) and the GPS receiver emits its 12-sentence burst once per second, the very first FB7 invocation after power-up typically finds the CP341 receive buffer empty. CP341 will return without raising NDR. On the next FB7 call, the first 13 bytes of $GPRMC,... are already buffered inside the CP341's UART FIFO. The ASCII driver treats them as part of the current receive job, but the CP341 ring-buffer pointer logic paired with the FB7 L_NO offset has been observed to discard characters that arrived before the FB7 job started when the start-of-text flag is latched but the delimiter flag was already set by a stray idle-line interpretation of an earlier boot string.
Candidate 2: Spurious early <CR> recognition
Garmin eTrex boot messages and some firmware revisions emit short strings (for example, firmware announcement lines beginning with $P) that may contain <CR> or <LF> bytes that the CP341 ASCII driver interprets as end-of-message markers. If such a string is received between FB7 jobs, the internal CP341 state machine believes a previous message terminated early, and the first 13 bytes of the next legal $GPRMC line are attributed to the previous (incorrectly terminated) message.
Candidate 3: Buffer overrun between sentences 12 and 1
NMEA 0183 sentences are emitted in a single burst every 1 Hz. Between bursts the line is idle for hundreds of milliseconds. If the application counter logic that switches DB_NO (see NMEA Sentence Handling Architecture below) overruns the CP341 ring buffer, the first sentence of the next burst can be truncated to the remainder of the previous job. This matches the observation that the missing bytes are exactly 13 – the CP341 FIFO size minus the trailing <CR><LF> already consumed.
COUNT_ERROR counter on every rising edge of ERROR and a COUNT_NDR counter on every rising edge of NDR. The site report in the field report confirmed COUNT_ERROR remained zero and COUNT_NDR incremented once per sentence. That finding eliminates Candidate 2 and points to Candidate 1 (cold-start desynchronization) or Candidate 3 (DB-switch race).Diagnostic Procedure
- Connect a PC running a serial terminal (HyperTerminal, Tera Term, or PuTTY) to the GPS receiver directly. Confirm 12 sentences per second at 4800 bps 8N1, each terminated by
<CR><LF>. - Use a serial tap or a Y-cable with a line monitor to capture the bytes the CP341 actually sees. Compare against the direct capture. If the direct capture contains the first 13 bytes of
$GPRMCbut the CP341 capture does not, the truncation is inside the CP341/FB7 path. - Expose
STATUSandERRORof FB7 in VAT.STATUS = 0000hon success; non-zero values indicate CP341 internal diagnostics. The commonSTATUSvalues for the CP341 ASCII driver are listed in the CP 341 manual, Section 6. - Add
COUNT_NDRandCOUNT_ERRORcounters and read them online. IfCOUNT_NDRrises exactly 12 per burst andCOUNT_ERRORstays at 0, the receive path is healthy and the truncation is a buffer-management issue. - Add a watchdog timestamp in OB1 and log the OB1 cycle at each
NDRrising edge. If the firstNDRafter a 1-second idle gap carries a stale OB1 cycle counter, the FB7 job began before the GPS burst arrived.
Solution
The fix is twofold: (a) gate FB7 so it only issues a receive job when the CP341 has flagged data ready, and (b) use a small state machine to drop the first burst after power-up, which is the one most affected by cold-start desynchronization.
Solution A: Gate FB7 on CP341 status flags
Read the CP341 status word (input area at LADDR) and call FB7 only when the receive buffer not empty flag is set. This is the canonical pattern documented for the ASCII driver and prevents FB7 from issuing a receive job against an empty buffer. A simplified skeleton in STL:
A IW [LADDR] // CP341 status word
A "CP341_RDY_RCV" // bit assigned in HW Config
JC CALL_FB7
BEU
CALL_FB7: CALL FB7, DB45
REQ :=TRUE
R :=FALSE
LADDR :="CP341_ADDR"
DB_NO :=#curDB
DBB_NO:=0
L_TYP :='B'
L_NO :=2
NDR :="cp341_ndr"
ERROR :="cp341_err"
STATUS:="cp341_status"
Solution B: Discard the cold-start burst
Force a CP341 reset (set R TRUE for one cycle after power-up) and ignore the first NDR sequence. Add a BURST_VALID flag that becomes TRUE only on the second burst after power-up. This eliminates the cold-start race because by the second burst the CP341 internal ring buffer and the FB7 receive pointer are aligned.
Solution C: Suppress stray delimiter interpretation
If the diagnostic tap shows stray <CR> or <LF> bytes from the GPS boot string, configure the CP341 ASCII driver to use only <LF> (0x0A) as the end-of-message delimiter, not <CR><LF>. NMEA 0183 sentences are always terminated by <CR><LF>, so a single-byte <LF> delimiter is sufficient and immune to the trailing <CR> that some boot strings emit on its own line.
NMEA Sentence Handling Architecture
The original site implementation uses 12 destination data blocks (DB51–DB62), one per NMEA sentence type. A counter C3 holds the currently active destination DB number. C3 is incremented on every NDR rising edge (DB45.DBX 0.4) and reset to C#51 when the inter-sentence gap (measured by a 100 ms tick counter C4) exceeds 8, which corresponds to the typical 1-second NMEA burst interval.
| Element | Symbol | Function |
|---|---|---|
| Receive-done flag | DB45.DBX 0.4 | FB7 NDR output |
| Burst-slot counter | C3 | Current DB number (51–62) |
| Idle-gap counter | C4 | Counts 100 ms ticks since last NDR |
| Tick | M0.0 | Clock bit, 100 ms |
| Destination DB | DB45.DBW 2 | Mirror of C3 for FB7 DB_NO
|
The implementation in STL:
// NDR rising edge -> advance slot
A DB45.DBX 0.4
CU C3
R C4
// 100 ms tick -> accumulate idle gap
A M0.0
CU C4
// If gap > 800 ms -> wrap to first sentence slot
L C4
L 8
>I
L C#51
S C3
// Mirror to FB7 DB_NO
A DB45.DBX 0.4
L C3
T DB45.DBW 2
IF gap > 800 ms THEN slot := 51; END_IF; block to gain a symbolic, watchable representation in STEP 7 and to break less under online edits. The same logic is implemented cleanly in the Siemens example zXX21_01_PtP_Com_CP34X using a cyclic interrupt OB (OB35) for the 100 ms tick.Verification
- Force a CP341 reset and observe VAT
BURST_VALID. It must rise after the first full 1-Hz burst is received and discarded. - Watch DB51 in VAT or with a table view during a burst. The first 6 characters of DB51 must read
$GPRMCin ASCII. - Confirm
STATUSremains0000hfor the full 12-sentence burst. - Confirm
COUNT_NDRadvances exactly 12 per burst andCOUNT_ERRORstays at 0 over a 10-minute observation window. - Capture the GPS burst with a serial tap and compare byte-for-byte against DB51–DB62 contents.
Alternative Architecture: ET200S 1SI with FB2
The Siemens Support entry referenced in the source (Siemens entry ID 22865909) demonstrates a CP341-class receive using an ET200S 1SI serial interface module (6ES7 138-4DF01-0AB0) and the FB2 (P_RCV) block. The architectural differences relevant to the missing-bytes symptom:
| Aspect | CP341 + FB7 (P_RCV_RK) | ET200S 1SI + FB2 (P_RCV) |
|---|---|---|
| Module placement | Central rack of S7-300 | Distributed I/O on PROFIBUS DP |
| Driver | Loadable ASCII / 3964R / RK512 | Integrated, no driver load |
| Cold-start race | Possible at power-up | Typically absent, PROFIBUS startup sequence aligns the receive path |
| Buffer | 1024-byte internal ring buffer | Per-channel 32-byte FIFO plus application buffer |
| Application focus | Multi-protocol, high-volume | Compact, single-protocol nodes |
For sites that already operate the S7-300 on PROFIBUS and need a distributed GPS receiver per station, the ET200S 1SI path with FB2 is more deterministic and avoids the cold-start 13-byte loss because PROFIBUS DP startup does not begin transmitting application data until the slave is in data exchange, by which time the GPS burst has already been framed.
Robustness Considerations and Field Notes
-
Baud-rate mismatch: some Garmin eTrex firmware revisions reconfigure to 9600 bps after cold start. Verify the receiver stays at 4800 bps 8N1; CP341 will report
STATUS = 0E01h(framing error) under rate mismatch. - Cable length: RS232 is specified to 15 m. For an outdoor GPS antenna mount, use a short RS232 pigtail and a longer RS422 segment with the 6ES7 341-1CH0x-0AE0 CP341 variant.
-
Checksum validation: every NMEA 0183 sentence ends with
*hhfollowed by<CR><LF>. Add a CRC16-XOR checksum check on the received string inside the destination DB before using the data. - Modbus coexistence: if the same CP341 is later re-tasked as a Modbus slave using MODB_341, the ASCII driver must be replaced by the MODB_341 driver. The two drivers are not co-resident on the same CP341 firmware image.
Summary of Recommended Fixes
| Symptom | Recommended action |
|---|---|
First 13 bytes of $GPRMC missing at power-up only |
Discard first burst; gate FB7 on CP341 ready-to-receive flag |
| Truncation persists on every burst | Switch delimiter from <CR><LF> to <LF> only; verify GPS baud rate |
| STATUS non-zero | Check CP341 manual diagnostics table; reduce baud rate or replace cable |
| Need UTC time only | Read $GPGLL instead of $GPRMC; the time field is in the same offset |
| Distributed topology | Migrate to ET200S 1SI with FB2 per Siemens entry 22865909 |
Why are exactly 13 bytes of the first $GPRMC sentence missing when receiving NMEA 0183 on a CP341?
The most likely cause is a cold-start race between the FB7 (P_RCV_RK) receive job and the start of the GPS burst: characters arrive at the CP341 UART before FB7 issues its receive job, and the CP341 ASCII driver attributes them to the prior (empty) frame. The 13-byte size matches the CP341 FIFO plus <CR><LF> consumption. The fix is to gate FB7 on the CP341 ready-to-receive flag and discard the first burst after power-up.
Can I use FB7 (P_RCV_RK) with the ASCII driver for NMEA 0183 GPS data?
Yes. FB7 with the loadable ASCII driver and <LF> or <CR><LF> as the end-of-message delimiter is a supported configuration for NMEA 0183 on CP341 at 4800 bps 8N1. The driver must be loaded into the CP341 via HW Config; refer to the CP 341 manual, Section 4.
Which FB block is correct for CP341 ASCII receive – FB2 or FB7?
FB7 (P_RCV_RK) is the canonical receive block for the CP341 loadable drivers. FB2 (P_RCV) belongs to the ET200S 1SI serial interface module and is documented in the Siemens Support entry referenced in the source. Mixing FB2 with CP341 will not work.
How do I separate the 12 NMEA sentences into 12 destination data blocks?
Use a slot counter incremented on each FB7 NDR rising edge and reset when the inter-sentence gap exceeds the burst interval (typically 800 ms). The slot counter value is transferred to the FB7 DB_NO input so each sentence is stored in its dedicated DB (DB51–DB62 in the original implementation).
Is MODB_341 usable on the same CP341 that receives NMEA 0183 ASCII?
No. The ASCII driver and the MODB_341 Modbus RTU slave driver are mutually exclusive loadable images on the CP341. Switching protocols requires reloading the driver in HW Config and re-initializing the CP341.