수색…


소개

직렬 포트는 외부 센서 또는 Arduinos와 같은 임베디드 시스템과 통신하기위한 공통 인터페이스입니다. 최신 직렬 통신은 종종 USB 직렬 어댑터를 사용하여 USB 연결을 통해 구현됩니다. MATLAB은 RS-232 및 RS-485 프로토콜을 포함하여 직렬 통신을위한 내장 함수를 제공합니다. 이 기능은 하드웨어 직렬 포트 또는 "가상"USB 직렬 연결에 사용할 수 있습니다. 여기의 예제는 MATLAB의 직렬 통신을 보여줍니다.

매개 변수

직렬 포트 매개 변수 그것이하는 일
BaudRate 전송 속도를 설정합니다. 오늘날 가장 흔한 것은 57600이지만 4800, 9600 및 115200이 자주 보입니다.
InputBufferSize 메모리에 보관 된 바이트 수입니다. Matlab에는 FIFO가있어 새로운 바이트가 삭제됩니다. 기본값은 512 바이트이지만 문제없이 20MB로 쉽게 설정할 수 있습니다. 사용자가이 값을 작게하고 싶을 때만 있습니다.
BytesAvailable 읽을 대기중인 바이트 수
ValuesSent 포트가 열리고 나서 보낸 바이트 수
ValuesReceived 포트가 열리고 나서 읽은 바이트 수
BytesAvailableFcn 지정된 바이트 수를 입력 버퍼에서 사용할 수 있거나 터미네이터를 읽을 때 실행할 콜백 함수를 지정합니다.
BytesAvailableFcnCount bytes-available 이벤트를 생성하기 위해 입력 버퍼에서 사용할 수 있어야하는 바이트 수를 지정하십시오.
BytesAvailableFcnMode 지정된 바이트 수를 입력 버퍼에서 사용할 수 있거나 터미네이터를 읽은 후에 bytes-available 이벤트가 생성되는지 여부를 지정합니다.

Mac / Linux / Windows에서 직렬 포트 만들기

% Define serial port with a baud rate of 115200
rate = 115200;
if ispc
    s = serial('COM1', 'BaudRate',rate);
elseif ismac
    % Note that on OSX the serial device is uniquely enumerated. You will
    % have to look at /dev/tty.* to discover the exact signature of your
    % serial device
    s = serial('/dev/tty.usbserial-A104VFT7', 'BaudRate',rate);
elseif isunix
    s = serial('/dev/ttyusb0', 'BaudRate',rate);
end

% Set the input buffer size to 1,000,000 bytes (default: 512 bytes).
s.InputBufferSize = 1000000;    

% Open serial port    
fopen(s);

직렬 포트에서 읽기

직렬 포트 객체 생성 된 가정 s 과 같이 후, 예

% Read one byte
data = fread(s, 1);

% Read all the bytes, version 1
data = fread(s);

% Read all the bytes, version 2
data = fread(s, s.BytesAvailable);

% Close the serial port
fclose(s);

분실, 삭제 또는 덮어 쓴 경우에도 직렬 포트 닫기

직렬 포트 객체 생성 된 가정 s 과 같이 예하면, 다음을 닫습니다

fclose(s)

그러나 실수로 포트를 잃어 버릴 수 있습니다 (예 : 지우기, 덮어 쓰기, 범위 변경 등). fclose(s) 가 더 이상 작동하지 않습니다. 해결책은 간단합니다.

fclose(instrfindall)

instrfindall() 대한 자세한 정보.

직렬 포트에 쓰기

직렬 포트 객체 생성 된 가정 s 과 같이 후, 예

% Write one byte
fwrite(s, 255);

% Write one 16-bit signed integer
fwrite(s, 32767, 'int16');

% Write an array of unsigned 8-bit integers
fwrite(s,[48 49 50],'uchar');

% Close the serial port
fclose(s);

통신 모드 선택

Matlab은 직렬 포트와의 동기비동기 통신을 지원 합니다 . 올바른 통신 모드를 선택하는 것이 중요합니다. 선택은 다음에 따라 다릅니다.

  • 당신이 의사 소통하고있는 도구가 어떻게 행동하는지.
  • 주 프로그램 (또는 GUI)이 직렬 포트를 관리하는 것 외에 다른 기능은 무엇입니까?

가장 단순한 것부터 가장 까다로운 것에 이르기까지 설명하기 위해 3 가지 사례를 정의 할 것입니다. 3 가지 예를 들어, 내가 연결할 장비는 경사계가있는 회로 보드이며 아래에서 설명 할 3 가지 모드에서 작동 할 수 있습니다.


