Какую скорость передачи данных com порта можно использовать без ошибок?

Стандарт составляет 9600 бод. Это просто стандарт. Используя Arduino Uno SMD R2, какой максимальной практической скорости передачи данных я могу достичь?

Бонусные баллы для смелых: как бы вы поступили, создав механизм проверки ошибок, а затем увеличив скорость передачи данных высоко, чтобы получить высокие скорости передачи?

, 👍57

Обсуждение

Стоит отметить, что платы Arduino, использующие FTDI USB-последовательные микросхемы, могут работать ОЧЕНЬ быстро. Обычный FT232 может передавать 3 Мегабод (это 3 000 000 бод) без проблем. Использование ATmega16U2 является ограничивающим фактором., @Connor Wolf

Мой клон Arduino Nano, который я получил с eBay, превысил 1 099 999 долларов. Серьезно. Так оно и было. Как только он достиг 1 100 000, результат был искажен. лакк'на'фка'фга'фга'бкнгаа иин'ха'а'бга'фга'бккпаххкфк "фх'оопа'бка'фка`. Он использует чип CH340 для USB-связи., @PNDA


5 ответов


Лучший ответ:

80

Здесь есть несколько факторов:

  • Какой высокой скорости передачи данных может достичь микроконтроллер ATmega328P?
  • Какой высокой скорости передачи данных может достичь USB-последовательный интерфейс?
  • Какова частота генератора на ATmega328P?
  • Какова частота генератора на USB-последовательном интерфейсе (если он есть)?
  • Насколько устойчив интерфейс USB-serial к несоответствию скорости передачи данных в бодах?

Все эти факторы имеют отношение к определению максимально достижимой скорости передачи данных в бодах. ATmega328P использует аппаратный делитель своей тактовой частоты для генерации базовой тактовой частоты для последовательного интерфейса. Если нет целочисленного отношения от основного тактового сигнала к битовому времени желаемой скорости передачи в бодах, микроконтроллер не сможет точно выдать желаемую скорость. Это может привести к потенциальным проблемам, поскольку некоторые устройства гораздо более чувствительны к несоответствию скорости передачи данных, чем другие.

Интерфейсы на основе FTDI достаточно устойчивы к несоответствию скорости передачи данных, вплоть до ошибки в несколько процентов. Однако я работал со специализированными встроенными модулями GPS, которые не могли справиться даже с ошибкой скорости передачи данных в бодах 0,5%.

Общие последовательные интерфейсы допускают погрешность в скорости передачи данных ~5%. Однако, поскольку каждый конец может быть выключен, более распространенная спецификация составляет +-2,5%. Таким образом, если один конец работает на 2,5% быстрее, а другой - на 2,5% медленнее, ваша общая ошибка по-прежнему составляет всего 5%.


В любом случае. Uno использует ATmega328P в качестве основного MCU и ATmega16U2 в качестве USB-последовательного интерфейса. Нам также повезло в том, что оба этих микроконтроллера используют похожие интерфейсы harware USART, а также тактовые частоты 16 МГц.

Поскольку оба микроконтроллера имеют одинаковое программное обеспечение и тактовую частоту, они оба будут иметь одинаковую ошибку скорости передачи в одном и том же направлении, поэтому мы можем функционально игнорировать проблему с ошибкой в бодах.

В любом случае, "правильный" ответ на этот вопрос будет включать в себя поиск источника для ATmega16U2 и определение возможных скоростей передачи оттуда, но поскольку я ленив, я полагаю, что простое эмпирическое тестирование будет работать.

Беглый взгляд на спецификацию ATmega328P приводит к следующей таблице:

Поэтому, учитывая максимальную заявленную скорость передачи данных в бодах 2 Мбит / с, я написал быструю тестовую программу:

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 тактов на байт, поэтому было бы очень сложно поддерживать занятость последовательного интерфейса. Хотя отдельные байты могут передаваться очень быстро, вероятно, пройдет много времени, когда интерфейс просто простаивает.


Редактировать: Фактическое тестирование!

Скорость 2 Мбит / с вполне реальна:

каждое битовое время составляет 500 нс, что в точности соответствует ожидаемому.

Проблемы с производительностью! Общая длина пакета:
500 Кбод:

1 Мбод:

2 Мбод:
Примечание: Заметное превышение происходит из-за плохой практики заземления зонда и, вероятно, не является реальным. Я использую провод заземления, который является частью моего оптического зонда, и индуктивность провода, вероятно, является причиной большинства перерегулирований.

