USBセンサを使ってみよう 〜Phidgets活用講座 実践編 (2)〜
作成日: 2006/7/10  最終更新日: 2006/10/11



概要

このページの内容は,Software Design 2006年2月号pp.114-119,および2006年3月号pp.102-108に掲載された, 「USBセンサを使ってみよう Phidgets活用講座(2-3)」をHTML化したものです.分量が多いため,四つのページに分割してあります.本文中の「現在」などは「2005年12月」を指します.

ここでは,物理的なセンサ(スライダー)を用いて,複数のリスト(Webページなど)を閲覧するシステム「PhidgetBrowser」と,光センサを利用して,ユーザの状態に応じたスクリーンセーバーの制御を行うシステム「PhidgetSaver」について紹介します. USBセンサを使ってみよう(PhidgetApplication編)も参考にしてください.

連載目次




PhidgetApplicationの紹介(1)
1. PhidgetBrowser
PhidgetBrowserは,物理的なセンサー(スライダー)を用いて,複数のリスト(テキストファイル,Webページなど)を閲覧するシステムです(図1).たとえば,図2のように,スライダーの位置に応じて,次々と異なるWebページを表示することができます. ここでは,PhidgetBrowserのハードウェア/ソフトウェアについて説明します. なお,ソフトウェアのダウンロードはこちらから行えます.
図1 PhidgetBrowserの外観
(スライダが右端の場合) (スライダが中央の場合)
図2 PhidgetBrowserの動作例
ハードウェア

PhidgetBrowserは,InterfaceKitと一つのセンサー(スライダ)を用意するだけで利用することができます.スライダはぷらっとホームで販売されているInterfaceKit Packageには標準で含まれており,Phidgetsの公式サイトでも11CDNと安価に購入できます.

スライダをInterfaceKitのポート0に接続し,InterfaceKitとPCをUSBケーブルで接続するだけで,ハードウェアの準備は完了です.ここでは,スライダーをノートパソコンの液晶の左上部分に取り付けています.

ソフトウェア

PhidgetBrowserのソフトウェアは,PhidgetServerに接続するTCPクライアントとして,Rubyを用いて記述 しています.PhidgetBrowserを利用する前に,PhidgetServerを起動しておきます.本稿では,PhidgetServerはロー カルホスト(127.0.0.1),ポート4321で起動済みだと仮定します(以下共通). PhidgetBrowserを利用するためには,Cygwinから以下のように入力します.

  %./PhidgetBrowser.rb       

標準では,IP:127.0.0.1(localhost),ポート:4321へと接続を試みます. 任意のIP/ポートに接続するためには,以下のように引数を指定します.

  %./PhidgetBrowser.rb 127.0.0.1 4321       

ここでは,ソースコードの主要部分を参照しながら,PhidgetBrowserの処理の流れについて簡単に説明します.(前回の記事で紹介した内容と一部重複しますが,復習もかねて紹介します.)

1. PhidgetServerへの接続
TCPSocketクラスを用いて,PhidgetServerに接続します.
  require "socket"
 
  def main
    url_lists = load_url
    socket = TCPSocket.new("127.0.0.1", 4321)
    while line = socket.gets
      level = parse(line.chomp)
      if(level != nil)
        set_url(url_lists, num)
      end
    end
    socket.close
  end
      
2. リストファイルの読み込み
表示するURLのリストを読み込みます.以下のように,一行にひとつのURLを記載したファイル("url.txt")を読み込み,配列に格納します.
  [url.txt]
    http://mobiquitous.com/
    http://sappari.org/
    http://persistent.org/
      
   def load_url(file = "url.txt")
     urls = Array.new
     File.open(file)  do |f|
       f.each do |line|
         urls.push(line)
       end
     end
     urls
  end
      
3. 受信したコマンドを解析
次に,受信したコマンドを解析し,スライダの状態を検出します.
解析対象のコマンドは,
  In,InterfaceKit,Analog,0,[XXX]
  
というフォーマットになるため,以下のようなコードで[XXX]に代入される数値を取得します.
  def parse(line)
    args = line.split(",")
    if args[0] == "In" and
       args[1] == "InterfaceKit" and
       args[2] == "Analog"
       case args[3]
         when "0"
           level = args[4].to_i
       end
    end
    level
  end
4. Webページの表示
Webページの表示は,以下のように"cygstart"コマンドを起動することで実現できます.cygstartコマンドは,Windows上で関連付けられているプログラムを自動的に起動するため,画像/テキストなどの表示に幅広く活用することができます.
  LEVEL_MAX = 1024
  
  def set_url(url_list, level)
    num = (level / (LEVEL_MAX / url_list.length)).to_i
    system "cygstart #{url_list[num]}"  if num != @num_pre
    @num_pre = num
  end
