본문 바로가기

개발자/Raspberry Pi3

Python 및 C를 사용한 Raspberry Pi UART 통신

반응형

 

Python 및 C를 사용한 Raspberry Pi UART 통신 

 

UART (Universal Asynchronous Receiver/Transmitter)는 데이터가 비트 단위로 직렬로 전송되는 직렬 통신 프로토콜입니다. 비동기 직렬 통신은 바이트 지향 전송에 널리 사용됩니다. 비동기 직렬 통신에서는 한 번에 한 바이트의 데이터가 전송됩니다.

 

UART 직렬 통신 프로토콜은 데이터 바이트에 대해 정의 된 프레임 구조를 사용합니다. 비동기 통신의 프레임 구조는 다음과 같이 구성됩니다.

 

  • START 비트 : 시리얼 통신이 시작되었고 항상 로우임을 나타내는 비트입니다.
  • 데이터 비트 패킷 : 데이터 비트는 5 ~ 9 비트의 패킷 일 수 있습니다. 일반적으로 우리는 항상 START 비트 이후에 전송되는 8 비트 데이터 패킷을 사용합니다.
  • STOP 비트 : 일반적으로 길이가 1 ~ 2 비트입니다. 프레임의 끝을 나타 내기 위해 데이터 비트 패킷 후에 전송됩니다. 정지 비트는 항상 로직 하이입니다.

 

UART 직렬 통신 프로토콜

 

일반적으로 비동기 직렬 통신 프레임은 START 비트 (1 비트), 데이터 바이트 (8 비트), STOP 비트 (1 비트)로 구성되며 위 그림과 같이 10 비트 프레임을 형성합니다. 프레임은 또한 단일 비트 대신 2 개의 STOP 비트로 구성 될 수 있으며 STOP 비트 뒤에 PARITY 비트가 있을 수도 있습니다.

 

라즈베리 파이 UART

 

Raspberry Pi에는 다음과 같은 두 개의 내장 UART가 있습니다.

 

  • PL011 UART
  • 미니 UART

 

PL011 UART는 ARM 기반 UART입니다. 이 UART는 미니 UART 보다 처리량이 좋습니다 .

 

Raspberry Pi 3에서 mini UART는 Linux 콘솔 출력에 사용되는 반면 PL011은 온보드 Bluetooth 모듈에 연결됩니다. 그리고 다른 버전의 Raspberry Pi에서는 PL011이 Linux 콘솔 출력에 사용됩니다.

 

Mini UART는 GPU의 핵심 주파수와 연결된 주파수를 사용합니다. 따라서 GPU 코어 주파수가 변경되면 UART의 주파수도 변경되어 UART의 전송 속도도 변경됩니다. 이로 인해 미니 UART가 불안 정해져 데이터 손실 또는 손상이 발생할 수 있습니다. 미니 UART를 안정적으로 만들려면 코어 주파수를 고정하십시오. 미니 UART는 패리티를 지원하지 않습니다.

 

PL011은 안정적이고 고성능의 UART입니다. 보다 효율적이고 효과적인 통신을 위해 미니 UART 대신 PL011 UART를 사용하십시오.

 

직렬 통신을 위해 Raspberry Pi의 UART를 활성화하는 것이 좋습니다. 그렇지 않으면 UART 포트가 Linux 콘솔 출력 및 Bluetooth 모듈에 사용되므로 직렬로 통신 할 수 없습니다.

 

Raspberry Pi 3 UART 핀 

 

Raspberry Pi 3 UART 핀

 

Raspberry Pi에서 UART 구성

 

Raspberry Pi에서 터미널 창에 다음 명령을 입력하여 UART를 활성화합니다.

 

 

$sudo raspi-config 

 

선택 -> 인터페이스 옵션으로 갑니다.

 

Interfacing 옵션을 선택한 후  Serial  옵션을 선택 하여 UART를 활성화합니다.

 

그런 다음 Serial을 통해 액세스 할 수있는 로그인 셸을 요청 합니다. 다음과 같이  No를  선택 합니다.

 

마지막에 하드웨어 직렬 포트 활성화를 요청하고 예를 선택합니다 .

 

마지막으로 UART는 Raspberry Pi 3의 RX 및 TX 핀에서 직렬 통신을 위해 활성화됩니다.

 

Raspberry Pi를 재부팅

 

그런 다음 Raspberry Pi를 재부팅하십시오.

 

UART 통신용 직렬 포트

 

기본적으로 미니 UART는 UART 핀 (TX 및 RX)에 매핑되고 PL011은 Raspberry Pi 3의 온보드 Bluetooth 모듈에 연결됩니다.

 

