Scrolling text on an HMI screen with PLC logic

5 min read · Published November 8, 2026

No HMI text object, screen selector label or screen change button label scrolls on its own. The moving message comes from a dynamic text object whose PLC string tag changes under ladder logic: a timer steps a one-character offset through the message at the interval set in the worked example, and the object redraws each new frame. Keep the button label short and static.

Check the panel's object list first: if it offers a scrolling text or marquee object, place one and the job is done. Most small HMI panels do not, and on those the moving message has to come from PLC logic: a dynamic text object whose string tag the PLC rewrites one character per timer pulse, so the message slides through the window the object shows. Below is the ladder logic, the timing arithmetic for a 40-character message in a 20-character window, and the decision on where each kind of message belongs.

What scrolls and what never will

On a panel without a native marquee object, every caption is a fixed string. The static text object draws what you typed and holds it. A long label in a screen selector sits still, however long the label is. The screen change push button label is a fixed string too, which is the same limit that stops it taking a line break. Loading a longer caption into any of these objects changes nothing about how they draw.

The dynamic text object is built for changing text: it reads ASCII characters out of PLC memory starting at the tag address and draws what it finds there. Change the bytes in that memory area and the object changes on its next read. The crawl is nothing more than PLC logic rewriting those bytes one character per pulse, in its own object on the screen.

What you need

  • A dynamic text object on the screen, its tag bound to a string area in PLC memory and its visible width set to the window you want. The worked example uses 20 characters.
  • A string area for the tag sized to the window: 20 bytes for ASCII text, one byte per character.
  • The full message stored where the ladder logic can read it, 40 bytes for the example, as a constant or in a spare block.
  • A scratch string of window width for assembling each frame, so the tag area only ever receives complete frames.
  • A self-resetting on-delay timer. The preset sets the crawl speed; the worked example uses 250 ms.
  • An integer for the frame counter.
  • If the controller stores text as integer words instead of a string type, convert it first; that job is covered separately in displaying ASCII from integer words on an HMI.

Write the ladder logic

  1. Load the message. Store the 40-character message in the master area at startup. Nothing else writes to it.
  2. Bind and prove the object. Point the dynamic text object at the tag string area, set the window to 20 characters, and write a fixed test string such as SCROLL TEST 1234 into the area. The object must draw the test string before any crawl logic is written; if it shows nothing, the tag address is the first thing to check, exactly as with a numeric display that shows nothing.
  3. Pulse the timer. Self-resetting on-delay timer at the preset above, done bit live for one scan per pulse.
  4. Step one character per pulse. On the done pulse, shift the scratch string left by one character, write the next character of the master message into the last position, then move the whole scratch string into the tag string with a single instruction. The single move is what keeps the panel from reading a half-shifted frame.
  5. Count frames and reset. Add 1 to the frame counter on each pulse. After the 21st frame, rebuild frame 1 from the master copy, move it into the tag string, and set the counter back to 1.
  6. Leave the button alone. The screen change push button keeps its short label and its navigation function. The crawl lives beside it, not inside it.

If part of the message has to change with the job or the shift, embed the variable in the string the same way you would in any PLC message string; the crawl logic reads the result as ordinary characters.

Example: a 40-character message in a 20-character window

Inputs: message 40 characters, window 20 characters, step 250 ms.

Frames per pass: the window start moves from character 1 to character 21, so 40 - 20 + 1 = 21 frames.

Pass time: 21 frames x 0.25 s = 5.25 s, and the crawl rate is 1 / 0.25 s = 4 characters per second. For a fixed message and window, the step interval sets the pass time directly:

Step interval Pass time (21 frames) Crawl rate
200 ms 21 x 0.2 = 4.2 s 5 characters per second
250 ms 21 x 0.25 = 5.25 s 4 characters per second
400 ms 21 x 0.4 = 8.4 s 2.5 characters per second

At the 250 ms step the message crosses the window in 5.25 seconds and restarts. Lengthen the interval for more reading time, shorten it for more urgency.

How to check it worked

  • Watch the tag online. The test string draws before the logic runs; then one character advances per timer pulse, with no skipped or doubled frames.
  • Watch the restart. At the end of a pass the message begins again complete, with no characters left over from the previous pass. Leftover characters point to a reset step that is not firing.
  • Press the screen change button through every screen it serves. Navigation is unchanged and the crawl keeps running on the screen where it was placed.
  • If frames skip or characters jump two at a time, the panel reads the tag more slowly than the step interval delivers frames. Lengthen the interval until every frame shows; an HMI screen that updates slowly over serial is a tag update timing problem of its own.

Where each message belongs

  • Message fits the window: static text object, no logic. In the example that is anything 20 characters or shorter.
  • Message longer than the window: the crawl in a dynamic text object.
  • Instruction the operator must act on at once, such as a lockout step: static text, where the whole line is visible at a glance. A crawl can be half-way through a 5.25 s pass when the operator walks up.
  • Screen change push button: short label. The crawl object sits beside it.

Recommendation: keep the screen change push button label to a short fixed word, and put any instruction longer than the window width in a dynamic text object driven by the crawl from the example; when the whole message fits the window, delete the ladder logic and use a static text object.

Questions

How many frames does my message and window need?

Frames per pass = message characters - window characters + 1. A 60-character message in a 20-character window gives 60 - 20 + 1 = 41 frames; at 300 ms per frame one pass takes 41 x 0.3 = 12.3 seconds. Widen the window to 30 characters and the same message needs 31 frames, 9.3 seconds at 300 ms. If the message is shorter than the window, no crawl logic is needed.

Why does the text come out garbled or cut off mid-pass?

Usually the tag string area is smaller than the frame the logic writes, so characters drop or wrap. Size the tag area to the window, one byte per ASCII character, and the master message area to the full message length. If a frame looks torn, with old and new characters mixed, the copy into the tag string is not happening in a single instruction; assemble the frame in a scratch string and move it over once.

How do I make the crawl loop without pausing at the end of each pass?

Wrap the character that leaves the front of the window back onto the end of the string and drop the reset step. The message then circles for as long as the timer runs. With the 40-character message in the 20-character window the cycle is 40 frames, 40 x 0.25 = 10 seconds per revolution at the example step interval.

Planning information, not legal or engineering advice. Rules differ by place: check codes and permits with your local authority and your licensed trades.

Keep reading

Build your signAsk for a quote