Home
Name Modified Size InfoDownloads / Week
simulator.exe 2026-02-28 120.1 kB
README.md 2026-02-28 23.8 kB
Totals: 2 Items   143.9 kB 5

Bufferstack.IO Open Protocol Advanced Simulator

A production-grade Atlas Copco nutrunner controller simulator for Open Protocol R2.16.0 integration testing, OPC UA gateway development, and Node-RED prototyping.

Copyright © 2026 Harshad Joshi, Bufferstack.IO Analytics Technology LLP, Pune, Maharashtra, India


Table of Contents


Overview

This simulator emulates an Atlas Copco nutrunner tightening controller over TCP using the Open Protocol R2.16.0 specification. It is written in C and targets Windows (MinGW / MSYS2), compiling to a single self-contained executable with no external dependencies beyond the Windows socket library.

It is a C port of the advanced-traceability-simulator-rev-1-to-7.js JavaScript reference implementation, preserving identical simulation behaviour while adding lower-level protocol control, raw frame tracing, multi-client support, and a 1-hour runtime limit.

The simulator is the companion test tool for the Bufferstack.IO node-nutrunner-open-protocol library and the Open Protocol → OPC UA Gateway project. It allows full end-to-end integration testing of gateway software, Node-RED flows, and OPC UA clients against a realistic controller simulation — without needing physical Atlas Copco hardware.


Why This Exists

Developing and testing Open Protocol integrations against real nutrunner hardware is expensive, requires physical access to factory equipment, and cannot easily simulate NOK (not-OK) fault conditions on demand. This simulator solves that by:

  • Running entirely on a Windows development machine.

  • Generating realistic tightening results with random torque, angle, VIN, operator, and joint data.

  • Injecting controlled NOK fault scenarios (torque too low, torque too high, angle deviation, cross-thread detection).

  • Supporting all MID 0061 revisions 1 through 7 simultaneously across multiple clients.

  • Sending MID 0900 trace curve data (torque and angle) for every tightening cycle.

  • Providing raw ASCII frame dumps on the console for protocol-level debugging.


Features

Protocol Coverage

  • MID 0001 / 0002 — Communication start and acknowledgement

  • MID 0005 — Generic positive acknowledgement (sent in response to subscription MIDs)

  • MID 0004 — Error frame

  • MID 0018 — Parameter set selection

  • MID 0038 — Job selection

  • MID 0040 / 0041 — Tool data upload request and reply

  • MID 0042 / 0043 — Disable and enable tool

  • MID 0060 — Subscribe to tightening results (MID 0061), revision negotiation

  • MID 0061 — Tightening result, Revisions 1 through 7

  • MID 0062 — Tightening result acknowledge (received and silently accepted)

  • MID 0070 — Alarm subscribe

  • MID 0071 — Alarm (sent on NOK cycles)

  • MID 0900 — Trace curve data subscribe

  • MID 0901 — Trace curve data unsubscribe

  • MID 9999 — Keep-alive echo

Simulation

  • 5 pre-configured tightening joints with realistic torque and angle ranges.

  • Random VIN selection from a pool of 4 simulated vehicle IDs.

  • Random operator selection from a pool of 4 simulated operator IDs.

  • Batch management with automatic rollover every 10 cycles.

  • ~15% random NOK injection across 4 distinct fault types.

  • Torque values rounded to 2 decimal places (matching JS toFixed(2) behaviour).

  • Angle values floored to integer degrees.

  • Realistic prevail torque, self-tap torque, rundown angle, and current monitoring values.

Infrastructure

  • Up to 16 simultaneous TCP clients.

  • Per-client MID 0061 revision tracking.

  • Per-client MID 0900 curve subscription tracking.

  • Thread-per-client architecture with critical section locking.

  • Non-blocking accept loop with keyboard polling.

  • Blocking send with WSAEWOULDBLOCK retry.

  • 1-hour runtime limit with graceful shutdown and countdown warnings.


Requirements

  • Windows 7 or later (uses Winsock2, GetLocalTime, CreateThread)

  • GCC via MinGW or MSYS2, or MSVC


