Place a button in the controller's visualization and give it theFile Transfer input action. Point its File name field at an existing file on the drive, such as '$$USB$$/output.txt'. Then open the visualization in a PC browser at http://192.168.0.10:8080/webvisu.htm and click the button. The file lands in the browser's download folder.
Every failure on this path breaks one specific link: the string literal, the directory, the extension, the client, or the URL. Find the broken link before changing anything else.
Which link in the transfer chain is failing?
Treat the download as a signal chain. The IDE compiles a string. At runtime the controller resolves that string to a file on the USB mount and opens it. The controller's web server then streams the file to whichever browser issued the click, and the browser saves it wherever its settings say. The action reports its state back through variables you bind in the input configuration: a transfer-in-progress flag and an error code.
Read those variables and the compiler output before touching the configuration. Each stage fails in its own recognizable way:
| Signal / stage | Where the value comes from | Symptom when it is wrong |
|---|---|---|
| String delimiters in File name | Literal typed into the File Transfer action | Compile error that points at the file name |
| Directory part of the path | Archiver file layout on the USB drive | Nothing downloads; error code set; in-progress flag stays FALSE |
| File extension | Archive format, for example .csv
|
Same as a wrong directory: the named file does not exist |
| Client that executes the action | Browser web visualization vs. CODESYS IDE online visualization | Nothing downloads no matter how correct the path is |
| Browser URL | Address typed on the PC | Browser opens a search results page instead of the visualization |
| Error code variable | Bound in the action's input configuration | Nonzero value, for example 6
|
| Download destination | Browser settings on the PC | File appears to be missing but sits in the Downloads folder |
| Controller outbound network | PLC210 network settings (gateway, DNS) | pip reports no matching distribution; ping fails from the PLC shell while the PC pings the PLC |
Some faults show up at compile time and others only at runtime. That split alone halves the search. A compile error is always the literal. A runtime silence with a clean build is the path, the extension, or the client.
Why does File Transfer only work from a browser-hosted visualization?
The File Transfer action moves a file from the controller to the visualization client. In a web visualization the client is a browser. The controller's web server serves the file as an HTTP download, and the browser writes it to disk using its own download settings. That is also why the action has no destination-path field: the browser, not the PLC, decides where the file goes. On Windows the default is usually the Downloads folder.
The online visualization inside the CODESYS IDE is a development view. It has no browser download mechanism, so the action has nothing to deliver the file to. A correctly configured button therefore appears dead when clicked from the IDE.
This is the first thing to rule out whenever a transfer does nothing. Moving the test from the IDE to a real browser session fixes it without any change to the project.
How does the File name string reach the USB mount?
Enter it either as a literal or by binding a variable of typeSTRING.
Delimiters. The literal must be enclosed in plain ASCII single quotes. Typographic quotes, which word processors and some keyboard layouts insert, are not string delimiters to the compiler. The build fails with an error pointing at the file name. Copying a known-good literal such as '$$USB$$/output.txt' into the field clears this class of error at once.
Dollar escaping.$ is the escape character, so $$ produces one literal dollar sign. The literal '$$USB$$/output.txt' therefore reaches the runtime as the text $USB$/output.txt. The runtime then maps the $USB$ placeholder to the USB drive's mount point. A single dollar sign changes the escape sequence and breaks the placeholder.
Extension. The runtime opens exactly the name you give it. An archive written as a CSV file must be named with its .csv extension in the File name field. Leaving off the extension points the action at a file that does not exist.
Subdirectories. The path can include nested directories below the placeholder. A file does not need to sit in the drive root to be transferred. The path only has to match an existing file exactly.
Use a STRING variable instead of a literal when the file name changes over time, for example when it depends on the date. Build the path in the application and bind the variable to the File name field.
Where does the archiver actually write its files?
The archiver on this controller creates its own subdirectories. In the dated layout (year / month / day) you cannot configure it to create files in the drive root. A File Transfer action pointed at a root-level name then asks for a file that does not exist. In the case this article is based on, the target was a file named 09 with no extension, located inside an archiver-created subdirectory. The action was pointed at the root. That mismatch was the root cause of the failed transfers.
You have two ways to reconcile the archiver layout with the File Transfer path:
-
Keep the dated layout and put the full path in File name. Include every subdirectory level and the file's real name and extension. Because the dated folder changes daily, build the path in a
STRINGvariable from the current date, using the same folder naming the archiver uses. Browse the USB drive once to read the real structure before you write that logic. -
Switch the CSV format to continuous archive. In the archiver's CSV format settings, select continuous archive instead of year/month/day. The archive is then written as a single file in the drive root, so one fixed File name, including
.csv, always matches.
The continuous file grows without bound. Download time grows with it, and the transfer-in-progress window gets longer. If the file must stay small, or if you need per-day files for the customer, keep the dated layout and generate the path.
What does error code 6 from File Transfer mean?
The error variable bound to the action holds a value of the ERROR enumeration defined in the Visu Utils library. That library ships with CODESYS, so there is nothing to download. You only need to add it to the project to browse the enumeration. The action works without adding the library; you add it only to read the code meanings.
- Open the Library Manager in the project.
- Right-click and choose to add a library.
- In the dialog, switch the view to a flat list, or type
Visuinto the search field at the top. The category tree hides Visu Utils from users browsing by expected name. - Add Visu Utils and open the
ERRORenumeration to read its members.
You do not need any function block from this library to decode the code. The enumeration is only a lookup table for the integer you bound in the input configuration.
Code 6 corresponds to TRANSFER_IN_PROGRESS, the sixth entry in the enumeration. Read the declared values in the enumeration rather than counting lines, though. An enumeration that starts at 0, or one with explicit assignments, breaks the line-count shortcut when you look up other codes.
Code 6 does not always mean a transfer is really running. In the case this article is based on, the error variable showed 6 while the bound in-progress flag stayed FALSE. The actual fault was a File name that pointed at a non-existent file. Use this decision path when the code and the flag contradict each other:
- Confirm you are clicking from a browser web visualization, not the IDE.
- Confirm the exact file (directory, name, extension) exists on the USB drive.
- Only then treat the error code as describing a real transfer state.
How do you build and test the download button from scratch?
- Confirm the PC and the PLC210 are on the same subnet and that the PC can ping the controller's address (
192.168.0.10in this installation). - Enable the web visualization in the CODESYS project according to the controller's manual, and download the project to the PLC.
- Before configuring the button, browse the USB drive and note the exact path, name, and extension of the file you want. If the archiver writes it, check which layout it uses: dated subdirectories or continuous root file.
- Add a button (or a similar input element) to the visualization. Open its input configuration and add the File Transfer action.
- Enter the File name as a literal in ASCII single quotes, such as
'$$USB$$/output.txt', or bind aSTRINGvariable that holds the full path. Include subdirectories and the extension, for example.csv. - Bind a BOOL for the in-progress flag and a variable for the error code so you can watch the action's state.
- Build. Fix any error pointing at the file name before going further; it is almost always the quote characters.
- On the PC, type
http://192.168.0.10:8080/webvisu.htminto the browser's address bar exactly as shown, with no angle brackets. Placeholder notation such as<192.168.0.10>copied from a manual makes the browser treat the entry as a search query. - Click the button in the browser session, not in the IDE.
- Check the browser's download folder.
How do you confirm the file arrived complete?
A file in the Downloads folder only proves that the chain works end to end. It does not prove the content is what you expected. Check these before calling the job done:
- Watch the bound variables during the click. The in-progress flag should go TRUE and then return to FALSE, and the error code should return to its no-error member of the
ERRORenumeration. A code change with no flag transition means the action never started a transfer, so go back to the path. - Open the downloaded file and compare its last record with the latest values the archiver should have written. A stale last row points to the wrong file: an older dated folder, or a leftover root file from before you changed layouts.
- Compare the file size with the file on the USB drive if you can read the drive directly. A shorter download means the transfer was cut off, most often because the browser session was closed during a long transfer of a large continuous archive.
- If the download does not appear, check the browser's download settings. Some browsers ask for a location, and others save silently to a configured folder.
- Repeat the test with a small known file at a fixed path, such as
'$$USB$$/output.txt'. Success with the small file and failure with the archive isolates the fault to the archive path or name, not to the web visualization.
Can the PLC210 deliver the archive as PDF instead of CSV?
The archiver writes CSV. The route to a PDF is to keep archiving in .csv and convert the file at chosen moments with a Python script running on the controller's own Linux. OWEN provides example material for running Python scripts from a CODESYS project on this controller family; get it from OWEN's example downloads or OWEN support. The Linux environment is the one built into the PLC210. You do not install Linux anywhere. Reach its shell through the controller's web configurator or with an SSH client such as PuTTY.
Install a converter package from the controller shell:
pip3 install csv2pdf
If pip fails on certificate validation on the controller side, mark the Python package index hosts as trusted:
pip3 install --trusted-host pypi.org --trusted-host files.pythonhosted.org csv2pdf
The same pattern applies to other packages, for example python-docx if the customer wants a Word document:
pip3 install --trusted-host pypi.org --trusted-host files.pythonhosted.org python-docx
Once the PDF is written to the USB drive, deliver it with the same File Transfer button. Point File name at the PDF path and extension instead of the CSV. Run the conversion at a time when the archiver is not writing the source file, so the script never reads a half-written CSV.
Why does pip3 fail on the PLC when the PC pings it fine?
A successful ping from the PC to the PLC proves only that the two share a working local link. pip needs something else: an outbound route from the controller to the internet and working name resolution for the package index hosts. When the controller cannot reach the index, pip reports that it could not find a version that satisfies the requirement and that no matching distribution was found. The message sounds like a packaging problem, but the cause is network reachability. In this installation, ping from the PLC's own terminal failed, which settles the question.
The --trusted-host flags only relax TLS certificate checks. They do nothing for a controller that has no route out. Work the path outward from the controller shell:
- Ping the default gateway's IP address. If this fails, the gateway is missing or wrong in the controller's network settings. Set it in the web configurator.
- Ping a known external IP address. If the gateway answers but this fails, the upstream router or firewall is blocking the controller.
- Resolve
pypi.orgby name (ping it, or use a lookup tool if the image provides one). If IP pings succeed but names do not resolve, DNS servers are not configured on the controller. - When all three succeed, retry pip. Add the trusted-host flags only if the remaining error is about certificates.
A plant network often gives the controller no internet access, and that is frequently intentional. In that case install offline. Download the package files on a PC, copy them to the controller, and install from the local files. Any package with compiled components needs builds that match the controller's CPU architecture and Python version, so check both from the shell (uname -m and python3 --version) before downloading. Pure-Python packages avoid that constraint.
Which mistakes recur on this class of setup?
- Testing from the IDE. File Transfer does nothing from the CODESYS online visualization. Always test from a browser web visualization.
- Typographic quotes in File name. These cause compile errors that point at the file name. Use plain single quotes.
-
Single dollar signs. The placeholder needs doubled dollars inside the literal:
'$$USB$$/...'. -
Dropped extension. The archive name without
.csvis a different, non-existent file. - Root path for a dated archive. In dated mode the archiver writes only into its own subdirectories. Either put the full nested path in File name or switch to continuous archive.
- Trusting the error code over the file system. Code 6 alongside a FALSE in-progress flag means verify the file exists first.
-
Counting enumeration lines. Read the declared values in the Visu Utils
ERRORenumeration instead of counting rows. -
Library "missing" from the manager. Visu Utils is part of the CODESYS distribution. Use the flat-list view or type
Visuin the search field. -
Angle brackets in the URL. Type
http://192.168.0.10:8080/webvisu.htmliterally. - Assuming PC-to-PLC ping means PLC-to-internet. Test outbound reachability from the controller shell before troubleshooting pip.
- Faults that are not path problems. If CODESYS does not show the I/O modules that the controller itself detects, even after a device update, or if the archive never appears on the USB drive at all, the fault sits in the device description or the archiver configuration. Do not keep tuning the File Transfer action.
Frequently asked questions
Can I run the CODESYS File Transfer action from the IDE online visualization?
No. File Transfer works only in the web visualization opened in a browser, for example at http://192.168.0.10:8080/webvisu.htm. From the IDE, the button does nothing even with a correct path.
Does the File name field need the file extension?
Yes. Enter the exact name including the extension, such as .csv for a CSV archive. Without it the action points at a file that does not exist and nothing downloads.
Can I download a file that sits in a subdirectory on the PLC210 USB drive?
Yes. The File name path can include nested directories below $$USB$$, so the dated folders the archiver creates are reachable. Alternatively, set the CSV format to continuous archive so the archive is a single file in the drive root.
Does --trusted-host fix pip "No matching distribution found" on the PLC210?
Only when the cause is a certificate error. If ping fails from the controller's own shell, configure the gateway and DNS in the web configurator, or install the package offline from files copied to the controller.
When should I stop troubleshooting and contact OWEN support?
Escalate when CODESYS still does not show I/O modules that the controller detects after a device update, when the archiver writes nothing to the USB drive, or when pip still cannot reach the index after gateway and DNS test clean from the controller shell. Email [email protected]. Describe how you detect the problem, attach screenshots, and include the project.