USB-GEIGER を Linux で動かす

Pocket

やっとストロベリーリナックスのガイガーカウンターUSB-GEIGERを入手しました
Windows 用のUSB 経由で cpm と経過時間のデータは取得できるソフトはストロベリーリナックスで公開されています
しかし、Linux で動かしたいですよね

まずは、このガイガーを Linux マシンにつないでみます
/proc/bus/usb/devices をまず見てみます

<br />
T:  Bus=02 Lev=01 Prnt=01 Port=00 Cnt=01 Dev#=  2 Spd=1.5 MxCh= 0<br />
D:  Ver= 1.10 Cls=00(&gt;ifc ) Sub=00 Prot=00 MxPS= 8 #Cfgs=  1<br />
P:  Vendor=1774 ProdID=1002 Rev= 1.00<br />
S:  Manufacturer=Strawberry Linux Co.,Ltd.<br />
S:  Product=USB-Geiger Counter<br />
C:* #Ifs= 1 Cfg#= 1 Atr=80 MxPwr=100mA<br />
I:* If#= 0 Alt= 0 #EPs= 1 Cls=03(HID  ) Sub=00 Prot=00 Driver=usbhid<br />
E:  Ad=81(I) Atr=03(Int.) MxPS=   8 Ivl=10ms<br />

usbhid のドライバを使っているようです
次にdmesg も見てみます

<br />
usb 3-2: USB disconnect, address 2<br />
usb 2-1: new low speed USB device using uhci_hcd and address 2<br />
usb 2-1: New USB device found, idVendor=1774, idProduct=1002<br />
usb 2-1: New USB device strings: Mfr=1, Product=2, SerialNumber=0<br />
usb 2-1: Product: USB-Geiger Counter<br />
usb 2-1: Manufacturer: Strawberry Linux Co.,Ltd.<br />
generic-usb 0003:1774:1002.0002: hiddev96,hidraw0: USB HID v1.00 Device [Strawberry Linux Co.,Ltd. USB-Geiger Counter] on usb-0000:00:1d.0-1/input0<br />

hidraw0 として認識されるみたいです

に、参考となるソース発見!
Linux 版は動かないけど、mac 版なら動くらしい。

SnoopyPro のデータを見て、GEIGERMAP のソースを参考に Linux 用のソース ichigo-gg.c を書く。