Build

No external libraries. No CMake. No dependencies. Single file, single command.

Bash

gcc -o simulator simulator-shareware.c -lws2_32 -lm

Run

The simulator starts immediately, prints the configuration banner, and begins listening on TCP port 4545. Auto-mode starts generating tightening cycles every 5 seconds as soon as a client connects.

Bash

./simulator

Example startup output:

Plaintext

========================================================================
BUFFERSTACK.IO OPEN PROTOCOL ADVANCED SIMULATOR
© Harshad Joshi, 2026 - Bufferstack.IO Analytics Technology LLP
========================================================================
Port: 4545  Station: AdvancedStation01  Tool Serial: SN-TC-20260001
Auto-Mode: ON (5000ms interval)
MID 0061 Rev 1 - Rev 7 (negotiated per subscriber)
MID 0900: ENABLED   Raw Trace: ENABLED   Runtime: Max 1 hour auto-shutdown

Joints:

  1.  Engine Mount FL        45-55 Nm    80-120 deg
  2.  Engine Mount FR        45-55 Nm    80-120 deg
  3.  Transmission Mount     60-70 Nm    90-130 deg
  4.  Wheel Hub Bolt        120-140 Nm  360-420 deg
  5.  Suspension Arm         75-85 Nm   110-150 deg

Controls: q=Quit  m=Manual  b=Batch  j=Job  p=Pset  1-7=Rev  r=Layout

Configuration

All configuration is via #define constants at the top of simulator-shareware.c. No runtime arguments are needed. To change the port, tool serial, or any other parameter, edit the relevant #define and recompile. The build is fast — a few seconds at most.

Constant Default Description
PORT 4545 TCP listen port
STATION_NAME AdvancedStation01 Station name returned in MID 0002
TOOL_SERIAL SN-TC-20260001 Tool serial number (used in MID 0041 and MID 0061)
CONTROLLER_SN CTRL-SN-12345678 Controller serial number
AUTO_MODE 1 1 = auto-generate cycles, 0 = manual only
AUTO_INTERVAL 5000 Milliseconds between automatic tightening cycles
SEND_CURVES 1 1 = send MID 0900 after each cycle, 0 = disable
CURVE_POINTS 20 Number of torque/angle data points per curve
DEFAULT_REV 7 MID 0061 revision assigned to new clients before negotiation
MAX_RUNTIME_SEC 3600 Auto-shutdown after this many seconds (1 hour)

Keyboard Controls

The simulator polls for keypresses in the main accept loop without blocking. All controls work while clients are connected.

Key Action & Description
q / Q Graceful shutdown — closes all client sockets and exits
m / M Manual trigger — instantly generates one tightening cycle
b / B Force a batch change — increments batch counter and logs the new batch ID
j / J Increment Job — increments the current job number
p / P Increment Pset — increments the current parameter set (pset) number
17 Force Revision — forces all currently connected clients to MID 0061 revision N
r / R Print Layout — prints the full MID 0061 field layout for the current default revision

Simulated Joints and NOK Scenarios

Each tightening cycle selects a joint, VIN, and operator at random and generates torque and angle values within the joint's defined range, with ±10% variance.

Joints

ID Name Torque Min (Nm) Torque Max (Nm) Angle Min (°) Angle Max (°)
1 Engine Mount FL 45.0 55.0 80 120
2 Engine Mount FR 45.0 55.0 80 120
3 Transmission Mount 60.0 70.0 90 130
4 Wheel Hub Bolt 120.0 140.0 360 420
5 Suspension Arm 75.0 85.0 110 150

NOK Fault Injection

Approximately 15% of cycles are injected as NOK. The fault type is selected randomly. NOK cycles trigger a MID 0071 alarm in addition to the MID 0061 result.

Probability Fault Code Description
~5% E001 Torque Too Low — final torque falls below joint minimum
~5% E002 Torque Too High — final torque exceeds joint maximum
~3% E003 Angle Deviation — final angle exceeds joint maximum
~2% E004 Cross-Thread Detection — both torque and angle severely under-range

