WinCC Flexible 2008 VB Script: Read and Write S7-200 V Bytes on MP277
1. Overview
WinCC Flexible 2008 (Standard) ships with a VBScript runtime on the MP 277 10" Touch and other Windows CE-based panels. That runtime exposes the SmartTags object, which lets a script read any tag declared in the project's tag table and write the value back. Combined with the fact that S7-200 V memory is byte-addressable, you can perform tag-to-tag copies (for example, VB100 -> VB200) entirely from an HMI script, without adding a single instruction to the PLC program.
This approach is most useful when the S7-200 CPU has run out of user program memory. A CPU 226, for instance, only has 24 KB of program space (8 KB of which is reserved for the project and a further portion is consumed by the run-time library). Once that budget is exhausted, supplementary logic can be moved into the HMI, executed on tag-change events, scheduled timers, or screen-cycle triggers.
2. Prerequisites
| Item | Specification / Notes |
|---|---|
| Engineering tool | WinCC Flexible 2008 Standard (SP2 or later recommended), with ES installed on Windows XP SP3 / Windows 7 |
| HMI panel | SIMATIC MP 277 10" Touch (6AV6 643-0CD01-1AX1 or later); firmware ≥ V11.0.0.0 recommended for VBScript stability |
| PLC | SIMATIC S7-200 CPU 226 (6ES7 216-2BD23-0XB0 or comparable), STEP 7 Micro/WIN V4.0 SP9 for project transfer |
| Connection | PPI / MPI multi-master cable (6ES7 901-3DB30-0XA0) or Ethernet via CP 243-1 IT; configured in WinCC Flexible as a "SIMATIC S7-200" channel |
| VBScript runtime | Enabled by default on MP 277. Verify under Device Settings → Device Properties → Runtime → Script. |
| Tag count budget | MP 277 supports 4 096 tags. Each declared byte/word tag counts separately. |
Reference: WinCC Flexible 2008 System Manual (Siemens Support entry 18796084) and the S7-200 Programmable Controller System Manual (entry 1109657).
3. Tag Configuration in WinCC Flexible
For a script to access a V-memory location, the tag must already exist in the connection's tag table. Three configuration choices are critical:
-
PLC address — Point to a V-byte address. For example, the S7-200 tag "Tag_VB100" with PLC address
VB100(data type Byte). -
Acquisition mode — Set to
Cyclic continuousif the script is going to read or write this tag on a timer or screen event and you want the panel to refresh it independently. UseCyclic on useif you want to reduce bus load and only poll when the script touches the tag. -
Data type — Match the type used in the script's right-hand side. A
SmartTags("Tag_VB100") = SmartTags("Tag_VW50")assignment requires either an explicit conversion or that the destination tag's type accepts the value.
| S7-200 area | WinCC Flexible syntax | Typical data type |
|---|---|---|
| VB100 (single byte) | VB100 |
Byte / USInt |
| VW100 (16-bit word) | VW100 |
Word / Int |
| VD100 (32-bit double word) | VD100 |
DWord / DInt / Real |
| V100.0 – V100.7 (bit access) |
V100.0 through V100.7
|
Bool |
| VB100 and VB101 together | Declare two tags: VB100, VB101
|
Pair to form VW100 |
SmartTags("VW100").LowByte accessor.4. Direct Tag-to-Tag Copy: VB100 -> VB200
The simplest, most robust pattern is to declare both endpoints as tags and let VBScript perform the assignment. This works on the MP 277 runtime without any third-party add-on.
Procedure:
- In the project tree, open Communication → Tags for the S7-200 connection.
- Add tag Src_VB100, address
VB100, data type Byte, acquisition mode Cyclic continuous. - Add tag Dst_VB200, address
VB200, data type Byte, acquisition mode Cyclic on use. - Attach a new script to the event you want to drive the copy (e.g. a button's Press event, or a scheduler with a 100 ms cycle).
Script body:
Sub OnLButtonDown(ByVal Item)
Dim src, dst
src = SmartTags("Src_VB100")
dst = src ' implicit Byte-to-Byte copy
SmartTags("Dst_VB200") = dst
End Sub
For a word copy (VW100 → VW200) the structure is identical, but the tags are declared as Word / Int:
SmartTags("Tag_VW200") = SmartTags("Tag_VW100")
This one-liner was confirmed working in the field on an MP 277 10" Touch running WinCC Flexible 2008 RT against a CPU 226. After the script fires once, the value at VB200 on the CPU matches VB100.
5. Bit-Level Access Within a Byte
S7-200 V memory allows bit-granular addressing (V100.0 … V100.7). WinCC Flexible tag configuration lets you expose each of those bits as a Bool tag. From inside a script you can then read or write individual bits by name:
Dim allBits As Boolean
allBits = SmartTags("Tag_V100_0") Or _
SmartTags("Tag_V100_1") Or _
SmartTags("Tag_V100_2") Or _
SmartTags("Tag_V100_3")
SmartTags("Tag_AnyBit") = allBits
To set a specific bit:
SmartTags("Tag_V100_5") = True ' writes a 1 to V100.5
This gives you full read/write access to all bits, bytes, words, and double words of a declared tag, even though the script itself only sees them as discrete SmartTags(...) values. The cost is tag-count: an 8-bit byte becomes 8 Bool tags if you want to manipulate individual bits.
6. Simulating Indirect Addressing in VB Script
The S7-200 instruction set supports pointer-based indirect addressing, for example:
// S7-200 ladder (STEP 7 Micro/WIN)
MOVD &VB200, AC1 // load pointer to VB200 into accumulator AC1
MOVW *AC1, AC0 // copy the word pointed to by AC1 into AC0
VBScript on the MP 277 does not provide a comparable raw pointer model. The closest practical substitute is to use SmartTags with computed tag names combined with a VBScript Execute statement, but Execute is not available on the CE runtime, so a different pattern is required:
Approach A — explicit table lookup (preferred):
Dim idx As Integer
idx = SmartTags("Tag_Index") ' read 0..7 from the PLC
Select Case idx
Case 0: SmartTags("Tag_CopyDest") = SmartTags("Src_VB100")
Case 1: SmartTags("Tag_CopyDest") = SmartTags("Src_VB101")
Case 2: SmartTags("Tag_CopyDest") = SmartTags("Src_VB102")
Case 3: SmartTags("Tag_CopyDest") = SmartTags("Src_VB103")
Case 4: SmartTags("Tag_CopyDest") = SmartTags("Src_VB104")
Case 5: SmartTags("Tag_CopyDest") = SmartTags("Src_VB105")
Case 6: SmartTags("Tag_CopyDest") = SmartTags("Src_VB106")
Case 7: SmartTags("Tag_CopyDest") = SmartTags("Src_VB107")
Case Else: SmartTags("Tag_CopyDest") = 0
End Select
This trades tag declarations for branching code. It is the only portable way to mimic pointer-driven reads on the MP 277 runtime.
Approach B — array of tags via SmartTags array notation (WinCC Flexible 2008 SP2 and later):
Dim arr(7)
arr(0) = SmartTags("Src_VB100")
arr(1) = SmartTags("Src_VB101")
arr(2) = SmartTags("Src_VB102")
arr(3) = SmartTags("Src_VB103")
arr(4) = SmartTags("Src_VB104")
arr(5) = SmartTags("Src_VB105")
arr(6) = SmartTags("Src_VB106")
arr(7) = SmartTags("Src_VB107")
SmartTags("Tag_Index") = SmartTags("Tag_Index") ' clamp in PLC if needed
If (SmartTags("Tag_Index") >= 0) And (SmartTags("Tag_Index") <= 7) Then
SmartTags("Tag_CopyDest") = arr(SmartTags("Tag_Index"))
End If
This avoids the Select Case ladder while keeping the lookup deterministic and auditable. The downside is that each element still requires a declared tag.
Tag_CopyDest is a separate, fixed V-memory location. You cannot, on the MP 277, ask the script to "write to whatever address the index points to" without pre-declaring each destination tag as well.7. Memory Constraints on CPU 226 — Why Move Logic to the HMI?
The S7-200 CPU 226 reports 24 KB of program memory (8 KB of which is reserved for the project record; the remainder is the user-program budget). Once that budget is full the CPU refuses to download new code with SF/DIAG errors. A common field workaround is:
- Identify seldom-executed branches (data marshalling, alarm text composition, recipe-massaging) that do not need deterministic cycle time.
- Move those branches into WinCC Flexible scripts, triggered by button events, value-change events, or the scheduler.
- Keep anything time-critical (interlocks, fast I/O, PID) on the CPU.
| Resource | CPU 226 limit | MP 277 10" Touch limit |
|---|---|---|
| User program | 24 KB total | Not applicable |
| V data | 10 240 bytes (VB0 – VB10239) | Indirect via tags |
| Tags | n/a | 4 096 |
| Scripts (VBScript) | n/a | Limited only by project memory (~32 MB) |
| Number of connections | 1 PPI/MPI + 1 Ethernet (CP 243-1) | Up to 4 PLCs (depends on license) |
Avoid moving anything that affects safety or motion control to the HMI. The MP 277 is not part of any SIL-rated loop and the VBScript cycle time is not deterministic — it depends on the panel's main loop, screen redraws, and tag-update scheduling.
8. Connection Setup and Runtime Verification
Before any script can talk to the CPU, the panel must complete a successful connection handshake. The recommended verification sequence is:
- In WinCC Flexible ES, open Project → Transfer → Transfer Settings and set the panel's IP (or enable PPI autodetect via the supplied cable).
- Compile the project. Look for "0 errors, 0 warnings" in the output window. Warning 100xxx about unresolved tag addresses usually means a PLC address typo.
- Download to the MP 277 using Project → Transfer → Transfer to Device. The panel will restart Runtime.
- On the panel, open Start → Settings → OP → Connections (or the diagnostic overview) and confirm the CPU shows a green status indicator.
- Trigger the script manually (tap the assigned button). Watch the diagnostic view for the SmartTag value change.
Sanity-check ladder on the CPU:
// Status word that the HMI will write
NETW VB100, VW200 // monitor VW200 in STEP 7 Micro/WIN status chart
Add both VB100 and VB200 to a STEP 7 Micro/WIN status chart and observe them while the script runs. The values must mirror within one PPI cycle (~50–100 ms).
9. Troubleshooting Matrix
| Symptom | Likely cause | Remedy |
|---|---|---|
| Script runs but destination tag stays 0 | Source tag's acquisition mode is On demand and the script hasn't read it before | Set both source and destination to Cyclic continuous or read the source once first |
| Tag value visible in ES but not at runtime | Project not transferred, or transfer failed midway | Re-transfer; check the OP diagnostic page for "Connection: S7-200 OK/Error" |
| SmartTags("...") returns Empty / Null | Tag name typo, or tag exists in a different connection | Verify the tag name in Communication → Tags; case-sensitive on RT |
| Type-mismatch runtime error on assignment | Mixing Byte and Word tag types without conversion | Match data types exactly or use CByte(), CInt(), CLng()
|
| Values flicker between old and new | Two scripts writing the same destination on overlapping triggers | Centralise writes through a single scheduled script and disable button-level duplicates |
| Script fires but PPI red-light on CPU | Address outside V range, or CPU in STOP | Confirm CPU is RUN; check VBxxx is within VB0–VB10239 |
| Tag shows correct value in WinCC Flexible ES but the CPU never sees it | Wrong connection selected for that tag | Open the tag properties and verify the assigned connection points to the CPU 226 |
| MP 277 displays "VBScript error 0x800A000D" | Type mismatch — assigning a String to a Byte tag or similar | Validate the right-hand side type; coerce with CByte/CInt |
| Long scripts time out / abort | WinCE VBScript runtime is single-threaded; heavy work blocks UI | Break the script into chunks; trigger each chunk with the scheduler |
10. Best Practices and Field Notes
-
Tag naming: Prefix each tag with its memory area (
VB_,VW_,VBit_) so thatSmartTagslookups stay self-documenting in larger projects. - Acquisition mode: Reserve Cyclic continuous for tags that change on the PLC side without script prompting; everything else can use Cyclic on use to minimise PPI/MPI traffic.
- Determinism: Avoid placing critical interlocks in scripts. The MP 277 cycle is in the 100 ms range and can stall during screen changes, alarm logging, or recipe transfers.
- Watchdog: If a script writes a tag every cycle, add a "heartbeat" tag (toggling 0/1 on alternate cycles) so the PLC can detect a stalled HMI.
-
Diagnostics: Use
SmartTags("Tag_DiagWord")as a free-form error log;Hex()the last error code into a Word tag and have the PLC surface it on a status screen. -
Re-declaration pitfall: Do not declare both
VB100andVW100pointing to the same byte-pair on the PLC — WinCC Flexible will treat them as independent polls, doubling bus load. Decide whether the panel sees a byte or a word and stick to it. - Project size: A single MP 277 project can hold hundreds of scripts; just keep the per-script body under ~2 KB of source to keep the runtime compile time short.
11. Worked Example: Recipe Index Copy
Suppose you have eight recipes stored as eight bytes each in V-memory starting at VB1000, and you want the HMI to surface the active recipe in VB200 based on an index from the PLC.
- Declare tags
Src_VB1000throughSrc_VB1007, all Byte. - Declare tag
Dst_VB200, Byte. - Declare tag
Tag_RecipeIndex, Byte, addressVB50(PLC writes the active index 0–7 here). - Add a scheduler that fires every 200 ms and calls the script below.
Sub OnScheduled(ByVal Item)
Dim idx As Integer
idx = CInt(SmartTags("Tag_RecipeIndex"))
If idx < 0 Or idx > 7 Then
SmartTags("Dst_VB200") = 0
Exit Sub
End If
Select Case idx
Case 0: SmartTags("Dst_VB200") = SmartTags("Src_VB1000")
Case 1: SmartTags("Dst_VB200") = SmartTags("Src_VB1001")
Case 2: SmartTags("Dst_VB200") = SmartTags("Src_VB1002")
Case 3: SmartTags("Dst_VB200") = SmartTags("Src_VB1003")
Case 4: SmartTags("Dst_VB200") = SmartTags("Src_VB1004")
Case 5: SmartTags("Dst_VB200") = SmartTags("Src_VB1005")
Case 6: SmartTags("Dst_VB200") = SmartTags("Src_VB1006")
Case 7: SmartTags("Dst_VB200") = SmartTags("Src_VB1007")
End Select
End Sub
Verify in STEP 7 Micro/WIN by adding VB200 to a status chart and watching it follow the indexed source byte as you change VB50.
12. FAQ
Can a WinCC Flexible 2008 VB Script on an MP 277 directly read VB100 and write it to VB200 on a CPU 226?
Yes. Declare two Byte tags (VB100 and VB200) with acquisition mode Cyclic continuous, then use SmartTags("Dst_VB200") = SmartTags("Src_VB100") in a button, value-change, or scheduled script. This is the simplest supported pattern.
Can I do indirect addressing such as *AC1 from a script?
No. The WinCE VBScript runtime on the MP 277 does not expose raw S7-200 pointers. Use a Select Case ladder or a fixed arr(...) lookup table over pre-declared tags instead.
Why does my script's value disappear when I leave the screen?
Tags are read at runtime only while the screen or pop-up referencing them is active. Either keep the source tag on a permanently active screen, set its acquisition mode to Cyclic continuous, or read it into an internal Dim variable inside the script before leaving the screen.
How do I split a word (VW100) into its two bytes without using more ladder code?
Declare three tags: Tag_VW100 (Word), Tag_VB100 (Byte), Tag_VB101 (Byte). WinCC Flexible polls each independently, so the script can read either byte, the word, or both.
Is it safe to move PLC logic into the HMI when the CPU 226 is full?
For non-time-critical, non-safety logic — yes, the script approach is a recognised workaround. For interlocks, motion, or anything safety-rated, keep it in the PLC. The MP 277 cycle is not deterministic and is not part of any SIL-rated loop.