<br />
#include &lt;stdio.h&gt;<br />
#include &lt;string.h&gt;<br />
#include &lt;stdlib.h&gt;<br />
#include &lt;unistd.h&gt;<br />
#include &lt;time.h&gt;</p>
<p>#include &lt;sys/types.h&gt;<br />
#include &lt;sys/stat.h&gt;<br />
#include &lt;fcntl.h&gt;</p>
<p>#include &lt;getopt.h&gt;</p>
<p>static const char short_options[] = &quot;d:h&quot;;<br />
static const struct option long_options [] = {<br />
        { &quot;device&quot;,     required_argument,      NULL,   'd' },<br />
        { &quot;help&quot;,       no_argument,            NULL,   'h' },<br />
        { 0, 0, 0, 0 }<br />
};</p>
<p>static int<br />
usage()<br />
{<br />
        fprintf(stdout, &quot;Usage: ichigo-gg [-d device] [-h]\n&quot;<br />
                        &quot;Options are:\n&quot;<br />
                        &quot; -d, --device=DEVICE Select Device File(default: /dev/hidraw0)\n&quot;<br />
                        &quot; -h, --help          This Help\n&quot;<br />
                );<br />
        return 0;<br />
}</p>
<p>int main(int argc, char *argv[])<br />
{<br />
        int fd;<br />
        int res = -1;<br />
        unsigned char buf[65];<br />
        char *dev_name = NULL;</p>
<p>        for(;;)<br />
        {<br />
                int index;<br />
                int c;</p>
<p>                c = getopt_long( argc, argv,<br />
                                 short_options, long_options,<br />
                                 &amp;index);</p>
<p>                if ( c == -1)<br />
                        break;</p>
<p>                switch (c)<br />
                {<br />
                case 0:<br />
                        break;<br />
                case 'd':<br />
                        dev_name = strdup(optarg);<br />
                        break;<br />
                case 'h':<br />
                        usage();<br />
                        exit(0);<br />
                default:<br />
                        ;<br />
                }<br />
        }</p>
<p>        if (!dev_name)<br />
                dev_name = strdup(&quot;/dev/hidraw0&quot;);</p>
<p>        fd = open( dev_name, O_RDWR);<br />
        if (fd &lt; 0)<br />
        {<br />
                fprintf(stderr,&quot;Can't find device(%s)\n&quot;, dev_name);<br />
                exit(-1);<br />
        }</p>
<p>        memset(buf,0,65);<br />
        res = write(fd,buf,8);<br />
        if ( res != 8)<br />
        {<br />
                fprintf(stderr, &quot;Can't write device(%s)\n&quot;, dev_name);<br />
                goto end;<br />
        }</p>
<p>        res = read(fd,buf,sizeof(buf));<br />
        if ( res &lt; 0)<br />
        {<br />
                fprintf(stderr, &quot;Can't read device(%s)\n&quot;, dev_name);<br />
                goto end;<br />
        }</p>
<p>        usleep(10000);</p>
<p>        unsigned int count, total;</p>
<p>        count = (buf[3] &lt;&lt; 24) + (buf[2] &lt;&lt; 16) + (buf[1] &lt;&lt; 8) + buf[0];<br />
        total = (buf[6] &lt;&lt; 16) + (buf[5] &lt;&lt; 8)  + buf[4];</p>
<p>        time_t timer;<br />
        time(&amp;timer);<br />
#ifdef DEBUG<br />
        int i;<br />
        for(i=0;i&lt;7;i++)<br />
                fprintf(stdout,&quot;buf[%d] =&gt; 0x%02x\n&quot;, i,buf[i]);</p>
<p>#endif<br />
        fprintf(stdout,&quot;%ld,%d,%d\n&quot;, timer, count, total);<br />
end:<br />
        free(dev_name);<br />
        close(fd);</p>
<p>        exit(0);<br />
}<br />

無事、それらしきデータは取得できた。

<br />
$ gcc -c ichigo-gg.c<br />
$ gcc -o ichigo-gg ichigo-gg.o<br />

速いマシンだと usleep() なくても動きます。
遅いマシンだと usleep() ないと変なデータになります
controlからinterrupt でデータがやってくるのに処理が間に合わないのでしょうか・・・

でコンパイルできます。
実行は下記のようにお願いします

<br />
# ichigo-gg -d /dev/hidraw0<br />

/dev/hidraw0 は自分の環境にあったものに書き換えてくださいね

[2011/09/30 追記]
read だけだと値が取得できずに固まってしまうときがありました
Sizka だからかもしれませんが・・・。
なので、select 使うようにしてます

<br />
#include &lt;stdio.h&gt;<br />
#include &lt;string.h&gt;<br />
#include &lt;stdlib.h&gt;<br />
#include &lt;unistd.h&gt;<br />
#include &lt;time.h&gt;</p>
<p>#include &lt;sys/types.h&gt;<br />
#include &lt;sys/stat.h&gt;<br />
#include &lt;fcntl.h&gt;</p>
<p>#include &lt;getopt.h&gt;<br />
static const char short_options[] = &quot;d:h&quot;;<br />
static const struct option long_options [] = {<br />
	{ &quot;device&quot;,     required_argument,      NULL,   'd' },<br />
	{ &quot;help&quot;,       no_argument,            NULL,   'h' },<br />
	{ 0, 0, 0, 0 }<br />
};</p>
<p>static int<br />
usage()<br />
{<br />
	fprintf(stdout, &quot;Usage: ichigo-gg [-d device] [-h]\n&quot;<br />
		&quot;Options are:\n&quot;<br />
		&quot; -d, --device=DEVICE Select Device File(default: /dev/hidraw0)\n&quot;<br />
		&quot; -h, --help          This Help\n&quot;<br />
	);<br />
	return 0;<br />
}</p>
<p>int main(int argc, char *argv[])<br />
{<br />
	int fd;<br />
	int res = -1;<br />
	unsigned char buf[65];<br />
	char *dev_name = NULL;</p>
<p>	for(;;)<br />
	{<br />
		int index;<br />
		int c;</p>
<p>		c = getopt_long( argc, argv,<br />
			 short_options, long_options,<br />
			 &amp;index);</p>
<p>		if ( c == -1)<br />
			break;</p>
<p>		switch (c)<br />
		{<br />
		case 0:<br />
			break;<br />
		case 'd':<br />
			dev_name = strdup(optarg);<br />
			break;<br />
		case 'h':<br />
			usage();<br />
			exit(0);<br />
		default:<br />
			;<br />
		}<br />
	}</p>
<p>	if (!dev_name)<br />
		dev_name = strdup(&quot;/dev/hidraw0&quot;);</p>
<p>	fd = open( dev_name, O_RDWR);<br />
	if (fd &lt; 0)<br />
	{<br />
		fprintf(stderr,&quot;Can't find device(%s)\n&quot;, dev_name);<br />
		exit(-1);<br />
	}<br />
	memset(buf,0,65);</p>
<p>	res = write(fd,buf,8);<br />
	if ( res != 8)<br />
	{<br />
		fprintf(stderr, &quot;Can't write device(%s)\n&quot;, dev_name);<br />
		goto end;<br />
	}     </p>
<p>	struct timeval stv;</p>
<p>	stv.tv_usec = 500000; // 0.5 sec<br />
	stv.tv_sec  = 0;  </p>
<p>	fd_set fds;<br />
	FD_ZERO(&amp;fds);<br />
	FD_SET (fd, &amp;fds);<br />
	r = select ( fd + 1, &amp;fds, NULL, NULL, &amp;stv);</p>
<p>	switch(r)<br />
	{<br />
	case -1:<br />
	case 0:<br />
		goto end;<br />
		break;<br />
	default:<br />
		;<br />
	}     </p>
<p>	res = read(fd,buf,sizeof(buf));<br />
	if ( res &lt; 0)<br />
	{<br />
		fprintf(stderr, &quot;Can't read device(%s)\n&quot;, dev_name);<br />
		goto end;<br />
	}     </p>
<p>	unsigned int count, total;<br />
	count = (buf[3] &lt;&lt; 24) + (buf[2] &lt;&lt; 16) + (buf[1] &lt;&lt; 8) + buf[0];<br />
	total = (buf[6] &lt;&lt; 16) + (buf[5] &lt;&lt; 8)  + buf[4];</p>
<p>	time_t timer;<br />
	time(&amp;timer);<br />
#ifdef DEBUG<br />
	int i;<br />
	for(i=0;i&lt;7;i++)<br />
		fprintf(stdout,&quot;buf[%d] =&gt; 0x%02x\n&quot;, i,buf[i]);</p>
<p>#endif<br />
	snprintf(ostring,sizeof(ostring)-1,&quot;%ld,%d,%d\n&quot;, timer, count, total);<br />
	write(fp,ostring,strlen(ostring));<br />
end:<br />
	free(dev_name);<br />
	close(fd);<br />
	close(fp);</p>
<p>	exit(0);<br />
}<br />

[/2011/09/30 追記]

3件のコメント

  1. ピンバック:USB-RH + ZABBIXで室温・湿度のモニタリングを行う | blog::dameningen

  2. ピンバック:USB-RH + ZABBIXで室温・湿度のモニタリングを行う » blog::dameningen | blog::dameningen

  3. ピンバック:USB-RH + ZABBIXで室温・湿度のモニタリングを行う

コメントを残す