Senshu LAB
サイト内検索: AND検索 OR検索  


Counter: 97660, today: 4, yesterday: 8

HIDmonについて(2008年9月29日〜)

hidmonに関する疑問や使用レポートをお書きください。なお書込みが多かったので、
複数のページに分割しました。
このページは、HIDmonの基本的な利用法を解説するページとします。


hidmonとは

HIDクラスのUSB通信で、AVRマイコンのメモリやI/Oの読み書きするプログラムです。

irukaさんによる解説
なお、このページの以下の項目については、hidspx-1014a版では修正が行われたため、
解除の必要はありません。

AVRプログラムライターHIDaspxのファームウェアで使用する場合の注意 
   :
tiny2313内蔵のUSIをISPプログラム機能として初期化していますので、PORTB.6 が
USI側に接続されていて、bit6のみ出力制御出来ません。 解除するには、
手動にて AVR> p usicr 0 と入力されるか、
スクリプトの先頭で p usicr 0 というコマンドを実行するようにしてください。

hidmonを使用することで、AVRマイコンが持つレジスタやメモリの参照や変更をUSB経由で
行うことができます。

HIDクラスを採用したことにより、ドライバのインストールが不要で、誰でも容易に使える
のが特徴です。

graphやbenchコマンドのように、単純なIO操作では実現できないコマンドも、専用のコードを
書くことで実現できます。


hidmonの作者irukaさんによる特徴を引用します(文体を替えました)。

  • VBAからも呼び出し可能
  • 汎用USB I/Oよりちょっとだけ面白いところ。
    • PWMを出力できる(もちろん、音階も出せる)
      • タイマー2個あるから、2個まで和音も出せる(但しMIX回路(抵抗MIX)は自分で作る)
      • しかし高速PWMでD/Aでサイン波出力は無理(USB処理しない2313を追加する必要あり)。
    • TxDに1バイト単位で、遅いと思うけれどシリアルデータが出せる(はず)
      • 送信バッファ・エンプティーチェックが甘くなるとおもうけど。
    • ボーレートを31,250bpsにしておけば、TxDをMIDI出力にして楽器がドライブ出来る(はず)
      • VBAとかC言語で、MIDI演奏処理が可能に・・・(なるかも)

hidmonの使用例

senshu (2008-09-29 (月) 17:18:46)

irukaさんが作成されているhidmonは非常に興味深いツールです。

irukaさんが以前から取組まれているAVR_MonitのHID版です。ドライバが不要なので簡単に動作を確認できます。

HIDaspxをお持ちの方は、↑のURLから最新の「hidmon-***.zip」を入手し、展開後に
hidmon.exeを実行してください。

AVR> help
* HID_Monit Ver 0.1
Command List
 d  <ADDRESS1> <ADDRESS2>    Dump Memory(RAM)
 e  <ADDRESS1> <DATA>        Edit Memory
 f  <ADDRESS1> <ADDRESS2> <DATA> Fill Memory
 p ?                         Print PortName-List
 p .                         Print All Port (column format)
 p *                         Print All Port (dump format)
 p <PortName>                Print PortAddress and data
 p <PortName> <DATA>         Write Data to PortName
 sleep <n>                   sleep <n> mSec
 bench <CNT>                 HID Write Speed Test
 q                           Quit to DOS
AVR> p ?
    DIDR = 0x21   GPIOR0 = 0x33    GTCCR = 0x43   TCNT1H = 0x4d
   UBRRH = 0x22   GPIOR1 = 0x34     ICR1 = 0x44   TCCR1B = 0x4e
   UCSRC = 0x23   GPIOR2 = 0x35    ICR1L = 0x44   TCCR1A = 0x4f
    ACSR = 0x28     PINB = 0x36    ICR1H = 0x45   TCCR0A = 0x50
   UBRRL = 0x29     DDRB = 0x37    CLKPR = 0x46   OSCCAL = 0x51
   UCSRB = 0x2a    PORTB = 0x38    OCR1B = 0x48    TCNT0 = 0x52
   UCSRA = 0x2b     PINA = 0x39   OCR1BL = 0x48   TCCR0B = 0x53
     UDR = 0x2c     DDRA = 0x3a   OCR1BH = 0x49    MCUSR = 0x54
     RXB = 0x2c    PORTA = 0x3b     OCR1 = 0x4a    MCUCR = 0x55
     TXB = 0x2c     EECR = 0x3c    OCR1L = 0x4a    OCR0A = 0x56
   USICR = 0x2d     EEDR = 0x3d    OCR1H = 0x4b   SPMCSR = 0x57
   USISR = 0x2e     EEAR = 0x3e    OCR1A = 0x4a     TIFR = 0x58
   USIDR = 0x2f    EEARL = 0x3e   OCR1AL = 0x4a    TIMSK = 0x59
    PIND = 0x30    PCMSK = 0x40   OCR1AH = 0x4b     EIFR = 0x5a
    DDRD = 0x31   WDTCSR = 0x41    TCNT1 = 0x4c    GIMSK = 0x5b
   PORTD = 0x32   TCCR1C = 0x42   TCNT1L = 0x4c    OCR0B = 0x5c

