developer tip

간단한 직렬 지점 간 통신 프로토콜

copycodes 2021. 1. 8. 08:30
반응형

간단한 직렬 지점 간 통신 프로토콜


두 장치 (PC와 마이크로 컨트롤러)간에 간단한 통신 프로토콜이 필요합니다. PC는 몇 가지 명령과 매개 변수를 마이크로로 보내야합니다. 마이크로는 바이트 배열 (센서의 데이터)을 전송해야합니다.

데이터는 노이즈로부터 보호 되어야합니다 (패리티 검사 외에도 다른 데이터 수정 방법이 필요하다고 생각합니다).

이를위한 표준 솔루션이 있습니까? (완벽한 솔루션이 아닌 아이디어 만 필요합니다).

추신 모든 조언을 부탁드립니다. PPS 문법 오류에 대해 죄송합니다. 이해하시기 바랍니다.

편집 1. 마스터 / 슬레이브 프로토콜인지 양쪽 모두 통신을 시작할 수 있는지 결정하지 않았습니다 . PC는 마이크로가 작업을 완료하고 데이터를 보낼 수있는시기를 알아야합니다. 데이터가 준비되면 마이크로를 지속적으로 폴링하거나 작업이 완료되면 마이크로가 데이터를 보낼 수 있습니다. 어느 것이 더 낫고 더 간단한 지 모르겠습니다.

편집 2. 하드웨어 및 물리 계층 프로토콜. PC에서 사용하는 RS-232 C 시리얼 규격 이므로 비동기 통신 을 사용하겠습니다 . RxD, TxD 및 GND 신호 만 사용하겠습니다. 마이크로 컨트롤러 AFAIK가 지원하지 않기 때문에 추가 전선을 사용할 수 없습니다. BTW AVR ATmega128 칩을 사용하고 있습니다.

따라서 고정 전송 속도, 8 비트 데이터, 패리티 검사없이 (또는 포함?) 2 정지 비트를 사용합니다.

데이터 링크 프로토콜 . 그것이 내 질문이 주로 우려하는 것입니다. HDLC,PPPModbus프로토콜을 제안 해 주셔서 감사합니다. 나는 그것에 대해 조사 할 것이다.


나는 HDLC를 사용할 것 입니다. 나는 과거에 그것으로 행운이 있었다. 나는 점대 점 직렬을 위해 비동기 프레이밍을 사용하고 아마도 과잉 일 것이므로 다른 모든 제어 항목은 잊어 버릴 것입니다.

패킷 프레이밍을 위해 HDLC를 사용하는 것 외에도. 다음과 같이 패킷을 포맷합니다. 802.11을 사용하여 옵션을 전달하는 방법입니다.

U8 cmd;
U8 len;
u8 payload[len];

각 명령 패킷의 총 크기는 len +2입니다.

그런 다음 다음과 같은 명령을 정의합니다.

#define TRIGGER_SENSOR 0x01
#define SENSOR_RESPONSE 0x02

다른 장점은 새 명령을 추가 할 수 있으며 정의되지 않은 명령을 무시하도록 파서를 올바르게 설계하면 이전 버전과의 호환성을 갖게된다는 것입니다.

따라서 모든 것을 모아 패킷은 다음과 같이 보일 것입니다.

 // total packet length minus flags len+4
 U8 sflag;   //0x7e start of packet end of packet flag from HDLC
 U8 cmd;     //tells the other side what to do.
 U8 len;     // payload length
 U8 payload[len];  // could be zero len
 U16 crc;
 U8 eflag;   //end of frame flag

그런 다음 시스템은 플래그 0x7e에 대한 직렬 스트림을 모니터링하고 거기에있을 때 길이를 확인하여 pklen> = 4 및 pklen = len + 4이고 crc가 유효한지 확인합니다. 작은 패킷에 대해 crc에만 의존하지 마십시오. 많은 오 탐지가 발생하고 길이도 확인됩니다. 길이 또는 crc가 일치하지 않으면 길이와 crc를 재설정하고 새 프레임 디코딩을 시작하십시오. 일치하는 경우 패킷을 새 버퍼에 복사하고 명령 처리 기능에 전달합니다. 플래그가 수신되면 항상 길이와 crc를 재설정하십시오.

