====== RS232C 통신 함수 ====== CUBLOC2 NCB520, NCB540에는 RS232C (+/-10V 레벨) 통신 포트 2개가 내장되어 있습니다. 채널 번호는 0과 1을 사용합니다. 주의: 이 포트는 3.3V UART 신호가 아니라 RS232C 전압 레벨입니다. 결선 시 주의하십시오. 사용 예에서 공통으로 사용하는 변수는 다음과 같습니다. * ''ch'' : RS232C 채널 번호 (0 또는 1) * ''Sarr()'' : 송수신 데이터를 담는 Byte 배열 * ''Ires'' : 정수형 결과 변수 ===== 1. 포트 열기 / 닫기 ===== ^ CUBLOC2 명령어 ^ 설명 ^ | ''Opencom channel, baudRate, protocol'' | 지정한 채널을 열고 통신 파라미터를 설정합니다. | | ''Closecom channel'' | 지정한 채널을 닫습니다. | ===== Opencom ===== ''Opencom channel, baudRate, protocol'' ^ 파라미터 ^ 설명 ^ | //channel// | RS232C 채널 번호 (0 또는 1) | | //baudRate// | 통신 속도 (예: 9600, 19200, 38400, 57600, 115200) | | //protocol// | 통신 프로토콜 상수 | **protocol 값** ^ protocol 상수 ^ 데이터 비트 ^ 패리티 ^ 스톱 비트 ^ | ''PROTO_8N1'' | 8 | None | 1 | | ''PROTO_8N2'' | 8 | None | 2 | | ''PROTO_8E1'' | 8 | Even | 1 | | ''PROTO_8E2'' | 8 | Even | 2 | | ''PROTO_8O1'' | 8 | Odd | 1 | | ''PROTO_8O2'' | 8 | Odd | 2 | | ''PROTO_7N1'' | 7 | None | 1 | | ''PROTO_7N2'' | 7 | None | 2 | | ''PROTO_7E1'' | 7 | Even | 1 | | ''PROTO_7E2'' | 7 | Even | 2 | | ''PROTO_7O1'' | 7 | Odd | 1 | | ''PROTO_7O2'' | 7 | Odd | 2 | 참고: //protocol//은 미리 정의된 상수명임 ===== Closecom ===== ''Closecom channel'' ^ 파라미터 ^ 설명 ^ | //channel// | RS232C 채널 번호 (0 또는 1) | **사용 예** Opencom 0, 115200, PROTO_8N1 Opencom 1, 9600, PROTO_8E1 Closecom 0 ===== 2. 데이터 송신 ===== ^ CUBLOC2 명령어 ^ 설명 ^ | ''Putcom channel, data, byteLength'' | 값을 지정한 바이트 수만큼 송신합니다. | | ''PutStr channel, Sarr(), maxLength'' | NULL로 끝나는 Byte 배열 문자열을 최대 길이 안에서 송신합니다. | | ''variable = Txfree(channel)'' | 송신버퍼의 여유 공간을 반환합니다. | 송신명령은 송신데이터를 버퍼에 넣고 바로 종료됩니다. 버퍼에 있는 송신데이터는 백그라운드에서 차례대로 송신됩니다. 송신 버퍼의 크기는 1024바이트입니다. 따라서 버퍼의 남아있는 공간보다 큰 데이터는 한번에 송신할 수 없으며, Txfree로 버퍼의 남은 공간을 확인할 수 있습니다. 다만 실제 사용에서 한번에 1024바이트를 초과하는 경우는 드물기 때문에 대부분의 상황에서 버퍼 크기는 충분합니다. 만약 대용량 데이터를 전송해야 한다면 데이터를 작게 나눠 버퍼에 넣고, 잠시 대기 후 다시 전송하는 방식을 사용하세요. ===== Putcom ===== ''Putcom channel, data, byteLength'' ^ 파라미터 ^ 설명 ^ | //channel// | RS232C 채널 번호 (0 또는 1) | | //data// | 송신할 값 또는 Byte 배열 | | //byteLength// | 송신할 바이트 수 | //data// 형식에 따른 //byteLength// 범위는 다음과 같습니다. * Byte형 값 : 1 * Integer형 값 : 1 ~ 4 * Byte형 배열 : 1 ~ 65535 ===== PutStr ===== ''PutStr channel, Sarr(), maxLength'' ^ 파라미터 ^ 설명 ^ | //channel// | RS232C 채널 번호 (0 또는 1) | | //Sarr()// | 송신할 Byte 배열 문자열 | | //maxLength// | 송신할 최대 바이트 수 | PutStr은 Byte 배열의 데이터를 순차적으로 송신하며, 아래 두 가지 조건 중 하나라도 만족하면 전송을 중단합니다. * NULL 문자 탐지: 데이터 읽기 중 0x00 (NULL)을 만나면 문자열의 끝으로 간주하고 전송을 종료합니다. * 최대 길이 도달 (maxLength): NULL 문자를 만나기 전이라도, 미리 지정된 maxLength만큼 전송했다면 안전을 위해 전송을 멈춥니다. **사용 예** Dim Sarr() As Byte = "Hello" Putcom 0, 0x0D, 1 Putcom 0, 0x1234, 2 PutStr 0, Sarr(), 50 ===== Txfree ===== ''variable = Txfree(channel)'' ^ 파라미터 ^ 설명 ^ | //variable// | 송신 버퍼에 추가로 저장 가능한 남은 바이트 수 | | //channel// | RS232C 채널 번호 (0 또는 1) | ''Txfree''는 현재 송신 버퍼에 데이터를 추가로 저장할 수 있는 남은 공간의 바이트 수를 반환합니다. **사용 예** Dim Sarr(64) As Byte Dim Ires As Integer Dim Lens As Integer Lens = 32 If Txfree(0) >= Len Then Putcom 0, Sarr(), Lens End If ===== 3. 데이터 수신 ===== ^ CUBLOC2 명령어 ^ 설명 ^ | ''variable = Getcom(channel, byteLength)'' | 수신 버퍼에서 지정한 바이트 수만큼 읽어 정수로 반환합니다. | | ''variable = GetStr(channel, Sarr(), byteLength)'' | 수신 버퍼에서 데이터를 읽어 Byte 배열에 저장합니다. | | ''variable = Rxlen(channel)'' | 수신 버퍼에 쌓인 데이터 바이트 수를 반환합니다. | CUBLOC2에서 RS232C 데이터 수신은 내부 수신 버퍼를 통해 관리됩니다. Opencom을 실행하면 해당 채널에 1024바이트 크기의 수신 버퍼가 자동으로 할당됩니다. 이후 수신되는 모든 데이터는 이 버퍼에 순차적으로 저장됩니다. Getcom 또는 GetStr 명령으로 데이터를 읽으면, 읽은 만큼 수신 버퍼에서 제거됩니다. 1024바이트는 일반적인 RS232C 통신에서 충분한 크기입니다. RS232C는 보통 9600~115200bps의 저속 통신에 사용되며, 한 번에 주고받는 데이터는 대부분 수십~수백 바이트 수준의 짧은 명령어나 센서 값입니다. 따라서 Getcom이나 GetStr로 주기적으로 데이터를 읽어내는 일반적인 프로그램 구조에서는 버퍼가 가득 찰 일이 거의 없습니다. 수신 버퍼는 Overflow가 발생하지 않도록 관리하는 것이 중요합니다. 버퍼가 가득 찬 상태에서 데이터를 읽어내지 않으면, 새로 수신되는 데이터는 저장되지 않고 유실됩니다 ===== Getcom ===== ''variable = Getcom(channel, byteLength)'' ^ 파라미터 ^ 설명 ^ | //variable// | 수신 결과를 저장할 변수 | | //channel// | RS232C 채널 번호 (0 또는 1) | | //byteLength// | 읽을 바이트 수 (1 ~ 4) | ''Getcom''은 수신 버퍼에서 1~4바이트를 읽어 정수형 값으로 반환합니다. 읽은 데이터는 수신 버퍼에서 제거됩니다. 참고: //byteLength//가 1~4 범위를 벗어나면 정상 실행되지 않습니다. RS232C 포트에서 직접 데이터를 읽는 것이 아니라, 내부 수신 버퍼에 저장된 데이터를 읽어옵니다. 수신 버퍼에 데이터가 없을 경우, 데이터가 들어올 때까지 기다리지 않고 즉시 0을 반환합니다. 이때 반환된 0은 다음 두 가지 경우를 구분할 수 없습니다. * 실제로 수신된 데이터가 0인 경우 * 수신 버퍼가 비어 있어 반환된 경우 이러한 문제를 방지하기 위해, Getcom을 사용하기 전에 반드시 Blen으로 수신 데이터의 존재 여부를 확인해야 합니다. 권장 사용 방법: If Rxlen(0) > 0 Then Ires = Getcom(0, 1) End If ===== Getstr ===== ''variable = Getstr(channel, Sarr(), byteLength)'' ^ 파라미터 ^ 설명 ^ | //variable// | 반환값은 실제로 읽은 바이트 수이며, 필요하지 않은 경우 생략하고 명령문 형태로 사용할 수 있습니다. | | //channel// | RS232C 채널 번호 (0 또는 1) | | //Sarr()// | 수신 데이터를 저장할 Byte 배열 | | //byteLength// | 수신할 최대 바이트 수 | ''Getstr''은 수신 버퍼의 데이터를 읽어 Byte 배열에 저장합니다. 최대 //byteLength// 바이트까지 읽으며, 수신 버퍼에 데이터가 부족한 경우 현재 있는 만큼만 읽고, 즉시 반환 합니다. 특징은 다음과 같습니다. * Non-blocking 방식으로 동작합니다. * 데이터가 찰 때까지 기다리지 않고 즉시 반환합니다. * NULL(0x00)이 중간에 있어도 그대로 저장합니다. * 실제로 읽은 바이트 수를 반환합니다. * 읽은 데이터는 수신 버퍼에서 제거됩니다. ===== Rxlen ===== ''variable = Rxlen(channel)'' ^ 파라미터 ^ 설명 ^ | //variable// | 수신 버퍼에 쌓인 바이트 수 | | //channel// | RS232C 채널 번호 (0 또는 1) | ''Rxlen''은 현재 수신 버퍼에 쌓여 있는 데이터의 바이트 수를 반환합니다. **사용 예** Dim Sarr(64) As Byte Dim Ires As Integer If Rxlen(0) >= 4 Then Ires = Getcom(0, 4) End If If Blen(0) > 0 Then Ires = Getstr(0, Sarr(), 32) End If ===== 4. 수신 버퍼 처리 예 ===== 수신 버퍼에 데이터가 여러 바이트 쌓여 있을 때는 ''Blen''으로 개수를 확인한 뒤 필요한 만큼 읽습니다. ==== Getcom으로 읽기 ==== ''Getcom''은 한 번에 최대 4바이트까지만 읽을 수 있습니다. 따라서 4바이트 이상 데이터가 쌓일 수 있는 경우에는 여러 번 나누어 읽습니다. Dim tempI As Integer Dim N As Integer Dim Rx(4) As Byte ' 최대 4바이트 버퍼 Opencom 0, 115200, PROTO_8N1 If Comunder0 = 0 Then EndIf Do tempI = Rxlen(0) Do While tempI > 0 If tempI >= 4 Then N = 4 Else N = tempI EndIf GetStr 0, Rx(), N Putcom 0, Rx(), N tempI = Rxlen(0) Loop Loop ===== 5. 참고 사항 ===== * 수신 데이터는 내부 수신 버퍼에 저장됩니다. * ''Rxlen''으로 수신된 바이트 수를 확인할 수 있습니다. * ''Getcom''과 ''GetStr''로 읽은 데이터는 수신 버퍼에서 제거됩니다. * ''Getcom''은 정수형 값 수신에 적합합니다. * ''GetStr''은 Byte 배열 기반의 연속 데이터 수신에 적합합니다. ===== 6. 통신 상태 시스템 변수 ===== CUBLOC2에서는 RS232C 통신 상태를 확인하기 위한 **시스템 변수**를 제공합니다. 이 변수들은 내부 수신 버퍼 상태를 반영하며, Overflow 및 Underflow 상태를 확인하고 클리어할 수 있습니다. CUBLOC2는 각 시리얼 포트마다 **1024바이트 수신 버퍼(RX Buffer)** 와 **1024바이트 송신 버퍼(TX Buffer)** 를 기본 제공합니다. 수신된 데이터는 내부 RX 버퍼에 임시 저장되며, 사용자가 ''Comgetc'', ''Comread'' 등의 명령으로 읽어갑니다. 송신 데이터 역시 TX 버퍼에 저장된 후 백그라운드에서 자동 전송됩니다. 이 구조 덕분에 프로그램 실행 중에도 통신 데이터를 안정적으로 처리할 수 있으며, 짧은 순간에 많은 데이터가 들어오거나 전송되는 경우에도 유실 가능성을 줄일 수 있습니다. ==== 지원 변수 ==== ^ 변수명 ^ 설명 ^ | **''Comover0''** | 채널 0 수신 버퍼 Overflow 상태 (발생시 1)| | **''Comover1''** | 채널 1 수신 버퍼 Overflow 상태 (발생시 1)| | **''Comunder0''** | 채널 0 수신 버퍼 Underflow 상태 (발생시 1)| | **''Comunder1''** | 채널 1 수신 버퍼 Underflow 상태 (발생시 1)| If Comover0 = 1 Then Debug "Channel 0 Overflow", Cr End If If Comunder1 = 1 Then Debug "Channel 1 Underflow", Cr End If === 쓰기 (상태 클리어) === 시스템 변수에 ''0''을 대입하면 해당 상태가 클리어됩니다. If Comover0 = 1 Then Comover0 = 0 ' Overflow 클리어 End If If Comunder0 = 1 Then Comunder0 = 0 ' Underflow 클리어 End If * 상태는 내부적으로 **Latch 방식**으로 유지됩니다. * 한 번 발생한 상태는 사용자가 클리어하기 전까지 유지됩니다. ==== 참고 ==== * Overflow: 수신 버퍼가 가득 차 데이터가 유실된 상태 * Underflow: 읽을 데이터가 없는 상태에서 읽기를 시도한 경우 [[..:index|← CUBLOC2 목차로 돌아가기]]