1. Application Overview
The Siemens OP37 operator panel is a text/graphic HMI from the OP7/OP17/OP27/OP37 family designed for S7-300 and S7-400 controllers. A common field requirement is to allow the operator to enter a future calendar date and time on the OP37 and have the controller assert a digital output (or set a bit in a data block) at the exact moment the real-time clock reaches the scheduled value. Typical use cases include batch start times, shift overrides, lighting schedules, lubrication cycles, and one-shot maintenance interlocks.
Because the OP37 communicates over MPI or PROFIBUS and exposes a fixed set of "PLC jobs" to the CPU, the cleanest implementation is to keep all of the scheduling logic inside the S7-300/400 user program. The HMI is reduced to a simple operator entry surface (four to six integer fields) and the actual comparison runs against the value returned by SFC1 (READ_CLK). This article documents the configuration of the OP37, the PLC data block layout, the SFC1 call, the BCD-to-integer conversion of the date/time fields, and the equality comparison that drives the trigger bit.
References used in this article:
- Siemens FAQ: Reading date/time from an OP/TP via PLC job
- SFC1 READ_CLK - Read system clock (S7-300/400)
- SFC0 SET_CLK - Set system clock (S7-300/400)
- OP37 Operator Panel Equipment Manual
- ProTool/Pro V6 - Configuring Windows-based Panels
2. Prerequisites
Before starting the configuration, confirm the following:
- Controller: SIMATIC S7-300 (CPU 314/315/317) or S7-400 with firmware that exposes SFC0 and SFC1. Both system functions are part of the standard library and are available on every S7-300/400 CPU from the 314CIFM onward.
- HMI: OP37 (6AV3 637-1LL00-0AX0 or compatible variant) with ProTool/Pro configuration software matching the panel firmware.
- Engineering: STEP 7 V5.5 or STEP 7 Professional (TIA Portal migration is possible but the original toolchain for an OP37 is ProTool/Pro V6.x).
- Connection: MPI cable (6XV1 830-0EH10) or PROFIBUS DP cable, terminated per Siemens guidelines, with a valid bus address for the OP37 (default 1) and the CPU (default 2).
- Date/time data block: A shared DB (for example DB100) configured with at least 12 bytes of data: 8 bytes for the operator-entered target and 4 bytes of status.
3. OP37 Date/Time Field Configuration in ProTool
Two viable data-entry strategies are available on the OP37:
- Discretized numeric fields. Six separate integer input fields, one each for Year, Month, Day, Hour, Minute, Second. This is the most robust method because ProTool/Pro V6 does not support the modern "Date/Time Picker" widget on the OP37 text platform.
-
String field with PLC-side parsing. A single ASCII string field on the OP37 in which the operator types the target as
YYYY-MM-DD HH:MM:SS. The PLC converts the string using FC 38 (STRING to INT/BCD) and then assembles the eight-byte DT structure. This method is more compact on screen but is fragile if the operator mistypes the delimiters.
The discretized numeric approach is recommended for field installations. Configure six input fields on a screen labeled "Schedule Next Run":
| OP37 Field | Variable Tag | Data Type | Range |
|---|---|---|---|
| Year | DB100.DBW0 | INT | 2010 - 2089 |
| Month | DB100.DBW2 | INT | 1 - 12 |
| Day | DB100.DBW4 | INT | 1 - 31 |
| Hour | DB100.DBW6 | INT | 0 - 23 |
| Minute | DB100.DBW8 | INT | 0 - 59 |
| Second | DB100.DBW10 | INT | 0 - 59 |
In ProTool/Pro, define a new area pointer of type DB pointing at DB100 with a length of 12 bytes, then bind each field to the corresponding word offset. Set the field properties to Input, enable Limits with the minimum/maximum values above, and select the display format 9999 for year and 99 for the other fields. Tick "Apply value on ENTER" rather than "on every change"; this prevents partial entries (for example a momentary 2 for the month) from corrupting the comparison.
4. PLC Job 41 - Reading Date/Time from the OP37
The OP37 exposes a set of predefined PLC jobs to the CPU. The field report correctly identifies Job 41 as the function that requests the current date and time from the operator panel. The job is triggered by writing a specific value to a fixed interface word in the OP37 area pointer; the result is then placed by the OP37 into a configurable return area.
Mechanics of the job:
- The CPU writes the job number (41 decimal = 0x29) into the OP37 control word, typically at the offset defined by the area pointer Job mailbox.
- The OP37 receives the request, reads its internal RTC, and writes the eight-byte DATE_AND_TIME value into the configured Result mailbox area (a DB or flag range).
- The OP37 acknowledges by clearing the job number back to 0. The CPU can poll the job word or use a positive edge on a status bit to know the read is complete.
A typical STL sequence to trigger the read and to wait for acknowledgement:
// Trigger OP37 to read its current date/time
L 41 // Job number 41 = read date/time
T MW 200 // Job mailbox area pointer
// Wait for OP37 to clear the job word (acknowledgement)
WAIT: L MW 200
L 0
<>I
JC WAIT // Spin until OP37 finishes
// Result is now in DB101 (8 bytes, DT format)
The exact area pointer offsets are defined in the ProTool project under Area Pointers > Job Mailbox and Area Pointers > Result Mailbox; record the offsets you use and replace the MW 200 and DB101 references in the example above accordingly. The detailed step-by-step setup of the job mailbox is documented in the ProTool/Pro V6 manual chapter on communication between the panel and the PLC.
5. SFC1 READ_CLK - Reading the CPU Real-Time Clock
The PLC job in step 4 is only useful when you also want to display the panel clock or synchronize it. The actual scheduling comparison must run against the CPU clock, which is read with SFC1 (READ_CLK). The function fills an eight-byte buffer of type DATE_AND_TIME (DT) at the destination pointer supplied as the CDT input.
| Parameter | Declaration | Type | Description |
|---|---|---|---|
| RET_VAL | OUTPUT | INT | Error code (0 = no error). See SFC1 help for the W#16#80xx codes. |
| CDT | OUTPUT | DATE_AND_TIME | 8 bytes; current CPU date and time in BCD format. |
STL call against a temporary variable stored in DB1:
CALL SFC1
RET_VAL := MW 0
CDT := DB1.DBD 0 // Bytes 0..7 of DB1 hold the DT
The eight bytes returned are encoded in BCD according to the IEC 61131-3 DATE_AND_TIME layout:
| Offset | Content | Range (BCD) | Encoded Value |
|---|---|---|---|
| Byte 0 | Year (decade in high nibble, year within decade in low nibble) | 90..89 (= 1990..2089) | B#16#10 = 2010 |
| Byte 1 | Month | 01..12 | B#16#12 = December |
| Byte 2 | Day | 01..31 | B#16#08 = 8th |
| Byte 3 | Hour | 00..23 | B#16#06 = 06:00 |
| Byte 4 | Minute | 00..59 | B#16#00 |
| Byte 5 | Second | 00..59 | B#16#00 |
| Bytes 6-7 | Milliseconds (3 1/2 BCD digits) and day of week (1=Sun..7=Sat) in bits 0-3 of byte 7 | 000..999, 1..7 | varied |
6. SFC0 SET_CLK - Optional Master/Slave Clock Selection
If the S7 CPU is to act as a master clock for the OP37, call SFC0 (SET_CLK) in OB1 to write the current time back to the panel via a periodic PLC job. The function signature is:
CALL SFC0
RET_VAL := MW 2
PDT := DB1.DBD 0 // Source DT to push to the panel
RET_VAL codes for SFC0 are listed in the SFC0 documentation. The two most common values are W#16#0000 (success) and W#16#8081 (invalid date/time, typically an out-of-range month or day-of-month). Always evaluate the RET_VAL and latch a fault in the status DB if a write fails - an unsynchronized panel that drifts is a common root cause of "the schedule did not fire" complaints.
7. Converting the DT Structure to Comparable Integers
The SFC1 result is in BCD while the OP37 inputs are typically in decimal INT. Two strategies are available:
7.1 Strategy A - BCD-to-INT using standard library FC 21 (BCD_I)
STEP 7 provides a small library of BCD/INT conversion blocks. The relevant block is FC 21 (BCD_I) in the Standard Library > TI-S7 Converting Blocks. It accepts a BCD word and returns an INT.
// Convert each BCD byte of the DT to INT
CALL FC 21
BCD := DB1.DBB 0 // Year decade nibble is in B#16#10 (year 2010)
RET_VAL := MW 10 // Integer year (2010)
CALL FC 21
BCD := DB1.DBB 1
RET_VAL := MW 12 // Integer month
CALL FC 21
BCD := DB1.DBB 2
RET_VAL := MW 14 // Integer day
CALL FC 21
BCD := DB1.DBB 3
RET_VAL := MW 16 // Integer hour
CALL FC 21
BCD := DB1.DBB 4
RET_VAL := MW 18 // Integer minute
CALL FC 21
BCD := DB1.DBB 5
RET_VAL := MW 20 // Integer second
Caveat: FC 21 expects a full 16-bit BCD word, but the DT layout provides only a single byte for the year decade plus a partially-used byte for the milliseconds. For the year byte (DB1.DBB 0), the high nibble holds the decade and the low nibble holds the year within the decade. Build a temporary BCD word by shifting and combining, for example:
L DB1.DBB 0 // Load year decade/year (e.g. B#16#10 = 2010)
SLW 4 // Shift left 4 bits to align with FC21 word format
T MW 30 // Temporary BCD word
CALL FC 21
BCD := MW 30
RET_VAL := MW 10 // Integer year 2010
Month, day, hour, minute and second are direct single-byte BCD values; they can be converted by loading them into a word that has been pre-filled with zeros in the upper byte (the SFC1 storage guarantees zero in the unused half of the BCD word for these fields).
7.2 Strategy B - Direct byte-wise comparison
If you do not need the integer values for any other purpose (display, arithmetic, logging), the fastest comparison is a direct byte-wise compare of the OP37-supplied BCD with the SFC1-supplied BCD. To do this, store the OP37 inputs in BCD format rather than decimal INT. The ProTool/Pro field property Display format > BCD exists for precisely this reason, and the conversion in the PLC is then a single ==B per field.
L DB100.DBB 0 // OP37-supplied year (BCD, input by the operator)
L DB1.DBB 0 // SFC1 year (BCD, current)
==B
= M 50.0 // Year match
8. Comparison Logic and Trigger Bit
The trigger bit is set when all six fields match. Using a bitwise AND of the individual matches prevents a spurious assertion if, for example, the year and month match but the day differs.
// Individual matches (each is the result of a ==B or ==I compare)
U M 50.0 // Year
U M 50.1 // Month
U M 50.2 // Day
U M 50.3 // Hour
U M 50.4 // Minute
U M 50.5 // Second
= DB100.DBX 20.0 // "Schedule reached" trigger bit
// One-shot edge - fires for exactly one OB1 scan
UN M 51.0 // Previous-cycle state
U DB100.DBX 20.0
= M 51.0 // Latch for next cycle
S DB100.DBX 20.1 // Rising-edge pulse
For a sustained output (for example, a relay that must stay on for the entire minute), replace the one-shot with a self-latching coil that is reset by the operator with a second OP37 button.
(second == target-1) AND (minute already advanced) for the second-only case.9. Complete STL Implementation in OB1
The following is a working snippet that ties the OP37 inputs, SFC1 read, BCD conversion, and trigger logic into a single OB1 block. Paste it into a new STL source and connect to a CPU 315-2 DP for live testing.
// =========================================================
// OB1 - Schedule trigger for OP37-entered date/time
// Author : Field Engineering Notes
// Tested : CPU 315-2 DP / Firmware V3.3 / STEP 7 V5.5
// =========================================================
// --- 1. Read CPU clock ----------------------------------
CALL SFC1
RET_VAL := MW 0
CDT := DB1.DBD 0
// --- 2. Convert BCD to INT ------------------------------
// Year
L DB1.DBB 0 // BCD year byte
SLW 4 // Align to FC21 input format
T MW 30
CALL FC 21
BCD := MW 30
RET_VAL := MW 10 // Year as INT (1990..2089)
// Month
L B#16#0
L DB1.DBB 1
OW
T MW 32
CALL FC 21
BCD := MW 32
RET_VAL := MW 12 // Month as INT
// Day
L B#16#0
L DB1.DBB 2
OW
T MW 34
CALL FC 21
BCD := MW 34
RET_VAL := MW 14 // Day as INT
// Hour
L B#16#0
L DB1.DBB 3
OW
T MW 36
CALL FC 21
BCD := MW 36
RET_VAL := MW 16 // Hour as INT
// Minute
L B#16#0
L DB1.DBB 4
OW
T MW 38
CALL FC 21
BCD := MW 38
RET_VAL := MW 18 // Minute as INT
// Second
L B#16#0
L DB1.DBB 5
OW
T MW 40
CALL FC 21
BCD := MW 40
RET_VAL := MW 20 // Second as INT
// --- 3. Compare against OP37 targets --------------------
L MW 10
L DB100.DBW 0 // OP37 year (INT, from ProTool field)
==I
= M 50.0
L MW 12
L DB100.DBW 2 // OP37 month
==I
= M 50.1
L MW 14
L DB100.DBW 4 // OP37 day
==I
= M 50.2
L MW 16
L DB100.DBW 6 // OP37 hour
==I
= M 50.3
L MW 18
L DB100.DBW 8 // OP37 minute
==I
= M 50.4
L MW 20
L DB100.DBW 10 // OP37 second
==I
= M 50.5
// --- 4. Aggregate and edge-detect -----------------------
U M 50.0
U M 50.1
U M 50.2
U M 50.3
U M 50.4
U M 50.5
= DB100.DBX 20.0 // "Schedule reached" static flag
UN M 51.0 // Previous-cycle memory
U DB100.DBX 20.0
S DB100.DBX 20.1 // One-shot pulse
U DB100.DBX 20.0
= M 51.0 // Latch for next cycle
BE
10. Verification and Commissioning
- Download and go online. In STEP 7, select PLC > Download, then PLC > Monitor/Modify. Open DB1 and confirm the eight bytes at offset 0 are updating once per OB1 cycle with the current date/time in BCD.
- Cross-check against the panel. On the OP37, navigate to the System > Date/Time screen. The displayed values should match DB1 within one second.
- Force a near-term schedule. On the OP37, enter a target 60 seconds in the future and confirm via the monitor that the inputs in DB100 update. The trigger flag at DB100.DBX20.0 should rise exactly when the CPU clock crosses the target, and the one-shot pulse at DBX20.1 should be a single OB1 scan wide.
-
Wire the trigger to a real output. In the project, place a coil on
DB100.DBX20.0driving a digital output module. For safety, put the bit through a normally-closed hardware enable in the field wiring. - Document and back up. Use the Save as function in ProTool/Pro and STEP 7 to commit the project; store the .s7p, the .pdb, and the area-pointer table in the machine's documentation folder.
11. Troubleshooting Matrix
| Symptom | Likely Root Cause | Diagnostic | Corrective Action |
|---|---|---|---|
| OP37 displays "—" or "###" for input fields | Area pointer not connected, or DB100 missing in the S7 project | In ProTool/Pro, open Area Pointers and confirm the DB and length; in STEP 7 confirm DB100 exists with the configured length | Recompile the ProTool project, re-download, and power-cycle the OP37 |
| Trigger never asserts | SFC1 not called in OB1 (no cyclic read) or RET_VAL nonzero | Online > Monitor DB1: byte 0 should be the current year in BCD | Add CALL SFC1 in OB1; evaluate MW0 and clear any SFC1 error |
| Trigger fires on the wrong day | OP37 field configured as decimal INT but compared in BCD, or vice versa | Use Monitor/Modify to inspect both DB100 and DB1; check the FC21 conversions | Standardize on one encoding (INT recommended for the OP37 inputs) |
| Trigger fires continuously once the schedule is reached | Missing one-shot edge detection | Trace M51.0; the rising-edge pulse should be a single scan | Add the UN M51.0 / U DB100.DBX20.0 / S DBX20.1 sequence from section 9 |
| Time on OP37 drifts from the CPU clock | Panel configured as master clock and never resynced | Check whether PLC Job 0 (date/time) is being driven by the CPU | Switch the OP37 to slave mode and add a periodic SFC0 write from the CPU |
| SFC0 returns W#16#8081 | Invalid date (e.g. Feb 30) fed from a corrupt OP37 string | Inspect the source DT bytes; check day > days_in_month | Validate the OP37 inputs in ProTool/Pro with the limit tables from section 3 |
| SFC1 returns W#16#80A1 | CPU in STOP, or clock not yet synchronized after power-up | Check CPU status LED and the diagnostic buffer | Wait for the clock battery-backed time to be valid; restart the CPU |
| Year wraps from 2089 to 1990 unexpectedly | BCD storage is two-digit; year value entered as 2090+ | Read DB1.DBB0 and check the BCD value | Clamp the input range in ProTool to 1990-2089 |
12. Frequently Asked Questions
Does SFC1 have a one-second resolution on every S7-300 CPU?
The standard S7-300 CPUs (314, 315, 316, 317) return a one-second resolution from SFC1. The 318-2 and all S7-400 CPUs support one-millisecond resolution. If the application requires sub-second scheduling, migrate to a 318-2 or an S7-400.
What is the difference between PLC Job 40 and Job 41 on the OP37?
Job 40 writes the CPU date/time into the panel (set panel clock), and Job 41 reads the panel date/time back into the CPU. The exact job numbers and area-pointer offsets are listed in the OP37 Equipment Manual at Siemens Support entry 1408288.
Can I store the target schedule in a DATE_AND_TIME tag on the OP37?
The OP37 does not expose a true DT picker. Use six discrete integer fields (Year, Month, Day, Hour, Minute, Second) with limit validation. For string-based entry, parse the string on the PLC side using FC 38 from the IEC library.
How do I make the trigger fire for an entire minute rather than a single second?
Replace the one-shot pulse with a self-holding coil. Set the coil on the matching condition and reset it when (a) the operator presses a Reset button on the OP37, or (b) the current minute exceeds the scheduled minute.
What happens if the CPU clock is not yet valid when the OP37 starts up?
SFC1 returns RET_VAL = W#16#80A1 and the CDT buffer is left unchanged. In the user program, gate the comparison logic on a valid clock flag (for example, set the flag the first time RET_VAL = 0) to avoid a spurious trigger at the all-zero initial state.