명령 처리 기능의 경우 cmd 및 len을 잡고 스위치를 사용하여 각 유형의 명령을 처리하십시오. 또한 특정 이벤트가 응답을 보내야 시스템이 이벤트 기반의 원격 프로 시저 호출처럼 동작합니다.

예를 들어 센서 장치에는 타이머가 있거나 명령에 응답하여 판독 할 수 있습니다. 그런 다음 패킷을 포맷하여 PC로 보내면 PC가 패킷을 수신했다고 응답합니다. 그렇지 않으면 센서 장치가 시간 초과시 다시 보낼 수 있습니다.

또한 네트워크 전송을 수행 할 때 Foredecker 포인트가 물리 계층 에 대해 잊지 않도록 OSI 모델같은 네트워크 스택으로 설계해야합니다 . HDLC에 대한 내 게시물은 데이터 링크 계층 이고 RPC 및 명령 처리는 응용 프로그램 계층 입니다.


RS232 프로토콜은 까다 롭습니다. HDLC 사용에 대한 제안은 좋은 제안이지만 전체 솔루션은 아닙니다. 결정해야 할 다른 사항이 있습니다.

  • 두 장치 간의 전송 속도는 어떻게 결정됩니까? Autobuad? 미리 정의했거나 설명을 설정 하시겠습니까?
  • 소프트웨어 나 하드웨어 또는 둘 다에서 흐름 제어를 수행 하시겠습니까? 하드웨어 흐름 제어를 사용 하는 경우 케이블이 올바르게 구성되었는지 확인 해야 합니다.
  • 케이블에 대해 말하면 이것은 RS233에서 큰 고통입니다. 장치에 따라 스트레이트 스루 케이블, 크로스 오버 케이블 또는 변형을 사용해야 할 수 있습니다.
  • 소프트웨어 기반 흐름 제어 메커니즘을 사용하면 가장 간단한 케이블 (TX, RX 및 공통) 만 사용할 수 있으므로 효과적 일 수 있습니다.
  • 7 비트 또는 8 비트 단어를 선택합니까?
  • HW 패리티 또는 소프트웨어 오류 검사.

8 데이터 비트, 하드웨어 패리티 없음, 1 정지 비트를 사용하고 소프트웨어 기반 흐름 제어를 사용하는 것이 좋습니다. 하드웨어에서 지원하는 경우 autobaud를 사용해야합니다. 그렇지 않은 경우 autobaud는 소프트웨어에서 수행하기가 매우 어렵습니다.


여기에 몇 가지 좋은 답변이 있습니다. 다음은 몇 가지 유용한 정보입니다.

패킷이 시간으로 구분되지 않더라도 동기화 바이트는 패킷을 구성하려고 시도해야하는 위치의 수를 줄이는 데 필수적인 방법입니다. 장치는 종종 많은 정크 데이터를 처리해야합니다 (즉, 전원을 켰을 때 전송중인 패킷의 끝 또는 하드웨어 충돌의 결과). 동기화 바이트가 없으면 수신하는 모든 바이트에서 패킷을 만들어야합니다. 동기화 바이트는 1/255 바이트의 랜덤 노이즈 만 패킷의 첫 번째 바이트가 될 수 있음을 의미합니다. 프로토콜을 스누핑하고 싶을 때도 환상적입니다.

패킷에 주소가 있거나 마스터 / 슬레이브 또는 PC / 장치라고 말하는 것은 어떤 유형 또는 다른 유형 스눕 도구통해 패킷을 볼 때 유용합니다 . PC에 대해 DEVICE와 다른 동기화 바이트를 사용하여이를 수행 할 수 있습니다. 또한 이것은 장치가 자체 에코에 응답하지 않음을 의미합니다.

오류 수정 (예 : Hamming ) 을 살펴볼 수 있습니다 . 8 비트 데이터를 12 비트 보호 바이트로 패키징합니다. 이러한 12 비트 중 하나는 도중에 뒤집히고 원래의 8 비트를 검색 할 수 있습니다. 데이터 저장 (CD에 사용) 또는 장치가 쉽게 재전송 할 수없는 경우 (위성 링크, 단방향 RF)에 유용합니다.