Как вы можете видеть, общая длина передачи одинакова для 0,5, 1 и 2 Мбод. Это происходит потому, что код, который помещает байты в последовательный буфер, плохо оптимизирован. Таким образом, вы никогда не добьетесь ничего лучшего, чем эффективные 500 Кбод, если только не напишете свои собственные последовательные библиотеки. Библиотеки Arduino очень плохо оптимизированы, поэтому, вероятно, было бы не слишком сложно получить правильные 2 Мбод, по крайней мере, для пакетной передачи, если вы потратили на это немного времени.

,

Хорошая иллюстрация ограничения пропускной способности!, @jippie

@jippie - у меня был включен scope, и в моем ответе я запускал программу, которая циклически меняет скорость передачи данных. Это было очень мало дополнительной работы, и она довольно хорошо иллюстрирует проблему. Кроме того, сегментированная память в моем прицеле просто потрясающая., @Connor Wolf

Серия DS2000? Действительно ли снижение битрейта до 250 КБ удваивает время передачи? Я думаю, что я все еще могу легко определить начальные / стоп-биты в изображении размером 500 КБ., @jippie

@jippie - серия 4000. Я люблю свои 4 канала., @Connor Wolf

Если вы пропустите последовательную библиотеку, вы сможете работать намного быстрее., @Cybergibbons

@Cybergibbons - Ага. См. Примечание в конце об оптимизации., @Connor Wolf

Вау, я думал, что скорость передачи данных 9600 бод довольно хороша для устройства AVR, но я никогда не ожидал 2 МБИТ / с!, @Anonymous Penguin

@AnnonomusPerson - Если вы переключитесь на тактовую частоту 20 Мгц, вы сможете развивать скорость 2,5 Мбит / с., @Connor Wolf

@FakeName основной кристалл 20 МГц или на USB-чипе?, @Anonymous Penguin

@AnnonomusPerson - Вам нужно будет поменять местами оба или использовать usb-последовательный интерфейс FTDI с генератором ATmega328P с частотой 20 МГц. ATmega328P не может развивать скорость 2,5 Мбит / с без кристалла / резонатора 20 МГц. То же самое верно для любых интерфейсов ATmega16U2., @Connor Wolf

Отличный ответ! Только одна небольшая поправка: при скорости 2 Мб / с передача каждого байта занимает 80 циклов процессора, а не 64. Это связано с тем, что с точки зрения времени каждый байт равен 10 битам (1 начало, 8 данных, 1 остановка)., @Edgar Bonet

@EdgarBonet - Вы совершенно правы (и упс). Исправлено., @Connor Wolf

Это отличный ответ, за одним исключением, поскольку он не учитывает влияние физического носителя (провода / кабеля, используемого для подключения к другому устройству). Это также будет основным фактором, ограничивающим полезную скорость передачи данных в бодах. Последовательная связь довольно скучна только с одним устройством (включая loopback). :: усмешка::, @linhartr22

@linhartr22 - Провода действительно вступают в игру, только если они * длинные *, например, 12 "+. Я думаю, что, вероятно, маловероятно, что слишком много людей слишком часто используют кабели длиной 100 футов. Кроме того, вопрос заключался в том, насколько высокой может быть скорость передачи данных ** arduino / ATmega **, а не в том, насколько высокой может быть произвольная кабельная сборка., @Connor Wolf

@ConnorWolf, я не знаю, согласен ли я на 100% с этим утверждением: "Поскольку оба микроконтроллера имеют одинаковое программное обеспечение и тактовую частоту, они оба будут иметь одинаковую ошибку скорости передачи в одном и том же направлении, поэтому мы можем функционально игнорировать проблему с ошибкой в бодах". Я не понимаю, как один и тот же UART гарантирует ошибку в одном и том же направлении, поскольку отдельные чипы все равно могут меняться случайным образом, верно? - и хотя у обоих чипов одинаковая частота, что означает, что ошибка вычисления последовательной частоты находится в одном и том же направлении, я знаю, что чипы не используют один и тот же источник синхронизации (16U2 использует кристалл, 328 использует отдельный керамический генератор)., @Gabriel Staples

@GabrielStaples - Вы упускаете ошибку, о которой я говорю. По сути, способ работы ATmega UART заключается в том, что они используют целочисленный делитель из часов MCU для генерации последовательной синхронизации. Таким образом, некоторые скорости передачи данных в бодах не могут быть достигнуты напрямую, поскольку отношение между скоростью передачи данных в бодах и системными тактовыми часами не является целым числом. Как правило, в этой ситуации выбирается * ближайший вариант *, что приводит к ошибке, о которой я здесь говорю (abs(ближайший вариант - target baud) = err). ** Эта ошибка ** будет сопоставлена между двумя разными частями., @Connor Wolf

