Back to Blog
Engineering

Practical Advice for Equipment Control Software Development

Equipment control software runs in a different world from typical software — minimize debugger reliance, log strategically, follow conditional patterns and think about compatibility. Hands-on guidelines from years on the floor.

6 min read· ICT Engineering

Equipment control software development sits in a different environment from general software development. The constraints of code that runs on a production machine — and the cost of a single mistake — keep these practical guidelines relevant year after year.


Advice on Equipment Control Coding

Equipment control SW has a particular environment, so the following differs from general software development.

  • Minimize debugger use — You can't easily attach a debugger while a machine is running. Lean on logs aggressively, and train yourself to read source quickly.
  • Design the structure first — See the big picture first. When you sit down to code, then focus on the details.
  • Analyze the customer's request — Don't just take the surface request at face value. Spend time finding the underlying cause.
  • Find the common condition — Look for the simple, common condition that captures the essence while covering several specific cases. It collapses branches.
  • Side effects of changes — One fix often creates ten new problems. Adding a single checkbox option doubles the test cases and the bugs.
  • Cost of code branching — Maintaining the same machine across two separate codebases adds 1.5× to the workload, but 2× to maintenance cost and bugs.
  • New driver testing — Test new drivers thoroughly on a single machine before rolling them out to production fleet.
  • Deployment checklist — Don't ship just the executable. Confirm any new files the version-up needs are also included.
  • Logging strategy — Always log key conditions, sequences and data. Logs are mandatory for exception paths. And clean up logs that no longer matter.
  • UX basics — In the end, what matters is consideration for the user.

Conditional Statement Style

Order conditions so they read in the way humans think.

  • Lead with the largest premise.
  • At the same level, put conditions that are less likely to be true first (short-circuits faster, fails earlier).
  • Avoid wrapping the whole thing in negation (!(...)) — readers have to flip it back in their heads.
// GOOD
if (A == false && B == false && C == false) { ... }
 
// BAD
if (!(A || B || C)) { ... }

In comparisons, put the variable on the left, the constant on the right — it matches natural reading order.

// GOOD
if (A > 2) { ... }
 
// BAD
if (2 < A) { ... }

Pointer-Returning Functions

When a pointer-returning function fails, returning NULL invites the caller to forget the null check, which usually ends in a stopped machine.

  • Where it makes sense, return a meaningful dummy data pointer so the program keeps running.
  • Either way, always log so the team can trace where the fallback was triggered.

UI / UX

  • When you add an XEdit or similar input control, set a sensible default. An empty field forces the user to fill it every time.
  • If the user navigates away without saving, revert the data. The expected behavior of "don't save" must be consistent.

Management and Optimization

  • If you accommodate every customer request too easily, those become the new baseline.
  • The instant you see duplicated code, refactor it into a function. Wait, and the two copies drift.
  • Set Include Path per project, not as a global option. It reduces environment dependency.
  • Past the project midpoint, start thinking about the exit strategy — handover, documentation, log cleanup.

Logs and Searchability

In log messages, don't append () to function names — it hurts searchability.

// GOOD
LOG_PRINTF("", "DoFunc executing");
 
// BAD
LOG_PRINTF("", "DoFunc() executing");

Compatibility and Scenarios

  • When adding features, first consider compatibility with existing data and applicability to production machines. Data migration cost is bigger than it looks.
  • When a sequence problem occurs, don't stop until you have a clear, reproducible timing and scenario. Settling for "it sometimes happens" gets much more expensive in production.

Tools and Languages

Use powerful, productive tools and languages.

  • General purpose: Visual Studio (C++, C#)
  • Control-specific: BeckHoff TwinCAT, CodeSys
  • ICT's integrated control IDE: QMachineStudio — sequences, GUI and runtime debugging in one place.

Good tools and a strong language pay dividends in development efficiency. Even when you're comfortable with what you have, it's worth periodically auditing your environment.

PC controlAutomationCoding conventionsDebuggingEquipment development