複数のarduino通信(1マスター、nスレーブ)


8

以下で構成されるマスター/スレーブネットワークを開発したいと思います。

  • センサーを読み取り、センサー信号に基づいて速度ランププロファイルを生成し、それらのランプをスレーブに送信する1つのArduinoマスター

  • マスターから送信されたランプに続く12Vサーボモーターの速度を制御する3つ以上のArduinoスレーブ

これを達成するための良い通信プロトコルは何ですか?シリアル(SPI)?I2C?他に何か?シリアルの場合、新しいArduino Leonardoは良い選択ですか?プロトコルを選択する際に考慮すべき問題は何ですか?

私は次のようなものを想像しています:

主人:

void loop() {
    update_ramps()
    for(int i=0; i< num_slaves; i++) {
        send_to_all(i, ramps[i]);
    }
}

スレーブ1:

const int id = 1;
int recived_id, recived_value;
void loop() {
    read_data();
    if(recived_id == id) { 
        do_motor_step(recived_value);
    }
}

また、マスターからのRX / TXがすべてのスレーブに送信されるシリアル通信。

これは合理的な解決策のように見えますか?


すべてのスレーブにまったく同じ情報を送信したいだけですか?奴隷はまったく応答する必要がありますか?
Oli Glaser

いいえ、彼らは応答する必要はありません!
nkint

奴隷はどれくらい離れているのでしょうか?
geometrikal

15メートル以下だと思う
nkint 2012

回答:


12

私が理解しているように、各スレーブに異なるデータを送信する必要がありますが、スレーブはデータを返送する必要はありません。

I2Cはアドレス指定されたバスであるため、各スレーブに異なるI2Cアドレスを割り当てると、データを送信するのに2本のワイヤーで済みます。必要に応じて、データを要求することもできます。ArduinoのAVRには、I2C互換のシリアルバスがあります。さらに、追加のハードウェアなしで最大127までの3つ以上のスレーブに拡張できます。

UARTにはアドレス指定がないため、3つのUART(AVRにはない)、または外部ロジックを追加してUARTラインを切り替える(コストがかかる)必要があります。スレーブを追加するたびに追加のコストが発生します。推奨されません。
edit
Chrisのように、UARTを使用してマルチドロップバスを作成できると言います。次に、アドレッシングを追加する必要があります。これにより、UARTはI2Cのように機能しますが、非同期で、I2Cのようなアドレス一致ハードウェアがありません。したがって、それでも実際には利点はありません。 編集の終わり

SPIは、データ用の共有ライン、つまり単一のMOSI、および接続されたMISOラインも使用します。各スレーブを個別にアドレス指定するには、スレーブごとに1本のSS(スレーブ選択)ラインが必要です。つまり、少なくとも5つのI / Oです:MOSI、SCK、3×SS、およびスレーブからデータを読み取る場合はMISO。スレーブを追加するたびに、マスターにI / Oピンが1つ追加されます。

ここに画像の説明を入力してください

I2Cが最善のソリューションであり、必要なワイヤの数が最も少ないと思います。プロトコルはUARTまたはSPIよりも少し複雑ですが、AVRはそのためのハードウェアを備えているため、使いやすいはずです。


2
複数のUARTまたは外部ロジックが必要であるという主張は正確ではありません。バス型UART通信は、ソフトウェアアドレス指定を使用して常に行われます。送信と受信を共有することで、I2Cよりも多くのピンを必要としません。
Chris Stratton

@クリス-良い点、私は私の答えを更新します。
stevenvh

1
@capcom-SPIのブロック図を追加しました。MOSIはマスター用に出力され、スレーブ用に入力されます。MISOはスレーブに出力され、マスターに入力されます。はい、データを送信したいスレーブのSSを低くします。SSは、通信の開始と終了を示すだけでなく、選択されていないスレーブも、バスの競合についてMISOを高インピーダンスにする必要があります。
stevenvh

2
@nkint-8 mの容量は約800 pFであり、I2Cでは400 pFでのみ必要なエッジ速度を取得できます。最大50 mのケーブルでバスを駆動するP82B715などのバスエクステンダーを使用する必要があります。
stevenvh

1
@stevenvh P82B715は非常に機能し、プラグインは本当に簡単です!
nkint

5

シリアルとはUARTを意味すると思いますか?UART、SPI、I2Cはすべてシリアルプロトコルであることに注意してください。

SPIまたはI2Cはどちらもマスター/スレーブアーキテクチャを使用しているため、これで問題ありません。
グランドを含まず、3つのスレーブの場合、SPIには6つのピン(MOSI、MISO、CLK + 3 SSピン)とI2Cが2つ(SDAとSCK)だけ
必要です。レート(<400kHz)

追加するスレーブが多いほど、新しいスレーブごとに別のSS(スレーブ選択)が必要になるため、SPIの利便性は低くなります。I2Cの場合、アドレス指定はプロトコルの一部であるため、これは問題ではありません。したがって、必要なのは2本のライン(およびグランド)だけです。

Arduinoの場合、I2C / SPIライブラリを使用した多数のチュートリアルと上記の両方のサンプルコードが用意されているため、立ち上げて実行するのは非常に簡単です。


そうです、データはスレーブごとに異なります。「send_to_all」関数の名前に惑わされましたが、それぞれに異なるランプを使用しているようです(インデックスが付けられています)。最初の回答を削除しました。
stevenvh

1

RS485と同様の非同期信号方式の共有も可能です。

ラインドライバー/レシーバー(裸のATMEGAピンのみ)を使用していない場合は、話をする番ではないときにUART TXを入力にする必要があります。ラインドライバーを使用している場合は、追加のピンを使用して、話をする番ではないときにラインドライバーのトライステートイネーブルを制御する必要があります。

また、最後のバイトが送信レジスタに受け入れられたとき(別の文字を送信できる時点)にトランスミッタをトライステートにするだけではなく、ワードが完了するまでトランスミッタまたはラインドライバを有効にしておく必要があることにも注意してください。完全にシフトアウト。

同じワイヤ(または差動ペア)で送受信するスキームでは、自分の送信が聞こえることを考慮してください。


1

あなたは特別なケースにしたい経由で接続するにはUART、あなたが使用することができUART RS485 MODBUSを。これは、ソフトウェアアドレス、機能、チェックサムを備えた通信プロトコルです。

I THINK:RS-485により、I²CまたはSPIよりも信頼性が高く、SPIよりもワイヤの使用量が少ない

注:一部のライブラリでは標準として実装できますが、すべてのスレーブとマスターに1つずつRS485モジュールが必要なため、高価になる可能性がありますが、既存のネットワークと互換性があります。しかし、レガシーコンポーネントを使用して独自のデバイスを作成することで、コストを抑えることができます。MAX 485は、ハードウェア485バスを作るか、または使用して、塩基成分とすることができるソフトウェアをRS485


0

特定の要件に対する最も簡単なソリューションは、マスター(バスコントローラー)上のTXライン上のRS-422トランスミッターです。これは、複数のレシーバー(リモートターミナル)にファンアウトします。

すべてのRTはブロードキャストメッセージを聞きますが、RTアドレスを介して送信されたコマンドのみを認証および実行します。

1553と同様のバスプロトコルを使用した場合、実装は簡単です。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.