helpを参考にコマンドを入力してみてください。p .と入力すると2進表記で レジスタの内容を確認できます。多くのレジスタを対話的に確認しながら操作 できるので、AVRマイコンの理解を深めることができます。
なお、当然ですが、USB通信用のポートなどを操作してはいけません。
入力が面倒に思えますが、←→のキーで編集ができ、↑↓のキーにて過去に入力した コマンドを呼び出せるので、思った以上に便利に利用できます。

AVR> p .
  DIDR = 0000_0000  PORTD = 0000_0000 WDTCSR = 0000_0000 TCCR1A = 0000_0000
 UBRRH = 0000_0000 GPIOR0 = 0000_0000 TCCR1C = 0000_0000 TCCR0A = 0000_0000
 UCSRC = 0000_0110 GPIOR1 = 0000_0000  GTCCR = 0000_0000 OSCCAL = 0110_0100
  ACSR = 0011_0000 GPIOR2 = 0000_0000  ICR1L = 0000_0000  TCNT0 = 0000_0000
 UBRRL = 0000_0000   PINB = 1011_1000  ICR1H = 0000_0000 TCCR0B = 0000_0000
 UCSRB = 0000_0000   DDRB = 1111_1111  CLKPR = 0000_0000  MCUSR = 0000_0001
 UCSRA = 0010_0000  PORTB = 1111_1000 OCR1BL = 0000_0000  MCUCR = 0000_1100
   UDR = 0000_0000   PINA = 0000_0000 OCR1BH = 0000_0000  OCR0A = 0000_0000
   RXB = 0000_0000   DDRA = 0000_0000  OCR1L = 0000_0000 SPMCSR = 0000_0000
   TXB = 0000_0000  PORTA = 0000_0000  OCR1H = 0000_0000   TIFR = 0000_0000
 USICR = 0001_1010   EECR = 0000_0000 OCR1AL = 0000_0000  TIMSK = 0000_0000
 USISR = 1100_0000   EEDR = 0000_0000 OCR1AH = 0000_0000   EIFR = 0000_0000
 USIDR = 1111_1111   EEAR = 0111_1111 TCNT1L = 0000_0000  GIMSK = 1000_0000
  PIND = 0001_0100  EEARL = 0111_1111 TCNT1H = 0000_0000  OCR0B = 0000_0000
  DDRD = 0110_0111  PCMSK = 0000_0000 TCCR1B = 0000_0000

また、hidmonコマンド起動時にオプションを指定すれば、スクリプトの一括実行もできます。
HIDaspxのポートに、スイッチやLED、リレーなどを付けておけば、簡単な制御実験が可能です。

hidmon -i script.txt

を実行すると、このテキストに書かれた内容を順に実行します。

    1	#   サンプルスクリプトファイル(script.txtの内容).
    2	# 使い方:
    3	#   monit -i script.txt
    4	#
    5	dp 0 7ff
    6	dr 0 7f
    7	d 0 df
    8	
    9	p ddrb ff
   10	
   11	p portb 0
   12	sleep 100
   13	p portb ff
   14	sleep 100
:
   82	q

繰り返しの制御構造や条件判断があれば、高度なI/O制御にも使えそうですが、 HIDaspxは入出力が限られるので、本格的な利用には、PCと組み合わせて使うのが よいでしょう。HIDaspxは、USB I/Oの一種であることを実感できるツールです。

詳しい内容は、作者のirukaさんに解説してもらいたいと思います。


hidmonから利用可能なIOピン

senshu (2008-10-17 (金) 18:57:17)

hidmonを利用する場合、I/Oピンの操作には十分な注意が必要です。

             ATtiny2313
             ___    ___
RESET       [1  |__| 20] Vcc
PD0(RxD)    [2       19] PB7(SCK)
PD1(TxD)    [3       18] PB6(MISO)
XTAL2       [4       17] PB5(MOSI)
XTAL1       [5       16] PB4
PD2(CK OUT) [6       15] PB3
PD3(D+)     [7       14] PB2
PD4(D-)     [8       13] PB1
PD5(PULLUP) [9       12] PB0
GND         [10      11] PD6
            ~~~~~~~~~~~

このピン配置からもわかるように、HIDaspxとして利用している場合には、 PB0〜PB7は自由に操作可能、PD(0, 1, 6) の合計11本が利用可能です。 構成を工夫すれば、PD2を利用可能なピンに変更するのは可能と考えています。
この変更により、8+4の汎用USB-IOと同様のピン数が得られることになります。

