문제

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

어야 하는 데이터 소음을 보호 (외에 패리티 체크,내가 생각하기에 필요한 다른 데이터 보정 방법).

가 어떤 표준 솔루션을까요?(나만 생각하지 완벽한 솔루션).

P.S.한 조언에 감사드립니다. P.P.S Sorry 에 대한 모든 문법 실수를,나는 당신이 이해한다.

편집 1. 내가 결정하지 못했을 것입니다 여부 마스터/슬레이브 프로토콜쪽 또는 양쪽을 시작할 수 있는 통신입니다.PC 알고 있어야 합니다 마이크로가 수행하는 작업과 데이터를 보낼 수 있습니다.그것은 지속적으로 폴 마이크로 데이터가 준비 또는 마이크로 데이터를 전송할 때는 작업이 수행됩니다.나는 알 수 없는 더 나은,더 간단합니다.

편집 2. 웨어와 하드웨어 물리적 레이어 프로토콜입니다.RS-232C serial 표준 PC 에서 사용,내가 사용하는 것입 asynchronous communication.나만을 사용하 RxD,TxD 및 접지 신호가 있습니다.나는 사용할 수 없기 때문에 추가 철사 마이크로컨트롤러 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가 패킷을 수신했다고 응답합니다. 그렇지 않으면 센서 장치가 타임 아웃에서 재현 할 수 있습니다.

또한 네트워크 전송을 수행 할 때는 다음과 같은 네트워크 스택으로 설계해야합니다. OSI MODLE ~처럼 Foredecker 포인트는 잊지 않습니다 물리적 층 물건. HDLC와의 내 게시물입니다 데이터 링크 계층 그리고 RPC 및 명령 처리는 응용 프로그램 계층입니다.

다른 팁

RS232 프로토콜은 까다 롭습니다. HDLC를 사용하라는 제안은 좋은 것이지만 전체 솔루션은 아닙니다. 결정해야 할 다른 것들이 있습니다.

  • 두 장치 간의 보드 속도는 어떻게 결정됩니까? 오토 부드? 사전 정의 또는 세트 설명?
  • 소프트웨어 나 하드웨어 또는 둘 다에서 흐름 제어를 하시겠습니까? 하드웨어 흐름 제어를 사용하면 ~ 해야 하다 케이블이 올바르게 제작되었는지 확인하십시오.
  • 케이블에 대해 말하면, 이것은 RS233의 큰 고통입니다. 장치에 따라 스트레이트 케이블 또는 크로스 오버 케이블 또는 변형을 사용해야 할 수도 있습니다.
  • 소프트웨어 기반 흐름 제어 메커니즘을 사용하면 가장 간단한 케이블을 사용할 수 있으므로 3 개의 유선 (TX, RX 및 COMMON) 만 사용할 수 있습니다.
  • 당신은 7 또는 8 비트 단어를 선택합니까?
  • HW 패리티 또는 소프트웨어 오류 확인.

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

여기에는 몇 가지 좋은 답변이 있습니다. 여기에 유용한 포인터가 있습니다.

패킷이 시간을 분리하지 않더라도 동기화 바이트는 패킷을 구성하는 데 필요한 장소의 수를 줄이는 데 필수적인 방법입니다. 장치는 종종 많은 정크 데이터를 다루어야합니다 (예 : 비행 중에 패킷의 끝이 켜져 있거나 하드웨어 충돌이 발생 함). 동기화 바이트가 없으면받는 모든 바이트에서 패킷을 만들어야합니다. 동기화 바이트는 1/255 바이트의 임의 노이즈 만 패킷의 첫 바이트가 될 수 있음을 의미합니다. 프로토콜에서 스누핑하고 싶을 때도 환상적입니다.

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

오류 수정을 조사하고 싶을 수도 있습니다 (예 : 해밍). 8 비트의 데이터를 12 비트 보호 바이트에 포장합니다. 이 12 비트 중 하나는 경로를 뒤집을 수 있고 원래 8 비트를 검색 할 수 있습니다. 데이터 저장 (CDS에서 사용) 또는 장치가 쉽게 다시 제출할 수없는 경우 (위성 링크, 일방 통행 RF)에 유용합니다.

패킷 번호는 삶을 더 쉽게 만듭니다. 전송 된 패킷은 숫자를 가지고 있으며, 응답에는 "응답"이라는 깃발과 같은 숫자를 가지고 있습니다. 즉, 도착하지 않은 패킷 (Sync Insupted Say)은 발신자가 쉽게 감지하고 느린 링크가있는 전이중 모드에서는 첫 번째 응답을 받기 전에 두 개의 명령을 전송할 수 있습니다. 이로 인해 프로토콜 분석이 더 쉬워집니다 (제 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 정지 비트, 패리티 없음)을 수정했지만 보드 속도를 열어 두었습니다. 각 프레임은 바이너리에서 1010101010 인 3 개의 0xAA 바이트로 시작합니다. 1010101010, 한쪽 끝이 다른쪽에 동적으로 적응하기를 원할 경우 Autobaud rate 감지를 수행하는 멋진 펄셋 레인입니다. 프레임은 16 비트 플레처의 체크섬과 제어 바이트 및 8 비트 식별자 (페이로드 데이터에 포함 된 내용을 알리기 위해)와 함께 0-15 바이트의 페이로드입니다.

