4

COM3でリッスンしているArduinoマイクロコントローラーがあります。arduino IDEとシリアルモニターを使用すると、データの送受信に問題なく機能します。

Pythonとの間でデータを送受信したいのですが、その方法がすぐにはわかりません。(実質的に簡単であれば、C#でも問題ありません。)

arduino_serial.pyを見つけましたが、Unixでのみ機能します。幸い、Ubuntu10.10VBoxをセットアップしています。ただし、そのVMがシリアルポートにアクセスできるかどうか、またはアクセスするために特別な手順が必要かどうかはわかりません。

私はまた、かなり正当に見えるpySerialを見つけました。ただし、使い方もわかりません。シリアルポート名が必要です。これらの有効な値を確認するにはどうすればよいですか?

たとえばpySerial、次のコマンドを使用して、「名前付きポートを「19200,8、N、1」、1秒のタイムアウトで開く」ことができると述べています。

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

/dev/ttyS1しかし、それが有効なポート名であることがどうやってわかるのかわかりません。

これを始めるための良いドキュメントはありますか?

更新:arduino_serialでUbuntuを使用していますが、それでも問題が発生します。

このプログラムは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

4 に答える 4

4

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にあります。これは、次のコードを使用してLinuxボックス上のArduinoと通信できることを意味します。

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

注:ほとんどの人がそうであるように、Arduinoで9600のボーレートを使用する場合は、他のパラメーターを使用するserial.Serial("COM3")かどうかに関係なく使用できます。serial.Serial("/dev/ttyUSB0")

編集:現実の世界では、実際にポートを開いてデータ送信の準備をするのに1秒かかる場合があることにも注意してください。これは、serial.Serial()呼び出しの直後に書き込みを実行しても、実際には何も実行されない可能性があることを意味します。したがって、私が使用するコードは次のとおりです。

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

一種のハックですが、それが私のシステムでそれを機能させる方法を私が知っている唯一の方法です。

于 2011-03-03T04:24:27.237 に答える
2

シリアルポートの名前は、WindowsではCOM1以降、/ dev /ttyS0->COM1です。Pyserialを使用してWindowsとLinuxの両方で動作するQuadcopterコントローラー用のコードをPythonで作成しました(ポート名を適切に指定した場合)。

WindowsでCOM3をPyserialに渡してみてください。VMでは、最初にUSB-シリアルアダプタをVMに渡すか、シリアルポートセクションを設定する必要があります(私はVirtualBoxを使用しています)。USBルートを使用する場合、シリアルデバイスはの下に列挙され/dev/ttyUSBxxます。

于 2011-03-03T04:03:12.580 に答える
0

CodePlexにYaamというプロジェクトがあり、C#を使用してシリアルポートを介してデータを送信します。例を確認してください。C#側(Yaam \ Yaam.xaml.csを参照)では、名前空間のSerialPortクラスを使用するだけです。System.IO.Portsオブジェクトをインスタンス化し、プロパティ(ボーレート、COMポートなど)を設定したら、を呼び出すだけ.Open()です。Web上には他にもたくさんの例があります。これらを見てください:

于 2011-03-03T03:40:51.983 に答える
0

「しかし、/ dev/ttyS1が有効なポート名であることがどうやってわかるのかわかりません。」

PySerialのシリアルポートイニシャライザーは、引数として名前ではなく数字を受け入れます。これらの番号は、「通常の」シリアルポート(/dev/ttySXLinux、COMXWindows)に対応します。次に、作成したオブジェクトから名前を取得できます。ただし、試行する数値を事前に知る方法はないため、次のコードでわかるように、試行して失敗するだけです。

ただし、これはシミュレートされたポート(socatまたはを使用して作成された)またはUSBポートを常に検出するとは限らないため、 globcom0comモジュールを使用する必要があります(デバイスノードにglobまたはインデックスを使用するかどうかに大きな違いはないと思います)。これは、pySerial自身の例が行うことです。次のコードは、これらの例を基にしています。dev/ttySX

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
于 2011-03-03T07:48:06.000 に答える