Every conveyor belt, every robotic arm, every temperature probe on a factory floor is constantly broadcasting data — vibration, pressure, heat, fault codes. All of it flows through a single protocol the industrial world agreed on years ago.
But the engineers who needed that data — the ones keeping the machines running — couldn’t access it without opening a code editor and writing 50 lines of connection logic from memory. Every single time.
We built the tool that let them just look.
OPC UA is that protocol. This is the story of how we figured out what the tool should do — and shipped it.
My Role
Lead UX researcher and strategic partner in project planning.
Methods
4 contextual interviews · 5-participant external usability study · 13-area internal design review.
Scale
18 pain points → 14 requirements → 27 findings → 11 feature requests, distilled into 5 insight themes.
Outcome
Shipped in MATLAB R2026a, ~15 months from first interview to release.
~15 MONTHS
Scope
Dec 2023
Interview
Jan–Feb 2024
Study
Sep–Oct 2024
Review
Mar 2025
Ship
R2026a
I led the research and acted as a strategic partner in project planning — not just running studies, but shaping which problems were worth solving and which weren’t. I scoped the discovery phase, ran the contextual interviews, designed and ran the usability study, and presented findings to the developers and the internal design review board. When the team had to choose between competing feature requests, I was the one tying every recommendation back to evidence.
OPC UA is the language industrial machines speak to each other. A modern factory has thousands of sensors, motors, valves, controllers, and PLCs (programmable logic controllers — the small computers that run real-time hardware). They all need to share data: temperature, pressure, vibration, on/off state, fault codes. OPC UA is the standardized protocol that lets a sensor from one vendor and a controller from another talk without custom integration work.
When software like ours connects to a factory’s OPC UA server, what it sees is an address space — think of it as the table of contents of a factory’s data, with every sensor and motor organized like chapters and sub-chapters. Each individual entry — a single temperature reading, a single valve position — is a node. To watch a node change in real time, you create a subscription: a magazine subscription, basically. You ask for updates, and they arrive when something changes, instead of you having to keep checking.
Vocab · 1
Address space
Table of contents of a factory’s data — chapters and sub‑chapters.
Vocab · 2
Node
One entry — a single sensor value or valve position.
Vocab · 3
Subscription
Ask once; updates arrive whenever the value changes.
The protocol our customers had been using for two decades — OPC DA — was being deprecated industry-wide. Sensor manufacturers were dropping support. Our own product was scheduled to drop support too. Engineers in industries from amusement-park ride safety to ship-building to energy-grid monitoring had to migrate to OPC UA, and most of them didn’t have the programming background to write OPC UA scripts from scratch.
There was a market full of third-party OPC UA clients already. The question wasn’t whether we could build an OPC UA app. It was whether we could build one that would feel like it actually belonged in the hands of an engineer who already lives in MATLAB and Simulink — one that would let them go from “I need to read this sensor” to “I’m reading this sensor” without writing a line of code.
What were engineers actually trying to do? Not in the abstract — Tuesday‑morning, deadline‑three‑weeks‑out concrete.
I scoped a four-week discovery sprint with engineers across four industries: a controls engineer at an automotive supplier, a systems engineer building digital twins of amusement-park rides, an automation engineer doing virtual commissioning of PLCs, and a control engineer at a ship-building company. I built the screener, interview guide, and requirements document, and led synthesis with the developer and design lead.
Six months later, the team had a working prototype. I designed a task-based study with 5 external participants from four industries. The scenario: help a systems engineer at an amusement-park operator read ride vibration sensors and inspect their values. Each session was a contextual inquiry. Twenty-seven findings emerged, distilled into four high-priority themes.
I presented the prototype and findings to a five-person internal design review with senior product and design leadership. Reviewers walked through 13 interface areas. For each, I tracked their feedback and worked with the developer to write an honest design response — what we agreed with and would change, what we disagreed with and why.



Synthesis artifacts — affinity mapping, task flows, and competitor benchmarking across the 15-month process
Before we tested anything, four contextual interviews told us why the existing OPC UA workflow was failing engineers — and which engineer to design for first.
Discovery 01
What they actually want
Impact →
Locked the primary persona; established a hard design-review rule — every interaction discoverable without reading docs.
Discovery 02
The anchor isn’t the loudest — it’s the one with the worst alternative.
Impact →
Amusement-park digital-twin scenario became the canonical demo flow — the connect → browse → subscribe → see-it-update path users meet first.
Five high-priority insight themes from the usability study. Each follows the same shape: observation → insight → recommendation → what shipped.
Observation
Five separate findings circled the same problem: labels overloaded or contradicted terms engineers already used. Configure in the toolstrip read as “set up the nodes,” not “configure the connection.” Stop Monitoring read as “disconnect from the server.” Export Log got pulled into the gravitational field of “logging the data” — the engineer’s phrase for recording sensor values — so people clicked it expecting their captured data to come out. And in the right pane, Variable Information (which held the Data Type field engineers cared about most) sat collapsed behind a disclosure that participants didn’t open.
“I am already connected to the server. Configure may have user password, security password. I think configure is more of configuring the user ID, password.”— UT4, on the Configure / Connect ambiguity
Insight
Terminology debt compounds silently. Each label was defensible in isolation; together they formed a vocabulary that didn’t survive contact with a working engineer. The worst part of the failure mode: users didn’t say “I’m confused” — they confidently took the wrong action and assumed they’d succeeded.


