Skip to content

3.7 IoSignals IO 클래스

개요

IoSignals 는 단일 지점 및 배치 IO 읽기/쓰기를 담당합니다. Arm 연결이 완료된 뒤 arm.ioSignals 를 통해 Signals 인스턴스를 가져오며, 별도 초기화는 필요하지 않습니다. SDK는 디지털 신호, 그룹 신호, 아날로그 신호를 SignalType 으로 통합합니다.

지원 범위

인터페이스지원 범위
Read모든 SignalType 지원
Write 정수 오버로드DO , RO , GO , TDO 만 지원
Write 부동소수점 오버로드AO 만 지원
MultiReadDO 만 지원
MultiWriteDO 만 지원

포트 번호 기준

  • IoSignals 는 전달된 포트 번호를 그대로 컨트롤러에 전송합니다.
  • 포트 번호는 컨트롤러 측 번호를 그대로 사용합니다.

3.7.1 단일 채널 IO 읽기

cpp
Read(SignalType type, int32_t index) -> std::pair<Float64, STATUS_CODE>
항목설명
설명단일 채널 IO를 읽습니다. 디지털 신호, 그룹 신호, 아날로그 신호는 모두 Float64 로 반환됩니다.
요청 파라미터type : SignalType 신호 타입(DI/DO/UI/UO/RI/RO/GI/GO/TAI/TDI/TDO/AI/AO)
index : int32_t 포트 번호
반환값Float64: 읽은 값
STATUS_CODE: 함수 실행 결과
호환 로봇 소프트웨어 버전협동(Copper): v7.5.0.0+
산업용(Bronze): v7.5.0.0+

3.7.2 단일 채널 디지털 신호 쓰기

cpp
Write(SignalType type, int32_t index, int32_t value) -> STATUS_CODE
항목설명
설명단일 채널 디지털 신호 또는 정수형 그룹 신호를 씁니다.
요청 파라미터type : SignalType 신호 타입(DO/RO/GO/TDO만 지원)
index : int32_t 포트 번호
value : int32_t 쓸 값
반환값STATUS_CODE: 함수 실행 결과
비고지원하지 않는 신호 타입은 UNSUPPORTED_SIGNAL_TYPE 을 반환합니다.
호환 로봇 소프트웨어 버전협동(Copper): v7.5.0.0+
산업용(Bronze): v7.5.0.0+

3.7.3 단일 채널 아날로그 신호 쓰기

cpp
Write(SignalType type, int32_t index, Float64 value) -> STATUS_CODE
항목설명
설명단일 채널 아날로그 신호를 씁니다. AO 에만 사용됩니다.
요청 파라미터type : SignalType 신호 타입(AO만 지원)
index : int32_t 포트 번호
value : Float64 쓸 값
반환값STATUS_CODE: 함수 실행 결과
비고지원하지 않는 신호 타입은 UNSUPPORTED_SIGNAL_TYPE 을 반환합니다.
호환 로봇 소프트웨어 버전협동(Copper): v7.5.0.0+
산업용(Bronze): v7.5.0.0+

3.7.4 배치 읽기

cpp
MultiRead(SignalType type, const std::vector<int32_t>& portList) -> std::pair<std::vector<int32_t>, STATUS_CODE>
항목설명
설명IO를 배치로 읽습니다. DO 만 지원합니다.
요청 파라미터type : SignalType 신호 타입(DO만 지원)
portList : std::vector<int32_t> 포트 번호 목록
반환값std::vector<int32_t>: 읽은 값 목록( portList 순서와 대응)
STATUS_CODE: 함수 실행 결과
비고지원하지 않는 신호 타입은 UNSUPPORTED_SIGNAL_TYPE 을 반환합니다. portList 가 비어 있으면 INVALID_PARAMETER 를 반환합니다.
호환 로봇 소프트웨어 버전협동(Copper): v7.5.0.0+
산업용(Bronze): v7.5.0.0+

3.7.5 배치 쓰기

