Problem Details
A WAGO 750-881 Ethernet controller programmed in CoDeSys 2.3.9.22 is used to push a CSV log file to an in-house NAS running an FTP server. The application writes the log with DLOG_TO_CSV and then attempts to upload it with the FTP client file-transfer block (DLOG_FILE_TO_FTP-style call) taken from the WAGO network library.
Observed symptoms:
- The transfer block returns an error indicating a timeout while establishing the data connection from the PLC to the FTP server. The control connection is accepted; the data channel never completes.
- The
ftp_client_demoproject shipped in the demo folder of the network library works against the same NAS, from the same controller. - A conventional FTP client (PC) logs in to the NAS with the same credentials and path without problems.
- A download executed by the controller succeeds when only a bare file name is supplied — the file lands in the controller's
/PLCdirectory.
Parameterization in use:
ftp_url : STRING := 'ftp://wago:[email protected]/nWAGO/';
ftp_filename : STRING := '..\log\test.txt';
Controller file system (default directories plus one user-created folder):
/
/etc
/LOGS (created manually via FTP client)
/PLC (target of DLOG_TO_CSV)
/webserv
Root Cause Analysis
1. Passive-mode data connection timeout
The reported error is a connect timeout on the data socket opened by the PLC toward the server. That direction of connection establishment is characteristic of passive mode: the server answers PASV with an IP address and port, and the client then opens the data connection to that endpoint. A timeout therefore means the IP/port pair returned by the server, or the port the stack actually dialed, is not reachable from the controller.
Typical contributors, in the order worth checking:
| Cause | Evidence to collect |
|---|---|
Server returns an address in its 227 reply that the PLC cannot route (NAT/alias address configured on the NAS) |
Packet capture of the PASV / 227 exchange; compare the advertised IP with the NAS LAN IP 192.0.6.200
|
| Passive port range blocked or not opened on the NAS | NAS FTP service configuration; capture shows SYN retransmits from the PLC to the advertised high port |
| Active/passive mode mismatch between the demo block and the application block | Diff the mode/flag inputs of both instances; the demo project is the known-good reference |
| Local FTP server on the controller occupying the stack | Web-based Management > Port > Port Settings |
2. FTP server (port 21) enabled on the controller
The 750-881 runs its own FTP server on TCP 21 by default. Disabling that service in Web-based Management under Port → Port Settings has resolved comparable cases where a library client function on the same controller failed while equivalent third-party access worked. The same pattern has been observed with Modbus library functions that only started working after the built-in Modbus service was deactivated in the controller. Treat this as a service/port contention test, not a documented behavior.
3. Path syntax on both ends
Two independent path questions are being mixed in the failing parameterization:
-
Local (controller) path —
'..\log\test.txt'uses a relative parent reference and backslashes. The successful download proved that a bare file name resolves correctly and lands in/PLC. On classic controllers the local file argument is simply'logfile.csv', because there is effectively one root folder for files. A relative'..\'prefix and access to directories outside/PLCare not confirmed to be supported by the file-transfer block. -
Remote (server) path —
ftp://wago:[email protected]/nWAGO/. The directorynWAGOand the password beginning with a period were both verified as correct against a desktop FTP client, and replacing the password with one containing no period did not change the result. So the URL string is not the primary fault, but a leading.in a password inside a URL-form credential string is still worth eliminating during bisection.
4. File name case handling
The controller's file system treats case asymmetrically in practice:
| Origin of file | Resulting name on the controller |
|---|---|
| Copied onto the controller with a PC FTP client | Converted to ALL UPPERCASE |
Created by the PLC application (e.g. DLOG_TO_CSV) |
Case preserved exactly as written, e.g. LOG\weather_xx.csv
|
If the transfer block opens the source file by a name whose case does not match what is actually on the media, the local open fails before any useful FTP dialogue takes place — a different failure mode than the data timeout, but one that masks progress during trial-and-error.
Solution: Bisect from the Working Demo
The ftp_client_demo in the demo folder of the network library is the reference implementation. Do not debug the application block in isolation; migrate it toward the demo one parameter at a time.
-
Confirm the baseline. Run
ftp_client_demounchanged against192.0.6.200with the production credentials and record the returned status/error codes. This proves credentials, routing, DNS-free addressing, and library version. -
Flatten the local file argument. Replace
'..\log\test.txt'with a bare name, e.g.'test.txt', and place the file in/PLC. HaveDLOG_TO_CSVwrite directly into that same directory rather than into a separate/LOGStree. -
Normalize case. Use one case convention in the source that generates the file and in the transfer parameter. Verify the on-disk name with an FTP client listing of
/PLCbefore blaming the network. - Disable the controller's FTP server. In Web-based Management open Port → Port Settings, switch off FTP (TCP 21), save, and retest the block. Re-enable it afterward only if you still need inbound FTP to the controller.
-
Eliminate password/URL edge cases. Test once with a password containing only alphanumerics and no leading period, and once with the remote path written both with and without the trailing slash (
/nWAGO/vs/nWAGO). -
Force the transfer mode explicitly. If the block exposes a passive/active selector, set it to match the mode the demo uses. If the NAS is on the same subnet, active mode removes the
227-address dependency entirely. -
Capture the traffic. If steps 1–6 do not resolve it, take an unfiltered Wireshark trace on a mirrored port and record the PLC IP, gateway/router IP, NAS IP, and any DNS server in use. Read the
227reply and check whether the PLC's subsequent SYN goes to a reachable address and receives a SYN/ACK.
Reference parameterization after flattening
(* Local source file: bare name, resolves to the controller's PLC directory *)
ftp_filename : STRING := 'weather_xx.csv';
(* Remote target: explicit IP, no DNS dependency *)
ftp_url : STRING := 'ftp://wago:[email protected]/nWAGO/';
(* Verify the source file exists with EXACTLY this case before enabling xExecute *)
Verification
| Check | Method | Pass criterion |
|---|---|---|
| Control connection | Wireshark filter on TCP 21 between PLC and 192.0.6.200
|
220 banner, USER/PASS accepted with 230
|
| Directory change | Same capture |
CWD /nWAGO answered 250
|
| Passive negotiation | Same capture |
227 Entering Passive Mode advertises an address on the PLC's reachable subnet |
| Data channel | Same capture | PLC SYN to the advertised port receives SYN/ACK; no SYN retransmissions |
| Transfer completion | Same capture plus NAS directory listing |
226 Transfer complete; file present on the NAS with correct byte count |
| Local source resolution | FTP client listing of the controller's /PLC directory |
File name and case match the ftp_filename string exactly |
| Block status | CoDeSys online view of the FB outputs | Done/valid output set, error output cleared, error code 0 |
Operating Notes for the 750-881 File System
-
/PLCis the working directory for application-generated files; a download initiated by the controller with a bare file name lands there. Treat it as the default root for the file-transfer block. -
/etcand/webservare system directories. Do not use them as log destinations. - A user-created folder such as
/LOGSis visible to a PC FTP client but is not confirmed to be reachable from the file-transfer block. Prove access with a bare-name test in/PLCfirst, then extend. - Uploading a file to the controller from a PC FTP client can force the name to uppercase. Application logic that later opens that file by mixed-case name will fail to find it.
- Log files written by
DLOG_TO_CSVretain the case supplied in the program, including any leading directory component in the name string. - Keep the FTP endpoint on the local network addressed by IP. An internal NAS target removes DNS resolution and any WAN NAT translation from the failure set.
FAQ
What does an FTP data connection timeout mean on a WAGO 750-881?
It means the control connection on TCP 21 succeeded but the PLC could not open the data socket. In passive mode the PLC dials the address and port returned by the server in its 227 reply, so a timeout points to an unreachable advertised IP, a blocked passive port range, or a mode mismatch.
Which local path should I use for the file-transfer block?
Start with a bare file name such as 'weather_xx.csv'. A controller-initiated download with only a file name resolves into the /PLC directory, which confirms that directory is the working root. Relative prefixes like '..\log\' are unverified and should be removed while debugging.
Why does the ftp_client_demo work but my own block fails?
The demo proves the network path, credentials, and library are good, so the difference is in your parameter set or the runtime environment. Migrate your block toward the demo one parameter at a time — URL string, local file name, transfer mode — until the failure disappears.
Should I disable the controller's built-in FTP server?
Test it. Open Web-based Management, go to Port → Port Settings, disable FTP on TCP 21, and retest. The same approach has resolved library-function failures where a built-in service on the controller conflicted with the library client.
Why do my file names arrive in uppercase on the controller?
Files copied onto the 750-881 with a PC FTP client appear in all uppercase, while files created by the PLC application keep the exact case given in the program. Verify the on-disk name with a directory listing before assuming a network fault.