The four renames, line by line
| Label shown | What users heard | What shipped |
|---|---|---|
| Configure | “Set up which nodes to add” or “the place for user ID and password” | Renamed to Connection Settings. The button now carries the meaning it always implied. |
| Start Monitoring / Stop Monitoring | “Connect” / “Disconnect from the session” | Renamed to Add to Table / Remove from Table. The verb describes the effect on the visible UI, not the abstract subscription. |
| Export Log + Log tab | “Export my recorded data” — “logging” meant captured sensor values, not events | Export Log removed entirely. The bottom-dock Log tab renamed to Activity Log so its scope is unambiguous. |
| Variable Information (collapsed) | “Where’s the data type?” — the field engineers cared about most lived behind a disclosure | Expanded by default. Data Type is now visible at first glance alongside the rest of Node Information. |
Recommendation
Rename to verbs engineers say at the bench. Delete the action whose name is the source of the confusion rather than renaming it. And don’t hide the metadata users came to see.
What shipped
ShippedAll four changes landed in the next build. The most consequential move wasn’t a rename — it was deleting Export Log outright. Its presence was the entire reason “logging” collided with “recording.” A rename would have kept the trap; removing it closed it.
Observation
Every participant who tried to read a sensor value scrolled past the “Node Function” panel without seeing it. They were drawn to the larger “Node Information” panel — which only displays metadata — and then asked, “Where do I read the value?”
Insight
We had laid the panels out in the order the data structure suggested (“here’s what this node is, then here’s what you can do with it”) instead of the order the user’s intent demanded.

Recommendation
Swap the two panels. Action above metadata. Don’t try to teach the user a new mental model when their existing one is already correct.
What shipped
ShippedPanels swapped in the next build. We also added a Generate Script button — validated against the historical-data export pattern that surfaced six times across the study. A click produces a MATLAB Live Script that recreates the session as code.
Observation
Real factory address spaces have thousands of nodes. Participants spent 30–90 seconds per task hunting for nodes by hand-expanding tree branches.
“This is like opening every folder on a corporate file server to find one document.”— Participant struggling with the tree-without-search
Insight
An address space without search is a library without a card catalog. The tree was correct; what was missing was a way into the tree. Participants who’d used a competitor product — UA Expert — kept reaching for the search bar that didn’t exist.

Recommendation
Add a search bar at the top of the address space. Match nodes by name and by browse path. Ship search on the API side first (where it’s cheap), then bring it into the app.
What shipped
~ Partially shippedAPI-side search shipped in the same release. In-app search was deliberately de-scoped to a follow-up — we needed more data on which search behaviors mattered most (substring vs. fuzzy, recent vs. favorites).
Observation
Three of the five participants tried to write a value to a node that was server-side read-only. The app accepted the input, sent the write, and surfaced a vague BadWriteNotSupported error from the server. Two participants assumed they’d typed the value wrong and tried again. One walked away frustrated.
Insight
The mistake wasn’t a typing error. It was a discoverability failure — the app gave no visual signal that a node was read-only before you tried to write to it. Engineers who know read/write permissions exist still don’t carry that knowledge to every node they look at; they expect the interface to surface it.

Recommendation
Visually grey out cells in the monitoring table for read-only nodes. Don’t change the underlying behavior — just close the loop on the affordance.
What shipped
ShippedThe Node Function panel now exposes a Write tab only when the selected node permits writing. Read-only nodes show only a Read tab — so the user never starts a write the server will reject.
Observation
When a participant inspected a node, they expected to see four things together: the value, the unit (°C or psi or m/s²), the data quality (is this reading trustworthy right now?), and the sampling frequency (how fresh is this number?). The app showed value and partial metadata; the rest required clicking into a separate panel.
Insight
Engineers don’t read sensor values in the abstract. A temperature reading without a unit and a quality flag is decoration, not data. The app was forcing them to assemble context across multiple panels every time they checked a value.

