Atlas Copco PowerFocus (3000/4000) Nutrunner Tools Ethernet Communication Using C#.Net



Atlas-Copco-PowerFocus.jpg

Introduction

In one of my projects I had a chance to create an Atlas Copco PowerFocus (3000/4000) Nutrunner Tools communication using C# socket programming. The main purpose of this article is the result of when I started the Nutrunner tool communication program it was like a blank page. I din't have an idea of how to solve the problem, I even Googled for 2 or 3 days but couldn't find sample code to communicate with the Nutrunner tools using C#. Finally I got a solution using an Open protocol.

Today I will explain what is:

 C# Socket communication program for Nutrunner tool communication

 

 

First, we start with:

You can Download the Open protocol document from this website Link
Atlas Copco OpenProtocol Forum


Message structure

All information sent over the communication links is ASCII format. A message consists of three parts; header, data field and message end.
For example here we see how to start a communication. For Communication start we need to use the MID 0001

Communication messages

MID 0001 Communication start


This message enables the communication. The controller does not respond to any other command before this.

Message sent by: Integrator

Answers: MID 0002 Communication start acknowledge or MID 0004 Command error, Client already connected.

If the Communication is accepted then we can receive the result as MID 0002 if not we receive the MID 0004.

For more details about the Open Protocol, please review the attached open Protocol PDF document.

3. C# Socket communication program for Nutrunner tool communication

  1. Connect
  2. Communicate
  3. Data send and receive
  4. Disconnect.

The detailed code will be listed below.

Background

The main purpose was to develop a simple and easy to use .Net communication program for Atlas Copco Power Focus (3000/4000) – Nutrunner Tool.

Using the Code

The code is very simple and has comments on all functions. The main purpose is to make the program very simple and easy to use. All the functions have been well commented in the project.

1. First we start with namespace declarations.

using System.Net;

using System.IO;

using System.Net.Sockets;

2. Variable Declarations

 Socket server;// Declare your Socket

 IPEndPoint ip; // Declare your IPEndpoin

3. Connect (to connect the Nutrunner tool for communication)

For connection we need the Nutrunner tool IP Address. Here my tools IP Address was "10.126.224.186" and the default port for comuncication is "4545". Cross check with your hardware engineer for the port used on your tools. Here we use the Socket communication program for connection.