cpp
MultiWrite(SignalType type, const std::vector<int32_t>& ioList) -> STATUS_CODE
항목설명
설명IO를 배치로 씁니다. 평탄화된 파라미터 형식은 [port1, value1, port2, value2, ...] 이며 DO 만 지원합니다.
요청 파라미터type : SignalType 신호 타입(DO만 지원)
ioList : std::vector<int32_t> 평탄화된 포트-값 목록
반환값STATUS_CODE: 함수 실행 결과
비고지원하지 않는 신호 타입은 UNSUPPORTED_SIGNAL_TYPE 을 반환합니다. ioList 가 비어 있거나 요소 개수가 짝수가 아니면 INVALID_PARAMETER 를 반환합니다.
호환 로봇 소프트웨어 버전협동(Copper): v7.5.0.0+
산업용(Bronze): v7.5.0.0+

평탄화 파라미터 형식 설명

ioList 파라미터 형식은 포트 번호와 값이 번갈아 나오는 형태입니다.

cpp
// DO[0]=1, DO[1]=0, DO[2]=1 쓰기
std::vector<int32_t> ioList = {0, 1, 1, 0, 2, 1};  // 차례대로 포트와 값: 0/1, 1/0, 2/1
// 즉 [port0, value0, port1, value1, port2, value2]

3.7.6 시간 간격으로 IO 트리거

cpp
TriggerIOWithIntervals(int32_t inPort, const std::vector<int32_t>& intervals, const std::vector<int32_t>& outPorts, int32_t pulseDuration) -> STATUS_CODE
항목설명
설명입력 트리거 후 지정된 간격으로 여러 출력 포트를 구동합니다.
요청 파라미터inPort : int32_t 입력 포트 번호
intervals : std::vector<int32_t> 트리거 간격 목록(밀리초)
outPorts : std::vector<int32_t> 출력 포트 번호 목록
pulseDuration : int32_t 펄스 지속 시간(밀리초)
반환값STATUS_CODE: 함수 실행 결과
호환 로봇 소프트웨어 버전협동(Copper): v7.5.0.0+
산업용(Bronze): v7.5.0.0+

파라미터 제약

  • intervals 는 비어 있을 수 없습니다.
  • outPorts 는 비어 있을 수 없습니다.
  • pulseDuration0 보다 커야 합니다.

트리거 로직 설명

지정 입력 포트 inPort 가 트리거되면 intervals 에 정의된 시간 간격에 따라 outPorts 의 출력 포트를 순서대로 구동하며, 각 출력 펄스는 pulseDuration 밀리초 동안 지속됩니다.


최소 호출 예제

