Overview
WinCC (Windows Control Center) is Siemens' SCADA/HMI software capable of displaying process data on operator interfaces. A common requirement is displaying sensor readings sourced from external CSV files—updated continuously by wireless or serial data acquisition systems—directly on a WinCC screen without involving a PLC. This article details the architecture, C-script implementation, and Global Action configuration required to achieve continuous, automated CSV reading in WinCC.
The solution uses WinCC Global Actions (C-script based) triggered by a cyclic time interval or an internal tag change. This eliminates the need for manual button presses and provides near-real-time data updates on the HMI.
System Architecture
Prerequisites
- WinCC Explorer V7.0 or higher (tested on WinCC V7.4, V7.5 SP1)
- Internal WinCC tags defined to hold CSV column values (type: unsigned 8-bit for numeric conversion or direct string tags)
-
Filename tag: A WinCC text tag (8-bit array or string) containing the full path to the CSV file (e.g.,
C:\Data\sensor_log.csv) -
CSV format: The source file must use comma-separated values with one record per line:
TagName,Value - File access permissions: The WinCC Runtime user (typically the service account or logged-in operator) must have read access to the target file path
- WinCC Global Script Runtime license/option enabled in the project
\\192.168.1.100\Data\sensor.csv), ensure WinCC runs under an account with appropriate network share permissions. UNC paths are supported via GetTagChar().Step-by-Step Implementation
Step 1: Define WinCC Tags
In WinCC Explorer, create the following tags in the tag management:
| Tag Name | Data Type | Purpose |
|---|---|---|
| Filename | Text tag 8-bit (max length ≥ file path) | Holds full path to CSV file |
| Sensor_Temperature | IEEE 754 32-bit Float | Holds parsed temperature value |
| Sensor_Pressure | IEEE 754 32-bit Float | Holds parsed pressure value |
| CSV_ReadTrigger | Binary (internal) | Optional: External trigger tag |
Step 2: Create the Global Script (C-Script)
Navigate to WinCC Explorer → Global Script → C-Editor. Create a new function script named ReadCSVFile:
#include "apdefap.h"
void __stdcall ReadCSVFile(void)
{
#define MaxLineLength 256
FILE *fpFile;
char *strTag = NULL;
char *strValue = NULL;
char *pTmp = NULL;
char buffer[MaxLineLength];
double dVal = 0.0;
// Open CSV file in read mode
fpFile = fopen(GetTagChar("Filename"), "r");
printf("CScript: Opening file: %s\r\n", GetTagChar("Filename"));
if (fpFile == NULL)
{
printf("Error: File not found or inaccessible!\r\n");
return;
}
// Read each line of the CSV file
while (fgets(buffer, MaxLineLength, fpFile) != NULL)
{
strTag = buffer;
// Locate the comma delimiter separating tag name from value
pTmp = strchr(buffer, ',');
if (pTmp == NULL)
{
continue; // Skip malformed lines
}
*pTmp = '\0'; // Null-terminate the tag name
strValue = pTmp + 1;
// Strip trailing newline/carriage return characters
strValue[strcspn(strValue, "\r\n")] = '\0';
// Handle European decimal notation: replace ',' with '.'
pTmp = strchr(strValue, ',');
if (pTmp != NULL)
{
*pTmp = '.';
}
// Parse numeric value from string
sscanf(strValue, "%lf", &dVal);
// Write to the appropriate WinCC tag based on the parsed tag name
if (strcmp(strTag, "Sensor_Temperature") == 0)
{
SetTagDouble("Sensor_Temperature", dVal);
}
else if (strcmp(strTag, "Sensor_Pressure") == 0)
{
SetTagDouble("Sensor_Pressure", dVal);
}
printf("%s = %lf\r\n", strTag, dVal);
}
fclose(fpFile);
}Step 3: Configure the Global Action Trigger
Navigate to WinCC Explorer → Global Script → Actions. Create a new action and assign the ReadCSVFile function as the action body.
Time-Triggered Configuration (Recommended)
In the action's trigger properties, configure a cyclic trigger:
| Parameter | Recommended Value | Notes |
|---|---|---|
| Trigger Type | Cyclic | Executes on a fixed time interval |
| Cycle Time | 250 ms to 5 s | 250ms is minimum recommended; lower values increase CPU load |
| Phase offset | 0 ms | Optional; stagger if multiple actions exist |
Tag-Triggered Configuration (Event-Based)
Alternatively, trigger the action on a binary tag change:
- In Tag Management, create an internal binary tag (e.g.,
CSV_ReadTrigger). - In the Global Action, assign this tag as the trigger with Cyclic by Tag type and Positive transition edge.
- Configure the external data source (e.g., the data logger PC) to toggle
CSV_ReadTriggerwhenever the CSV file is updated.
Step 4: Link Tags to WinCC Picture Objects
In WinCC Graphics Designer, create an I/O field for each sensor tag:
- For
Sensor_Temperature: Set the object type to I/O Field, link the tag, and configure the format as999.9with aFloatdata type. - Add static labels (e.g., Temperature (°C), Pressure (bar)) using text objects.
- Set the update cycle of the picture to 1 second or By Tag to match the Global Action cycle.
Handling Continuous File Updates (File Locking)
When the CSV file is written continuously by another process, the file may be temporarily locked during write operations. The fopen() call in read mode ("r") will fail if the writer holds an exclusive lock. To handle this gracefully:
int maxRetries = 5;
int retryDelay_ms = 100;
FILE *fpFile = NULL;
for (int i = 0; i < maxRetries; i++)
{
fpFile = fopen(GetTagChar("Filename"), "r");
if (fpFile != NULL)
break;
Sleep(retryDelay_ms); // WinCC-compatible delay
}
if (fpFile == NULL)
{
printf("Error: Could not acquire file handle after %d attempts\r\n", maxRetries);
return;
}CSV File Format Requirements
The CSV file must conform to the following format for correct parsing:
| Field | Specification |
|---|---|
| Delimiter | Comma (,) between tag name and value |
| Line termination | LF (\n) or CRLF (\r\n) |
| Decimal separator | Period (.) in source, or handled by the comma-replacement logic in the script |
| Tag name | Must match WinCC tag names exactly (case-sensitive) |
| Example | Sensor_Temperature,23.5 |
Verification and Diagnostics
Monitor the Global Script diagnostics via the WinCC Runtime Logger or the CScript Output window:
printf("CScript: Opening file: %s\r\n", GetTagChar("Filename"));
printf("%s = %lf\r\n", strTag, dVal);
printf("Error: File not found or inaccessible!\r\n");- Enable the diagnostic output window via WinCC Explorer → Global Script → GSC Runtime → Output.
- Check Windows Event Viewer if file access is denied by security policies.
- Use WinCC V7 Global Script documentation (Pub 70011062) for additional troubleshooting.
Alternative Approaches
| Method | Pros | Cons | Best For |
|---|---|---|---|
| Global Action (C-Script) — Recommended | No PLC needed, fully automated, configurable cycle time | Requires Global Script runtime license | Continuous monitoring, wireless sensors |
| VBScript Scheduled Task (External) | No WinCC scripting license required | No direct tag writing; requires OPC or tag prefix method | Simple one-way data display |
| WinCC DataMonitor / Web Navigator | Web-based access, centralized reporting | Higher licensing cost | Multi-user environments |
| OPC DA/UA Server | Industry-standard, multi-vendor support | Requires OPC server for the data source | Integration with third-party SCADA |
Specifications Summary
| Parameter | Value |
|---|---|
| WinCC Versions Supported | V7.0, V7.2, V7.3, V7.4, V7.5 SP1 and higher |
| Script Language | ANSI-C (Global Script) |
| Minimum Update Cycle | 250 ms (limited by OS scheduling and file I/O) |
| File Path Length Support | Up to 256 characters via GetTagChar()
|
| Max CSV Line Length | 256 characters (configurable via #define MaxLineLength) |
| Required WinCC Options | Global Script Runtime |
| Supported File Encodings | ANSI, UTF-8 (with locale-aware functions) |
FAQ
What is the minimum cycle time for a WinCC Global Action reading a CSV file?
The practical minimum is approximately 250 ms, constrained by Windows OS task scheduling. Faster cycles may miss file updates or cause excessive CPU load. A 500 ms to 1 s cycle is typically sufficient for sensor data display.
Can WinCC read a CSV file on a network share without a PLC?
Yes. Use a UNC path (e.g., \\192.168.1.50\Data\sensor.csv) in the Filename tag. The WinCC Runtime service account must have read permissions to the network share. Alternatively, map the share to a drive letter accessible to the WinCC user.
Why does fopen() return NULL even though the CSV file exists?
The most common cause is file locking by the writer process. Implement a retry loop with a 100 ms delay (up to 5 retries) as shown in the script. Also verify Windows file permissions and that the WinCC user has read access to the target directory.
How do I handle CSV files with European decimal notation (commas instead of periods)?
Use the strchr() replacement logic in the script: pTmp = strchr(strValue, ','); if (pTmp != NULL) *pTmp = '.';. This converts European-formatted numbers to standard format before passing to sscanf().
Can I use VBScript instead of C-Script for reading CSV files in WinCC?
Yes. VBScript functions can be triggered by the Picture Windows Properties or a cyclic screen. However, VBScript cannot write directly to WinCC internal tags from a background action without COM automation. C-Script Global Actions provide the most direct and reliable method for automated CSV reading.