패킷 번호는 삶을 더 쉽게 만듭니다. 전송 된 패킷은 번호를 전달하고 응답은 "응답"이라는 플래그와 동일한 번호를 전달합니다. 즉, 도착하지 않은 패킷 (동기화 손상)은 발신자가 쉽게 감지하고 느린 링크를 사용하는 전이중 모드에서는 첫 번째 응답이 수신되기 전에 두 개의 명령을 보낼 수 있습니다. 이는 또한 프로토콜 분석을 더 쉽게 만듭니다 (제 3자가 기본 프로토콜에 대한 지식없이 수신 된 패킷을 이해할 수 있음).

단일 마스터를 갖는 것은 놀라운 단순화입니다. 즉, 전이중 환경에서는 그다지 중요하지 않습니다. 전력을 절약하려고하거나 장치 끝에서 이벤트 구동 (입력 상태 변경, 샘플 준비)을 수행하지 않는 한 항상해야한다고 말하면 충분합니다.


내 제안은 modbus입니다. 센서 및 매개 변수 (예 : PLC)가있는 장치와의 통신을위한 효율적이고 쉬운 표준 프로토콜입니다. http://www.modbus.org 에서 사양을 얻을 수 있습니다 . 1979 년부터 시작되어 인기를 얻고 있으며 예제와 라이브러리를 찾는 데 아무런 문제가 없을 것입니다.


나는이 질문을 몇 달 전에 읽었고 정확히 같은 문제를 가지고 있었지만 적은 양의 RAM을 가진 작은 8 비트 마이크로에 대해 충분히 효율적인 것을 찾지 못했습니다. 그래서 CAN과 LIN에서 영감을 받아 작업을 수행 할 무언가를 만들었습니다. MIN (Microcontroller Interconnect Network)이라고 부르고 여기에 GitHub에 업로드했습니다.

https://github.com/min-protocol/min

두 가지 구현이 있습니다. 하나는 임베디드 C, 다른 하나는 PC 용 Python입니다. 또한 PC가 명령을 보내고 펌웨어가 LED를 켜는 작은 "hello world"테스트 프로그램도 있습니다. 여기에 Arduino 보드에서 이것을 시작하고 실행하는 것에 대해 블로그를 작성했습니다.

https://kentindell.wordpress.com/2015/02/18/micrcontroller-interconnect-network-min-version-1-0/

MIN은 매우 간단합니다. 레이어 0 표현 (8 데이터 비트, 1 정지 비트, 패리티 없음)을 수정했지만 전송 속도는 열어 두었습니다. 각 프레임은 3 개의 0xAA 바이트로 시작하는데, 이진법은 1010101010이며, 한쪽 끝이 다른 쪽 끝에 동적으로 적응하기를 원할 경우 자동 보오율 감지를 수행하는 좋은 펄스열입니다. 프레임은 0 ~ 15 바이트의 페이로드이며, 16 비트 Fletcher의 체크섬, 제어 바이트 및 8 비트 식별자 (페이로드 데이터에 포함 된 내용을 애플리케이션에 알리기 위해)가 있습니다.

프로토콜은 문자 스터핑을 사용하므로 0xAA 0xAA 0xAA는 항상 프레임 시작을 나타냅니다. 즉, 장치가 재설정에서 나오면 항상 다음 프레임의 시작과 동기화됩니다 (MIN의 설계 목표는 불완전하거나 잘못된 프레임을 전달하는 것이 결코 아닙니다). 이는 또한 특정 바이트 간 및 프레임 간 타이밍 제약이 필요하지 않음을 의미합니다. 프로토콜에 대한 자세한 내용은 GitHub repo wiki에 있습니다.

MIN은 향후 개선 할 여지가 있습니다. 블록 메시지 전달 (제어 바이트의 4 비트가 예약 됨) 및 기능의 상위 수준 협상 (식별자 0xFF가 예약 됨)을 위해 거기에 몇 가지 후크를 남겨 두었으므로 일반적으로 필요한 기능에 대한 지원을 추가 할 수있는 범위가 충분합니다.


다음은 대체 프로토콜입니다.