cpp
#include <iostream>  // IO 읽기 결과를 출력하기 위한 표준 출력 스트림을 포함합니다.
#include <vector>  // 배치 IO 포트 목록에 사용할 std::vector를 포함합니다.
#include "arm_api.h"  // Arm 주 진입점을 포함하며, 연결 후 arm.ioSignals로 신호 인터페이스에 접근합니다.
#include "status_code.h"  // SDK 호출 결과 확인용 STATUS_CODE를 포함합니다.
int main()  // 예제 프로그램 진입점입니다.
{  // 예제 main 함수에 진입합니다.
    Arm arm;  // 로봇 세션 객체를 생성합니다.
    STATUS_CODE connectRet = arm.Connect("192.168.110.2", "");  // 컨트롤러에 연결합니다. 티치 펜던트 주소를 비워 기본 규칙을 사용합니다.
    if (connectRet != STATUS_CODE::OK) {  // 연결 실패 여부를 판단합니다.
        return 1;  // 연결 실패 시 바로 종료합니다.
    }  // 연결 결과 판단을 종료합니다.
    auto [di0, diRet] = arm.ioSignals.Read(SignalType::DI, 0);  // DI[0]의 현재 값을 읽습니다.
    if (diRet != STATUS_CODE::OK) {  // DI 읽기 실패 여부를 판단합니다.
        return 1;  // 읽기 실패 시 오류 코드로 반환합니다.
    }  // DI 읽기 판단을 종료합니다.
    std::cout << "DI[0]=" << di0 << "\n";  // DI[0] 읽기 결과를 출력합니다.
    auto [doBatch, multiRet] = arm.ioSignals.MultiRead(  // DO 포트를 배치로 읽습니다.
        SignalType::DO,  // 배치 읽기 신호 타입을 DO로 지정합니다.
        std::vector<int32_t>{0, 1, 2}  // 읽을 DO 포트 목록을 지정합니다.
    );  // 배치 읽기 호출을 종료합니다.
    if (multiRet != STATUS_CODE::OK) {  // 배치 읽기 실패 여부를 판단합니다.
        return 1;  // 배치 읽기 실패 시 오류 코드로 반환합니다.
    }  // 배치 읽기 판단을 종료합니다.
    std::cout << "batch_count=" << doBatch.size() << "\n";  // 배치 읽기가 반환한 값 개수를 출력합니다.
    // STATUS_CODE writeRet = arm.ioSignals.Write(SignalType::DO, 0, 1);  // DO 쓰기는 실제 부작용이 있으므로 확인한 뒤 주석을 해제하십시오.
    // STATUS_CODE multiWriteRet = arm.ioSignals.MultiWrite(  // DO 배치 쓰기는 실제 부작용이 있으므로 확인한 뒤 주석을 해제하십시오.
    //     SignalType::DO,  // 배치 쓰기 신호 타입을 DO로 지정합니다.
    //     std::vector<int32_t>{0, 1, 1, 0, 2, 1}  // 포트와 값을 쌍으로 씁니다: DO[0]=1, DO[1]=0, DO[2]=1
    // );  // 배치 쓰기 예제 호출을 종료합니다.
    return 0;  // 예제를 정상 종료합니다.
}  // 예제 main 함수를 종료합니다.

시나리오 예제

아래 조각들은 "읽기, 쓰기, 펄스 트리거" 흐름으로 이 페이지의 API를 교차해서 다룹니다. 조각들은 최소 호출 예제에서 이미 연결에 성공한 arm 객체를 이어받는다고 가정합니다. IO 쓰기와 IO 트리거는 컨트롤러 출력을 변경하므로 현장을 확인한 뒤 실행하십시오.

단일 채널 및 배치 IO 읽기

cpp
auto [singleValue, readRet] = arm.ioSignals.Read(SignalType::DI, 0);  // 단일 채널 DI를 읽습니다.
auto [batchValues, multiReadRet] = arm.ioSignals.MultiRead(SignalType::DO, std::vector<int32_t>{0, 1, 2});  // DO를 배치로 읽습니다.
if (readRet == STATUS_CODE::OK && multiReadRet == STATUS_CODE::OK) {  // 읽기 인터페이스 성공 여부를 판단합니다.
    std::cout << "DI[0]=" << singleValue << " batch_count=" << batchValues.size() << "\n";  // 단일 채널 및 배치 읽기 결과를 출력합니다.
}  // 읽기 결과 판단을 종료합니다.

디지털 및 아날로그 신호 쓰기

cpp
// STATUS_CODE writeIntRet = arm.ioSignals.Write(SignalType::DO, 0, 1);  // 디지털 출력 쓰기는 컨트롤러 IO 상태를 변경하므로 확인한 뒤 실행하십시오.
// STATUS_CODE writeFloatRet = arm.ioSignals.Write(SignalType::AO, 0, Float64{1.0});  // 아날로그 출력 쓰기는 컨트롤러 IO 상태를 변경하므로 확인한 뒤 실행하십시오.
// STATUS_CODE multiWriteRet = arm.ioSignals.MultiWrite(SignalType::DO, std::vector<int32_t>{0, 1, 1, 0});  // DO 배치 쓰기는 여러 출력을 변경하므로 확인한 뒤 실행하십시오.

시간 간격으로 IO 트리거

