콘텐츠로 건너뛰기
한국어 - 대한민국
  • 검색 필드가 비어 있으므로 제안 사항이 없습니다.

6축 힘/토크 센서(AFT200, EtherCAT)

✅ revision date: 2026.04.29

메뉴얼 안내


저희 힘/토크 센서를 구매해 주셔서 감사합니다.

이 매뉴얼에는 AIDIN ROBOTICS AFT200-D80 센서를 올바르게 사용하기 위한 필수 정보가 포함되어 있습니다.

소프트웨어 사용 시 반드시 본 매뉴얼을 자세히 확인해주시기 바랍니다.

로봇 시스템이 규정된 조건 밖에서 사용될 경우, 제품의 기본 성능이 발휘되지 않을 수 있음을 알려드립니다.

이 매뉴얼은 힘/토크 센서 사용 중 발생할 수 있는 위험과 그로 인한 결과에 대해 설명하고 있습니다.

안전하고 올바른 사용을 위해 반드시 본 매뉴얼에 명시된 안전 수칙을 준수하시기 바랍니다.

공지

본 매뉴얼은 AIDIN ROBOTICS의 허가 없이 복사, 재생산, 공유를 엄격히 금지합니다.

매뉴얼 또는 제공된 지침에서 오류를 발견하시면 저희에게 반드시 알려주시기 바랍니다.

(연락처: Sales@aidinrobotics.co.kr)

제조사

주식회사 에이딘로보틱스

안전 수칙

🚫 이 기호는 관련 지침을 제대로 따르지 않을 경우 심각한 부상 또는 사망 위험이 있음을 나타냅니다.

⚠️ 이 기호는 관련 지침을 제대로 따르지 않을 경우 인명 피해나 장비 및 시설의 물리적 손상 위험이 있음을 나타냅니다. 

✅ AIDIN ROBOTICS의 AFT200-D80-EC 센서는 CE 인증 “A 등급”을 획득하였습니다.

1. 개요

1.1 6축 힘/토크 센서 AFT200-D80-EC

1.2 주요 특징

  • 정전용량 방식의 스마트 6축 힘/토크 센서

  • 올인원 센서 (추가 증폭기 불필요)

  • 디지털 출력 통신 (EtherCAT)

  • 간편한 설치 및 데이터 수집

  • 그리퍼, 로봇 손, 협동 로봇, 산업용 로봇에 적용 가능

1.3 사양

Index

Unit

Value    

Operating voltage ​

VDC​

12

   

Max. safe excitation voltage ​

VDC​

24

   

Nominal force range​

N ​

200​

Nominal torque range ​

Nm ​

15​

Limit force (Fxyz) ​

N ​

300​

Limit torque ​

Nm ​

22.5

Force Resolution  ​

N ​

0.15​

Torque Resolution  ​

Nm ​

0.015​

Force Noise-free resolution (STD)​

N​

0.4​

Torque Noise-free resolution (STD)​

Nm​

0.025​

Maximum sample rate ​

Hz ​

1,000​

Dimensions ​

mm ​

D80 x H21.5 ​

IP rating ​

IP65

   

Operating temperature ​

10-50℃ ​

1.4 Flyer

[AIDIN ROBOTICS] AFT MINI+AFT200 leaflet(KO, 25.10).pdf

 

2. 설치 가이드

2.1 Basic Components

  • AFT200-D80 x 1 EA

  • 3m 케이블 x 1 EA

2.2 마운팅

  • M5 볼트의 체결 토크는 5.2Nm입니다.

  • 내부/외부 볼트를 분해할 경우 성능 보증이 불가능하며, A/S가 제공되지 않습니다.

  • 센서 체결순서

  • 케이블 절단 및 과도한 당김에 대한 주의사항

  • 센서 라인이 로봇 움직임에 따라 당겨지지 않도록 로봇과 함께 안전하게 고정해 주세요.

    • 케이블 타이 등으로 로봇에 직접 고정하거나, 다른 선들과 함께 묶어서 케이블 타이로 고정하는 것은 금지합니다.

    • 로봇과 고정할 때는 벨크로(찍찍이)를 사용하는 것을 권장하며, 다른 선들과 묶을 경우에도 벨크로를 사용해 고정해 주세요.

💡 체결 토크 가이드에 따르지 않을 경우 성능 보증이 불가능합니다.

💡 센서 라인이 로봇에 고정되지 않으면, 당기는 힘으로 인해 출력 신호에 노이즈가 발생할 수 있습니다.

💡 자세한 설치 가이드는 다음을 참고해 주세요:

2.3 축&도면

Drawing File : 

AFT200_D80.pdf

STEP File :

AFT200-D80-EC_배포용.zip

2.4 와이어링

이더캣(EtherCAT) 장치는 POE 인젝터와 12-24V AC/DB 전원 공급장치와 함께 제공됩니다. 센서는 802.3af Mode A 프로토콜을 준수하지만, 전원은 Cat5e 이더캣 케이블 내 사용하지 않은 선을 통해서만 공급됩니다. 센서 케이블에 전압을 과도하게 주지 마십시오. 사용자는 센서 케이블을 인젝터의 ‘POE’ 표시가 있는 포트에 연결해야 합니다. 802.3af Mode A와 호환되며 12-24V 전원 공급이 가능한 다른 POE 인젝터도 사용할 수 있습니다. 

2.4.1 핀 홀

 


 

  Cable wires color EtherCAT Signal
1 Green/White TX+
2 Green TX-
3 Orange/White RX+
4 Blue 12V
5 Blue/White NC
6 Orange RX-
7 Brown/White NC
8 Brown GND

2.5 EtherCAT 인터페이스(EtherCAT interface)

AFT200-D80-EC 모델은 힘/토크 측정값을 제공하는 RUN 상태를 지원합니다.

또한 AFT200-D80-EC 센서에 활성화 신호를 입력하면 IMU 측정 기능을 활성화할 수 있습니다.

IMU 신호를 활성화하거나 센서 신호의 바이어스를 설정하려면 2.6의 지침을 따르십시오.

 

EtherCAT 인터페이스를 통해 사용자는 다음과 같은 기능을 사용할 수 있습니다.

  • 제품 번호, 시리얼 번호 등 읽기

  • 힘/토크 데이터 읽기

    → 힘 [N] = Force output / 100-300, Torque = Torque output/500-50

  • IMU 데이터 읽기

    → 가속도 [m/s²] = (Acceleration value – 32767) / 1000

    → 자이로스코프 [˚/s] = (Gyroscope value – 32767) / 16.4

2.5.1 PDO 인터페이스(PDO interface)

PDO 인터페이스는 F/T 센서와 실시간으로 데이터를 교환합니다.

사용되는 PDO 매핑은 다음과 같습니다.

2.5.1.1 RxPDO1: Object 0x1600 디지털 출력

Name Type Index Subindex Size Bit Size Access
Digital Output 0x7000 0x00 BOOL 1 RO
BIAS_ON 0x7000 0x01 BOOL 1 RO
ACC_ON 0x7000 0x02 BOOL 1 RO
GYRO_ON 0x7000 0x03 BOOL 1 RO
NC 0x7000 0x04 BOOL 1 RO

2.5.1.2 TxPDO1: Object 0x1A00 디지털 출력

