LibUsbDotNetを使ってUSB機器と通信するアプリケーションを作成する - C#

LibUsbDotNetを使ったアプリケーションを作成します。

事前準備

LibUsbDotNetをインストールします。インストール手順はこちらの記事を参照してください。

LibUsbDotNetの参照

新規にWindows Formアプリケーションを作成します。作成完了後、ソリューションエクスプローラの[参照設定]ノードを選択し、右クリックしポップアップメニューを表示させ、[参照の追加]メニューをクリックします。


[参照の追加]ダイアログが開きますので、[参照]タブをクリックし、LibUsbDotNet.dllを指定します。


LibUsbDotNet.dllは正しくビルドされた場合はソースコードのディレクトリの/LibWinUsb/bin/Debug (またはRelease)ディレクトリにあります。


参照できると[参照設定]ノードの中にLibUsbDotNetが追加されます。

アプリケーションの作成

下図のフォームを作成します。ボタンを3つラベルを2つフォームに配置します。

usingの記述

LibUsbDotNetの名前空間をusingします。コードの先頭部分に以下のusingを追記します。
using LibUsbDotNet;
using LibUsbDotNet.Main;

UsbDevice, UsbDeviceFinderの定義

UsbDeviceとUsbDeviceFinderを定義します。UsbDeviceFinderのコンストラクタ引数には接続するUSB機器のベンダーIDとプロダクトIDを指定します。(下のコードの例ではベンダーIDが 0x04D8、プロダクトIDが0x0053となります。)
public static UsbDevice MyUsbDevice;
public static UsbDeviceFinder MyUsbFinder = new UsbDeviceFinder(0x04d8, 0x0053);

USB機器の接続処理

Button1のClickイベントに以下のコードを記述します。このボタンを押すとUSB機器に接続します。
    
private void button1_Click(object sender, EventArgs e)
{
  ErrorCode ec = ErrorCode.None;

  try {
    MyUsbDevice = UsbDevice.OpenUsbDevice(MyUsbFinder);

    if (MyUsbDevice == null) throw new Exception("Device Not Found.");
    IUsbDevice wholeUsbDevice = MyUsbDevice as IUsbDevice;
    if (!ReferenceEquals(wholeUsbDevice, null)) {
      wholeUsbDevice.SetConfiguration(1);
      wholeUsbDevice.ClaimInterface(0);
    }

  }
  catch (Exception ex) {
    label2.Text=ec != ErrorCode.None ? ec + ":" : String.Empty + ex.Message;
  }
}

下記コードで先ほど定義したUsbDeviceFinderを用いて接続対象の機器を探します。接続機器が見つかった場合はMyUsbDeviceにデバイス情報が格納されます。接続対象となる機器がなかった場合は nullを返します。
 MyUsbDevice = UsbDevice.OpenUsbDevice(MyUsbFinder);

USB機器へのデータ転送

Button2のClickイベントハンドラを実装します。Button2を押すと0X80をUSB機器に送信します。
    
private void button2_Click(object sender, EventArgs e)
{
  UsbEndpointWriter writer = MyUsbDevice.OpenEndpointWriter(WriteEndpointID.Ep01);
      
  ErrorCode ec = ErrorCode.None;
      
  int bytesWritten;
  byte[] data = new byte[64];
  data[0]=0x80;

  ec = writer.Write(data, 2000, out bytesWritten);
  if (ec != ErrorCode.None) throw new Exception(UsbDevice.LastErrorString);
}

下記のコードで接続されたMyUsbDeviceからUsbEndpointWriterを取得します。UsbEndpointWriterを用いてUSB機器に情報を書き込みます。USB機器のコントロール転送では64バイトで転送するため、64バイトの配列を用意します。下記のコードでは64バイトの配列を用意し最初のバイトに0x80を書き込んでいます。これにより0x80をUSB機器に転送します。
USB機器へのデータの転送はUsbEndpointWriter.Writeメソッドで書き込みます。下記のコードではタイムアウト2秒でUSB機器へデータを転送しています。
 UsbEndpointWriter writer = MyUsbDevice.OpenEndpointWriter(WriteEndpointID.Ep01);

USB機器へのデータ転送とデータ受信

Button3のClickイベントハンドラに以下のコードを記述します。
    
private void button3_Click(object sender, EventArgs e)
{
  UsbEndpointWriter writer = MyUsbDevice.OpenEndpointWriter(WriteEndpointID.Ep01);

  ErrorCode ec = ErrorCode.None;

  int bytesWritten;
  byte[] data = new byte[64];
  data[0] = 0x81;

  ec = writer.Write(data, 2000, out bytesWritten);
  if (ec != ErrorCode.None) throw new Exception(UsbDevice.LastErrorString);


  UsbEndpointReader reader = MyUsbDevice.OpenEndpointReader(ReadEndpointID.Ep01);
  byte[] readBuffer = new byte[64];
  int bytesRead;


  ec = reader.Read(readBuffer, 100, out bytesRead);
  if (readBuffer[1] == 0x01) {
    label1.Text = "ON";
  }
  else {
    label1.Text = "OFF";
  }
}

USB機器へのデータ転送に関しては先のButton2と同様UsbEndpointWriterを取得してデータの転送をします。一方USB機器からのデータの読み取りに関してはUSBデバイスクラスのMyUsbDeviceを用いて、UsbEndpointReaderを取得しこれを利用します。USB機器からのデータ読み込みについても64バイト単位で処理されるため、64バイトのbyte配列を用意します。データの読み取りはUsbEndPointReader.Readメソッドを用います。下記のコードの例ではタイムアウト100msecでUSB機器からデータを読み込んでいます。データの内容が1かそれ以外かを判定し、label1にメッセージを表示します。

プログラムの実行

コードが実装できたらプログラムを実行します。下図の画面が表示されます。USB機器をPCにつなぎ、フォームのボタンを押すことでデータをUSB機器に転送したり、USB機器からデータを読み取ることができます。


著者
iPentecのメインプログラマー
C#, ASP.NET の開発がメイン、少し前まではDelphiを愛用
掲載日: 2010-10-04
iPentec all rights reserverd.