こうしたマイコンでは、一本のピンに複数の役割が割り当てられており、
ピンの割り振りは経験が必要です。そこで、このマイコンをよく知っている方の ご意見をお聞きしたいと思います。

参考(ATtiny2313のピン配置、赤線以外が利用可能)
ATtiny2313pin1.png


[AVR] hidmon88登場

senshu (2008-10-01 (水) 18:15:28)

hidmonのATmega88版が公開されました。

http://hp.vector.co.jp/authors/VA000177/html/HIDmon88.html

WSN172(mega48/88/168用のボード)で試してみるつもりです。
アナログ入力を持たないという問題もこれで解決できます。

不幸にもUSBの接続ポートのDDR(データ方向レジスタ)などを触って
しまうと通信が途絶します。

に関しては、USB用の割り当てを触れないようにソフトでガードする、 というのはいかがでしょうか。
また、ATmega88でもUSBasp互換の回路でHIDaspxを動作させたいと思っています。
世界的に見れば、USBasp互換の回路(基板)は広く製作されており、この回路で
HIDaspxが動作すれば、多くの方が利用できることになります。


USB-IOとしての利用法(HIDmonのDLL化)

  • iruka? 2008-10-13 (月) 23:01:08
    senshuさん。
    当方のゲストブックにて、akakusaさんという方から、HIDmonのDLL化のリクエスト
    を頂きました。汎用USBIOのほうはよく存知ませんのでとりあえずUsbPeek/UsbPoke
    だけをexportしてみたのですが・・・
    DLLの作り方等良く分からないので間違っているかもしれません。
    C言語以外からの呼び出し方法等が私はさっぱり分かりません。
    hidmon-1012.zip で公開してあります。
  • senshu 2008-10-14 (火) 07:59:29
    >当方のゲストブックにて、akakusaさんという方から、HIDmonのDLL化
    この方は、私がHIDaspxに取り組むキッカケを与えてくれた方です。この方からの
    相談に応えるため、HIDasp(後にHIDaspx)の製作を行い、改良に努めてきました。

    USB-IOはプリンタポート利用が難しくなった現在では、貴重な学習教材になると
    考えます。DLLの作成を行っていいただいたことで、今後はこれを元に発展さ
    せることができればと思います。

    irukaさんには大変お世話になっていますが、今後もご協力をお願いいたします。

hidmon.dll の使い方

配布ファイルのtestディレクトリに使用例があります。

    1	#include <stdio.h>
    2	
    3	#include "hidmon.h"
    4	
    5	
    6	#define	NAME	"pinb"
    7	
    8	int main()
    9	{
   10		int i, adr;
   11		UsbInit("*");
   12	
   13		printf("%s(%x)\n", "portb", PortAddress("portb"));
   14	
   15		adr = PortAddress(NAME);
   16		printf("%s(%x)\n", NAME, adr);
   17	
   18		for (i = 0; i < 1000; i++) {
   19			printf("%s = 0x%02x\r", NAME, UsbPeek(adr, 0));
   20		}
   21	
   22		UsbExit();
   23		return 0;
   24	}

この例では、PORT-Bの内容を1000回読み出し、コンソールに結果を出力します。
通常のプログラムとそれほど変わる所はありません。

USBinit("*");
  処理
USBExit();

と書くことで、I/O制御が可能になるわけです。作成済みのdlltest.exeを実行すると

>timeit dlltest
portb(38)
pinb(36)
pinb = 0x1b
:
Elapsed Time:     0:00:01.625

のように表示されます。この実行には1.625秒要したことがわかります。
試しに、表示にかかる時間も無視できないので、以下のように書き換えてみました。

   10		int i, adr, data;
     :
   18		for (i = 0; i < 1000; i++) {
   19			data = UsbPeek(adr, 0);
   20			if (i%100 == 0) {
   21				printf("%4d: %s = 0x%02x\r", i, NAME, data);
   22			}
   23		}

100回に1回だけ表示させるわけです。1000回の表示が10回に減少することになります。 これで1.406秒となりました。

1.625-1.406 = 0.219
1表示あたり 0.219/990 = 0.221ミリ秒

の時間が必要とわかります。つまり1000回の表示では0.22秒を要しているわけです。
これにより、1000回の読み出しには1.4秒を要しているわけです。これは、パケット方式の USB通信(LOW SPeed)の特徴であり、これ以下の高速処理は期待できませんが、必要なら AVRマイコン側に高速な処理を分担させます。

HIDaspx(AVRライタ)では、AVRマイコンにMHzオーダーの高速パルスを発生させ、高速化を 実現しています。

なお、リレーやシーケンサなどを代替する制御実験には十分な処理速度だと思います。