모드 1 : 동기식 (마스터 / 슬레이브)

이 모드가 가장 간단합니다. PC가 마스터 이고 장비가 슬레이브 인 경우에 해당 합니다. 이 장비는 자체적으로 직렬 포트에 아무 것도 보내지 않고 마스터 (PC, 프로그램)의 질문 / 명령을받은 후에 만 응답 합니다. 예 :

  • PC가 "지금 측정 해주세요"라는 명령을 보냅니다.
  • 장비는 명령을 수신하고 측정 한 다음 측정 값을 직렬 회선으로 되돌립니다 : "경사계 값은 XXX"입니다.

또는

  • PC가 "모드 X에서 모드 Y로 변경"명령을 전송합니다.
  • 장비는 명령을 수신하여 실행 한 다음 " 명령 실행 됨 "(또는 " 명령 실행되지 않음 ")이라는 확인 메시지를 직렬 회선으로 다시 보냅니다. 이것은 일반적으로 ACK / NACK 응답 ( "수신 확인 (d)"/ "수신 확인되지 않음")으로 불립니다.

요약 : 이 모드에서 장비 ( 슬레이브 )는 PC ( 마스터 )가 요청한 직후에 데이터를 직렬 회선으로 보냅니다.

동기 일러스트


모드 2 : 비동기

이제는 저의 악기를 시작했다고 가정하겠습니다.하지만 그것은 단순한 멍청한 센서 이상입니다. 끊임없이 자신의 성향을 모니터하고, 수직 (허용 오차 내에서 ± 15도라고 가정)하는 한 조용히 모니터링합니다. 장치가 15도 이상 기울어 져 수평에 가까워지면 직렬 회선으로 경고 메시지를 보내고 즉시 기울기를 읽습니다. 기울기가 임계 값 이상이면, 5 초마다 기울기를 계속해서 보냅니다.

주 프로그램 (또는 GUI)이 직렬 회선에 도착하는 메시지를 계속 "대기"하고 있다면 잘 처리 할 수 ​​있지만 그 동안에는 다른 작업을 수행 할 수 없습니다. 주 프로그램이 GUI 인 경우 GUI에서 사용자가 입력을 받아들이지 않기 때문에 GUI가 "고정"되어있는 것이 매우 실망 스럽습니다. 본질적으로, 그것은 슬레이브 가되었고 악기는 마스터 입니다. 계측기에서 GUI를 제어 할 수있는 멋진 방법이 없다면, 이는 피해야 할 사항입니다. 다행히도 비동기 통신 모드를 사용하면 다음을 수행 할 수 있습니다.

  • 메시지가 수신되었을 때 프로그램이 무엇을해야하는지 알려주는 별도의 함수 정의
  • 구석에이 기능을 유지하면 메시지가 직렬 회선에 도착할 때만 호출되어 실행 됩니다 . GUI가 실행해야하는 다른 코드를 실행할 수있는 나머지 시간.

요약 : 이 모드에서 장비는 언제든지 직렬 회선으로 메시지를 보낼 수 있습니다 (반드시 모든 시간이 필요하지는 않음). PC는 처리 할 메시지를 영구적으로 기다리지 않습니다. 다른 코드를 실행할 수 있습니다. 메시지가 도착할 때만이 기능은 메시지를 읽고 처리합니다.

여기에 이미지 설명을 입력하십시오.


모드 3 : 스트리밍 ( 실시간 )

이제 내 악기의 힘을 최대한 발휘하십시오. 시리얼 라인에 지속적으로 측정을 전송할 모드로 설정했습니다. 내 프로그램은 이러한 패킷을 수신하여 커브 또는 디지털 디스플레이에 표시하려고합니다. 위와 같이 5 초마다 값을 보내면 아무런 문제가 없습니다. 위의 모드를 유지하십시오. 그러나 full whack에서의 나의 장비는 1000Hz에서 시리얼 라인으로 데이터 포인트를 보낸다. 즉, 그것은 매 밀리 초마다 새로운 값을 보낸다. 위에서 설명한 비동기 모드를 유지하면 새 패킷을 처리하기 위해 정의한 특수 함수가 실행될 때 1ms 이상 걸릴 위험이 있습니다 (실제로 보장 된 확실성). (값을 플로팅하거나 표시하려는 경우, 그래픽 함수는 상당히 느리고, 필터링이나 FFT를 고려하지 않습니다.) 함수가 실행되기 시작하지만, 완료되기 전에 새 패킷이 도착하고 함수를 다시 트리거합니다. 두 번째 함수는 실행을 위해 대기열에 배치되며 첫 번째 함수가 완료 될 때 시작됩니다. 그러나이 시간까지 몇 개의 새 패킷이 도착하고 각 함수가 대기열에서 실행됩니다. 당신은 결과를 빨리 예측할 수 있습니다 : 나는 5 점을 계획하고있을 때까지 이미 수백 명을 기다리고 있습니다 ... gui는 속도를 늦추고, 결국 얼어 붙고, 스택이 커지고, 버퍼가 가득 찰 때까지 기다립니다. 결국 당신은 완전히 얼어 버린 프로그램이나 단순히 추락 한 프로그램을 남겨 둡니다.

