전송 속도를 얼마나 높일 수 있습니까 (오류 없음)?


40

표준은 9600 보드입니다. 그것은 단지 표준 입니다. Arduino Uno SMD R2를 사용하면 달성 할 수있는 가장 높은 실제 전송 속도는 얼마입니까?

대담한 보너스 포인트 : 오류 검사 메커니즘을 만든 다음 전송 속도를 높이기 위해 엄청나게 높은 전송 속도를 올리려면 어떻게해야합니까?


1
FTDI USB 직렬 IC를 사용하는 Arduino 보드는 정말 빠를 수 있습니다. 일반적인 FT232는 문제없이 3 Megabaud (3,000,000 보드)를 사용할 수 있습니다. ATmega16U2의 사용이 제한 요인입니다.
코너 울프

eBay에서 얻은 클론 Arduino Nano는 1,099,999로 최대치에 도달했습니다. 진심으로. 그게했다. 1,100,000에 도달하면 출력이 깨졌습니다. laqq`na`fca`fga`fga`bcngaah````iin`ha`a`a`bga`fga`bcqpahhqfq```fh`oopa`bca`fca. USB 통신에 CH340 칩을 사용합니다.
PNDA

답변:


59

여기 몇 가지 요소가 있습니다.

  • ATmega328P MCU는 얼마나 높은 전송 속도를 달성 할 수 있습니까?
  • USB- 시리얼 인터페이스는 얼마나 높은 전송 속도를 달성 할 수 있습니까?
  • ATmega328P의 발진기 주파수는 무엇입니까?
  • USB 직렬 인터페이스의 발진기 주파수는 무엇입니까 (있는 경우)?
  • 전송 속도 불일치의 USB 직렬 인터페이스는 얼마나 허용됩니까?

이러한 모든 요소는 최대 달성 가능한 전송 속도를 결정하는 것과 관련이 있습니다. ATmega328P는 클럭 속도의 하드웨어 제수를 사용하여 직렬 인터페이스의 기본 클럭을 생성합니다. 메인 클럭과 원하는 전송 속도의 비트 시간에 대한 정수 비율이 없으면 MCU가 원하는 속도 를 정확하게 생성 할 수 없습니다 . 일부 장치는 다른 장치보다 전송 속도 불일치에 훨씬 민감하기 때문에 잠재적 인 문제가 발생할 수 있습니다.

FTDI 기반 인터페이스는 전송 속도 불일치에 대해 최대 몇 퍼센트의 오차를 허용합니다. 그러나 0.5 %의 전송 속도 오류도 처리 할 수없는 특수 내장 GPS 모듈을 사용했습니다.

일반 직렬 인터페이스는 ~ 5 % 전송 속도 오류를 허용합니다. 그러나 각 끝을 끌 수 있으므로 더 일반적인 사양은 + -2.5 %입니다. 이렇게하면 한쪽 끝이 2.5 % 빠르고 다른 쪽 끝이 2.5 % 느리면 전체 오류는 여전히 5 %에 ​​불과합니다.


어쨌든 Uno는 ATmega328P를 기본 MCU로 사용하고 ATmega16U2를 USB 직렬 인터페이스로 사용합니다. 또한이 두 MCU 모두 유사한 하드웨어 USART와 16Mhz 클럭을 사용한다는 점에서 운이 좋았습니다.

두 MCU 모두 동일한 하드웨어 및 클럭 속도를 갖기 때문에 동일한 방향으로 동일한 보드 속도 오류가 발생하므로 보드 오류 문제를 기능적으로 무시할 수 있습니다.

어쨌든,이 질문에 대한 "적절한"대답은 ATmega16U2의 소스를 파고 거기에서 가능한 전송 속도를 계산하는 것을 포함하지만, 게으 르기 때문에 간단하고 경험적인 테스트가 효과가있을 것입니다.

ATmega328P 데이터 시트를 간단히 살펴보면 다음 표가 생성됩니다.
여기에 이미지 설명을 입력하십시오

따라서 최대 명시된 전송 속도 2 Mbps를 감안할 때 빠른 테스트 프로그램을 작성했습니다.

void setup(){};

void loop()
{

  delay(1000);
  Serial.begin(57600);
  Serial.println("\r\rBaud-rate = 57600");
  delay(1000);
  Serial.begin(76800);
  Serial.println("\r\rBaud-rate = 76800");
  delay(1000);
  Serial.begin(115200);
  Serial.println("\r\rBaud-rate = 115200");
  delay(1000);
  Serial.begin(230400);
  Serial.println("\r\rBaud-rate = 230400");
  delay(1000);
  Serial.begin(250000);
  Serial.println("\r\rBaud-rate = 250000");
  delay(1000);
  Serial.begin(500000);
  Serial.println("\r\rBaud-rate = 500000");
  delay(1000);
  Serial.begin(1000000);
  Serial.println("\r\rBaud-rate = 1000000");
  delay(1000);
  Serial.begin(2000000);
  Serial.println("\r\rBaud-rate = 2000000");
};

그런 다음 직렬 터미널이있는 관련 직렬 포트를 살펴보십시오.

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

따라서 하드웨어가 문제없이 2,000,000 보드에서 실행될 수있는 것으로 보입니다.

이 전송 속도 는 바이트 당 MCU 64 80 클럭 사이클 만 제공 하므로 직렬 인터페이스를 사용 중으로 유지하는 것은 매우 어려울 수 있습니다. 개별 바이트가 매우 빠르게 전송 될 수 있지만 인터페이스가 단순히 유휴 상태 인 경우 많은 시간이 걸릴 수 있습니다.


편집 : 실제 테스트!

2Mbps는 실제입니다.
여기에 이미지 설명을 입력하십시오
각 비트 시간은 500ns이며 예상되는 것과 정확히 일치합니다.

성능 문제! 전체 패킷 길이 :
500 Kbaud : 여기에 이미지 설명을 입력하십시오

1 Mbaud : 여기에 이미지 설명을 입력하십시오

2MBaud의 : 여기에 이미지 설명을 입력하십시오
참고 : 눈에 띄는 오버 슈트가 좋지 스코프 프로브 접지 관행에 기인하고, 아마 진짜. 내 스코프 프로브의 일부인 접지 클립 리드를 사용하고 있으며 리드 인덕턴스가 오버 슈트의 대부분의 원인 일 수 있습니다.

보다시피, 전체 전송 길이는 0.5, 1 및 2 Mbaud에서 동일합니다. 직렬 버퍼에 바이트를 배치하는 코드가 제대로 최적화되지 않았기 때문입니다. 따라서 자체 직렬 라이브러리를 작성하지 않는 한 효과적인 500 Kbaud 보다 더 나은 것을 달성하지 못할 것 입니다. Arduino 라이브러리는 최적화가 잘되어 있지 않기 때문에 버스트 전송에 약간의 시간을 투자한다면 적절한 2Mbaud를 얻는 것이 그리 어렵지 않을 것입니다 .


4
처리량 제한의 멋진 그림!
jippie

1
@AnnonomusPerson-20Mhz 클럭으로 전환하면 2.5Mbps를 수행 할 수 있습니다.
코너 울프

1
@AnnonomusPerson-20Mhz ATmega328P 발진기와 함께 FTDI USB 직렬 인터페이스를 사용해야합니다. ATmega328P는 20Mhz 크리스털 / 공진기가 없으면 2.5Mbps를 수행 할 수 없습니다. 모든 ATmega16U2 인터페이스도 마찬가지입니다.
코너 울프

1
좋은 답변입니다! 단지 하나의 작은 수정 : 2Mb / s에서 각 바이트 전송에는 64 개가 아닌 80 개의 CPU 사이클이 필요합니다. 이는 시간별 각 바이트의 가치가 10 비트 (1 개 시작, 8 개 데이터, 1 개 정지)이기 때문입니다.
Edgar Bonet

1
@ linhartr22-전선 은 12 "+와 같이 경우에만 실제로 작동합니다 . 너무 많은 사람들이 100 피트 길이의 케이블을 너무 많이 사용하지는 않을 것입니다. 게다가, 문제는 arduino / ATmega의 높이가 임의의 케이블 어셈블리가 아무리 높아도 전송 속도는
Connor Wolf

7

Arduino Serial Monitor 창은 115200으로 제한하지만 최고 전송 속도는 아닙니다. Atmel 및 FT232 (또는 사용중인 모든) 데이터 시트를 읽어 최대 값을 확인할 수 있지만 문제없이 230400 (Arduino 직렬 모니터가 지원하는 최대 속도의 두 배)을 성공적으로 사용할 수 있습니다.

컴퓨터에서 결과를 보려면 다른 전송 속도 옵션을 지원하는 다른 직렬 모니터가 필요합니다. 나는 CoolTermTermite를 좋아한다 .

이것은 클럭 속도에 따라 크게 달라집니다.

가능한 계산 에 도움이되는 계산기가 있습니다.


점점 더 빨라지기 시작하면 제한이 직렬 라이브러리가됩니다. 구현은 그다지 효율적이지 않습니다.
Cybergibbons

링크의 웹 사이트가 죽었습니다
Codebeat

3

이것은 아마도 el-Cheapo 보드가 원래 보드와 다른 몇 가지 측면 중 하나 일 것입니다. 최대 직렬 전송 속도는 보드의 품질과 레이아웃에 의해서만 제한됩니다. 직렬 데이터가 AVR 또는 USB 인터페이스 칩에 입력되면 직렬 UART 프로토콜과 다르게 처리됩니다.

마이크로 컨트롤러에는 직렬 데이터를 IO 핀으로주고받을 수있는 기본 하드웨어가 있지만 절대 최대 속도는 16MHz 클럭 (AVR의 경우)으로 제한됩니다. 바이트가 직렬 버퍼로 이동되면 UART 하드웨어가 자체적으로 비트를 인계 / 풀인합니다. AVR은 초당 최대 16M 명령에 도달하고 직렬 버퍼를 채우는 데 사용되는 인터럽트에는 약간의 오버 헤드가 있습니다 (인터럽트 처리를위한 최소 8 클럭 틱 + 현재 상태를 저장하기위한 명령 + 실제로 버퍼를 채우기위한 몇 가지 명령). 지정된 비트 전송률에서 프로토콜은 초당 n 비트의 무려 n 비트에서 실행되지만 컨트롤러는 실제로 데이터를 출력하는 데 필요한 것보다 직렬 버퍼를 채우는 데 더 많은 시간이 필요하므로 예상보다 낮은 평균 처리량과 UART 유휴 비교적 오랫동안.

기억해야 할 또 다른 효과는 데이터를 UART로 푸시 (또는 가져 오기)하는 데 필요한 모든 오버 헤드를 실제 프로그램에서 사용할 수 없으므로 평균 실제 처리량에 다시 영향을줍니다. 버퍼를 채우거나 메인 루프를 계산하기 위해 모든 명령어 사이클을 한 번만 사용할 수 있습니다.

따라서 최대 처리량은 사용하는 응용 프로그램에 따라 (직렬 버퍼에서 데이터를 빠르게 생성 / 계산 / 준비 할 수있는 속도) 실제 '물리적'비트 전송률은 설계 결정의 일부에 지나지 않습니다.


1
실제로 2Mhz 신호가 제대로 작동하지 않도록 레이아웃 문제가 심각한 보드가 있는지 의심합니다. 2Mhz는 정확히 고주파수는 아닙니다.
코너 울프

@FakeName 직렬 속도를 누를 때 책상에있는 보드 중 하나 이상이 BER을 증가 시켰습니다. 나는 보통 9600을 사용하는데, 이는 대부분의 어플리케이션에 충분하고 강력합니다.
jippie

농담 아니야! 허. 레이아웃이 얼마나 나쁜지 궁금합니다. 그래도 허용 오차 공진기 / 수정만큼 레이아웃이 아닌 것으로 의심됩니다.
코너 울프

1
특히 U2Xn = 1USART의 경우 높은 전송 속도 는 불일치에 대해 꽤 까다로운 경향이 있습니다.
코너 울프

@FakeName 나는 공룡, 나는 당신이 생각할 수있는 모든 잘못된 유산 때문에 "9600 8N1"과 비슷하다; o)
jippie

2

오류 검사는 실제로 매우 쉽고 하나의 라이너에 AVR 라이브러리가 있습니다.

계속 읽어 util/crc16.h보면 포함 된 예제를 사용하여 바로 갈 수 있습니다.

CRC는 간단한 응용 프로그램을 위해 매우 강력하고 빠릅니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.