2014年6月1日

続・赤外線LEDとフォトトランジスタでシリアル通信

このエントリーをブックマークに追加 このエントリーを含むはてなブックマーク

前回の続き。
赤外線LED(OSI5FU5111C-40)とフォトトランジスタ(L-51ROPT1D1)を使ったシリアル通信。
今回は、送受信×2で双方向(全二重)通信を実現させます。

構成は...
PC <---Serial---> Arduino <---赤外線---> Arduino <---Serial---> PC
こんな感じ。

前回のものを一体化して、以下のようにする。

これを2個用意し、互い違いになるように向かい合わせて配置。


プログラムは以下の通り。

#include <SoftwareSerial.h>

SoftwareSerial irPort(10, 11, false);

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

void loop() {
  int i = 0;
  char c;
  char buf[100];
  if(Serial.available()){
    while(Serial.available()){
      c = Serial.read();
      buf[i] = c;
      i++;
      buf[i] = '\0';
      delay(2);
    }
    irPort.print(buf);
  }

  if (irPort.available())
    Serial.write(irPort.read());
}

最初はSerialから赤外線へ渡す部分を
if (Serial.available()) {
    irPort.write(Serial.read());
}
こんな感じにしていたけど、これだとループの早さにSerial.readが追いつかないっぽい。
abcdefgと送るとabcgになる等、データが途中で抜けたりするので一旦バッファに全部溜めてからprintするようにしました。
ちなみに、上記コード中のdelay(2)を取ると、途中が抜けたり最初の3文字くらいしか取れない現象が発生するので、やはりSerial.readが原因の模様。
当初のコードのirPort.writeの前行にdelayを入れるのも試してみたが、10msくらいにしないとダメだったので、バッファに溜めた方が早いかなと。

上記写真のような配置で距離を離して双方同時に送信すると、互いが干渉して文字抜けや化けが発生するので、実際は間に遮蔽を入れるなどの工夫が必要。
試しに紙を1枚入れてみたら安定して通信できました。