Скорость последовательной передачи в бодах меньше указанной

Я хочу прочитать значения выводов arduino и отправить их на ПК через USB-кабель. Проблема в том, что запись/чтение байтов происходит со скоростью, которая примерно в 10 раз меньше скорости передачи данных последовательного порта.

Я записываю 8 символов в последовательный "abcdefgh", а затем println добавляет еще два символа "\r\n", так что это 10 байт на строку (я отдельно проверил, что время чтения линейно зависит от количества байтов в строке). Вот мой код arduino для случая заданной скорости передачи данных = 9600.

void setup() {
  Serial.begin(9600);
}

void loop() {
  for (char c ='a'; c < 'h'; c++)
    Serial.print(c);
  Serial.println('h');
}

Затем я использую python для чтения последовательного порта и измерения прошедшего времени (я также использовал Matlab и получил те же результаты).

import numpy as np
import serial 
import time

ser = serial.Serial('COM5', 9600);

bytes_per_line = 10;
num_lines = 1000;
lines = np.empty(num_lines, dtype='|S11');

t0 = time.time()
for i in range(num_lines):
    lines[i] = ser.readline();
t1 = time.time()

ser.close();

baud_calc = bytes_per_line*num_lines/(t1-t0);

Для указанной скорости передачи данных 9600 я измеряю только 837, я также тестирую скорость передачи данных 38400, 74880, 230400, 5e5, 1e6, 2e6 (я масштабирую количество строк для чтения со скоростью передачи данных так, чтобы общее чтение заняло ~10 секунд). Вы можете увидеть результат на графике ниже.

Measured baud rate

Легенда сюжета следующая:

  • синий: измеренная скорость передачи данных в бодах
  • красный: недостижимая идеальная скорость передачи данных (т. е. измеренная = указанная)
  • черный: скорость передачи 230400 бод, которую я хотел бы достичь для своих приложений.

P.S. Причина, по которой я хочу, чтобы скорость передачи данных составляла 230400, заключается в том, что я считываю значения по кабелю GPIB и вижу, что данные, которые я измеряю, не соответствуют тому, что я знаю о протоколе GPIB. Если быть более точным, я вижу, что количество различных состояний GPIB-кабеля увеличивается, когда я увеличиваю скорость передачи данных.

, 👍2

Обсуждение

Скорость передачи данных в битах в секунду или, по крайней мере, символ в секунду. С помощью начального бита и стоп-бита вы получаете байт на 10 последовательных битов. Это сюрприз или я что-то неправильно понял?, @timemage

@timemage да, это сюрприз. Спасибо. Я думаю, что мой вопрос глуп, и вы ответили на него. Я все еще не понимаю, почему мои показания недостаточно быстры для GPIB., @David Saykin

Ну, он, конечно, отформатирован и все такое. Если часть вопроса остается без ответа, вы всегда можете отредактировать его, чтобы удалить более тривиальную путаницу байт/бит и оставить вопрос о других частях., @timemage

Ваш метод измерения несовершенен. Во время записи " t0 " Arduino может сбросить настройки и начнет передачу только через некоторое время. Также очень вероятно, что в " t0 "буфер RX вашего компьютера уже заполнен, и первые вызовы" ser.readline() просто считывают (очень быстро) этот буфер. Я предлагаю прочитать много килобайт, прежде чем записывать " t0. Это гарантировало бы, что вы достигли устойчивого состояния. В установившемся режиме скорость приема должна соответствовать скорости передачи., @Edgar Bonet


1 ответ


0

Как указывает timemage, скорость передачи данных составляет биты в секунду. Поскольку формат кадра по умолчанию для последовательного порта использует 8 битов данных, 1 Начальный бит, 1 Стоп-бит и отсутствие четности, это составляет 10 бит на символ. Таким образом, теоретический предел при скорости 9600 Бод составляет 960 символов (или байт) в секунду. Если это передается в виде отдельных символов, как вы делаете это в своем примере, также добавляются некоторые накладные расходы на программное обеспечение, которые приведут к небольшому разрыву между передачей двух символов. Я бы предположил, что это около 10%. Имея это в виду, ваши измерения абсолютно разумны.

Чтобы повысить производительность, попробуйте изменить код arduino на

void setup() {
  Serial.begin(9600);
}

void loop() {
  Serial.println("abcdefgh");
}

Это должно немного снизить накладные расходы и увеличить пропускную способность, чтобы вы приблизились к теоретическому пределу. Но достижение 230400 Байт/сек, вероятно, невозможно (я подозреваю, что "вмятина" в вашей кривой связана с приближением к другому ограничению, такому как скорость процессора).

,

Да, я определенно ошибся и перепутал байты и биты, но теперь, когда я обновляю свои измерения, они все еще не имеют для меня смысла. Например, теперь иногда измеренный бод становится больше, чем указанный бод., @David Saykin

@DavidSaykin Это странно. Можете ли вы поделиться своим обновленным графиком?, @PMF

Нет никаких накладных расходов на программное обеспечение. UART, передающий байты, и инструкции по обработке процессора выполняются _ параллельно_. Только при самых высоких скоростях передачи данных, когда UART начинает опустошать буфер TX быстрее, чем процессор может его заполнить, вы начинаете получать пробелы в передаче., @Edgar Bonet

Педантичное примечание: бод-это символ/секунда, а для двоичных данных бод эффективно соответствует биту/секунде., @Sacha