Хотя микросхемы могут различаться, работа UART детерминирована, поэтому, если вы управляете двумя частями с одним и тем же источником синхронизации, вы получите одинаковые выходные сигналы (за вычетом небольшого потенциального дрожания)., @Connor Wolf

@ConnorWolf, я понимаю, так что это подразумевает, что если вы хотите максимизировать возможность обмена данными между двумя устройствами с очень высокой скоростью передачи данных, поскольку это асинхронная связь, вы должны заставить их обоих использовать одни и те же тактовые частоты, чтобы их фактические скорости передачи данных были искажены одинаково направление, тем самым лучше выравнивая их битовую синхронизацию? Это правильно? ie: Arduino 16 МГц с устройством USB-UART 16 МГц лучше, чем Arduino 16 МГц с устройством USB-UART 20 МГц?, @Gabriel Staples

По сути, проблема заключается в том, что у вас есть MCU с тактовой частотой 20 МГц, вы можете получить ошибку -1,5% от делителя скорости передачи * и * дисперсия генератора может составлять -1%. Затем, если вы разговариваете с микроконтроллером с osc 16 МГц, который выдает ошибку делителя + 2% и ошибку генератора + 1,5%, все ваши ошибки в сумме составляют 5%. Однако, если вы используете одну и ту же опорную частоту генератора, ошибки делителя скорости передачи совпадают, поэтому они компенсируются, и единственным релевантным фактором становится ошибка генератора., @Connor Wolf

Редактировать: Да, у вас это есть. Однако логика генерации скорости передачи данных зависит от конкретного устройства / линейки устройств, поэтому сравнение между различными производителями может быть сложным., @Connor Wolf

