Лучший способ запросить у Arduino данные из Python?

Я пытаюсь отправить числовые данные с инерциальных датчиков с моего Arduino на скрипт Python через последовательный порт (PySerial). Я обнаружил, что если я непрерывно отправляю данные с Arduino без остановки, последовательный буфер быстро заполняется, и измерения датчика, которые считывает Python, задерживаются.

Чтобы исправить это, я подумал о том, чтобы сценарий Python отправлял команду передачи на Arduino, когда ему нужны данные. Я отправляю символ 't' для обозначения этой команды, но задержка между отправкой команды Python и отправкой данных Arduino слишком велика.

Мне интересно, есть ли "правильный" способ сделать это, поскольку я уверен, что это, вероятно, делалось раньше?

, 👍1

Обсуждение

Вы должны быть в состоянии получить мгновенный ответ на ваши команды. Вы, должно быть, делаете что-то не так в своем коде., @Majenko

Вы не пытаетесь использовать readString на Arduino для чтения одного символа из python, не так ли?, @Delta_G

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

Я читаю строки с обеих сторон Python и Arduino. Я не могу допустить переполнения выходного буфера Arduino, потому что буфер не очищается, пока я не прочитаю его на стороне Python. Мне нужны самые последние значения датчиков (гироскоп, ускорение IMU), поэтому, если я позволю буферу переполниться и начну чтение из него, я получу данные датчика, которым несколько циклов., @james_erikson

Мне интересно, возможно ли, что скорость передачи данных, которую я использую, слишком высока (19200-115200) для датчика IMU? Может быть, я считываю данные быстрее, чем может обеспечить датчик?, @james_erikson


1 ответ


1

Это не полный ответ на вашу проблему, но в настоящее время у вас, кажется, есть некоторые неправильные представления, которые мешают вам определить настоящую проблему.

Передача данных от датчика через Arduino к вашему скрипту Python на ПК имеет несколько мест, где может возникнуть узкое место. Тогда общая скорость передачи данных будет максимальной настолько, насколько позволяет наименьшее узкое место.

Во-первых, у вас есть потенциальное узкое место в связи между датчиком и Arduino. Вы не указали, какой у вас чип IMU и как он взаимодействует. Типичные микросхемы IMU, такие как серия MPU, представляют собой интерфейсы через I2C или SPI. SPI можно значительно ускорить, в то время как I2C ускорить не так-то просто. Но это сильно зависит от возможностей используемого чипа. Информацию об этом можно найти в соответствующем даташите на чип.


Следующий интерфейс — последовательный (UART) интерфейс между Arduino и ПК. Этот интерфейс имеет фиксированную скорость передачи данных. Когда вы используете Serial.write() или его аналоги, вы просто заполняете буфер отправки библиотеки Serial. Затем данные будут отправлены автоматически в правильное время для вашей скорости передачи данных. Передача происходит всегда, независимо от того, читает скрипт Python или нет. Передача также происходит, когда последовательный буфер скрипта заполнен. Arduino не знает о заполнении буфера. Так что в этом случае данные не задерживаются, а теряются.


Последнее — и, вероятно, самое важное — потенциальное узкое место — это то, как вы читаете и отправляете данные на Arduino и в скрипте Python. Здесь я освещаю сторону Arduino.

Не следует использовать такие функции, как Serial.readString(), поскольку они работают с тайм-аутом, что значительно замедляет работу вашего кода. Вместо этого вы должны читать последовательные данные байт за байтом в буфер, разделяя ваше сообщение специальным символом (например, символом новой строки \n). Вы проверяете, есть ли данные Serial.available(), и если да, то считываете один байт в массив char, который является вашим собственным буфером. Вы делаете это неоднократно, пока не прочитаете символ-разделитель. Затем вы обрабатываете полное сообщение. Таким образом, вы получите несколько важных улучшений:

  • Тем временем вы можете что-то делать (например, считывать новые данные с вашего датчика)
  • Он работает без произвольного тайм-аута, поэтому ваш код не замедляется без необходимости
  • Символ-разделитель обрамляет полное сообщение, чтобы вы могли отличить два разных сообщения друг от друга и, таким образом, упростить их обработку.

Учитывая вышеизложенное, вам следует уточнить требования:

  • Какую задержку между фактическими измерениями датчика и получением в скрипте Python вы считаете приемлемой, то есть насколько старыми могут быть измерения, которые получает скрипт Python? (Вы только что сказали, что он слишком большой, но не упомянули, насколько большой)

  • Вам нужна непрерывная передача данных или только один или несколько наборов данных IMU?

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

Кроме того, нам будет легче помочь вам, если вы покажете свой текущий код в своем вопросе.

,

Обратите внимание, что для односимвольных команд вам не нужны кадрирование сообщений и буферизация., @Edgar Bonet