Recommendation
Surface unit, data quality, and last-update timestamp inline with every value, in the monitoring table. Make the answer to “is this reading trustworthy right now?” a glance, not a workflow.
What shipped
ShippedQuality and timestamp shipped as inline columns. Units were deliberately kept out of the table; they sit in the Node Information panel as secondary data. Mixing unit strings into the table would force every Generate-Script consumer to strip them before computation — the secondary-data placement preserves both context and the numeric pipeline.
The Internal Design Review wasn’t a checkpoint — it was the round where I had to make decisions about what to ship now, what to defer, and what to push back on with five senior reviewers across engineering and design. These three moments are where the work was less “research findings” and more “strategic partner in project planning.”
IDR Moment 01
Observation
The product team’s instinct was to defer export functionality — “they can copy it manually, or use the API for that.” From the usability study, I’d already seen three of five participants reach for some equivalent of “save this to a file” or “get this into a script” within the first five minutes.
My Stance
I argued — with the usability evidence behind it — that export was the moment the app stopped being a viewer and started being a tool. Without it, every digital-twin use case would have the engineer dropping back to the API the moment they had data they wanted to keep. I framed it as a v1 must-have, not a stretch goal.
Outcome
Shipped in R2026a. The Generate-Script button sits in the toolbar under CODE GENERATION; a click produces a MATLAB Live Script with the session reconstructed as code.

IDR Moment 02
Observation
Four of five reviewers and three of five usability participants asked for in-app search of the address space. The temptation to add it for v1 was strong. But the engineering cost was substantial — the address-space tree isn’t always fully loaded; search has to handle partial-load semantics and permissions — and we were already at scope on v1.
My Stance
I pushed for shipping API-side search in v1 and deferring the in-app version. The digital-twin engineer who needs to find a specific node fast is also the one most likely to be scripting. Holding v1 for in-app search would have delayed export, the read/write affordance fix, and the panel-order swap — all of which had stronger usability evidence.
Outcome
API-side search shipped in R2026a. In-app search is on the roadmap for the next release with stronger discoverability scaffolding — recents, favorites, filter chips — informed by v1 telemetry.
IDR Moment 03
Observation
The first design draft had the Node Information panel above Node Function. A principal engineer noted, almost in passing, that this was “probably right because information comes before action.” From the usability study, four of five participants had hit the bottom panel first looking for what to do, then scrolled up — the opposite mental model.
My Stance
I proposed swapping the order: Node Function (what can I do here) above Node Information (what is this). The argument wasn’t about hierarchy or convention — it was that tools answer “what can I do” before “what is this,” especially for users who already know what an OPC UA node is.
Outcome
Panels were swapped — the cleanest before/after in the shipped app.

Node Information was the largest panel by default; Node Function (the action panel) sat below it, off-screen on smaller monitors. After: action panel on top, metadata below, with a Generate Script button added.
The OPC UA Explorer shipped in MATLAB R2026a, ~15 months after the first contextual interview. You can read its public documentation at mathworks.com/help/icomm/ug/opcuaexplorer-app.html.
Beyond the headline shipped features, the research generated an 11-item feature-request pipeline that has shaped the next two releases. As a strategic partner in project planning, I helped the team decide what not to ship in v1 just as much as what to ship.

| Feature request | Decision | Rationale |
|---|---|---|
| In-app address-space search | Deferred to next release | Search shipped on the API first; in-app search needed more data on which behaviors mattered |
| Right-click contextual menus on monitoring table rows | Deferred — enhancement request to underlying UI table component | Required platform-level change; not blocked on UX |
| Cross-correlation plots between two nodes | Deferred to a later release | Strong signal but small sample of users requesting it |
| Custom alarms on monitoring values | Deferred — covered by Simulink workflow today | Use case existed but had a viable workaround |
| Save/load app session layout | Deferred — enhancement request to platform | Required Hardware Manager–level change |
| Five other smaller asks | Deferred or absorbed into existing features | Mix of low frequency, high cost, or already in the roadmap |
Saying no with reasons is part of the job. Every deferral above traces back to a specific finding from the usability study or design review — not to engineering fatigue.
I’d start the strategic-planning conversation earlier. The research drove the right product, but I waited until I had data to bring strong opinions to the form-factor and scoping discussions. If I’d had this lens from week one, I’d have run a structured form-factor workshop before the usability study — committing the team to “this will be an app, not a Simulink block, because here’s the reasoning” before we sunk months into a particular UI direction. (For our next product — the OPC UA Server — that’s exactly what we did. The discipline came directly from this case.)
I’d run a smaller, faster usability round earlier — with 2 or 3 participants — to validate the prototype skeleton before the full 5-participant study. Several of the 27 findings were structural enough that an early micro-study would have caught them at a fraction of the cost. Five-participant studies are the right tool for “is this ready to ship?” — they’re a heavy hammer for “is this on the right track?”