On an S7-1200 or an S7-1500 there are four places a function block can keep state that is not in its instance DB, and every one of them makes a second FB instance of FB_Valve share memory with the first. The report is always one of three: valve 2 opens when valve 1 is commanded, or valve 1’s open timer runs from the moment valve 2 was told to open, or valve 2 does nothing at all until valve 1 is cycled.
Find which one it is in this order, because the first is a thirty second check and the last needs a compile setting.
- Both calls were given the same instance DB.
- The FB uses a bit memory address, a SIMATIC timer or counter, or a global DB tag internally.
- An edge instruction inside the FB has a global M_BIT, or an IEC timer inside it has a single-instance DB.
- A Temp variable is read before it is written, in a block with standard access.
The rest is what each looks like, why the manual says it will happen, and what the block should have looked like.

The two calls in this project had the same DB, and the block also carried a global edge bit and a single-instance timer. Fixing the DB alone would have moved the fault, not removed it.
The instance DB the second FB instance was given instead of its own
The S7-1200 manual states the model in one sentence: you can call an FB multiple times, each time with a unique instance DB, and calls to the same FB with different instance DBs do not affect the data values in any of the other instance DBs. Different instance DBs. When you drag a second call of FB_Valve into a network, the Call options dialog opens, and its drop-down offers the DBs that already exist for that FB. Picking FB_Valve_DB there instead of letting it create FB_Valve_DB_1 compiles clean, downloads clean, and gives both valves one set of Inputs, Outputs and Statics. The symptom is specific: the last call in the scan wins. Both calls write their Inputs into the same DB, so valve 2’s call overwrites what valve 1’s call put there, then valve 1’s Outputs are read from whatever valve 2 left. If valve 1 seems to obey valve 2’s command and valve 2 seems to obey its own, this is it.
Nothing in the compile, the load preview or the diagnostics buffer will tell you so.
Check it without opening either call, and before you touch any code. In the project tree, open the instance DB and look at the cross-reference, or right-click the FB and open its call structure; two calls pointing at one DB show up in a second.
The fix is one new DB per call. Delete the second call’s DB assignment, open Call options again, and let it create a new one, or better, call FB_Valve as a multi-instance inside a station FB so the DB count stops growing at all.
The global bit inside the block
An FB that touches %M10.0, a global DB tag, or a SIMATIC timer T1 by name is not a block with two instances. It is a block with one, called twice.
The programming guideline draws the line at global memory: memories are called global when they can be accessed from any location of the user program, which covers bit memory, timers, counters and global DBs. Its recommendation is not to use bit memory at all, to use global DBs instead, and for timers and counters to use the IEC instructions in connection with multi-instances. Inside an FB that is called more than once, that recommendation is not style. It is the difference between two valves and one. Symptoms vary with what the bit does. A global Step word means both instances run one sequence. A global timer means the second valve’s open delay starts when the first valve started it, which is the “valve 2 opens early” report. A global flag used as a one-shot means whichever instance runs first in the scan consumes the pulse and the other never sees it. Search the FB for every absolute address and every "DB_name".tag that is not on the interface. Each one moves to the Static section, or comes in through an InOut pin if the two instances are meant to share it. Sharing is fine when it is deliberate and visible on the call.
The edge bit and the timer that came with a DB

