안경잡이개발자

728x90
반응형

  초당 비트 수(Bit Per Second, BPS)1초에 전송할 수 있는 비트의 수를 의미합니다. 예를 들어 500 BPS라면, 초당 500개의 비트를 전송할 수 있다는 의미입니다. 보 레이트(Baud Rate)1초에 전송할 수 있는 의미 있는 정보의 수를 의미합니다. 예를 들어 의미 있는 정보의 단위를 32비트라고 규정할 때, 보 레이트가 500이라면 초당 16,000개의 비트를 전송한다는 의미가 될 것입니다. 다른 예시로 정보의 단위를 1비트라고 할 때, 보 레이트는 BPS와 동일할 것입니다.

 

  기본적으로 Serial 통신을 할 때는 보 레이트(Baud Rate)를 맞추어 통신을 진행합니다. 아두이노는 UART를 이용하여 하드웨어 시리얼과 소프트웨어 시리얼을 지원합니다. 하드웨어 시리얼은 하드웨어적으로 지원하는 RX, TX 핀을 이용하는 방식입니다. 혹은 가상 COM 포트 기능을 이용하여 USB 포트로 시리얼 통신이 가능할 수도 있습니다. 일반적으로 시리얼 통신을 할 때는 Serial.print()와 같은 함수를 이용하고, 하드웨어 시리얼은 Serial1, Serial2과 같은 형태의 라이브러리를 사용합니다.

 

  한 번 다음과 같이 가장 기본적인 아두이노 예제 소스코드를 작성해 봅시다. Serial.read() 함수를 이용하여 한 바이트(Byte)씩 입력을 받을 수 있습니다. 간단한 에코(Echo) 프로그램은 다음과 같습니다.

 

※ 아두이노 시리얼 통신 예제 소스코드 ※

 

void setup() {
    Serial.begin(9600);
}

void loop() {
    int incomingByte;
    if (Serial.available() > 0) {
        incomingByte = Serial.read();
        Serial.print("USB received: ");
        Serial.println(incomingByte, DEC);
    }
}

 

  실제로 위 프로그램을 업로드 한 이후에 시리얼 모니터(Serial Monitor)를 실행하면 다음과 같습니다.

 

 

※ 파이썬으로 호스트(Host) 프로그램 만들기 ※

 

  호스트(Host) 쪽에서 데이터를 보낼 때 별도의 프로그램을 이용할 수도 있습니다. 프로그램은 다음과 같이 작성할 수 있습니다. 프로그래밍 언어는 Python 3.7이며 serial 라이브러리를 이용하면 됩니다.

 

import serial

values = [1, 2, 3, 4, 5, 6, 7, 8, 9]

s = serial.Serial("COM4", 9600)
s.write(b'Hello')
s.write(bytearray(values))

while True:
    data = s.readline()
    print(data)

s.close()

 

  실행 결과는 다음과 같습니다.

 

 

  참고로 기본적으로 해당 Serial 포트를 이미 다른 프로세스가 사용 중이라면, 액세스가 거부되었다는 메시지가 출력될 수 있습니다. 오류 메시지는 대략 다음과 같습니다. 아두이노에서 시리얼 모니터가 켜져 있으면 오류가 발생할 수 있습니다.

 

serial.serialutil.SerialException: could not open port 'COM4': PermissionError(13, '액세스가 거부되었습니다.', None, 5)
728x90
반응형

Comment +1

728x90
반응형

  시리얼(Serial)은 말 그대로 직렬이라는 의미를 가지고 있습니다.

 

  일반적인 시리얼 통신 방식은 UART (Universal Asynchronous serial Receiver and Transmitter) 방식을 의미합니다. UART는 하드웨어적으로 구현이 간단한 편이며, 대표적인 비동기 통신 방식입니다. 다시 말해 통신을 수행하는 두 기기가 클럭(Clock)을 공유하지 않습니다. 그래서 두 기기가 동일한 속도를 가지도록 추가적으로 속도를 맞추어 주어야 합니다.

 

  시리얼 통신 속도 (Speed)는 여러 개의 BPS (Bits Per Second) 중에서 하나를 선택해야 합니다. 4800, 9600, 19200 등이 있는데요. 대표적인 것이 바로 9600입니다. 당연히 호스트(Host) 컴퓨터와 USB 장치랑 이러한 BPS를 맞추지 않으면 통신이 안 되겠죠? 그러한 작업은 기본적으로 수행됩니다.

 

  다른 시리얼 통신 방법으로는 SPI (Serial Peripheral Interface)가 있습니다. SPI는 라인이 더 많아 데이터 송수신을 동시에 할 수 있으며 UART에 비해서 훨씬 빠릅니다.  또한 두 기기가 같은 클럭(Clock)을 사용하여 통신을 하므로 시작 단계부터 동기화 작업이 수행됩니다.

 

  한 번 예시 코드를 확인해 보겠습니다. Serial.begin() 함수를 이용하여 초기화를 수행할 수 있습니다. 다만 기본적으로 Serial 객체가 초기화 될 때까지 기다려야 합니다. 초기화 된 이후에는 바로 Serial.println() 함수를 이용하여 원하는 문자열을 호스트(Host) 쪽으로 보내어 출력할 수 있습니다.

 

void setup() {
    // 시리얼 통신을 열고 포트가 열릴 때까지 기다립니다.
    Serial.begin(9600);
    while (!Serial) {
        ; // 시리얼 포트가 연결될 때까지 기다립니다.
    }
    Serial.println("Setup이 완료되었습니다.");
}

void loop() {
    Serial.println("Loop 함수를 호출합니다.");
    delay(1000);
}

 

  코드를 작성한 뒤에 USB Type으로는 [Serial]을 선택합니다.

 

 

  업로드를 해보시면 1초에 한 번씩 Serial 통신이 수행되어 문자열이 출력됩니다.

 

 

※ 유의할 점 ※

 

  Teensy에서는 기본적으로 Serial 통신을 이용할 때 Serial을 포함하는 USB Type을 설정했는지 확인할 필요가 있습니다. 만약에 RawHID와 Serial 통신을 같이 사용해야 할 때에는 RawHID를 선택할 수 있는데요. 다만 RawHID는 기본적으로 Serial 통신을 메인으로 사용하지 않으며, setup() 함수에 포함되어 있는 Serial 작업은 무시될 수 있습니다. 이 점을 유의하셔야 합니다.

 

 

  예를 들어 이와 같이 USB TypeRaw HID로 설정하여 동일한 코드를 실행하면 다음과 같이 setup() 함수에 정의되어 있던 출력 구문은 출력되지 않는 것을 알 수 있습니다.

 

728x90
반응형

Comment +0