2014年5月30日金曜日

ダ・ヴィンチ32Uとフォトリフレクターで非接触操作



赤外線フォトリフレクター2個を使い手をかざしてPC等を操作できるようにしてみました。
左右2個並べどちらからどちらの方向へ手をかざしたかを認識するようにしています。

本当は1つのセンサーを使い、手をかざす距離でPC画面の縦スクロールをさせようとしたのですが、照明の影響やセンサーの感知距離の関係でこうなりました。




センサーを天井に向けているために、照明の影響があります。
明るい部屋だとうまく操作できないでしょう。



キーボードとしてに認識させるために、leonardo互換のダ・ヴィンチ32Uを使いました。
arduinoUNOだと、USB-シリアル変換をしているATmega16U2のファームを書き換えないといけないのでハードルが高いです。



動画では、windows付属のフォトビューアーを起動し、右に手を動かすとキーボードの「→」(0xD7)、 左に手を動かすとキーボードの「←」(0xD8)を送信し、次の写真、前の写真を表示しています。
http://arduino.cc/en/Reference/KeyboardModifiers

回路図省略

スケッチ


byte pin_sensor_0 = A0;
byte pin_sensor_1 = A2;
byte pin_threshold = A5;
byte pin_led = 13;
int value_0;
int value_1;
int value_th;
unsigned long st;

void setup(){
  Keyboard.begin();
  Serial.begin(9600);
  pinMode(pin_sensor_0, INPUT);
  pinMode(pin_sensor_1, INPUT);
  pinMode(pin_threshold, INPUT);
  pinMode(pin_led, OUTPUT);
}

void loop(){
  value_0 = analogRead(pin_sensor_0);
  value_1 = analogRead(pin_sensor_1);
  value_th = analogRead(pin_threshold);
  Serial.print(value_0);
  Serial.print("\t");
  Serial.print(value_1);
  Serial.print("\t");
  Serial.print(value_th);
  Serial.print("\t");
  st = millis();
  if(value_0 > value_th){
    digitalWrite(pin_led, HIGH);
    while(analogRead(pin_sensor_1) < value_th){
      if(millis() - st > 500){
        Serial.print("TIMEOUT");
        Serial.print("\t");
        break;
      }
    }
//    Keyboard.write(0xD8);
    Serial.print("0 -> 1");
    Serial.print("\t");
    Serial.print(millis() - st);
    while(analogRead(pin_sensor_0) > analogRead(pin_threshold)
           || analogRead(pin_sensor_1) > analogRead(pin_threshold)){
    }
    delay(200);
    digitalWrite(pin_led, LOW);
  }
  else if(value_1 > value_th){
    digitalWrite(pin_led, HIGH);
    while(analogRead(pin_sensor_0) < value_th){
      if(millis() - st > 500){
        Serial.print("TIMEOUT");
        Serial.print("\t");
        break;
      }
    }
//    Keyboard.write(0xD7);
    Serial.print("1 -> 0");
    Serial.print("\t");
    Serial.print(millis() - st);
    while(analogRead(pin_sensor_0) > analogRead(pin_threshold)
           || analogRead(pin_sensor_1) > analogRead(pin_threshold)){
    }
    delay(200);
    digitalWrite(pin_led, LOW);
  }
  Serial.println("");
}




環境:ダ・ヴィンチ32U、arduinoIDE1.0.5、win7(64)



0 件のコメント:

コメントを投稿