Supported MIDs

Incoming (RX)

Any unrecognised MID receives a MID 0005 positive acknowledgement.

MID Description
0001 Communication Start
0018 Select Parameter Set
0038 Select Job
0040 Tool Data Upload Request
0042 Disable Tool
0043 Enable Tool
0060 Subscribe to Tightening Results (revision negotiation)
0062 Tightening Result Acknowledge
0070 Alarm Subscribe
0900 Trace Curve Data Subscribe
0901 Trace Curve Data Unsubscribe
9999 Keep-Alive

Outgoing (TX)

MID Description
0002 Communication Start Acknowledge
0004 Error
0005 Command Accepted (positive ACK)
0041 Tool Data Upload Reply
0061 Tightening Result (Rev 1–7)
0071 Alarm
0900 Trace Curve Data

MID 0061 Revision Details

MID 0061 revision is negotiated per client via MID 0060. Each client stores its own revision independently. The revision controls how many fields are appended to the result payload. Use keyboard key r at runtime to print the full byte-offset field layout for the current revision.

Rev Cumulative Fields Added
1 Cell ID, Channel ID, Controller Name, VIN, Job ID, Pset No, Batch Size, Batch Counter, Tighten Status, Torque Status, Angle Status, Torque Min/Max/Target/Final, Angle Min/Max/Target/Final, Timestamp, Last Pset Change TS, Batch Status, Tightening ID, Job Seq, Sync ID, Tool Serial, Full Timestamp
2 Strategy Options, Current Monitor Status, Prevail Monitor Status, Prevail Comp Status, Tightening Error Status, Rundown Angle, Current Min/Max/Final, Self-Tap Torque, Prevail Torque Min/Max/Final
3 Operator ID (Identifier Part 2)
4 Joint Identifier (Part 3), Job-Pset Identifier (Part 4)
5 Customer Error Code
6 Prevail Torque Compensate Value, Angle Error Status
7 Batch ID, Tool Serial (extended, 25 chars)

MID 0041 — node-open-protocol Compatibility

Critical note for integrators using the node-open-protocol npm package (st-one-io).

The Open Protocol R2.16.0 specification (Table 74) defines MID 0041 Rev 1 with fields 01 through 11 in sequential order, with toolSerialNumber = 14 characters. However, the node-open-protocol library parses MID 0041 with a different internal layout:

  1. toolSerialNumber is read as 10 characters (not 14).

  2. lastCalibrationDate is located at byte offset 10 from the start of the payload — immediately after the tool serial, with fields 02–08 placed after the date.

This was determined experimentally by observing what values appeared in the lastCalibrationDate field for different payload constructions.

Layout used by this simulator (node-open-protocol compatible)

Field Name Offset Width Notes
01 toolSerialNumber 0 10 Truncated from TOOL_SERIAL
09 lastCalibrationDate 10 19 YYYY-MM-DD:HH:MM:SS format
02 customerToolNumber 29 6
03 toolType 35 2 01 = torque wrench
04 tighteningDirection 37 1 1 = clockwise
05 motorSize 38 2
06 openEndType 40 2 00 = none
07 controllerID 42 4
08 numberOfTightenings 46 10 Increments with each cycle
10 controllerSerialNumber 56 10 Truncated from CONTROLLER_SN
11 calibrationValue 66 6 In cNm (Nm × 100), 005000 = 50.00 Nm

Total payload: 72 bytes

If you are using a different Open Protocol client library, verify its MID 0041 field layout independently. The spec-compliant layout (fields 01–11 in order, toolSerial=14, calibDate at offset 41) may be required instead.


MID 0900 — Trace Curve Data

After each tightening cycle, the simulator spawns a background thread that sends MID 0900 trace curve data 150ms after the MID 0061 result, to simulate the real controller's asynchronous curve delivery. Curve data is only sent to clients that have subscribed via MID 0900. Unsubscribe via MID 0901.