One M_BIT shared by two instances. Valve 2 has been on since scan 1, so when valve 1 rises at scan 3 the bit already reads 1 and the edge is missed. With its own bit, valve 1’s Q would pulse for one scan.
This is the version of cause 2 that hides in plain sight, because the address was typed by the editor and not by you. P_TRIG and the P contact take an M_BIT operand, and the S7-1200 manual says exactly what it is for: the previous state of the monitored input is stored in a memory bit, and because that bit must be maintained from one execution to the next, you should use a unique bit for each edge instruction and not use that bit anywhere else in your program. Two instances of the same P_TRIG on %M10.0 are two edge instructions on one bit. The mechanics are in the figure. Valve 2’s command has been on since scan 1, so on every scan its call writes 1 into %M10.0. Valve 1’s command rises at scan 3; its P_TRIG compares the input, 1, with the memory bit, already 1 from valve 2’s call, and reports no edge. Valve 1 never gets its one-scan pulse, which is the “valve 2 does nothing until valve 1 is cycled” report, seen from the other side.
R_TRIG and F_TRIG avoid this because they carry their own instance, and the manual notes that when you insert one, the Call options dialog asks whether the edge memory is stored in its own data block, a single instance, or as a local tag in the block interface, a multi-instance. A single-instance R_TRIG_DB inside an FB is the same shared-bit fault with a longer name. The IEC timers have the identical shape. TON placed inside an FB with a single-instance IEC_Timer_0_DB is one timer for every instance of the FB. The manual describes the alternative in its timer chapter: when you place a timer in an FB you can select the multi-instance option, and the timer data then lives in the FB’s own instance DB, one copy per instance. The guideline says the same thing more bluntly: program local functions, for example timer, counter, edge evaluation, as multi-instances.
Inside an FB the answer is multi-instance, every time, for the edge and for the timer.

What the interface of FB_Valve should look like. Every block with memory is a Static of FB_Valve, so a second instance DB carries a second copy of each, and the only Temp is written first thing.
The Temp that was never written

Only the first three rows are per instance. The two Temp rows differ by one block attribute, and the standard-access one is the case that produces the strangest symptoms.
Temp variables live on the L stack, which the guideline says is valid only for the current processing, so temporary tags have to be initialised in each cycle. What happens if you do not depends on one attribute of the block. In an optimized block, Temps are preset with their default value at every call, on an S7-1500 and on an S7-1200 from firmware V4. In a block with standard access, the guideline says they are undefined for each call. Undefined in practice means: whatever the previous block left on the stack. Call FB_Valve twice in a row from OB1 and the previous block is FB_Valve, for the other valve. A Temp that valve 1’s call wrote and valve 2’s call reads before writing carries valve 1’s value across. That is the purest form of “the second instance behaves like the first”, and it is the hardest to see, because the value is not in any DB and the watch table cannot show it to you. The symptom shifts with the scan order, with what runs between the two calls, and with the size of the blocks in between, which is why it gets reported as intermittent. Two fixes, and do both. Write every Temp before you read it, at the top of the block, unconditionally. And leave “Optimized block access” on for every FB that does not need absolute addressing — the guideline’s own reason for it is that the resulting behaviour is then not accidental but reproducible. A block that has to be standard access for a PUT or GET pointer or an old panel should be a DB, not an FB with logic in it.
The dead end here is the FB’s Static section. People look for the leak there first, because that is where the state is supposed to be, and Statics are the one place the compiler already keeps separate. If both instances have their own DB and the fault is still there, the leak is somewhere the instance DB does not reach: an M address, a timer DB, or the stack.
Making it not happen again
One habit removes all four causes. Inside an FB, every stateful thing is declared in the Static section — a Bool for a latch, R_TRIG and TON as multi-instances, a nested FB as a multi-instance — and the only things the block reaches for outside itself are its interface pins. The guideline recommends multi-instances for reducing the number of instance DBs and for local functions such as timer, counter and edge evaluation, and both reasons are really the same one: a block that owns all of its memory can be called as often as you like. Then, when you do call it twice, let the dialog create the DB. On an S7-1500 this is also what makes an interface change in RUN survivable, because each instance carries its own memory reserve and its own retained values.
If you are on the Rockwell side of the shop, the same fault has the same four shapes in an Add-On Instruction — a tag typed as the same backing tag twice, a controller-scoped tag inside the logic, a timer that is not a local — and the place to start is how Add-On Instructions are built.
What to check first
Open the cross-reference for the FB and count the instance DBs against the calls. If the numbers match, search the block body for %M, %T, %C and any "DB string. If that is clean, compile with the block’s Temps in view and write each one at the top before anything reads it.
One of those three passes finds it, and the order is by how long each takes.