2014年7月31日

ATtiny85で赤外線シリアル通信

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

前回前々回の続き。
赤外線LED(OSI5FU5111C-40)とフォトトランジスタ(L-51ROPT1D1)を使ったシリアル通信をATtiny85で実現させます。
さらに、このATtiny85とArduinoをI2Cで接続し、I2C-赤外線通信コンバーター化します。

構成はこんな感じ。

ATtiny85の各ピンは以下の通り。

pin1 - RESET
pin2 - Serial RX (from フォトトランジスタ)
pin3 - Serial TX (to 赤外線LED)
pin4 - GND
pin5 - I2C SDA (Arduino A4)
pin7 - I2C SCL (Arduino A5)
pin6 - not used(D1)
pin8 - VCC

pin6が空いているので、更に何か追加することもできますが、今回は未使用。

ATtiny85をArduinoとして扱う方法は「Programming an ATtiny w/ Arduino 1.0」 を参考にしました。
書き込みはaitendoで購入し、以前の記事でファームウェアのアップデートを行ったUSBasp-Bを使用。
ATtiny85は内蔵RC 8MHz駆動です。

プログラムは以下の様な感じ。(たぶんもっとキレイに書けるはず...)

#include <SoftwareSerial.h>
#include "TinyWireS.h"

#define I2C_SLAVE_ADDR  13
#define IR_RX 3 // pin2
#define IR_TX 4 // pin3

SoftwareSerial irPort(IR_RX, IR_TX, false);

void receiveEvent(uint8_t a) {
  int i = 0;
  char c;
  char buf[100];
  if (TinyWireS.available()) {
    while(TinyWireS.available()){
      c = TinyWireS.receive();
      buf[i] = c;
      i++;
      buf[i] = '\0';
      delay(2);
    }
    irPort.write(buf);
  }
}

void requestEvent() {
  if(irPort.available()){
    char c = irPort.read();
    if(c!=255)
      TinyWireS.send(c);
  }
}

void setup() {
  TinyWireS.begin(I2C_SLAVE_ADDR);
  irPort.begin(1200);

  TinyWireS.onReceive(receiveEvent);
  TinyWireS.onRequest(requestEvent);
}

void loop() {

}

Arduino UNO側はこんな感じ。

#include <Wire.h>

void setup(){
  Serial.begin(9600);
  Wire.begin();
}

void loop(){
  if(Serial.available()){
    int i = 0;
    char c;
    char buf[100];
    while(Serial.available()){
      c = Serial.read();
      buf[i] = c;
      i++;
      buf[i] = '\0';
      delay(2);
    }
    Wire.beginTransmission(0); //broadcast
    Wire.write(buf);
    Wire.endTransmission();
  }

  Wire.requestFrom(13,1);
  if(Wire.available()){
    byte b = Wire.read();
    if(b!=0xff && b!=0x0a && b!=0x00)
      Serial.write(b);
  }
}

これで、一番上の写真のように向かい合わせにして赤外線通信ができます。
UNO側のコードでbroadcastにしているのは訳があって、このあとATtiny85を複数個ぶら下げる予定。