9

Raspberry PiRainbowduinoを自家製のI²Cレベル シフターで接続し、 PythonモジュールSMBusをインストールしました。Raspberry Pi は Rainbowduino と通信できますが、コマンドを実行しようとすると入出力エラー メッセージが表示されることがよくありますbus.write_i2c_block_data(address, signal, data)

それは言います:

IOError: [Errno 5] 入出力エラー

このエラーが発生する理由と、これらのエラーを修正または無視するにはどうすればよいですか?

4

5 に答える 5

3

i2c を使用して Raspberry Pi と Arduino UNO を使用して賑やかなサーバーを作成していますが、同じ問題が発生しました。私の設計では、Piがソケットから(ネットワーク上のいくつかの外部マシンによって)接続要求を受信すると、Arduinoに「1」が書き込まれ、Arduinoはグローバル変数を変更してloop()でループを有効にします。書き込み後、Pi は Arduino からバイトを継続的に読み取り、ボタンの状態を確認します。Pi が読み取りを停止する場合は、「0」を送信してループを停止し、すべてのカウンターと LED をリセットします。

何が起こるかというと、バイトを書き込むときに Python がランダムに IOError を通過することです。Arduino のシリアル モニタで、最後に受信したバイトが 0 ではなく 1 であることに気付きました。これは pi が送信すべきものです。i2cdetect -y 1 を見て、アドレスが間違っていることに気づき、Jon の方法を試しましたが、user3126397 が言及したように、不良データが送信され、Arduino が停止しました。私は彼のmodprobeを試みましたが、それはエラーメッセージを抑制しただけで、Arduinoはまだ停止状態にあります.

私は当初、不完全な読み取り/書き込みが原因でデータが劣化したと考えているため、onReceive() の引数 byteCount を確認するために Serial.println() を追加しました。他のコードを変更せずに、いいえであることがわかりました。IOError が大幅に増加する前に成功した操作の数。したがって、相関関係をテストするためにさらに println() を追加しようとしたところ、失敗が劇的に増加していることに気付きました。最後に、すべての Serial ステートメントにコメントを付けたところ、サーバーを何回も問題なく使用できるようになりました (30 回ほどテストしましたが、まだ IOError は発生しませんでした)。

ボーレートのリセットに関するuser3126397の解決策とSerial.println()関係に関する私の観察に関して、そのエラーは実際にはpiとArduinoの間の同期の問題によって引き起こされていると思われます(Serialは比較的遅く、プログラムでより多くの遅延を引き起こすため) 、したがって、失敗の可能性が高くなります。

于 2014-02-08T21:19:44.287 に答える
3

簡単に言えば、多くの人がこれに悩まされています。非常に簡単な回避策が次のとおりであることがわかりました。

エラーを無視して tx/rx-ing を維持できます。i2cdetect を呼び出すと、arduino がバスから消えるのではなく、何らかの形でバスが再初期化されるようです。

ここでこのソリューションを見つけた方法の説明を投稿しました(現在modの承認を待っています) http://www.raspberrypi.org/phpBB3/viewtopic.php?f=41&t=52517

try:
    bus.write_i2c_block_data(address, signal, data)
except IOError:
    subprocess.call(['i2cdetect', '-y', '1'])
    flag = 1     #optional flag to signal your code to resend or something

これにより、Pi は不良データを送信し続けることができますが、依然として arduino に送信されています。これを回避するために私が見つけた最も簡単な方法は、データ ブロックの最後に追加のチェックサム バイトを追加することでした。

バイト変数内のメッセージの各バイトを合計して、値をロールオーバーできるようにし、メッセージ全体を合計してゼロにするために必要な値をチェックサム バイトに割り当てました。

その後、arduino は、すべてのバイトを合計することによって、各着信伝送をチェックできます。メッセージの合計がゼロにならない場合、それは誤った送信として無視されます。

また、送信が成功するたびに増加する 1 バイトのメッセージ ID をメッセージに割り当て、偶発的な二重送信の可能性を排除しました。しかし、それは本当に必要ではないかもしれません。

于 2013-12-17T22:36:40.070 に答える
1

RPi によっては、bus = SMBus(0)またはを使用bus = SMBus(1)して SMBus を初期化する場合があります。

これで問題が解決することを願っています。

于 2013-04-10T18:53:34.463 に答える
0

最近、この同じ問題に遭遇しました。teensy のシリアル インターフェイスを無効にすると、エラーは完全になくなりました。

私は、2.4mhz で i2c を介して通信する 10 代の 3.2 で RPi 2 を使用しており、33 バイトのペイロードを約 38 Kbps の速度で送信しています。

于 2016-04-07T21:35:59.487 に答える