Two traces are included per frame:

  • Trace type 01 — Torque: 20 points, eased curve (ease-in-out from 0 to final torque), with ±3% random noise. Values in cNm.

  • Trace type 02 — Angle: 20 points, linear ramp from 0 to final angle, with ±2% random noise. Values in 0.1° units.


Frame Format

All Open Protocol frames use the standard 20-byte ASCII header. Frames are NUL-terminated on the wire. The receiver accumulates bytes until a NUL is found, then dispatches the complete message. Partial frames are buffered per client.

Plaintext

Bytes [0:4]   — Total frame length, 4-digit zero-padded integer (includes header)
Bytes [4:8]   — MID, 4-digit zero-padded string
Bytes [8:11]  — Revision, 3-digit zero-padded integer
Byte          — No-Ack flag (1 char)[1]
Bytes [12:14] — Station ID (2 chars)
Bytes [14:16] — Spindle ID (2 chars)
Bytes [16:20] — Sequence number (4 chars)
Bytes [20:]   — Payload (variable length)

Console Output

The simulator prints colour-coded output to the console using ANSI escape codes:

  • Green: OK tightening result or TX frame

  • Red: NOK tightening result, alarm, or error

  • Cyan: RX frame

  • Yellow: Batch change event or field layout dump

  • Grey: Timestamps and frame hex/ASCII trace

Every TX and RX frame is dumped in hex + ASCII at 32 bytes per line, with byte offset annotations. This provides full protocol-level visibility for debugging without a separate packet capture tool.


Architecture Notes

  • One thread per client: Each accepted client socket runs in its own thread, which handles all receive buffering and message dispatch for that connection.

  • Critical section locking: All access to the shared client array, result counter, batch ID, and controller state is protected by a single CRITICAL_SECTION.

  • Non-blocking accept loop: The server socket is set to non-blocking mode (FIONBIO=1) so the main thread can poll for keypresses between accept calls. Accepted client sockets are explicitly reset to blocking mode.

  • Async curve and alarm delivery: MID 0900 curves and MID 0071 alarms are delivered from separate short-lived threads with deliberate delays (150ms and 100ms respectively) to simulate real controller timing.

  • NUL-terminated framing: The receive buffer accumulates raw bytes and scans for NUL terminators to extract complete frames, correctly handling TCP stream fragmentation.


Known Quirks and Compatibility Notes

  • node-open-protocol (st-one-io)

The lastCalibrationDate field in MID 0041 is read at byte offset 10, not the spec-defined offset 41. See the MID 0041 section above for the full compatible layout.

  • ANSI Colours on Windows

Console colours require Windows 10 version 1511 or later (Virtual Terminal Processing). On older Windows versions the ANSI escape sequences will appear as literal characters. Redirect output to a file if needed: ./simulator > log.txt.

  • 1-Hour Runtime Limit

The simulator automatically shuts down after 3600 seconds. This is intentional for the shareware release. Warning messages are printed at 55, 50, 30, 10, and 5 minutes remaining. To run indefinitely, increase MAX_RUNTIME_SEC and recompile.

  • VIN and Operator Pools

VINs and operator IDs are randomly selected from small hardcoded pools. For production-like testing, expand the VINS[] and OPERATORS[] arrays in the source.


Disclaimer

This software is provided for development and testing purposes only. It is not intended for use in production environments, safety-critical systems, or real manufacturing lines. Bufferstack.IO Analytics Technology LLP and Harshad Joshi accept no liability for any damages, data loss, or equipment malfunction arising from the use of this software. The simulator does not control any physical hardware. It is a pure software simulation intended solely for protocol integration testing.


License

All rights reserved.

© 2026 Harshad Joshi, Bufferstack.IO Analytics Technology LLP, Pune, Maharashtra, India.

This software is part of the Bufferstack.IO Open Protocol OPC UA Gateway project. Redistribution or use outside of its intended development and testing purpose is not permitted without explicit written permission from the author.

Built with ❤️ in Pune, India — Bufferstack.IO Analytics Technology LLP

Source: README.md, updated 2026-02-28