5. TIPS:連続表示の防止
1〜4でプログラムの説明はほぼ完了ですが,このままのプログラムでは,スライダをすばやく動かした場合,目的のWebページだけでな く,すべてのページを連続的に表示してしまいます.これを防止するためには,以下のように一定の待機時間を設け,最終的なスライダ位置を判定して,イベン トを起こすようにする方法が考えられます.
  def set_url_with_sleep(url_list, level, sleep_time = 1)
    @num = (level / (LEVEL_MAX / url_list.length)).to_i
    if @num != @num_pre && !@sleeping 
      Thread.start do |t|
        @sleeping = true
        sleep(sleep_time)  
        system "cygstart #{url_list[@num]}"  
        @sleeping  = false
      end
    end
  end



2. PhidgetSaver
PhidgetSaverは,光センサを利用して,ユーザの状態に応じたスクリーンセーバーの制御を行うシステムです.図3に示すように, コンピュータの利用が中断される(ユーザの手がキーボード付近から離される)と,光センサがユーザの影の変化を検出し,自動的にスクリーンセーバーが起動 します.さらに,コンピュータの利用が再開される(ユーザの手がキーボード付近に置かれる)と,自動的にスクリーンセーバーを解除します. ここでは,PhidgetSaverのハードウェア/ソフトウェアについて説明します. なお,ソフトウェアのダウンロードはこちらから行えます.
(作業中) (作業中断&スクリーンセーバー起動)
図3 PhidgetSaverの利用例
ハードウェア

PhidgetSaverは,PhidgetBrowserと同様,InterfaceKitと一つのセンサ(光センサ)を用意するだけ で利用することができます.光センサ(CDS)はぷらっとホームで販売されているInterfaceKit Packageには標準で含まれており,Phidgetsの公式サイトでも7CDNと安価に購入できます.

光センサをInterfaceKitのポート0に接続し,InterfaceKitとPCをUSBケーブルで接続するだけで,ハードウェアの準備は完了です.ここでは,光センサをノートパソコンのパームレスト部分に取り付けています.

ソフトウェア

PhidgetSaverのソフトウェアは,PhidgetServerに接続するTCPクライアントとして,Rubyを用いて記述しています.PhidgetSaverを利用するためには,Cygwinから以下のように入力します.

  %./PhidgetSaver.rb       

オプションの設定などは,PhidgetBrowserとほぼ同様です.

ここでは,ソースコードの主要部分を参照しながら,PhidgetServerの処理の流れについて簡単に説明します.なお,PhidgetBrowserと共通する説明については割愛します.

1. PhidgetServerへの接続
TCPSocketクラスを用いて,PhidgetServerに接続します.
2. 受信したコマンドを解析
受信したコマンドを解析し,光センサの状態を検出します.光センサの入力が特定の閾値を上回った/下回った場合,スクリーンセーバーの起動/終了処理を行います.
  def main
    ...
    if check_brightness (level)
      start_screen_saver
    else
      stop_screen_saver
    end
    ...
   end


  def check_brightness?(level, threshold = 200)
    flag = false
    flag = true if level > threshold
  end
3. スクリーンセーバーの起動
スクリーンセーバーが起動中でない場合,cygstartコマンドを用いて起動します.ここでは,Windows標準のスクリーンセーバーのひとつ,"logon.scr"を起動しています.
  def start_screen_saver (file = "logon.scr")
    if(!@saver_working)
      system "cygstart #{file}" 
      @saver_working = true
    end
  end
4. スクリーンセーバーの終了

スクリーンセーバーが起動している場合,キーボードイベント(シフトキー)を発生させて,スクリーンセーバーを終了します. Windows上でのキーボードイベントの生成は,Win32APIの"keybd_event"か,"SendInput" 関数を利用します.両者の違いは,SendInputはWindows2000から搭載されたより高機能な関数であり,マウスやその他のハードウェアのイ ベントも生成することができる点です.

ここでは,シフトキーイベントを生成するだけが目的ですので,よりシンプルなkeybd_event関数を用いた方法を紹介します.(なお,後述するPhidgetMouseでは,SendInputを用いてマウスイベントを生成しています.)

  def stop_screen_saver
    if(@saver_working)
      Win32.send_keybd_event(Win32::VK_SHIFT)
      Win32.send_keybd_event(Win32::VK_SHIFT, Win32::KEYEVENTF_KEYUP)
      @saver_working = false
    end
  end
	
  module Win32
    extend DL::Importable
	
    typealias "DWORD", "unsigned long"
    typealias "BYTE", "unsigned char"
    typealias "ULONG", "unsigned long"
  
    KEYEVENTF_KEYUP =   0x02
    VK_SHIFT          = 0x10
 
    dlload "user32.dll"
    extern "void keybd_event(BYTE, BYTE, DWORD, ULONG)"
  
    def send_keybd_event(bVk, dwFlags = 0)
      keybd_event(bVk, 0, dwFlags, 0)
    end
 
    module_function :send_keybd_event
  end 
目次へ


[次へ->PhidgetApplicationの紹介(2)]


[1] [2] [3] [4]

[デバイスぶらり旅]