UnderAutomation
質問ですか?

[email protected]

お問い合わせ
UnderAutomation
⌘Q
Fanuc SDK documentation
Move robot with mouse
Documentation home

Starting and Supervising FANUC Programs via SNPX

Using System Variables or UI, you can start, stop and suupervise jobs on your Fanuc robot remotely via SNPX protocol. This article explains how to achieve this with C# code examples.

Overview

This guide demonstrates how to remotely control and monitor FANUC robot programs using the SNPX protocol through the UnderAutomation Fanuc SDK. You will learn how to:

  • Connect to a FANUC controller using SNPX
  • Select and start programs remotely
  • Hold, stop, and reset programs
  • Supervise program execution in real time
  • Monitor and clear alarms

The SNPX protocol provides a high-speed, low-latency communication channel ideal for production environments requiring real-time monitoring and control.


Prerequisites

Before proceeding, ensure you have:

RequirementDetails
SNPX OptionR651 FRL or R650 FRA + R553 installed on the controller
NetworkRobot accessible over Ethernet
SNPX EnabledSee the SNPX setup guide for configuration
Teach PendantKey switch set to REMOTE (Auto mode)
Controller StateFree of active alarms and no programs running
SDK ReferenceUnderAutomation Fanuc SDK added to your project

Controller Configuration

Program Select Mode Setup

Navigate on the teach pendant to: MENU → SETUP → Prog Select

  1. Set Program Select Mode to OTHER
  2. Set Production Start Method based on your preferred startup approach:
    • OTHER – Start via $SHELL_WRK.$CUST_START system variable
    • UOP – Start via UI[6:Cycle Start] or UI[18:Prod Start] signal (recommended for production)
  3. Cold start the controller after making changes

Program Select Mode Configuration


Connecting to the Robot

Initialize the SDK and connect using SNPX (we disable other protocols for clarity):

using UnderAutomation.Fanuc;
// Create robot instance
var robot = new FanucRobot();
// Configure connection parameters
var parameters = new ConnectionParameters("192.168.0.1");
// Disable other protocols (optional - they are disabled by default)
parameters.Telnet.Enable = false;
parameters.Ftp.Enable = false;
// Enable SNPX
parameters.Snpx.Enable = true;
// Connect to the robot
robot.Connect(parameters);
// Verify connection
if (robot.Snpx.Connected)
{
Console.WriteLine("Successfully connected via SNPX");
}

Connection Validation

Use PollAndGetUpdatedConnectedState() to actively check the connection health:

bool isAlive = robot.Snpx.PollAndGetUpdatedConnectedState();

Selecting the Target Program

Set the program name using the $SHELL_WRK.$CUST_NAME system variable. Do not include the .TP extension:

// Select the program to run (without .TP extension)
robot.Snpx.StringSystemVariables.Write("$SHELL_WRK.$CUST_NAME", "MY_PROGRAM");

Starting the Program

Enable Remote Control

To allow external control, the system variable $RMT_MASTER must be set to 0.

Before starting any program, allow remote control:

robot.Snpx.IntegerSystemVariables.Write("$RMT_MASTER", 0);

Option 1: System Variable Start (Production Start Method = OTHER)

When Production Start Method is set to OTHER, trigger the start by setting $SHELL_WRK.$CUST_START to 1:

// Start the selected program
robot.Snpx.IntegerSystemVariables.Write("$SHELL_WRK.$CUST_START", 1);

The controller automatically clears this bit once it acknowledges the command.

Option 2: UOP Cycle Start (Production Start Method = UOP)

This method uses UI (User Input) signals, providing additional control capabilities.

Step 1: Configure UI-to-Flag Mapping

Navigate to: MENU → I/O → UOP → select UI → CONFIG

Link UI signals to Flags (Rack 34, Slot 1):

ConfigurationResult
UI[1-8] → Rack 34, Slot 1, Start 1UI[1]=F[1], UI[2]=F[2], ... UI[8]=F[8]
UI[1-8] → Rack 34, Slot 1, Start 4UI[1]=F[4], UI[2]=F[5], ... UI[8]=F[11]
UI[6-6] → Rack 34, Slot 1, Start 9UI[6]=F[9]

Cold start the controller after configuration.

Step 2: Pulse the Cycle Start Flag

using System.Threading;
// Pulse the flag linked to UI[6:Cycle Start]
robot.Snpx.Flags.Write(6, true);