이전 버전의 Raspberry Pi 모델에서 PL011은 Linux 콘솔 출력 (UART 핀에 매핑 됨)에 사용되며 온보드 Bluetooth 모듈이 없습니다.

 

위와 같이 구성한 후 UART 핀 (GPIO14 및 GPIO15)에서 UART를 사용할 수 있습니다.

 

Raspberry Pi 3에서 미니 UART에 액세스하기 위해 ttyS0 포트가 할당됩니다. 그리고 Raspberry Pi 3 ttyAMA0 포트 에서 PL011에 액세스하기 위해 할당됩니다. 그러나 다른 Raspberry Pi 모델에서는 ttyAMA0 포트만 액세스 할 수 있습니다.

 

하드웨어 UART 포트, 즉 GPIO14 (TXD) 및 GPIO15 (RXD)는 serial0 이라고도하며 Bluetooth 모듈에 연결된 다른 UART 포트는 serial1 로 알려져 있습니다 . 이러한 이름은 Raspberry Pi 버전 이식성을 위해 직렬 별칭으로 생성됩니다.

 

UART 핀 (GPIO14 및 GPIO15)에 매핑 된 UART 즉, 미니 UART (ttyS0) 또는 PL011 UART (ttyAMA0)를 확인할 수 있습니다. UART 매핑을 확인하려면 다음 명령을 입력하십시오.

 

 

$ls -l /dev

 

 

/dev/ttyS0 및 /dev/ttyAMA0에 대한 UART 매핑은 다음과 같습니다. 

 

/dev/ttyS0 및 /dev/ttyAMA0에 대한 UART 매핑

 

Raspberry Pi와 PC 간의 직렬 통신 테스트

 

직렬 통신이 작동하는지 테스트하려면 아래 그림과 같이 연결하십시오. 

 

Raspberry Pi와 PC 간의 직렬 통신 테스트

 

노트북 / PC에서 터미널을 열어 Raspberry Pi에서 전송할 데이터를 수신합니다.

이제 다음 명령을 입력하여 Raspberry Pi 터미널에서 데이터를 전송합니다.

 

 

$echo “Hello” > /dev/ttyS0

 

이 명령은 UART 포트, 즉 Tx 핀에 "Hello"문자열을 출력하고 PC / 노트북의 터미널 응용 프로그램에 표시합니다.

 

기본적으로 미니 UART는 GPIO14 (TX) 및 GPIO15 (RX)에 매핑됩니다. PL011 즉 ttyAMA0은 온보드 Bluetooth 모듈에 연결되어 있습니다.

 

UART를 사용하여 Raspberry Pi 3와 Laptop / PC 간의 직렬 통신을 설정해 보겠습니다. Python 및 C를 사용하여 UART 기반 직렬 통신을 수행 할 수 있습니다.

 

여기에서는 PC에서 에코를 생성합니다.

 

Python을 사용한 Raspberry Pi의 UART 통신 

 

'''
UART communication on Raspberry Pi using Pyhton
http://www.electronicwings.com
'''
import serial
from time import sleep

ser = serial.Serial ("/dev/ttyS0", 9600)    #Open port with baud rate
while True:
    received_data = ser.read()              #read serial port
    sleep(0.03)
    data_left = ser.inWaiting()             #check for remaining byte
    received_data += ser.read(data_left)
    print (received_data)                   #print received data
    ser.write(received_data)                #transmit data serially 

 

사용되는 기능 :

 

serial.Serial (port, baudrate)

 

포트를 여는 데 사용되는 Serial 용 클래스입니다. 이 클래스의 인스턴스를 생성 (여기가로 명명되어 버리는 , 우리는 어떤 이름을 사용할 수 있습니다).

 

예 ser = serial.Serial (/ dev / ttyS0, 9600)

 

매개 변수 :

 

포트 – 포트 이름 (예 : ttyUSB0, ttyS0 등) 또는 없음

Baudrate – 9600, 38400 등과 같은 전송 속도입니다.

 

위의 기능에는 더 많은 매개 변수가 있지만 여기에서는 사용되지 않습니다. 따라서 매개 변수에 대한 자세한 내용은 Python API for PySerial을 참조 하세요 .

 

읽기 ( 크기 )

 

이 기능은 시리얼 포트의 데이터를 읽는 데 사용됩니다.

매개 변수 : 크기 – 읽을 바이트 수. 기본 크기는 1입니다.

반환: 포트에서 읽은 바이트.

 

쓰기 ( 데이터 )

 

이 기능은 Serial Port에서 데이터를 송수신하는 데 사용됩니다.

매개 변수 : 데이터 – 전송할 데이터