u8  Sync          // A constant value which always marks the start of a packet
u16 Length        // Number of bytes in payload
u8  Data[Length]  // The payload
u16 Crc           // CRC

RS232 / UART를 PC (직렬 포트)와 프로세서 (UART)가 최소한의 번거 로움으로 처리 할 수 ​​있으므로 ( 레벨 이동을 수행하려면 MAX232 칩 또는 이와 유사한 것이 필요합니다) 사용하십시오.

그리고 RS232 / UART를 사용하면 관련이없는 경우 마스터 / 슬레이브에 대해 걱정할 필요가 없습니다. 필요한 경우 흐름 제어를 사용할 수 있습니다.

권장 PC 소프트웨어 : 직접 작성하거나 간단한 모니터링 및 제어를위한 Docklight (평가 버전은 무료).

더 큰 오류 검사를 위해 가장 간단한 것은 패리티 검사이거나 더 강력한 것이 필요한 경우 컨볼 루션 코딩 일 수 있습니다.

어쨌든 당신이 무엇을 하든지 간단하게 유지하십시오!

편집 : PC에서 RS232를 사용하는 것이 예전보다 훨씬 쉽습니다. 이제 USB to RS232 / TTL 변환기를 사용할 수 있습니다. 한쪽 끝은 PC의 USB 소켓에 들어가고 일반 직렬 포트로 나타납니다. 다른 하나는 레벨 시프 팅없이 프로세서에 직접 연결할 수있는 5V 또는 3.3V 신호로 나옵니다 .

우리는 이러한 종류의 애플리케이션에 완벽하게 작동하는 FDTI 칩의 TTL-232R-3V3 를 사용했습니다.


내 유일한 제안은 소음 방지가 필요한 경우 전이중 RS-422 / 485를 사용할 수 있다는 것입니다. 당신은에 IC와 유사한 사용할 수있는 같은 PC 측의 AVR 측에 다음 RS-Delay Time을> RS-422 컨버터를 여기 485PTBR . 차폐 케이블 (2 개의 꼬인 차폐 쌍)을 찾거나 만들 수 있다면 더 많은 보호를받을 수 있습니다. 그리고이 모든 것이 마이크로와 PC에 보이지 않으며 소프트웨어 변경이 없습니다.

무엇을 하든지 전이중 시스템을 사용하고 있는지 확인하고 읽기 / 쓰기 활성화 라인이 IC에서 어설 션되는지 확인하십시오.


패리티 검사와 관련하여 (여기에 몇 번 표시됨) :

대부분 쓸모가 없습니다. 단일 비트가 오류로 변경 될 수 있다고 우려되는 경우 두 번째 비트도 변경 될 가능성이 높고 패리티 검사에서 오탐을 얻을 수 있습니다.

조회 테이블과 함께 CRC16과 같은 가벼운 것을 사용하십시오. 각 바이트가 수신 될 때 계산할 수 있으며 기본적으로 XOR입니다. Steve Melnikoff의 제안은 작은 마이크로에 적합합니다.

또한 원시 바이너리가 아닌 사람이 읽을 수있는 데이터를 전송하는 것이 좋습니다 (성능이 최우선 순위가 아닌 경우). 디버깅 및 로그 파일이 훨씬 더 즐겁습니다.


Telemetry파이썬 에서 살펴보고 관련 데스크탑 구현을 볼 수 있습니다.Pytelemetry

주요 특징

그것은이다 PubSub 기반 프로토콜 ,하지만 MQTT는 달리이 지점 간 프로토콜이며, 어떤 브로커 .

모든 pubsub 프로토콜과 마찬가지로 a의 한쪽 끝에서 게시topic 하고 해당 주제에 대해 다른 쪽 끝에서 알림을받을 수 있습니다.

임베디드 측면에서 주제에 대한 게시는 다음과 같이 간단합니다.

publish("someTopic","someMessage")

숫자 :

publish_f32("foo",1.23e-4)
publish_u32("bar",56789)

이러한 변수 전송 방법은 제한적으로 보일 수 있지만 다음 마일스톤은 다음과 같은 작업을 수행하여 주제의 구문 분석에 추가 의미를 추가하려고합니다.

