Последовательные порты на Windows или Ubuntu VBox для общения с Arduino из Python - PullRequest
3 голосов
/ 03 марта 2011

У меня есть микроконтроллер Arduino, слушающий COM3. Использование arduino IDE и монитора Serial прекрасно работает для отправки и получения данных.

Я хотел бы отправлять и получать данные из Python, но не сразу понятно, как это сделать. (Я бы тоже хорошо делал это в C #, если бы это было существенно проще.)

Я нашел arduino_serial.py , но он работает только для Unix. К счастью, у меня есть Ubuntu 10.10 VBox. Однако я понятия не имею, может ли эта виртуальная машина получать доступ к последовательным портам или для этого требуются специальные действия.

Я также нашел pySerial , что выглядит вполне законно. Тем не менее, я также не уверен, как его использовать. Он хочет имена последовательного порта. Как я могу узнать, какие допустимые значения для них?

Например, pySerial упоминает, что вы можете «Открыть именованный порт в« 19200,8, N, 1 », 1s timeout» с помощью следующей команды:

>>> ser = serial.Serial('/dev/ttyS1', 19200, timeout=1)

Но я понятия не имею, как вы узнали бы, что /dev/ttyS1 было допустимым именем порта.

Есть ли хорошая документация для начала работы с этим?

Обновление : Я использую Ubuntu с arduino_serial, но все еще возникают проблемы.

Эта программа работает на Arduino:

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

void loop() { 
  if (Serial.available()) {
    Serial.print((char)Serial.read());
  }
}

Я вижу, что доступен порт с именем tty0:

foo@bar:~/baz$ dmesg | grep tty
[    0.000000] console [tty0] enabled

Я тогда пытаюсь соединиться с arduino_serial:

foo@bar:~/baz$ sudo python
[sudo] password for foo: 
Python 2.6.6 (r266:84292, Sep 15 2010, 15:52:39) 
[GCC 4.4.5] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> import arduino_serial
>>> sp = arduino_serial.SerialPort("/dev/tty0", 9600)
>>> sp.write("foo")
>>> sp.read_until("\n")
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "arduino_serial.py", line 107, in read_until
    n = os.read(self.fd, 1)
OSError: [Errno 11] Resource temporarily unavailable

Почему я получаю эту ошибку? Что я делаю не так?

Ответы [ 4 ]

3 голосов
/ 03 марта 2011

pySerial может быть встроен или не встроен в Python. В любом случае pySerial - это библиотека для загрузки и установки.

И поскольку вы уже знаете, что Arduino работает на COM3, просто используйте это:

import serial
ser = serial.Serial("COM3", 19200, timeout=1)
ser.write("Whatever")

Для Linux достаточно легко узнать, какой последовательный порт использует ваш Arduino:

dmesg | grep tty

Это даст вам вывод, похожий на этот: [ 7.944654] usb 1-1.6: FTDI USB Serial Device converter now attached to ttyUSB0

Итак, мой Arduino работает на ttyUSB0. Это означает, что вы можете использовать следующий код для общения с Arduino в Linux:

import serial
ser = serial.Serial("/dev/ttyUSB0", 19200, timeout=1)
ser.write("Whatever")

Примечание. Если вы используете скорость передачи 9600 бод на Arduino, как и большинство людей, вы можете просто использовать serial.Serial("COM3") или serial.Serial("/dev/ttyUSB0") без каких-либо других параметров.

EDIT: Вам также следует помнить, что в реальном мире может потребоваться секунда, чтобы фактически открыть порт и подготовить его к передаче данных. Это означает, что выполнение записи НЕМЕДЛЕННО после вызова serial.Serial () может на самом деле ничего не делать. Поэтому код, который я бы использовал, выглядит следующим образом:

import serial
import time
ser = serial.Serial("/dev/ttyUSB0", 19200, timeout=1)
time.sleep(1.5)
ser.write("Whatever")

Что-то вроде хака, но это единственный способ, которым я знаю, как заставить его работать в моей системе.

1 голос
/ 03 марта 2011

Последовательные порты называются COM1 и выше в Windows, / dev / ttyS0-> COM1. Я написал код на Python для нашего контроллера Quadcopter, который работает как в Windows, так и в Linux (если вы правильно указали имя порта), используя Pyserial.

Попробуйте передать COM3 в Pyserial на Windows. На виртуальной машине вам сначала нужно будет передать адаптер USB-последовательный порт на виртуальную машину или настроить секцию последовательных портов (я использую VirtualBox ). Если вы идете по маршруту USB, последовательные устройства будут перечислены в /dev/ttyUSBxx.

0 голосов
/ 03 марта 2011

"Но я понятия не имею, как вы узнали бы, что / dev / ttyS1 было допустимым именем порта."

Инициализатор последовательного порта PySerial принимает число вместо имени как имяаргумент.Эти цифры будут соответствовать «обычным» последовательным портам (/dev/ttySX в Linux, COMX в Windows).Затем вы можете получить имя из созданного объекта.Нет никакого способа заранее узнать, какие цифры попробовать, так как, как вы увидите в следующем коде, вам просто нужно попытаться и потерпеть неудачу.

Это не всегда обнаруживает симулированные порты (созданные с использованиемsocat или com0com), или USB-порты, так что для тех, кому нужно использовать модуль glob (я не думаю, что это имеет огромное значение, если вы используете Globbing или индексы для dev/ttySX узлы устройства).Это то, что собственные примеры pySerial делают.Следующий код адаптирован из этих примеров:

import glob, os

import serial

USB_SERIAL_GLOB = "/dev/ttyUSB*"

def try_open(port, args = (), kwargs = {}):
    try:
        port = serial.Serial(port, *args, **kwargs)
    except serial.SerialException:
        return None
    else:
        return port

def serial_scan(max_range = 32, args = (), kwargs = {}):
    for i in range(max_range):
        port = try_open(i, args, kwargs)
        if port is not None:
            yield port

    # Look for USB serial ports:     
    if os.name == 'posix':
        for fn in glob.glob(USB_SERIAL_GLOB):
            port = try_open(fn)
            if port is not None:
                yield port

if __name__ == "__main__":
    for port in serial_scan(kwargs = {'baudrate':9600, 'timeout':0.5}):
        port.close()
        print "Found: %s" % port.name
0 голосов
/ 03 марта 2011

У меня есть проект под названием Yaam на CodePlex , который использует C # для отправки данных через последовательный порт. Проверьте это для примера. На стороне C # (см. Yaam \ Yaam.xaml.cs) просто используйте класс SerialPort в пространстве имен System.IO.Ports. Как только вы создадите экземпляр объекта и зададите свойства (скорость передачи, com-порт и т. Д.), Просто наберите .Open(). Есть также много других примеров в Интернете. Взгляните на это:

...