cpp
std::vector<int32_t> intervals = {100, 200};  // 두 개의 트리거 간격을 준비합니다. 단위는 밀리초입니다.
std::vector<int32_t> values = {0, 1};  // 대응하는 출력 값 시퀀스를 준비합니다.
// STATUS_CODE triggerRet = arm.ioSignals.TriggerIOWithIntervals(0, intervals, values, 50);  // 간격 기반 IO 트리거는 출력 상태를 변경하므로 확인한 뒤 실행하십시오.

예제 코드

cpp17/signals_basic/src/main.cpp
cpp
#include "query_signals/run.h"
#include "write_signals/run.h"

int main(void)
{
    // [ZH] 默认只调用一个门面方法;如需体验其他接口,请把下一行替换成下面任意一行。
    // [EN] The main function calls only one facade by default. Replace the next line with any line below to try other APIs.
    return RunSignalsBasicQuerySignals();
    // return RunSignalsBasicWriteSignals();
}
c99/signals_basic/src/main.cpp
cpp
#include <stdio.h>

extern "C" {
#include "c_arm_api.h"
}

int main(void)
{
    // [ZH] 本示例直接在源码中写死连接地址,不解析命令行参数。
    // [EN] This example hard-codes the connection addresses in the source code and does not parse command-line arguments.
    // [ZH] 创建并连接 SDK 句柄。
    // [EN] Create the SDK handle and connect to the robot.
    ArmHandle* handle = Arm_Create();
    if (handle == NULL) {
        printf("[c99_signals] 创建句柄失败 / Failed to create the handle\n");
        return 1;
    }
    int ret = Arm_Connect(handle, "10.27.1.2", "10.27.1.102");
    if (ret != 0) {
        printf("[c99_signals] 连接失败 / Connect failed, 状态码 / Status code: %d\n", ret);
        Arm_Destroy(handle);
        return 1;
    }
    printf("[c99_signals] 机器人连接成功 / Robot connected successfully\n");

    // [ZH] 读取单路信号与批量信号。
    // [EN] Read a single signal and a batch of signals.
    double diValue = 0.0;
    int ports[2] = {0, 1};
    int values[2] = {0, 0};
    size_t outCount = 0U;
    ret = Arm_Signals_Read(handle, ARM_SIGNAL_DI, 0, &diValue);
    printf("[c99_signals] Read 状态码 / Read status code: %d, DI[0]=%.6f\n", ret, diValue);
    ret = Arm_Signals_MultiRead(handle, ARM_SIGNAL_DI, ports, 2U, values, 2U, &outCount);
    printf("[c99_signals] MultiRead 状态码 / MultiRead status code: %d, 数量 / Count: %zu, 值 / Values: [%d, %d]\n",
        ret,
        outCount,
        values[0],
        values[1]);

    // [ZH] 顺序执行全部写接口。
    // [EN] Execute all write APIs in sequence.
    ret = Arm_Signals_WriteInt(handle, ARM_SIGNAL_DO, 1, 1);
    printf("[c99_signals] WriteInt 状态码 / WriteInt status code: %d\n", ret);
    ret = Arm_Signals_WriteFloat(handle, ARM_SIGNAL_AO, 1, 1.5);
    printf("[c99_signals] WriteFloat 状态码 / WriteFloat status code: %d\n", ret);
    int ioList[4] = {4, 1, 6, 0};
    ret = Arm_Signals_MultiWrite(handle, ARM_SIGNAL_DO, ioList, 4U);
    printf("[c99_signals] MultiWrite 状态码 / MultiWrite status code: %d\n", ret);
    int intervals[2] = {100, 200};
    int outPorts[2] = {4, 5};
    ret = Arm_Signals_TriggerIOWithIntervals(handle, 1, intervals, 2U, outPorts, 2U, 60);
    printf("[c99_signals] TriggerIOWithIntervals 状态码 / TriggerIOWithIntervals status code: %d\n", ret);

    // [ZH] 断开连接并销毁句柄。
    // [EN] Disconnect and destroy the handle.
    Arm_Disconnect(handle);
    Arm_Destroy(handle);
    printf("[c99_signals] 示例结束 / Example finished\n");
    return 0;
}