After the connection is okay we need to send the Communication Start signal to the nutrunner tools " MID 0001" – ("00200001000000000000#)

Server.Send()

String szData = "00200001000000000000#";//Nutrunner Communication Start
byte[] byData = Encoding.Default.GetBytes(szData);
//convert the string as Byte

int sent = server.Send(byData, SocketFlags.None);

server.Receive()
 

byte[] bytesFrom = new byte[1025];

int iRx = server.Receive(bytesFrom);

string dataFromClient = System.Text.Encoding.ASCII.GetString(bytesFrom);

String resultchk = dataFromClient.Substring(4, 4).ToString();

If we receive MID 0002 as the result then the communication start is successful. If we receive MID 0004 as the result then there is an error in communication start.

The detailed connect functions.

private void button1_Click(object sender, EventArgs e)
{
    try
    {
        server = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
        String ipaddress = "10.126.224.186";
        ip = new IPEndPoint(IPAddress.Parse(ipaddress), 4545);
        server.Connect(ip);
        label2.BackColor = System.Drawing.Color.GreenYellow;
        label2.Text = "Connected";
        connectServer(); 
    }
    catch (Exception ex)
    {
    }

}

private void connectServer()
{
    try
    {
        if (server.Connected == false)
        {
            label2.BackColor = System.Drawing.Color.Red;
            server = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
            String ipaddress = textips.Text.Trim();
            ip = new IPEndPoint(IPAddress.Parse(ipaddress), 4545);
            server.Connect(ip);
            label2.BackColor = System.Drawing.Color.GreenYellow;
            label2.Text = "Connected";
        }

        if (server.Connected == true)
        {
            String szData = "00200001000000000000#";//Nutrunner Communication Start
            byte[] byData = Encoding.Default.GetBytes(szData);//System.Text.Encoding.ASCII.GetBytes(szData);
            int sent = server.Send(byData, SocketFlags.None);
            byte[] bytesFrom = new byte[1025];
            //  string bytesSent = server.Send(
            int iRx = server.Receive(bytesFrom);
            string dataFromClient = System.Text.Encoding.ASCII.GetString(bytesFrom);
            String resultchk = dataFromClient.Substring(4, 4).ToString();
            timer1.Enabled = true;
        }

    }

    catch (Exception ex)

    {

        MessageBox.Show(ex.Message.ToString());

    }

}

4. Torque Data Receive

Here in my program I have used a Timer control for the Torque data receive.

In the timer we frequently check for the connection. If the connection fails then we reconnect to the nutrunner tools.

To receive the Torque data we use the message id MID 0060.

To receive the Torque data we send MID 0060 to the Nutrunner tool.

MID 0060 Last tightening result data subscribe

Set the subscription for the result tightenings. The result of this command will be the transmission of the tightening result after the tightening is performed (push function). The MID revision in the header is used to subscribe to various revisions of MID 0061. Last tightening result data upload reply.

Message sent by: Integrator

Answer: MID 0005 Command accepted or MID 0004 Command error, Last tightening subscription already exists or MID revision is not supported.

Send data to get Torque result:

String szData = "00200060000000000000#";//Torque data Request Send

byte[] byData = Encoding.Default.GetBytes(szData);

int sent = server.Send(byData, SocketFlags.None);

Receive Torque result

byte[] bytesFrom = new byte[1025];

int iRx = server.Receive(bytesFrom);

string dataFromClient = System.Text.Encoding.ASCII.GetString(bytesFrom);

String resultchk = dataFromClient.Substring(4, 4).ToString();

We receive the MID 0061 as the result with Torque data.

We will receive the result data something like this:

023100610010 010001020103airbag7 04KPOL3456JKLO897 05000600307000008000009010011112000840 1300140014001
20015000739160000017099991800000 1900000202001-06-02:09:54:09212001-05-29:12:34:3322123345675 NUL

Format the result string and get the Torque final result.

For example I have used the substring and get the final torque result here

txtfinaltorque.Text = dataFromClient.Substring(132, 6).ToString();

The detailed Timer code.
 

private void timer1_Tick(object sender, EventArgs e)

{

    try

    {

        if (server.Connected == false)

        {

            label2.BackColor = System.Drawing.Color.Red;

            label2.Text = "Not Connected";

            server.Disconnect(true);

            server.Close();

            server.Dispose();

            connectServer();

        }

        String szData = "00200060000000000000#";//Nutrunner Communication Start

        byte[] byData = Encoding.Default.GetBytes(szData);//System.Text.Encoding.ASCII.GetBytes(szData);

        int sent = server.Send(byData, SocketFlags.None); 

        byte[] bytesFrom = new byte[1025];

        //  string bytesSent = server.Send(

        int iRx = server.Receive(bytesFrom); 

        string dataFromClient = System.Text.Encoding.ASCII.GetString(bytesFrom);

        String resultchk = dataFromClient.Substring(4, 4).ToString();

        if (resultchk == "0061")

        {

            label2.BackColor = Color.Violet;

            label2.Text = "Torque Data Readed ";

            textBox1.Text = dataFromClient.ToString();

            txtcellid.Text = dataFromClient.Substring(22, 4).ToString(); 

            txtchannelid.Text = dataFromClient.Substring(28, 2).ToString(); 

            txtjobid.Text = dataFromClient.Substring(86, 2).ToString(); 

            txtControlorName.Text = dataFromClient.Substring(32, 25).ToString(); 

            txtBatchSize.Text = dataFromClient.Substring(95, 4).ToString(); 

            txtBatchCount.Text = dataFromClient.Substring(101, 4).ToString(); 

            txttighteningstatus.Text = dataFromClient.Substring(107, 1).ToString();

            if (txttighteningstatus.Text.Trim() == "0")

            {

                txttighteningstatusok.Text = "NOK";

            }

            else

            {

                txttighteningstatusok.Text = "OK";

            } 

            txttorquestatus.Text = dataFromClient.Substring(110, 1).ToString(); 

            if (txttorquestatus.Text.Trim() == "0")

            {

                txttorquestatusok.Text = "Low";

            }

            else if (txttorquestatus.Text.Trim() == "1")

            {

                txttorquestatusok.Text = "OK";

            }

            else

            {

                txttorquestatusok.Text = "High";

            }

            txtanglestatus.Text = dataFromClient.Substring(113, 1).ToString(); 

            txttorqueminlimit.Text = dataFromClient.Substring(116, 6).ToString(); 

            txttorquemax.Text = dataFromClient.Substring(124, 6).ToString(); 

            txtfinaltorque.Text = dataFromClient.Substring(132, 6).ToString(); 

            txttorque.Text = dataFromClient.Substring(142, 2).ToString() + "." + dataFromClient.Substring(144, 2).ToString();//dataFromClient.Substring(140,6).ToString()

            txtTighteningID.Text = dataFromClient.Substring(221, 10).ToString(); 

            String szData3 = "00200062000000000000#";//Nutrunner Communication Start

            byte[] byData3 = Encoding.Default.GetBytes(szData3);//System.Text.Encoding.ASCII.GetBytes(szData);
            int sent3 = server.Send(byData3, SocketFlags.None);
 

        }

    }

    catch (Exception ex)

    {

    }

}


5. Disconnect the Connection

Check for the connection. If it's connected then disconnect the communication. The detailed code is below.

 

private void button2_Click(object sender, EventArgs e)

{

    if (server.Connected == true)

    {

        label2.BackColor = System.Drawing.Color.Red;

        label2.Text = "Not Connected";

        server.Disconnect(true);

        server.Close();

        server.Dispose();

        clears();

    }

}


Points of Interest

I love to work and play with the HMI (Human Interface Program). I have worked with several HML programs using C#, like PLC, Sensor Programing and Nutrunner tool communication Program. While working with this program I didn't get the proper guides to get the result, finally I got it. I want the end users to read this article since they should benefit from this program.