A CoDeSys 2.3 target visualization loads every bitmap once, when the runtime starts, and draws from memory after that, so an image overwritten by FTP only appears after the next restart. No bitmap element setting changes that. Move the changing image to a viewer that re-reads the file on its own reload period, or load a fixed image set into a bitmap list.
A CoDeSys 2.3 target visualization reads each bitmap file exactly once, when the runtime starts, and draws from the copy in memory after that. An FTP client can overwrite the image on the target every cycle and the screen never notices; the new frame appears only after the next restart. Nothing you set inside the bitmap element changes that read count of one.
The two fixes that work sit outside the visualization's bitmap cache: a viewer that re-reads the file on its own reload period, or a bitmap list holding a fixed image set loaded at start. This page covers why the in-visualization fixes fail, the check that separates an FTP fault from the cache, the numbers behind both workarounds, and the test that proves the refresh.
Why does the bitmap only update after the controller restarts?
The runtime loads every bitmap the visualization references exactly once per runtime start, then draws from the copy in memory. The FTP client can overwrite the file on the target on every cycle, and the screen still shows the frame it read at start-up.
Set the two rates side by side and the mismatch is the whole fault: you need one bitmap read per FTP update, and the runtime delivers one read per runtime start. The design reason is the drawing loop. A target visualization redraws on every cycle, and a file read in that loop would slow it, so the load happens once at initialization and the file on the target is never consulted again.
The behavior is the same in a bitmap list: the entries load at start as well. On panels and runtimes that re-read storage on demand, reloading an HMI image from disk without rebooting is a real job; a CoDeSys 2.3 target visualization is not that.
Why do all the fixes inside the visualization fail?
Every fix inside the visualization changes what the screen points at, not when the runtime reads the file. Each one leaves the read count at one per runtime start, so the FTP-updated image stays off the screen until the next restart.
| Fix attempted | Why it cannot refresh the file |
|---|---|
Link to file in the Bitmap Configuration menu |
It sets where the bitmap data comes from at load time. The load still happens once per runtime start. |
| Bitmap variable | It swaps which image the element shows, and every image it can select is already loaded at start. |
| Bitmap list | The list entries load at start as well, so replacing the file behind an entry changes nothing on screen. |
| Switching between two identical visualizations | The switch changes the page, not the resource; both pages draw the same loaded copy. Setting up a persistent HMI layout for changing screens shows what page switching can and cannot move. |
| ActiveX element | ActiveX is Windows COM technology; a Linux runtime has no COM host to instantiate it, so it cannot carry the picture on the target. |
How do you tell an FTP fault from the bitmap cache?
Overwrite the file once, confirm its size and timestamp changed in the FTP listing, then restart. If the new picture appears after the restart, the transfer works and the fault is the load-once bitmap cache, not the FTP job. The two faults look identical on a frozen screen, so run this check before changing the design. What you see points to one cause each:
- The size or timestamp never changes on the target: the FTP job is the fault. Fix the transfer schedule, the path and the credentials before touching the visualization.
- The size and timestamp change, and the new picture appears only after a restart: the transfer works and the load-once cache is the fault. The rest of this page is for that case.
- Random half-drawn or corrupt frames in a viewer: the viewer reloaded while the upload was still writing. Upload to a temporary file name and rename it to the final name once the transfer completes, if the FTP server supports rename; the reader then sees the old file or the complete new one.
- The refresh runs for hours and then stops: a stalled FTP job or a viewer that stopped reloading. Check both logs before redesigning anything.
How do you show the changing image without a reboot?
Put the picture in a viewer that re-reads the file from storage on its own reload period, and set that period at or above the FTP update period. The screen then follows the file without any restart.
Any HTTP-capable viewer or browser panel that can reach the image does this, because it owns its read schedule instead of borrowing the visualization's. An HTML page carrying <meta http-equiv="refresh" content="N"> reloads every N seconds; set N to the FTP update period or longer.
When the source is a camera, drop the FTP chain entirely and point the viewer at the camera's own HTTP image or stream endpoint, which removes the write and the transfer from the age calculation; refreshing a camera still image on an operator display covers that wiring.
The other workaround serves the other case: a fixed, known set of images, one per machine state, held in a bitmap list and selected by an index variable. It needs no runtime file read at all, and the images are fixed at download time. For the wider choice of where images live in a CoDeSys project, CODESYS dynamic image display options compare the file, ImagePool and database routes.
Worked example: how old is the picture on a 300-second FTP cycle?
With the camera writing every 300 seconds, a 10-second transfer and the viewer reloading every 300 seconds, the picture on screen is at worst 610 seconds old: 300 + 10 + 300 = 610, about ten minutes.
The three terms stack like this: the frame shown can be one full capture cycle older than the newest one, the transfer needs its seconds to land, and the viewer waits up to one reload period to fetch it. Shortening the reload period below the FTP update period still helps, at the cost of re-fetching an unchanged file between updates: at a 60-second reload the same cycle gives 300 + 10 + 60 = 370 seconds. For the rate limits on the links that move images, serial image refresh rate limits works the same arithmetic from the transport side.
How much memory does a bitmap list take?
Each list entry holds the uncompressed pixel array plus its header, in bytes 4 x ceil(W x bpp / 32) x H + header, so a 640 x 480 24-bit bitmap needs 921,654 bytes before any other entries join it.
Read W, H and bpp from the camera or image-generator settings, and read the header size from the BMP file header: 54 bytes in the common case of a 14-byte file header plus a 40-byte information header.
The arithmetic for the example: 640 x 24 = 15,360 bits per row; 15,360 / 32 = 480; x 4 = 1,920 bytes per row; 1,920 x 480 = 921,600 bytes; + 54 = 921,654 bytes, about 0.9 MB. Ten machine states need 10 x 921,654 = 9,216,540 bytes, about 9.2 MB, held for the life of the runtime.
The formula covers uncompressed pixel arrays only, so check the compression setting in the image source before budgeting. Compare the total against the memory limit in your controller documentation: if it fits, the list route wins for a finite image set; if it does not, take the viewer route.
How do you prove the refresh works?
Alternate two unmistakable test images, one with a large numeral 1 and one with a large numeral 2, and confirm the screen flips within one reload period after each transfer completes, without any restart.
- Put the two test images in the FTP cycle in turn.
- Watch the screen without restarting. The numeral must flip within one reload period of each transfer completing.
- Time the delay from the end of the FTP put to the visible change. It must stay under the sum from the worked example, T_ftp + transfer + reload period. A longer delay points to the viewer caching the frame or a reload period set longer than you intended.
- Leave the alternation running overnight. A refresh that stops after hours points to a stalled FTP job or a viewer that stopped reloading, so read both logs before you change the design.
Could a newer runtime or a reload call fix it?
The answer is in the runtime documentation, not in the visualization. Ask the controller maker whether your runtime version offers a bitmap reload call or a newer runtime with one, because that single answer decides between a code fix and the viewer workaround.
Some controller makers publish an image and runtime update procedure with its own loader, as a documented vendor procedure. That is the shape of documentation to look for. Give the support line the exact symptom, a bitmap that changes only at runtime start, together with your runtime version, and ask for a reload call by name. If one exists, it replaces the whole workaround.
Restarting the runtime is the fallback that always works, because the next start re-reads every bitmap. It fits only a process that tolerates the screen going down for the restart. If the picture is an operator's only view of a moving machine, rule this fallback out.
Recommendation: For a fixed, known set of images, load them into a bitmap list and drive the element with an index variable, provided the memory total fits the limit in your controller documentation. For a file that keeps changing, display it in a viewer whose reload period is set at or above the FTP update period, and point that viewer straight at the camera's HTTP image endpoint when a camera is the source. Ask the controller maker about a bitmap reload call before you build either route, and use a runtime restart only where the process tolerates the blank screen.
Questions
Does the Link to file option in the Bitmap Configuration menu re-read the file?
No. It sets the source the runtime loads at start-up, and the load still happens once per runtime start. Prove it in one cycle: overwrite the linked file, confirm the size and timestamp changed in the FTP listing, and watch the screen hold the old frame until the next restart.
What reload period should a viewer use for an image that updates every 300 seconds?
Set it to 300 seconds or longer, so every reload fetches a fresh frame and the viewer never races the transfer. Shorter reloads still help when you need a fresher picture: at 60 seconds the worst-case age drops from 610 seconds to 370 seconds, and the only cost is re-fetching an unchanged file between updates.
Can I force the bitmap to reload by restarting the CoDeSys runtime?
Yes, a runtime restart re-reads every bitmap the visualization references, so the new file appears at the next start. It blanks the screen while it runs and clears every loaded image, so it suits processes that tolerate a restart. If the picture is an operator's only view of a moving machine, use the viewer route instead.
How much RAM do ten 640 x 480, 24-bit bitmaps need?
About 9.2 MB. Each entry is 921,654 bytes, which is 1,920 bytes per row times 480 rows plus a 54-byte header; ten entries total 9,216,540 bytes. That RAM is held for the life of the runtime, so compare the total against the memory limit in your controller documentation before building the list.
Planning information, not legal or engineering advice. Rules differ by place: check codes and permits with your local authority and your licensed trades.