How to create popups on a Universal Robots teach pendant

Based on contributions by BoazvdV.

Use popups to show messages to the operator on the PolyScope run screen: a warning that stops the program until it’s acknowledged, or a status message that updates itself in the background. This guide covers both types and how to format them.

What you need

  • A Universal Robot (CB2, CB3, or e-Series) with PolyScope.
  • No extra hardware. Examples below were tested on e-Series 5.16, but both popup types work on all e-Series versions.

Which popup do I use

Standard popup Informational popup
Created with popup() script function Socket commands to the Dashboard Server
Styles Info, Warning, Error Free-form (HTML only)
Blocks the program Optional (blocking=True/False) No
User can dismiss it Yes, with an on-screen button Yes, with an on-screen button
Minimum version CB2 1.8.16941, CB3 3.1.17779, e-Series: all :warning: Check: exact CB2/CB3 build numbers unverified CB2 1.8.1694, CB3 3.1.17779, e-Series: all :warning: Check: exact CB2/CB3 build numbers unverified
  • A standard popup is the easiest option and is suited for user intervention: it can pause the program (blocking=True) until the operator presses Continue. Downsides: the operator could accidentally press “Stop program” instead, and no other on-screen buttons work while it’s open.
  • An informational popup never pauses or interrupts the program, so it’s better for status messages you want to keep updating (e.g. “kit level: 40%”). It can only be styled with HTML, and it also blocks other on-screen buttons while open.

Official references: Create a popup, Create informational popups in the run screen.

Steps

1. Create a standard popup

Add a popup() call anywhere in your URScript program:

popup("here I am", title="Popup #1", blocking=True)

Signature (from the UR Script Manual, 5.16):

popup(s, title='Popup', warning=False, error=False, blocking=False)
  • s: the message text.
  • title: the popup title.
  • warning / error: set one to True to change the popup’s style.
  • blocking: if True, the program pauses until the operator presses Continue.

The exact parameter list can differ slightly between software versions — check the Script Manual for your installed version if a parameter is rejected.

2. Create an informational popup

Informational popups aren’t a built-in function. You create and close them by sending raw commands to the controller’s own Dashboard Server (a local service on port 29999):

# open a connection to the Dashboard Server for popups
socket_open("127.0.0.1", 29999, "internal")
    # "127.0.0.1" = the Dashboard Server always runs on the controller itself
    #  29999      = Dashboard Server port
    # "internal"  = local name for this socket connection

# show a popup
socket_send_string("popup The text I want", "internal")
socket_send_byte(10, "internal")
    # the byte 10 is a newline, which the Dashboard Server needs to end the command

# close the popup
socket_send_string("close popup", "internal")
socket_send_byte(10, "internal")

If you show informational popups often, wrap this in a function that closes any existing popup first and formats the text as a heading:

def newmsg(text):
  # close the current popup, if any
  socket_send_string("close popup", "internal")
  socket_send_byte(10, "internal")

  # wrap the text in an <h1> tag and show it
  text = str_cat("popup <h1>", text)
  text = str_cat(text, "</h1>")
  socket_send_string(text, "internal")
  socket_send_byte(10, "internal")
end

Call socket_open() once at the start of your program before using newmsg().

3. Format the popup text with HTML

Both popup types support basic HTML: headings, bold/italic, line breaks, simple inline styles, and some emoji. Full HTML reference: w3schools.com/html.

To build a message from variables, use str_cat(). It only concatenates two values at a time, so chain calls to join more:

newmsg(str_cat(str_cat(
  "Replace tube <br><br> kit level = ", kit_percentage), "%")
)
Emoji reference (checked working in PolyScope)

These UTF-8 emoji codepoints were confirmed to render inside popup HTML:

:grinning_face: U+1F600 · :smiley: U+1F603 · :grinning_face_with_smiling_eyes: U+1F604 · :grin: U+1F601 · :sweat_smile: U+1F605 · :laughing: U+1F606 · :joy: U+1F602 · :wink: U+1F609 · :blush: U+1F60A · :innocent: U+1F607 · :smiling_face_with_sunglasses: U+1F60E · :heart_eyes: U+1F60D · :face_blowing_a_kiss: U+1F618 · :kissing_face: U+1F617 · :smiling_face: U+263A · :kissing_face_with_closed_eyes: U+1F61A · :kissing_face_with_smiling_eyes: U+1F619 · :face_savoring_food: U+1F60B · :face_with_tongue: U+1F61B · :winking_face_with_tongue: U+1F61C · :squinting_face_with_tongue: U+1F61D · :neutral_face: U+1F610 · :expressionless_face: U+1F611 · :face_without_mouth: U+1F636 · :smirking_face: U+1F60F · :unamused_face: U+1F612 · :sleepy_face: U+1F62A · :sleeping_face: U+1F634 · :relieved_face: U+1F60C · :pensive_face: U+1F614 · :face_with_medical_mask: U+1F637 · :face_with_crossed_out_eyes: U+1F635 · :confused: U+1F615 · :worried: U+1F61F · :frowning: U+2639 · :open_mouth: U+1F62E · :hushed_face: U+1F62F · :astonished_face: U+1F632 · :flushed_face: U+1F633 · :frowning_face_with_open_mouth: U+1F626 · :anguished_face: U+1F627 · :fearful: U+1F628 · :anxious_face_with_sweat: U+1F630 · :sad_but_relieved_face: U+1F625 · :cry: U+1F622 · :sob: U+1F62D · :scream: U+1F631 · :confounded_face: U+1F616 · :persevering_face: U+1F623 · :disappointed_face: U+1F61E · :downcast_face_with_sweat: U+1F613 · :weary_face: U+1F629 · :tired_face: U+1F62B · :enraged_face: U+1F621 · :angry: U+1F620 · :smiling_face_with_horns: U+1F608 · :skull_and_crossbones: U+2620 · :grinning_cat: U+1F63A · :grinning_cat_with_smiling_eyes: U+1F638 · :joy_cat: U+1F639 · :smiling_cat_with_heart_eyes: U+1F63B · :cat_with_wry_smile: U+1F63C · :kissing_cat: U+1F63D · :weary_cat: U+1F640 · :crying_cat: U+1F63F · :pouting_cat: U+1F63E · :heart_exclamation: U+2763 · :heart: U+2764 · :victory_hand: U+270C · :index_pointing_up: U+261D · :writing_hand: U+270D · :monkey_face: U+1F435 · :cat_face: U+1F431 · :cow_face: U+1F42E · :mouse_face: U+1F42D · :shamrock: U+2618 · :hot_beverage: U+2615

Common mistakes

  • Forgetting blocking=True on a standard popup when you actually need the program to wait for the operator.
  • Reusing an informational popup’s socket connection without closing the old popup first — always send close popup before opening a new one, or use the newmsg() helper.
  • Not accounting for the fact that both popup types block the other on-screen buttons while open, so avoid stacking popups.

Related


Rewritten and consolidated (Sept 2026) from the original student how-to’s: How to use two kinds of popups (Universal Robots).