VBAでのSPEEDテストの結果(HUB無しの場合)

  • 宮前? 2008-10-23 (木) 11:05:18
    VBAでは、1,000回の読みだしで8秒程かかりました。10,000回では、80秒でした。
    結構遅くなりますね。VBでコンパイルしたのはどうでしょうかね。
    http://yokohama.cool.ne.jp/s8426cl/hidmon03.lzh
    「SPEED」ボタンをクリックします。結果は、log.txt に保存。
  • senshu 2008-10-23 (木) 11:17:01
    C言語はコンパイラ、VBはインタープリタです。10倍程度の時間差はあるのが
    普通だと思います。コンパイルすればある程度は速くなりますが、それほど
    変わらないという話も聞いたことがあります(コードの隠蔽に意味がある)。

  • senshu 2008-10-23 (木) 15:27:14
    hidmon03.lzhを試してみました。

    その結果ですが、私の環境ではVBでも2秒程度です。hidmon のbenchの結果を
    教えてください。2.0規格であれば、USB-HUBを使うことで速度向上が可能です。

  • 宮前? 2008-10-23 (木) 17:32:01
    すいぶん速いですね。VBAですよね。
    USB-HUBは、持っていません。
    ファームは、1014a。hidmon.exeは、1020のです。
    hid write start
    hid write end, 38000 bytes/10937 ms, 3474 bytes/s
    コンパイルしたVBどなたたかやりませんかね。
  • 宮前? 2008-10-23 (木) 17:42:51
    質問です。上記の
    >1000回の読み出しには1.4秒
    これは、USB-HUBを使用した結果ですか?
  • senshu 2008-10-23 (木) 18:19:15
    >これは、USB-HUBを使用した結果ですか?

    そうです。HUB経由でdlltestで評価しました。私の使っているPCはそれ程高速なものでは
    ありませんが、「hidmon bench で18,000bytes/s」程度の速度です。
    HUB無しでは、3〜4kbytes/sなので、宮前さんとほぼ同じです。

    USB-HUBを介すると、多くの場合3〜4倍高速になります。HUB利用者のほとんどから
    高速になったとの報告をもらっています。

    hidmonのbenchの結果を向上させないと、この通信がボトルネックになり、
    どんなコンパイラを使っても速度は向上しないと思います。

    今は、HUBも安価なので、ぜひ入手して、HUB経由で使ってみてください。

openoffice BASICから使ってみる

配布ファイルのtestディレクトリには、BASIC用のサンプルソースもあります。
私は、openofficeの組込みBASICからhidmon.dllを使ってみました。
C言語の寡黙なUI(ユーザインターフェース)に比べ、至れり尽せりのUIに迷いそうになりました。
果たしてこれは教育的に見ると、使いやすいのでしょうか。

実行させると、メッセージボックスには読み取った値が10進数で表示されます。
Cのサンプルに倣って繰り返すようにコーディングしたところ、「OK」をクリックする
のが面倒で、一秒間に1000回近くも動作させるのは不可能です。

VBAに詳しい方に、適切なデモプログラムの作成をお願いしたいと思います。
LEDのイメージを表示させ、対応するビットの点滅でもさせるのが良いのでしょうね。

まずは、BASICからDLLを呼び出して、動作することを確認しました。
hidmon.dllをPATH設定された場所にコピーすれば、自動的に呼び出しが可能になります。
(これがインストールということでしょうか)

REM  *****  BASIC  *****

' ----------------------------------------------------------------------
'	hidmon.dll
'
Declare Function UsbInit Lib "hidmon.dll" (ByVal device as string) as long
Declare Function UsbExit Lib "hidmon.dll" () as long
Declare Function UsbPeek Lib "hidmon.dll" (ByVal address as long,ByVal arena as long) as long
Declare Function UsbPoke Lib "hidmon.dll" (ByVal address as long,ByVal arena as long, -
                                 ByVal data as long,ByVal mask as long) as long
Declare Function PortAddress Lib "hidmon.dll" (ByVal portname as string) as long

Sub Main
	UsbInit()
	print PortAddress("pinb")
	print UsbPeek(PortAddress("pinb"),0)
	UsbExit()
End Sub

  • senshu 2008-10-19 (日) 20:58:14
    VBAでの動作の検証に時間がかかっています。

    VBAでの動作を確認した方は、その方法(手順)をお書きください。

  • senshu 2008-10-20 (月) 10:47:44
    VS2008EEでの動作確認はできました。VBAは、VBとは違いがあるようです。

    更に検証作業が必要ですが、解決は時間の問題だと思います。
  • senshu 2008-10-21 (火) 16:06:43
    hidmon-1020.zip以降の版で、VBAの問題が改善されています。

    これを使ってください。