Измерить время Sofware Serial write()

Как вы, вероятно, знаете, SoftwareSerial использует прерывания для выполнения некоторых задач по синхронизации последовательной связи.

Я пытаюсь измерить время, необходимое SoftwareSerial.write() для записи/отправки одного байта.

Очевидно, я начал пробовать использовать временные метки на основе millis(), но обнаружил, что SoftwareSerial портит таймер millis(), и он просто не считается должным образом. .

У меня есть что-то вроде этого:

timestamp = millis();
HC12.write(endByte); //HC12 — это объект SoftwareSerial

//После отправки ждём ответа
while (HC12.available() > 0) {
  byte r = HC12.read();
  if (r == (byte) 254) { //Другой модуль HC12 отправляет 0xFE
    unsigned long received = millis() - timestamp;
    Serial.println(received);
  }
...

Есть какие-нибудь предложения о том, как это измерить?

Я пытаюсь реализовать полудуплексную связь с модулями HC12 433 МГц и проверяю некоторые теоретические/реальные значения времени для связи между двумя платами.

, 👍1

Обсуждение

время зависит от скорости передачи данных (бит/секунду)...... передается не менее 10 бит.... один стартовый бит, 8 бит данных и один стоповый бит..... стоповый бит должна быть длиной не менее одного бита, но может быть и длиннее, @jsotola

@jsotola, привет. Спасибо за вашу помощь. Ну я знаю :-). Дело в том, что это теоретически. Кроме того, я хочу попробовать больше байтов и не думаю, что время точно такое же, как при расчетах, основанных на скорости передачи данных., @Fred

на самом деле решение довольно простое..... передающий Arduino на самом деле является автономным..... не обязательно должен быть принимающий Arduino........ соедините два Arduino вместе, используя один из цифровые контакты... передающий Arduino устанавливает цифровой вывод, отправляет программный последовательный байт и очищает цифровой вывод... другой Arduino измеряет время между установкой и очисткой вывода... ........ вы также можете синхронизировать сам последовательный вывод программного обеспечения, @jsotola

попробуйте это.... https://github.com/gillham/logic_analyzer, @jsotola

@juraj, фрагмент теперь правильный. Что значит, название вопроса не соответствует вопросу?, @Fred

@jsotola, отличная идея! Большое спасибо., @Fred


1 ответ


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

1

Это очень просто, и для этого вам не нужен какой-либо код.

SoftwareSerial полностью синхронен (т. е. блокируется) при записи. Это означает, что время, затраченное на запись, равно времени, затраченному на отправку данных по линии, плюс небольшие накладные расходы на вызов функции.

Это означает, что затраченное время:

1 / baud * 10 seconds

Итак, при скорости 9600 бод один бит отправляется за 1/9600 секунды, а бит 10 (1 стартовый, 8 данных и 1 стоповый бит), поэтому это занимает 1/960 секунды.

>

Это около 1 мс на байт плюс несколько дополнительных тактов для вызова реальных функций.

Подробнее, когда вы отправляете байт, происходит следующее:

  1. Установить уровень строки на уровне начального бита
  2. Подождите 1/9600 секунды.
  3. Установить уровень строки на уровне первого бита данных.
  4. Подождите 1/9600 секунды.
  5. Повторите действия 3 и 4 для остальных битов данных.
  6. Установить уровень строки на уровне стоп-бита
  7. Подождите 1/9600 секунды.
  8. Установить уровень линии на уровне ожидания

Итак, всего у вас есть 10 «ожиданий 1/9600 секунды» или общее время 1/960 секунды.

То же самое можно сказать и о получении данных. Когда приходит стартовый бит, он запускает прерывание смены контакта. Затем выполняется процедура синхронного блокирующего прерывания, которая делает то же самое, что и выше, но с чтением вместо записи. Таким образом, выполнение этого процесса на скорости 9600 бод занимает около 1 мс, плюс еще немного времени на вставку входящего байта в кольцевой буфер, из которого вы затем читаете свой скетч.

Таким образом, время прохождения одного байта туда и обратно от устройства A к устройству B, а затем от устройства B к устройству A можно оценить как:

1/960 + 1/960 + overheads

Это означает, что минимальное время будет составлять 1/480 секунды плюс время, затрачиваемое удаленным устройством на обработку байта для отправки данных обратно к вам, и немного времени на накладные расходы на вызов функции.

Кстати, именно последняя операция в прерывании , «добавление байта в кольцевой буфер», означает, что вы не можете надежно получать данные на скорости 115200 бод с помощью SoftwareSerial. Это требует больше времени для обработки, чем типичный промежуток между байтами (может быть равен нулю - просто ширина стопового бита...), когда следующий байт мог уже начать поступать на вывод GPIO до того, как Arduino сможет запустить ISR снова, поэтому он пропускает стартовый бит.

,

Привет, Потрясающее объяснение. Спасибо за ваше время!, @Fred