Controlling Program Execution via UOP

The UOP interface provides comprehensive control through UI signals:

UI SignalNameFunctionCode Example
UI[2]HoldPause program executionrobot.Snpx.Flags.Write(2, false);
UI[4]Cycle StopStop the current cyclerobot.Snpx.Flags.Write(4, false);
UI[5]Fault ResetClear active alarmsrobot.Snpx.Flags.Write(5, true);
UI[6]Cycle StartStart/resume programrobot.Snpx.Flags.Write(6, true);
UI[18]Prod StartAlternative production startrobot.Snpx.Flags.Write(18, true);

Supervising Program Execution

The SDK provides real-time access to task status through CurrentTaskStatus, which exposes RobotTaskStatus objects containing:

PropertyTypeDescription
ProgramNamestringName of the running program
LineNumbershortCurrent line being executed
StateRobotTaskStateCurrent state: Stopped, Paused, or Running
CallerstringParent program that called this one (if applicable)

Reading Task Status

using UnderAutomation.Fanuc.Snpx.Internal;
// Read the main task (index 1)
RobotTaskStatus mainTask = robot.Snpx.CurrentTaskStatus.Read(1);
// Clean up string values (remove null terminators and trailing spaces)
string programName = mainTask.ProgramName.TrimEnd('\0', ' ');
string caller = mainTask.Caller.TrimEnd('\0', ' ');
Console.WriteLine($"Program: {programName}");
Console.WriteLine($"State: {mainTask.State}");
Console.WriteLine($"Line: {mainTask.LineNumber}");
if (!string.IsNullOrEmpty(caller))
{
Console.WriteLine($"Called from: {caller}");
}

Task Index Reference

IndexDescription
1Main task (primary program)
2-5Background or concurrent tasks (when configured)

Monitoring Continuously

Implement a monitoring loop to track program execution in real time:

using System;
using System.Threading;
using UnderAutomation.Fanuc.Snpx.Internal;
RobotTaskStatus previousStatus = null;
while (robot.Snpx.PollAndGetUpdatedConnectedState())
{
RobotTaskStatus currentStatus = robot.Snpx.CurrentTaskStatus.Read(1);
// Only report changes
if (!currentStatus.Equals(previousStatus))
{
previousStatus = currentStatus;
string name = currentStatus.ProgramName.TrimEnd('\0', ' ');
Console.WriteLine($"[{DateTime.Now:HH:mm:ss}] {name} - {currentStatus.State} @ Line {currentStatus.LineNumber}");
// Check for completion
if (currentStatus.State == RobotTaskState.Stopped && previousStatus?.State == RobotTaskState.Running)
{
Console.WriteLine("Program execution completed!");
}
}
Thread.Sleep(200); // Polling interval
}

Waiting for Program Completion

public void WaitForProgramCompletion(FanucRobot robot, int timeoutSeconds = 300)
{
DateTime startTime = DateTime.Now;
while (robot.Snpx.PollAndGetUpdatedConnectedState())
{
RobotTaskStatus status = robot.Snpx.CurrentTaskStatus.Read(1);
if (status.State == RobotTaskState.Stopped)
{
Console.WriteLine("Program completed successfully");
return;
}
if ((DateTime.Now - startTime).TotalSeconds > timeoutSeconds)
{
throw new TimeoutException("Program execution timeout");
}
Thread.Sleep(100);
}
throw new Exception("Connection lost during execution");
}

Alarm Monitoring

Monitor and manage alarms alongside program supervision:

Reading Active Alarms

using UnderAutomation.Fanuc.Snpx.Internal;
// Read active alarm at index 1
RobotAlarm activeAlarm = robot.Snpx.ActiveAlarm.Read(1);
if (activeAlarm != null && activeAlarm.Number != 0)
{
Console.WriteLine($"Active Alarm: {activeAlarm.Id}-{activeAlarm.Number:000}");
Console.WriteLine($"Message: {activeAlarm.Message}");
Console.WriteLine($"Severity: {activeAlarm.Severity} ({activeAlarm.SeverityMessage})");
Console.WriteLine($"Time: {activeAlarm.Time:yyyy/MM/dd HH:mm:ss}");
if (!string.IsNullOrEmpty(activeAlarm.CauseMessage))
{
Console.WriteLine($"Cause: {activeAlarm.CauseMessage}");
}
}

Reading Alarm History