Name Type Index Subindex Size Bit Size Access
Status 0x6000 0x00 SINT 8 RO
Force x 0x6000 0x01 REAL 32 RO
Force y 0x6000 0x02 REAL 32 RO
Force z 0x6000 0x03 REAL 32 RO
Torque x 0x6000 0x04 REAL 32 RO
Torque y 0x6000 0x05 REAL 32 RO
Torque z 0x6000 0x06 REAL 32 RO
Out of Range 0x6000 0x07 REAL 32 RO
Out of Range status 0x6000 0x08 REAL 32 RO
Acceleration x 0x6000 0x09 REAL 32 RO
Acceleration y 0x6000 0x0a REAL 32 RO
Acceleration z 0x6000 0x0b REAL 32 RO
Angular Rate x 0x6000 0x0c REAL 32 RO
Angular Rate y 0x6000 0x0d REAL 32 RO
Angular Rate z 0x6000 0x0e REAL 32 RO
Temperature 0x6000 0x0f REAL 32 RO
    2.5.2 SDO 인터페이스(SDO interface)

    SDO 데이터는 센서를 구성하고, 제조 및 보정 데이터를 읽는 데 사용됩니다. 이 섹션에서는 EtherCAT F/T 센서 응용에 특화된 사전(dictionary) 객체를 나열하며, EtherCAT 표준의 필수 객체는 포함하지 않습니다. 이 사전 객체들은 웹사이트에서 제공되는 ESI 파일에서도 확인할 수 있습니다.

    Object   Name Type Description
    0x2000 0 Status RO  
    0x6000 0 Sensor Data RO Used to read the Force/Torque data, IMU etc.from the sensor
    0x7000 0 Digital Output RO  

    💡 센서 신호를 안정적으로 유지하기 위해 약 30분간 작동하는 것을 권장합니다.

    • 사용 전 최소 10분 이상 센서 데이터를 켜주시기 바랍니다.

    💡 데이터를 켠 직후 10분간의 센서 출력 데이터는 다소 변동이 있을 수 있습니다.

    2.6 힘/토크 범위 초과

    • 센서는 단일 축 부하에서 정격 용량(nominal capacity)까지 동작할 수 있습니다. 정격 용량을 초과한 측정값은 올바르지 않으며 유효하지 않습니다.

    • 복합 부하(composite loading)의 정격 용량은 아래 그림과 같은 시나리오로 나타낼 수 있습니다.

    • 센서는 정상 동작 영역(normal operating area) 밖에서는 작동할 수 없습니다.

    다음 그래프는 높은 정밀도 또는 중간 정밀도가 요구되는 응용에서 AFT200-D80-EC 센서와 함께 사용할 수 있는 페이로드(payload) 및 툴(tool) 길이 범위를 보여줍니다.

    F/T 부하는 센서의 측정 범위를 초과할 수 있습니다. TxPDO1[0x6000, Index: 0x08]은 값 타입(value type)을 나타내며, TxPDO1[0x6000, Index: 0x09]은 상태(status)를 표시합니다.

    • Fxy 축Tz 축에서 사용되는 보정 범위의 총 비율이 105%를 초과하는 경우. 해당 내용은 아래의 Fxy, Tz 계산식을 참조하십시오.

    • Fz 축과 Txy 축에서 사용되는 보정 범위의 총 비율이 105%를 초과하는 경우. 해당 내용은 아래의 Fz, Txy 계산식을 참조하십시오. 



    3. 소프트웨어(SOFTWARE)

    3.1 Windows 애플리케이션에서 EtherCAT 테스트(TwinCAT3)

    EtherCAT_manual.pdf

    3.1.1 EtherCAT용 ESI(EtherCAT Slave Information) XML 파일
    • XML 파일 이름: AFT200_D80_EC.XML

    • XML 파일을 다운로드한 후 TwinCAT 설치 디렉터리에 붙여넣습니다.

      경로 예: “C:/TwinCAT/3.1/Config/Io/EtherCAT”

    3.1.2 테스트 순서(Sequence of Testing)
    1. Visual Studio를 사용하여 TwinCAT 프로젝트를 생성합니다.

    2. LAN 케이블을 EtherCAT 마스터(Ethernet 어댑터)에 연결합니다.

    3. AFT 센서를 켭니다.

    4. 장치를 스캔합니다.

    5. TwinCAT을 **프리런 모드(free-run mode)**로 활성화합니다.

    6. PDO(Process Data Object) 및 **SDO(Service Data Object)**의 출력 값을 관찰합니다.

     

    3.2 Linux 애플리케이션에서 EtherCAT 테스트(SOEM)

    3.2.1 SOEM 소스 코드 복제(Clone)
    • 다음 페이지에서 SOEM 소스 코드를 복제합니다. (C++)

    git clone https://github.com/OpenEtherCATsociety/SOEM

    GitHub - OpenEtherCATsociety/SOEM: Simple Open Source EtherCAT Master

    1. SOEM 웹페이지에 안내된 설치 단계를 따라 진행합니다.

    • mkdir build
    • cd build
    • cmake ..
    • make

    2. 다음 코드를 복사하여 simpletest.c 코드에 붙여넣습니다.(C++)

    /** \file
     * \brief Example code for Simple Open EtherCAT master
     *
     * Usage : simple_test [ifname1]
     * ifname is NIC interface, f.e. eth0
     *
     * This is a minimal test.
     *
     * (c)Arthur Ketels 2010 - 2011
     */

    #include <stdio.h>
    #include <string.h>
    #include <inttypes.h>

    #include "ethercat.h"

    #define EC_TIMEOUTMON 500

    char IOmap[4096];
    OSAL_THREAD_HANDLE thread1;
    int expectedWKC;
    boolean needlf;
    volatile int wkc;
    boolean inOP;
    uint8 currentgroup = 0;
    boolean forceByteAlignment = FALSE;

    void simpletest(char *ifname)
    {
        int i, j, oloop, iloop, chk;
        needlf = FALSE;
        inOP = FALSE;

       printf("Starting simple test\n");

       /* initialise SOEM, bind socket to ifname */
       if (ec_init(ifname))
       {
          printf("ec_init on %s succeeded.\n",ifname);
          /* find and auto-config slaves */


           if ( ec_config_init(FALSE) > 0 )
          {
             printf("%d slaves found and configured.\n",ec_slavecount);

             if (forceByteAlignment)
             {
                ec_config_map_aligned(&IOmap);
             }
             else
             {
                ec_config_map(&IOmap);
             }

             ec_configdc();

             printf("Slaves mapped, state to SAFE_OP.\n");
             /* wait for all slaves to reach SAFE_OP state */
             ec_statecheck(0, EC_STATE_SAFE_OP,  EC_TIMEOUTSTATE * 4);

             oloop = ec_slave[0].Obytes;
             if ((oloop == 0) && (ec_slave[0].Obits > 0)) oloop = 1;
             if (oloop > 8) oloop = 8;
             iloop = ec_slave[0].Ibytes;
             if ((iloop == 0) && (ec_slave[0].Ibits > 0)) iloop = 1;
             if (iloop > 8) iloop = 8;

             printf("segments : %d : %d %d %d %d\n",ec_group[0].nsegments ,ec_group[0].IOsegment[0],ec_group[0].IOsegment[1],ec_group[0].IOsegment[2],ec_group[0].IOsegment[3]);

             printf("Request operational state for all slaves\n");
             expectedWKC = (ec_group[0].outputsWKC * 2) + ec_group[0].inputsWKC;
             printf("Calculated workcounter %d\n", expectedWKC);
             ec_slave[0].state = EC_STATE_OPERATIONAL;
             /* send one valid process data to make outputs in slaves happy*/
             ec_send_processdata();
             ec_receive_processdata(EC_TIMEOUTRET);
             /* request OP state for all slaves */
             ec_writestate(0);
             chk = 200;
             /* wait for all slaves to reach OP state */
             do
             {
                ec_send_processdata();
                ec_receive_processdata(EC_TIMEOUTRET);
                ec_statecheck(0, EC_STATE_OPERATIONAL, 50000);
             }
             while (chk-- && (ec_slave[0].state != EC_STATE_OPERATIONAL));
             if (ec_slave[0].state == EC_STATE_OPERATIONAL )
             {
                printf("Operational state reached for all slaves.\n");
                inOP = TRUE;
                    /* cyclic loop */
                for(i = 1; i <= 10000; i++)
                {
                   ec_send_processdata();
                   wkc = ec_receive_processdata(EC_TIMEOUTRET);

       

                        if(wkc >= expectedWKC)
                        {
                            printf("Processdata cycle %4d, WKC %d , O:", i, wkc);

                            for(j = 0 ; j < oloop; j++)
                            {
                                printf(" %2.2x", *(ec_slave[0].outputs + j));
                            }

                            printf(" I:");
                         //Test
                            int Fx= *(ec_slave[0].inputs+1)*256+*(ec_slave[0].inputs);
                            int Fy= *(ec_slave[0].inputs+5)*256+*(ec_slave[0].inputs+4);
                            int Fz= *(ec_slave[0].inputs+9)*256+*(ec_slave[0].inputs+8);
                            int Tx= *(ec_slave[0].inputs+13)*256+*(ec_slave[0].inputs+12);
                            int Ty= *(ec_slave[0].inputs+17)*256+*(ec_slave[0].inputs+16);
                            int Tz= *(ec_slave[0].inputs+21)*256+*(ec_slave[0].inputs+20);
                            int Ax= *(ec_slave[0].inputs+25)*256+*(ec_slave[0].inputs+24);
                            int Ay= *(ec_slave[0].inputs+29)*256+*(ec_slave[0].inputs+28);
                            int Az= *(ec_slave[0].inputs+33)*256+*(ec_slave[0].inputs+32);

                            printf(" Fx: %d, Fy: %d,Fz: %d,Tx: %d,Ty: %d,Tz: %d,Ax: %d,Ay: %d,Az: %d, ", Fx, Fy,Fz,Tx,Ty,Tz,Ax,Ay,Az);
                            printf(" T:%"PRId64"\n",ec_DCtime);
                            needlf = TRUE;
                        }
                        osal_usleep(5000);

                    }
                    inOP = FALSE;
                }
                else
                {
                    printf("Not all slaves reached operational state.\n");
                    ec_readstate();
                    for(i = 1; i<=ec_slavecount ; i++)
                    {
                        if(ec_slave[i].state != EC_STATE_OPERATIONAL)
                        {
                            printf("Slave %d State=0x%2.2x StatusCode=0x%4.4x : %s\n",
                                i, ec_slave[i].state, ec_slave[i].ALstatuscode, ec_ALstatuscode2string(ec_slave[i].ALstatuscode));
                        }
                    }
                }
                printf("\nRequest init state for all slaves\n");
                ec_slave[0].state = EC_STATE_INIT;
                /* request INIT state for all slaves */
                ec_writestate(0);
            }
            else
            {
                printf("No slaves found!\n");
            }
            printf("End simple test, close socket\n");
            /* stop SOEM, close socket */
            ec_close();
        }
        else
        {
            printf("No socket connection on %s\nExecute as root\n",ifname);
        }
    }

    OSAL_THREAD_FUNC ecatcheck( void *ptr )
    {
        int slave;
        (void)ptr;                  /* Not used */

        while(1)
        {
            if( inOP && ((wkc < expectedWKC) || ec_group[currentgroup].docheckstate))
            {
                if (needlf)
                {
                   needlf = FALSE;
                   printf("\n");
                }
                /* one ore more slaves are not responding */
                ec_group[currentgroup].docheckstate = FALSE;
                ec_readstate();
                for (slave = 1; slave <= ec_slavecount; slave++)
                {
                   if ((ec_slave[slave].group == currentgroup) && (ec_slave[slave].state != EC_STATE_OPERATIONAL))
                   {
                      ec_group[currentgroup].docheckstate = TRUE;
                      if (ec_slave[slave].state == (EC_STATE_SAFE_OP + EC_STATE_ERROR))
                      {
                         printf("ERROR : slave %d is in SAFE_OP + ERROR, attempting ack.\n", slave);
                         ec_slave[slave].state = (EC_STATE_SAFE_OP + EC_STATE_ACK);
                         ec_writestate(slave);
                      }
                      else if(ec_slave[slave].state == EC_STATE_SAFE_OP)
                      {
                         printf("WARNING : slave %d is in SAFE_OP, change to OPERATIONAL.\n", slave);
                         ec_slave[slave].state = EC_STATE_OPERATIONAL;
                         ec_writestate(slave);
                      }
                      else if(ec_slave[slave].state > EC_STATE_NONE)
                      {
                         if (ec_reconfig_slave(slave, EC_TIMEOUTMON))
                         {
                            ec_slave[slave].islost = FALSE;
                            printf("MESSAGE : slave %d reconfigured\n",slave);
                         }
                      }
                      else if(!ec_slave[slave].islost)
                      {
                         /* re-check state */
                         ec_statecheck(slave, EC_STATE_OPERATIONAL, EC_TIMEOUTRET);
                         if (ec_slave[slave].state == EC_STATE_NONE)
                         {
                            ec_slave[slave].islost = TRUE;
                            printf("ERROR : slave %d lost\n",slave);
                         }
                      }
                   }
                   if (ec_slave[slave].islost)
                   {
                      if(ec_slave[slave].state == EC_STATE_NONE)
                      {
                         if (ec_recover_slave(slave, EC_TIMEOUTMON))
                         {
                            ec_slave[slave].islost = FALSE;
                            printf("MESSAGE : slave %d recovered\n",slave);
                         }
                      }
                      else
                      {
                         ec_slave[slave].islost = FALSE;
                         printf("MESSAGE : slave %d found\n",slave);
                      }
                   }
                }
                if(!ec_group[currentgroup].docheckstate)
                   printf("OK : all slaves resumed OPERATIONAL.\n");
            }
            osal_usleep(10000);
        }
    }

    int main(int argc, char *argv[])
    {
       printf("SOEM (Simple Open EtherCAT Master)\nSimple test\n");

       if (argc > 1)
       {
          /* create thread to handle slave error handling in OP */
    //      pthread_create( &thread1, NULL, (void *) &ecatcheck, (void*) &ctime);
          osal_thread_create(&thread1, 128000, &ecatcheck, (void*) &ctime);
          /* start cyclic part */
          simpletest(argv[1]);
       }
       else
       {
          ec_adaptert * adapter = NULL;
          printf("Usage: simple_test ifname1\nifname = eth0 for example\n");

          printf ("\nAvailable adapters:\n");
          adapter = ec_find_adapters ();
          while (adapter != NULL)
          {
             printf ("    - %s  (%s)\n", adapter->name, adapter->desc);
             adapter = adapter->next;
          }
          ec_free_adapters(adapter);
       }

       printf("End program\n");
       return (0);
    }

    3. build 폴더에서 make 명령을 실행합니다.

    4. 이후 다음과 같이 simpletest 프로그램을 실행합니다.(C++)

    SOEM/build/test/linux/simple_test

    sudo ./simple_test -(port)

     

    ^ 처음으로 돌아가기