반환: 쓰거나 보낸 바이트 수

 

더 많은 직렬 API 및 세부 정보 는 PySerial 용 Python API를 참조 할 수 있습니다 . 

 

C를 사용하는 Raspberry Pi에서 UART 통신

 

C 언어로 작성된 프로그램을 사용하여 Raspberry Pi 3와 Laptop / PC 간의 UART 직렬 통신을 구현해 보겠습니다. 여기에서는 WiringPi 라이브러리를 사용하여 Raspberry Pi에서 UART 통신을 설정합니다. 

 

/*
	UART communication on Raspberry Pi using C (WiringPi Library)
	http://www.electronicwings.com
*/

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

#include <wiringPi.h>
#include <wiringSerial.h>

int main ()
{
  int serial_port ;
  char dat;
  if ((serial_port = serialOpen ("/dev/ttyS0", 9600)) < 0)	/* open serial port */
  {
    fprintf (stderr, "Unable to open serial device: %s\n", strerror (errno)) ;
    return 1 ;
  }

  if (wiringPiSetup () == -1)					/* initializes wiringPi setup */
  {
    fprintf (stdout, "Unable to start wiringPi: %s\n", strerror (errno)) ;
    return 1 ;
  }

  while(1){
	  
	if(serialDataAvail (serial_port) )
	{ 
		dat = serialGetchar (serial_port);		/* receive character serially*/	
		printf ("%c", dat) ;
		fflush (stdout) ;
		serialPutchar(serial_port, dat);		/* transmit character serially on port */
		  }
	}

}

 

Raspberry Pi 터미널에서 출력  

 

Raspberry Pi 터미널의 직렬 출력

 

PC/노트북에서 터미널 출력

 

PC / 노트북에서 직렬 출력

 

PC / 노트북 끝에서는 여기에서 Realterm 소프트웨어를 사용합니다.

 

직렬 별칭

 

여기에서는 Raspberry Pi 3에서 UART (GPIO14 및 GPIO15)가 매핑 된 ttyS0 포트를 사용했습니다. 하지만 다른 Raspberry Pi 모델에서는 온보드 Bluetooth 모듈이 없기 때문에 ttyAMA0에 매핑됩니다 .

 

따라서 Raspberry Pi 3 용으로 작성된 프로그램은 포트 이름이 다르기 때문에 이전 모델의 Raspberry Pi에서 오류가 발생합니다. 포트 이름에 이식성을 제공하기 위해 serial0 및 serial1 이라는 이름의 직렬 별칭이 Raspbian에 생성됩니다 . serial0은 기본 포트 (ttyS0 또는 ttyAMA0)에 매핑 된 UART 포트를 나타냅니다. 따라서 ttyS0 또는 ttyAMA0을 serial0으로 바꿀 수 있습니다.

 

ttyS0 또는 ttyAMA0 대신 serial0을 UART 포트로 사용하면 Raspberry Pi 3 용으로 작성된 프로그램이 이전 모델의 Raspberry Pi에서도 실행됩니다.

 

Raspberry Pi 3에서 직렬 포트 교체

 

더 나은 성능을 위해 GPIO14 및 GPIO15의 직렬 통신은 Bluetooth 모듈에 연결된 ttyAMA0 포트를 사용해야합니다. 이 포트를 사용하려면 UART 포트를 교체해야합니다. 즉, ttyAMA0을 GPIO14 및 GPIO15에 매핑하고 ttyS0 (미니 UART)을 Bluetooth 모듈에 매핑해야합니다.

 

직렬 포트의 스와핑은 장치 오버레이 (예 : pi3-miniuart-bt)를 통해 Bluetooth 모듈 용 미니 UART (ttyS0)를 사용하여 수행 할 수 있습니다. 또는 장치 오버레이 (예 : pi3-disable-bt)를 통해 Bluetooth를 완전히 비활성화하여 수행 할 수 있습니다.

 

UART 포트를 교체하려면 아래와 같이 config.txt 파일을 엽니 다.

 

 

sudo nano /boot/config.txt

 

그런 다음 아래 그림과 같이 파일 끝에 아래 줄을 추가하십시오.

 

 

dtoverlay = pi3-miniuart-bt 

 

또는

 

dtoverlay = pi3-disable-bt

 

위 줄을 추가 한 후 변경 사항을 파일에 저장하고 시스템을 재부팅합니다. 직렬 포트의 새로운 매핑을 확인할 수 있습니다.

 

 

ls -l /dev

 

UART 포트의 매핑은 다음과 같습니다.  

 

UART 포트의 매핑

 

 

 

 

반응형

더욱 좋은 정보를 제공하겠습니다.~ ^^