// Add an indexing meaning to the topic
publish("foo:1",45) // foo with index = 1
publish("foo:2",56) // foo with index = 2

// Add a grouping meaning to the topic
publish("bar/foo",67) // foo is under group 'bar'

// Combine
publish("bar/foo:45",54)

배열, 복잡한 데이터 구조 등을 보내야하는 경우 유용합니다.

또한 PubSub 패턴은 유연성 때문에 훌륭합니다. 마스터 / 슬레이브 애플리케이션, 장치 대 장치 등을 빌드 할 수 있습니다.

C 라이브러리 GitHub 버전

C 라이브러리는 괜찮은 UART 라이브러리가있는 한 모든 새 장치에 추가하는 것이 매우 간단합니다.

TM_transport(에 의해 정의 됨 Telemetry) 라는 데이터 구조를 인스턴스화 하고 4 개의 함수 포인터를 할당 하기 만하면 read readable write writeable됩니다.

// your device's uart library function signatures (usually you already have them)
int32_t read(void * buf, uint32_t sizeToRead);
int32_t readable();
int32_t write(void * buf, uint32_t sizeToWrite);
int32_t writeable();

Telemetry를 사용하려면 다음 코드를 추가하기 만하면됩니다.

// At the beginning of main function, this is the ONLY code you have to add to support a new device with telemetry
TM_transport transport;
transport.read = read;
transport.write = write;
transport.readable = readable;
transport.writeable = writeable;

// Init telemetry with the transport structure
init_telemetry(&transport);  

// and you're good to start publishing
publish_i32("foobar",...

Python 라이브러리 PyPI 버전

데스크탑 측에는 pytelemetry프로토콜을 구현하는 모듈이 있습니다.

파이썬을 알고 있다면 다음 코드는 직렬 포트에 연결하고 topic에 한 번 게시하고 foo3 초 동안 수신 된 모든 주제 를 인쇄 한 다음 종료합니다.

import runner
import pytelemetry.pytelemetry as tm
import pytelemetry.transports.serialtransport as transports
import time

transport = transports.SerialTransport()
telemetry = tm.pytelemetry(transport)
app = runner.Runner(transport,telemetry)

def printer(topic, data):
    print(topic," : ", data)

options = dict()
options['port'] = "COM20"
options['baudrate'] = 9600

app.connect(options)

telemetry.subscribe(None, printer)
telemetry.publish('bar',1354,'int32')
time.sleep(3)

app.terminate()

파이썬을 모르는 경우 명령 줄 인터페이스를 사용할 수 있습니다.

Pytelemetry CLI PyPI 버전

명령 줄은 다음으로 시작할 수 있습니다.

pytlm

그럼 당신은 수 connect, ls(목록)받은 주제는, print데이터는 주제, 수신 pub, 주제에 (게시) 또는 열려 plot실시간으로 수신 된 데이터를 표시하는 주제에

여기에 이미지 설명 입력

여기에 이미지 설명 입력


You do not specify exactly how the microcontroller behaves, but will everything transmitted from the micro be a direct response to a command from the PC? If do then it seems like you can use a master/slave protocol of some kind (this will typically be the simplest solution). If both sides can initiate communication, you need a more general data link layer protocol. HDLC is a classic protocol for this. Although the full protocol probably is a overkill for your needs, you could for instance at least use the same frame format. You might also have a look at PPP to see if there are something useful parts.


maybe this question can be completely stupid but has anyone considered use of one of X/Y/Z MODEM protocols?

위의 프로토콜 중 하나를 사용하는 주요 이점은 다양한 프로그래밍 환경에서 즉시 사용할 수있는 구현의 뛰어난 가용성입니다.


SLIP 및 UDP. 진지하게.

모든 PC 및 유사한 장치가이를 말합니다.

TCP Lean 의 좋은 책과 예제가 있습니다.

Jeremy Bentham은 작동하는 TCP / IP를 수행하는 PIC를 몰래 얻었습니다. AVR은 PIC만큼 좋습니다.

대신 UDP를 권장합니다. 매우 쉽습니다.

참조 URL : https://stackoverflow.com/questions/815758/simple-serial-point-to-point-communication-protocol

반응형