이 프로토콜은 캐릭터 스터핑을 사용하여 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 에 대한 간단하 모니터링 및 제어(평가 버전은 무료입니다).

더 오류를 확인하고,가장 간단하는 패리티 체크,또는 당신이 무언가를 필요로 하는 경우에 더 강력하고,어쩌면 나선형 코딩.

어떤 경우에,당신이 무엇을 할: 간단하게 유지한다.

편집: 를 사용하여 RS232PC 도 쉽게 사용할 수 있듯이,지금 USB to RS232/TTL 컨버터입니다.한쪽 끝로 PC 의 USB 소켓으로 나타납니다 일반 직렬 포트;기타 오 5V or3.3V 신호를 연결할 수 있는 바로 귀하의 프로세서 없이 수준의 변화 필요합니다.

우리가 사용하는 TTL-232R-3 대 3 에서 FDTI 칩,이는 작품을 위해 완벽하게 이런 종류 응용 프로그램입니다.

내 유일한 제안은 소음 내성이 필요한 경우 전이중 RS-422/485를 사용하고 싶을 수도 있습니다. 유사한 IC를 사용할 수 있습니다 이것 AVR 쪽에서는 PC 쪽의 RS-232-> RS-422 컨버터 여기 485ptbr. 차폐 케이블 (2 개의 꼬인 차폐 쌍)을 찾거나 만들 수 있다면 더 많은 보호 기능이 있습니다. 그리고이 모든 것은 마이크로 및 PC에 보이지 않습니다. 소프트웨어는 변경되지 않습니다.

당신이 무엇을하든, 당신은 당신이 전체 이중 시스템을 사용하고 있는지 확인하고 IC에서 읽기/쓰기 활성화 라인이 주장되어 있는지 확인하십시오.

당신은 볼 수 있습니다 Telemetry Python에서 관련 데스크탑 구현 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 version

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();

원격 측정을 사용하려면 다음 코드를 추가하면됩니다.

// 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",...

파이썬 라이브러리 PyPI version

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

Python을 알고 있다면 다음 코드는 직렬 포트에 연결하고 주제에 한 번 게시합니다. foo, 3 초 동안받은 모든 주제를 인쇄 한 다음 종료됩니다.

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()

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

pytelemetry cli PyPI version

명령 줄은 시작할 수 있습니다

pytlm

그럼 당신은 할 수 있습니다 connect, ls(목록) 수신 주제, print 주제에 대해받은 데이터, pub(게시) 주제에 대해 또는 plot 수신 된 데이터를 실시간으로 표시하는 주제

enter image description here

enter image description here

패리티 검사와 관련하여 (여기에 몇 번 등장 함) :

그들은 대부분 쓸모가 없습니다. 단일 비트가 오류로 변경 될 수 있다고 우려되면 두 번째 비트도 변경 될 가능성이 높으며 패리티 검사에서 잘못된 양의 긍정적이 될 가능성이 높습니다.

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

또한 생 바이너리보다는 인간 읽기 가능한 데이터를 전송하는 것이 좋습니다 (성능이 최우선 순위가 아닌 경우). 디버깅과 로그 파일이 훨씬 더 즐겁게 만듭니다.

마이크로 컨트롤러가 어떻게 행동하는지 정확히 지정하지는 않지만 마이크로에서 전송되는 모든 것이 PC의 명령에 대한 직접 응답이 될까요? 그렇다면 어떤 종류의 마스터/슬레이브 프로토콜을 사용할 수있는 것 같습니다 (일반적으로 가장 간단한 솔루션이 될 것입니다). 양측이 통신을 시작할 수 있다면보다 일반적인 데이터 링크 계층 프로토콜이 필요합니다. HDLC 이를위한 고전적인 프로토콜입니다. 전체 프로토콜은 아마도 귀하의 요구에 대한 과잉 일 것입니다. 예를 들어 최소한 동일한 프레임 형식을 사용할 수 있습니다. 당신은 또한 살펴볼 수도 있습니다 PPP 유용한 부분이 있는지 확인하기 위해.

어쩌면이 질문은 완전히 바보 일 수 있지만 누구나 x/y/z 모뎀 프로토콜?

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

슬립 및 UDP. 진지하게.

모든 PC와 유사한 장치가 말합니다.

좋은 책과 예가 있습니다 TCP 린

Jeremy Bentham은 TCP/IP 작업을 수행하는 사진을 몰래 얻었습니다. AVR은 그림만큼 좋습니까?

대신 UDP를 추천합니다. 매우 쉽습니다.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top