이를 극복하기 위해 우리는 PC와 계측기 간의 동기화 링크를 더 이상 연결 해제 할 것입니다. 각 패킷 도착시 즉시 기능을 트리거하지 않고 계측기가 자신의 속도대로 데이터를 전송하도록합니다. 직렬 포트 버퍼는 수신 된 패킷을 누적합니다. PC는 관리 할 수있는 속도 (일정한 간격, PC 측에서 설정)로만 버퍼에서 데이터를 수집하고, 버퍼가 장비로 다시 채워지는 동안 무언가를 수행 한 다음 새 배치를 수집합니다. 버퍼의 데이터 ... 등등.

요약 : 이 모드에서 계측기는 직렬 포트 버퍼에 의해 수집 된 데이터를 지속적으로 보냅니다. 정기적 인 간격으로 PC는 버퍼에서 데이터를 수집하고 함께 데이터를 처리합니다. PC와 계측기간에 하드 동기화 링크가 없습니다. 둘 다 자신의 타이밍에서 작업을 실행합니다.

여기에 이미지 설명을 입력하십시오.


직렬 포트에서 수신 한 데이터 자동 처리

직렬 포트를 통해 연결된 일부 장치는 일정한 속도 (데이터 스트리밍)로 프로그램에 데이터를 보내거나 예측할 수없는 간격으로 데이터를 보냅니다. 직렬 포트가 도착할 때마다 데이터를 자동으로 처리하는 기능을 실행하도록 구성 할 수 있습니다. 이것은 직렬 포트 개체에 대한 "콜백 함수" 라고합니다.

당신은 콜백 (원하는 함수의 이름 :이이 개 기능을 사용하도록 설정해야합니다 직렬 포트의 호텔을 고를 수 있습니다 BytesAvailableFcn ), 콜백 기능 (실행 트리거해야하는 조건 BytesAvailableFcnMode ).

콜백 함수를 트리거하는 두 가지 방법이 있습니다.

  1. 직렬 포트에서 특정 바이트 수가 수신되면 (일반적으로 이진 데이터로 사용됨)
  2. 특정 문자가 직렬 포트에서 수신되면 (일반적으로 텍스트 또는 ASCII 데이터 용으로 사용됨)

콜백 함수에는 objevent 라는 두 개의 필수 입력 인수가 있습니다. obj 는 직렬 포트입니다. 예를 들어 직렬 포트에서받은 데이터를 인쇄하려면 newdata 라는 데이터를 인쇄하는 함수를 정의하십시오.

function newdata(obj,event)
    [d,c] = fread(obj);  % get the data from the serial port
    % Note: for ASCII data, use fscanf(obj) to return characters instead of binary values
    fprintf(1,'Received %d bytes\n',c);
    disp(d)
end

예를 들어 64 바이트의 데이터가 수신 될 때마다 newdata 함수를 실행하려면 다음과 같이 직렬 포트를 구성하십시오.

s = serial(port_name);
s.BytesAvailableFcnMode = 'byte';
s.BytesAvailableFcnCount = 64;
s.BytesAvailableFcn = @newdata;

텍스트 또는 ASCII 데이터의 경우 데이터는 일반적으로 페이지의 텍스트와 마찬가지로 "터미네이터 문자"가있는 행으로 나뉩니다. 캐리지 리턴 문자가 수신 될 때마다 newdata 함수를 실행하려면 다음과 같이 직렬 포트를 구성하십시오.

s = serial(port_name);
s.BytesAvailableFcnMode = 'terminator';
s.Terminator = 'CR';  % the carriage return, ASCII code 13
s.BytesAvailableFcn = @newdata;


Modified text is an extract of the original Stack Overflow Documentation
아래 라이선스 CC BY-SA 3.0
와 제휴하지 않음 Stack Overflow