// Read alarm history (most recent first)
for (int i = 1; i <= 5; i++)
{
RobotAlarm historyAlarm = robot.Snpx.AlarmHistory.Read(i);
if (historyAlarm != null && historyAlarm.Number != 0)
{
Console.WriteLine($"[{i}] {historyAlarm.Time:yyyy/MM/dd HH:mm:ss} - {historyAlarm.Message}");
}
}

Clearing Alarms

// Clear all active alarms via SNPX command
robot.Snpx.ClearAlarms();
// Or via UI[5] Fault Reset
robot.Snpx.Flags.Write(5, true);

Complete Example

Here is a comprehensive example that ties everything together:

using System;
using System.Threading;
using UnderAutomation.Fanuc;
using UnderAutomation.Fanuc.Snpx.Internal;
class Program
{
static void Main()
{
var robot = new FanucRobot();
var parameters = new ConnectionParameters("192.168.0.1");
parameters.Snpx.Enable = true;
parameters.Telnet.Enable = false;
parameters.Ftp.Enable = false;
try
{
// Connect to the robot
Console.WriteLine("Connecting to robot...");
robot.Connect(parameters);
Console.WriteLine("Connected successfully");
// Clear any existing alarms
robot.Snpx.ClearAlarms();
// Enable remote control
robot.Snpx.IntegerSystemVariables.Write("$RMT_MASTER", 0);
// Select the program to run
string programName = "MY_PROGRAM";
robot.Snpx.StringSystemVariables.Write("$SHELL_WRK.$CUST_NAME", programName);
Console.WriteLine($"Selected program: {programName}");
// Start the program (using system variable method)
Console.WriteLine("Starting program...");
robot.Snpx.IntegerSystemVariables.Write("$SHELL_WRK.$CUST_START", 1);
// Monitor execution
RobotTaskStatus previousStatus = null;
DateTime startTime = DateTime.Now;
int timeoutSeconds = 300;
while (robot.Snpx.PollAndGetUpdatedConnectedState())
{
// Check for timeout
if ((DateTime.Now - startTime).TotalSeconds > timeoutSeconds)
{
Console.WriteLine("Timeout reached - stopping program");
robot.Snpx.Flags.Write(4, true); // Cycle Stop
Thread.Sleep(100);
robot.Snpx.Flags.Write(4, false);
break;
}
// Read current task status
RobotTaskStatus status = robot.Snpx.CurrentTaskStatus.Read(1);
// Report changes
if (!status.Equals(previousStatus))
{
string name = status.ProgramName.TrimEnd('\0', ' ');
Console.WriteLine($"[{DateTime.Now:HH:mm:ss}] {name} - {status.State} @ Line {status.LineNumber}");
// Check for completion
if (status.State == RobotTaskState.Stopped &&
previousStatus != null &&
previousStatus.State == RobotTaskState.Running)
{
Console.WriteLine("Program completed!");
break;
}
previousStatus = status;
}
// Check for alarms
RobotAlarm alarm = robot.Snpx.ActiveAlarm.Read(1);
if (alarm != null && alarm.Number != 0)
{
Console.WriteLine($"ALARM: {alarm.Message}");
break;
}
Thread.Sleep(200);
}
}
catch (Exception ex)
{
Console.WriteLine($"Error: {ex.Message}");
}
finally
{
// Always disconnect
robot.Disconnect();
Console.WriteLine("Disconnected");
}
}
}

Troubleshooting

IssuePossible CauseSolution
Connection refusedSNPX option not installed or enabledVerify R651 FRL or R650 FRA + R553 options are active
Start command ignoredRobot not in remote modeSet teach pendant to REMOTE/Auto, verify $RMT_MASTER = 0
Program not selectedWrong Program Select ModeSet Program Select Mode to OTHER and cold start
Task status always StoppedStart signal not receivedCheck alarms, verify UI mapping, ensure Cycle Start was pulsed
Intermittent disconnectsNetwork issuesCheck Ethernet cable, verify IP configuration
Alarm prevents startActive fault on controllerClear alarms with ClearAlarms() or UI[5]

  • SNPX Setup Guide – Configure SNPX on your FANUC controller
  • Telnet Protocol – Alternative remote control method
  • FTP File Operations – Upload/download programs and files

Universal Robots、Fanuc、Yaskawa、Staubli ロボットを .NET、Python、LabVIEW、または Matlab アプリケーションに簡単に統合

UnderAutomation
お問い合わせLegal

© All rights reserved.