2016年10月2日日曜日

Arduino同士でSerial通信(UART)して最大速度を調べる。

配線図

信号線はRXとTXの2本だけ。UART通信ではRX-RX、TX-TXではなく、RX-TX、TX-RXという風に接続する。

SerialでPCと通信できなくなるので、8個のLEDを状態表示用として接続した。


Arduinoのスケッチ


TX側
Serial_Write_Test.ino

#define BAUD_RATE  (460800)

byte sendChar = 0;

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

void loop() {
  if (Serial.availableForWrite() > 0) {
    Serial.write(sendChar);
    sendChar++;
  }
}

Serial.begin()でUART通信速度(BAUD_RATE)を設定。RX側でも同じ値を指定する。送信データはBYTE型をインクリメント。

RX側
Serial_Read_Test.ino

#define BAUD_RATE  (460800)

byte prevRv = 0;
byte errorCnt = 0;

void dispNum(int num) {
  digitalWrite(2, (num & 0x01));
  digitalWrite(3, (num & 0x02));
  digitalWrite(4, (num & 0x04));
  digitalWrite(5, (num & 0x08));
  digitalWrite(6, (num & 0x10));
  digitalWrite(7, (num & 0x20));
  digitalWrite(8, (num & 0x40));
  digitalWrite(9, (num & 0x80));
}

void setup() {
  // LED Check
  pinMode(2, OUTPUT);
  pinMode(3, OUTPUT);
  pinMode(4, OUTPUT);
  pinMode(5, OUTPUT);
  pinMode(6, OUTPUT);
  pinMode(7, OUTPUT);
  pinMode(8, OUTPUT);
  pinMode(9, OUTPUT);
  pinMode(10, OUTPUT);
 
  for (int i = 0; i < 5; i++) {
      digitalWrite(2, HIGH);
      digitalWrite(3, HIGH);
      digitalWrite(4, HIGH);
      digitalWrite(5, HIGH);
      digitalWrite(6, HIGH);
      digitalWrite(7, HIGH);
      digitalWrite(8, HIGH);
      digitalWrite(9, HIGH);
      delay(100);
      digitalWrite(2, LOW);
      digitalWrite(3, LOW);
      digitalWrite(4, LOW);
      digitalWrite(5, LOW);
      digitalWrite(6, LOW);
      digitalWrite(7, LOW);
      digitalWrite(8, LOW);
      digitalWrite(9, LOW);
      delay(100);
  }  
  Serial.begin(BAUD_RATE);
}

void loop() {
  if (Serial.available() > 0) {
      int rv = Serial.read();
      prevRv++;
      if (rv != prevRv) {
        errorCnt++;
        dispNum(errorCnt);
      }
      prevRv = rv;
      digitalWrite(10, !digitalRead(10));
  }
}

PORTDを全部使えればもっと簡単になるが、UARTでPD0、PD1を使うのでめんどくさい書き方になってしまった(@@;

RX側のDispNum()で8本のLEDでBYTE型のデータを表示できるようにした。受信データをそのまま表示しても早すぎて視認できないので、受信データが1ずつインクリメントされているかどうかを監視して、値が異なったらエラーカウント(errorCnt)をインクリメントしてLEDに表示。

結果

115200 OK
230400 OK
460800 NG
961600 NG

230400bpsまではLEDの点灯状態が変化しないが、460800bps以上ではLEDが全点灯する(最上位ビットはちらつく程度に点滅)

エラーなく送受信できるのは230400bps程度までだろう。

通信波形

230400bps(OK)

ch1:RX側D10 ch2:RX側D1

ch1のD10は1byte分受信したときにH/Lを切り替えている。ch2はUARTの通信波形。

460800bps(NG)

メモ:


公式のAruduino Uno Rev.3とaitendoのびんぼうでいいのを使った。シリアルポートの割り当ては以下の様に。


公式のArduino Unoは「Arduino Uno(COM3)」、びんぼうでいいのは「USB-SERIAL CH340(COM6)」と表示されている。(公式同士だとややこしいかも?)

Arduino IDEで書き込みするときにArduino同士のUART通信の配線をいったん外さないと書き込みがうまくいかないので注意。