Теперь я понимаю. Я только что проверил спецификацию ATmega328. Вот [еще одна таблица](http://i.stack.imgur.com/muABX.png ) (из стр. 175) возможно, вы захотите добавить свой ответ под первым. Это помогает рассчитать скорость передачи данных в бодах, чтобы проверить их ошибки в таблице, и мне становится ясно, как они получили свои ошибки. Например, 115,2k показывает ошибку -3,5% для асинхронного нормального режима (U2Xn = 0). Формула выглядит следующим образом: 16e6/(16*(8+1)) = 111111.11 бпс. Это самый близкий вариант. Итак, ошибка составляет 111111,11/115200 = 0,9645 = -3,5%., @Gabriel Staples

Забавно, что передача данных со скоростью 1 Мбит/с и 2 Мбит/ с займет одинаковое время. Это из-за того, что байты копируются недостаточно быстро? Это также может означать, что вы не сможете получать байты с такой скоростью. Конечно, вы можете получить 1 байт со скоростью 2 Мбод, но для получения нескольких байтов это зависит от того, насколько быстро Arduino очищает последовательный буфер (и, следовательно, может быть получен еще один байт)., @Paul

@Paul - arduino ничего не делает. ** ATmega328P **, с другой стороны, делает много вещей. В любом случае, проблемы с пропускной способностью зависят от эффективности скорости обработки прерываний передачи. Как правило, код в библиотеках arduino по умолчанию, ну, действительно низкого качества. Должна быть вполне возможна насыщенность последовательной линии связи, по крайней мере, короткими очередями., @Connor Wolf

Считаете ли вы, что добавление противооткатных колпачков (~ 10-2pf) к земле может повысить стабильность?, @tuskiomi

@tuskiomi - Что? Нет, проблема в индуктивности провода заземления, который является частью моего оптического зонда. Правильное решение - использовать [заземление наконечника зонда] (https://electronics.stackexchange.com/a/40421/1374 ), но если вы специально не пытаетесь измерить такие вещи, как время подъема, пока вы знаете, что звонок ненастоящий, это не является существенной проблемой., @Connor Wolf

@ConnorWolf Я не уверен. например, на [моем question](https://arduinoprosto.ru/q/41661/arduino-due-not-properly-detecting-sd-card) , конденсаторы сводили на нет большую часть скачков напряжения, чего не произошло бы, если бы это был зонд., @tuskiomi

@tuskiomi - Этого следовало ожидать, поскольку конденсаторы замедляют граничную скорость, что означает, что индуктивность зажима заземления оказывает меньшее влияние. Дело в том, что всплеск 1. не вреден, 2. в подавляющем большинстве случаев на самом деле не реален, а скорее является артефактом измерения. Кроме того, во всяком случае, конденсаторы * хуже * для схемы, поскольку они являются нагрузкой непосредственно на выходные драйверы микросхемы, управляющей шиной. В общем, существует ** очень** мало случаев, когда вы когда-либо захотите * добавить* емкость к шине данных., @Connor Wolf

В принципе, прежде чем начать повсюду наклеивать конденсаторы, [научитесь пользоваться своим наконечником ground](https://electronics.stackexchange.com/questions/40420/what-is-the-name-of-this-springy-type-oscilloscope-probe-accessory/40421#40421) , и сверьтесь с этим. [Здесь](http://teledynelecroy.com/doc/passive-probe-ground-lead-effects ) - это белая книга Теледайн Лекрой по этой теме. [Здесь](http://web.mit.edu/6.101/www/reference/ABCprobes_s.pdf ) - еще один от Tektronix., @Connor Wolf

Помните, что даже если ваша скорость передачи данных относительно низкая, именно * граничная скорость * определяет влияние индуктивности провода заземления, а не граничная частота. Даже медленные маленькие устройства, такие как микросхемы ATmega, могут создавать довольно быстрые края., @Connor Wolf

Существует также проблема [керамического резонатора] (https://en.wikipedia.org/wiki/Ceramic_resonator), используемого для часов MCU на некоторых Arduinos, например [Arduino Uno] (http://arduino.cc/en). /Main/ArduinoBoardUno) (технически они не лежат на странице товара, но [кварцевый осциллятор](https://en.wikipedia.org/wiki/Crystal_oscillator) используется ***только*** для USB вспомогательный MCU, а не основной микроконтроллер). Это вносит погрешность до 0,5%. Это может быть или не быть значительным, в зависимости от обстоятельств (например, при использовании второго последовательного порта). Возможно, это также будет отражено в ответе?, @Peter Mortensen

Ошибка накапливается, так что время последнего бита уже может быть сбито почти на 5% из-за керамического резонатора. Сколько можно терпеть в качестве накопленной ошибки? 8%?, @Peter Mortensen


9

Окно последовательного монитора Arduino ограничивает вас до 115200, но это не самая высокая скорость передачи данных. Вы можете прочитать спецификации Atmel и FT232 (или что бы вы ни использовали), чтобы узнать максимум, но я могу успешно использовать 230400 (в два раза быстрее, чем самый большой, который поддерживает последовательный монитор Arduino) без проблем.

Если вы хотите просмотреть результаты на своем компьютере, вам понадобится другой последовательный монитор, поддерживающий другие параметры скорости передачи данных в бодах. Мне нравятся CoolTerm и Termite.

Обратите внимание, что это также сильно зависит от вашей тактовой частоты.

Вот калькулятор, который поможет вам рассчитать, что возможно.

,

По мере того, как вы начинаете работать все быстрее и быстрее, ограничением становится последовательная библиотека - ее реализация не очень эффективна., @Cybergibbons

сайт ссылки мертв, @Codebeat

"Окно последовательного монитора Arduino ограничивает вас до 115200", - это уже не так. Скорость передачи данных достигает 2 Мбит/с, @Thomas Weller


3

Это, вероятно, один из немногих аспектов, в котором платы el-Cheapo отличаются от оригинальных плат. Максимальная скорость последовательной передачи данных в значительной степени ограничена только качеством платы и ее компоновкой. Как только последовательные данные поступают на микросхему интерфейса AVR или USB, обработка данных будет отличаться от последовательного протокола UART.

Имейте в виду, однако, что микроконтроллер имеет некоторое базовое оборудование для передачи последовательных данных ввода-вывода на/с выводов ввода-вывода, но абсолютная максимальная частота ограничена тактовой частотой 16 МГц (для AVR). Как только байт перемещается в последовательный буфер, аппаратное обеспечение UART берет верх и выталкивает/втягивает биты самостоятельно. AVR в лучшем случае достигает 16 миллионов команд в секунду, а прерывания, используемые для заполнения последовательного буфера, имеют некоторые накладные расходы (по крайней мере, 8 тактов для обработки прерывания + инструкции для сохранения текущего состояния + несколько инструкций для фактического заполнения буфера). При заданном битрейте протокол будет работать со скоростью целых n бит в секунду, но вашему контроллеру требуется больше времени для заполнения последовательного буфера, чем для фактического вывода данных, что приводит к более низкой средней пропускной способности, чем вы ожидаете, и к относительно длительному бездействию UART. Недостатком является повышенная вероятность битовых ошибок.

Еще один эффект, о котором следует помнить, заключается в том, что все накладные расходы, необходимые для передачи данных в UART (или их извлечения), не могут быть потрачены в вашей реальной программе, что снова влияет на среднюю практическую пропускную способность. Вы можете использовать каждый цикл команд только один раз, либо для заполнения буфера, либо для вычисления основного цикла.

Таким образом, максимальная пропускная способность зависит от используемого вами приложения (насколько быстро генерируются / вычисляются / готовы к перемещению в / из последовательного буфера данные), а фактический "физический" битрейт является лишь небольшой частью проектного решения.

,

Я очень, ОЧЕНЬ сомневаюсь, что какая-либо из существующих плат имеет проблемы с компоновкой, достаточно серьезные, чтобы сигнал 2 МГц не работал нормально. 2 МГц - это не совсем высокая частота., @Connor Wolf

@FakeName По крайней мере, одна плата на моем столе здесь увеличила BER, когда я нажимаю последовательную скорость. Обычно я использую 9600, этого более чем достаточно для большинства приложений и является надежным., @jippie

Без шуток! Хм. Интересно, насколько плохой должна быть планировка, чтобы это произошло? Однако я бы заподозрил, что дело не столько в компоновке, сколько в резонаторах / кристаллах с плохим допуском., @Connor Wolf

Высокие скорости передачи данных в бодах, особенно если U2Xn = 1 в USART, как правило, вызывают недовольство несоответствием., @Connor Wolf

@FakeName Я динозавр, мне вроде как нравится "9600 8N1" по всем неправильным причинам устаревания, которые вы можете придумать; о), @jippie

Черт возьми, я сам использую 9600 для большинства отладочных работ. Дело не только в тебе. Просто иногда мне нужно распространять * много * данных, и важно знать пределы., @Connor Wolf

Я не удивлюсь, если увеличение BER связано с дешевым поддельным серийным чипом. (Подделка FTDI) @ConnorWolf, @jippie


3

Проверка ошибок на самом деле очень проста, и есть библиотека AVR, которая делает это в один лайнер.

Ознакомьтесь с util/crc16.h, и вы должны быть готовы в кратчайшие сроки ознакомиться с прилагаемыми примерами.

CRC достаточно надежен и быстр для простых приложений.

,

-5

Самая высокая скорость передачи данных в бодах - это прицеп трактора, набитый магнитными лентами.

Ленточные картриджи для хранения данных имеют размеры 102 x 105,4 x 21,5 мм и вмещают до 18 ТБ в несжатом виде:

https://www.fujifilm.com/us/en/business/data-storage/data-storage-media/lto-ultrium-9/specifications

Большой грузовик вмещает 45 000 фунтов и имеет размеры около 100 "X 100"X 600".

https://streamlogistics.com/trailer-dimensions /

Коробка из 20 лент весит 10,5 фунтов, и я оцениваю примерно 10 "X 10"X 5", так что получается примерно 10 картонных коробок, по 10 картонных коробок на 120 картонных коробок или максимум 12 000 картонных коробок. Но это был бы избыточный вес, поэтому максимум составляет около 4000 картонных коробок (оставляя некоторый вес для поддонов и упаковочного материала).

Таким образом, грузовик может вместить 18 Тб X 20 / коробка X 4000 картонных коробок = 1 440 000 ТБ в несжатом виде.

Если грузовик едет из Нью-Йорка в Сан-Франциско, это займет около 42 часов езды. Это предполагает, что несколько водителей могут отказаться от вождения. На одного водителя ушло бы примерно в 3 раза больше времени. 42 часа - это 151 200 секунд. Таким образом, максимальная скорость передачи данных в бодах (при условии 9 бит на бит для проверки четности) = 85,7 Терабод по пересеченной местности для нескольких драйверов и 28,6 Терабод для одного драйвера. Если контейнер придется перевозить на лодке, это будет намного медленнее, но все же на несколько терабод. И практически никаких ошибок!

,

Каким образом это даже отдаленно имеет какое-либо отношение к связи UART на Arduino?, @Majenko

Связанный: *[Почему мне нужно 50 репутации, чтобы комментировать? Что я могу сделать вместо этого?](https://meta.stackexchange.com/questions/214173/)*., @Peter Mortensen