とりあえず無線LANにする
Raspberry Pi、線がダラダラつながっているのは面倒くさいから、メインのifをWiFiにしてみたい。たまたま、Raspberry Piと相性がいいと言われるUSBのWiFiアダプタ「PLANEX GW-USNano2」というのをかなり前から持っている。
USBポートにとりあえずこれを挿入し、
# lsusb
Bus 001 Device 002: ID 0424:9514 Standard Microsystems Corp.
Bus 001 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub
Bus 001 Device 003: ID 0424:ec00 Standard Microsystems Corp.
Bus 001 Device 004: ID 2019:ab2a PLANEX GW-USNano2 802.11n Wireless Adapter [Realtek RTL8188CUS]
……もう、サクッとプラグアンドプレイの一発認識である。
# ifconfig
eth0 Link encap:イーサネット ハードウェアアドレス b8:27:eb:45:1d:d0
inetアドレス:192.168.1.105 ブロードキャスト:192.168.1.255 マスク:255.255.255.0
UP BROADCAST RUNNING MULTICAST MTU:1500 メトリック:1
RXパケット:498 エラー:0 損失:1 オーバラン:0 フレーム:0
TXパケット:253 エラー:0 損失:0 オーバラン:0 キャリア:0
衝突(Collisions):0 TXキュー長:1000
RXバイト:46665 (45.5 KiB) TXバイト:34011 (33.2 KiB)
lo Link encap:ローカルループバック
inetアドレス:127.0.0.1 マスク:255.0.0.0
UP LOOPBACK RUNNING MTU:65536 メトリック:1
RXパケット:8 エラー:0 損失:0 オーバラン:0 フレーム:0
TXパケット:8 エラー:0 損失:0 オーバラン:0 キャリア:0
衝突(Collisions):0 TXキュー長:0
RXバイト:1104 (1.0 KiB) TXバイト:1104 (1.0 KiB)
wlan0 Link encap:イーサネット ハードウェアアドレス 00:22:cf:97:fe:b9
inetアドレス:192.168.1.107 ブロードキャスト:192.168.1.255 マスク:255.255.255.0
UP BROADCAST RUNNING MULTICAST MTU:1500 メトリック:1
RXパケット:506 エラー:0 損失:169 オーバラン:0 フレーム:0
TXパケット:25 エラー:0 損失:0 オーバラン:0 キャリア:0
衝突(Collisions):0 TXキュー長:1000
RXバイト:128714 (125.6 KiB) TXバイト:4541 (4.4 KiB)
これも、もう、イッパツ。
で、# shutdown -i0 -g0 -y、LANケーブル抜いて電源を入れなおす。
サクッとつながる。ケーブルがだらだらつながっていたのが減って、これはとてもいいなあ。
USBのWiFiアダプタが快調に作動している様子
アナログ入力をしてみる
さて、今度はいろいろといじってみよう。
Raspberry PiとArduinoにはいろいろと違いがある。その違い認識は世間ではもうとうの昔に確定済みであるようだが、私はその無視できない一つが「アナログ入力のあるなしではないだろうか?」と思い至っている。
Arduinoはシンプルで扱いやすいにもかかわらず、10ビットのアナログ入力が6個もあり、これは意外と使い応えがある。抵抗やポテンショメータ、サーミスタ、CDSセル、音声など、実にいろいろなものをつなぐことができるのだ。
だが、Raspberry Piにはアナログ入力は、ない。
アナログ入力をしたければ、手段の一つに「Arduinoをつなぐ」というのがある。Arduinoを持っているなら、これは良い手段だが、なんだか無駄が大きい。
もう一つが、「A/D変換器をつなぐ」ということだ。A/D変換IC、つまり「ADC」は、百何十円~数百円だから安い。合理的である。
これについて解説しておられるサイトはたくさんある。それを参考にさせていただき、早速秋葉原へ行って2種類ばかりICを買い込む。
これは、マイクロチップ・テクノロジー社製の「MCP3008-I/P」。8チャンネル10ビット、千石電商で320円。
MCP3008-I/P
コッチは、同じくマイクロチップ・テクノロジー社の「MCP3208-CI/P」。こちらも8チャンネルだが、幅は12ビット。秋月電子でソケット付き、データシート付きで320円。
MCP3208-CI/P
ついでにこの前壊したTLC5940NTも二つ買い込む。これも390円。
TLC5940NT
で、まずはMCP3208から試してみよう。
Raspberry PiとICは、SPI通信でつなぐ。そのため、まず、Raspberry PiでSPI通信を行う要領を知る必要がある。
Raspberry Piの場合は、SPIのモジュールをインストールしたり、ブラックリストから外すなどの着意が必要であったようだが、Raspberry Pi 2 の場合は、どうやらそのような操作は必要がなく、「# raspi-config」でAdvancedの中からSPIを選び、enableにすればよい。
lsmodで確認し、次のように「spi_bcm2835」というモジュールが入っていればSPIが使える。
$ lsmod
Module Size Used by
cfg80211 420690 0
rfkill 16659 1 cfg80211
snd_bcm2835 19769 0
snd_pcm 74825 1 snd_bcm2835
snd_seq 53561 0
snd_seq_device 3650 1 snd_seq
snd_timer 18157 2 snd_pcm,snd_seq
snd 52116 5 snd_bcm2835,snd_timer,snd_pcm,snd_seq,snd_seq_device
8192cu 528485 0
spi_bcm2835 7100 0
i2c_bcm2708 5014 0
uio_pdrv_genirq 2966 0
uio 8235 1 uio_pdrv_genirq
さっそくブレッドボードにMCP3208を配置し宮城大学のサイトの記事にあるコードを使わせてもらったのだが、これがそのままでは動かず、ハマッた、ハマッた……。
ブレッドボードの状況
何か、Raspberry PiとRaspberry Pi 2 で、ioctrlに渡すデータ長に違いでもあるらしく、かなり試行錯誤した末、このようになった。
宮城大学のサイトにあった元のコード(“raspSPI.cpp”内)
// sendRecN: Nバイトデータの送信と受信(2048バイトまで)
void SPI::sendRecN (unsigned char *send, unsigned char *rec, int n)
{
// setup a block
struct spi_ioc_transfer tr[1];
tr[0].tx_buf = (unsigned int) send;
tr[0].rx_buf = (unsigned int) rec;
tr[0].len = n;
tr[0].speed_hz = clock;
tr[0].delay_usecs = SPI_DELAY;
tr[0].bits_per_word = SPI_BITS;
tr[0].cs_change = 0;
// send this byte
int ret = ioctl(fd, SPI_IOC_MESSAGE(1), tr);
if (ret < 0) {
printf("error: cannot send spi message (SPI::sendRecN)\n");
exit(-1);
}
}
Raspberry Pi model Bで動くように少し変更したコード(tr[]の個数と、tr[0]に渡す値のキャストを「int」から「unsigned long」に変更している)
// sendRecN: Nバイトデータの送信と受信(2048バイトまで)
void SPI::sendRecN (unsigned char *send, unsigned char *rec, int n)
{
// setup a block
struct spi_ioc_transfer tr[3];
tr[0].tx_buf = (unsigned long) send;
tr[0].rx_buf = (unsigned long) rec;
tr[0].len = n;
tr[0].speed_hz = clock;
tr[0].delay_usecs = SPI_DELAY;
tr[0].bits_per_word = SPI_BITS;
tr[0].cs_change = 0;
// send this byte
int ret = ioctl(fd, SPI_IOC_MESSAGE(1), tr);
if (ret < 0) {
printf("error: cannot send spi message (SPI::sendRecN)\n");
exit(-1);
}
}
(作動させた画面の様子)
1132 867 827 829 833 838 877 2670
1090 829 787 787 792 797 845 2668
1028 768 725 721 724 732 796 2671
929 678 631 623 625 636 737 2669
791 534 471 444 429 435 572 2667
408 172 94 54 29 53 281 2668
84 0 0 0 0 0 111 2666
0 0 0 0 0 0 20 2671
0 0 0 0 0 0 0 2670
0 0 0 0 0 0 0 2668
19 29 34 39 41 36 27 2670
87 93 101 110 114 107 81 2670
173 173 183 195 201 186 146 2671
274 276 300 327 347 339 276 2667
614 609 650 692 727 698 552 2668
948 901 907 902 911 916 741 2672
1102 916 878 886 894 899 854 2670
1160 888 865 868 873 878 913 2671
1137 872 832 833 838 843 903 2665
1093 830 788 787 792 796 869 2668
1027 767 723 717 721 727 815 2669
938 685 638 631 632 643 748 2669
821 566 504 482 467 474 603 2665
447 206 128 89 62 85 303 2669
107 0 0 0 0 0 123 2670
0 0 0 0 0 0 32 2669
0 0 0 0 0 0 0 2667
0 0 0 0 0 0 0 2670
14 23 29 34 37 32 29 2669
81 86 94 102 104 98 80 2665
170 167 177 186 191 174 141 2671
267 267 290 314 333 323 263 2668
598 593 631 669 702 672 536 2670
936 888 908 904 913 914 723 2669
1098 917 876 888 894 899 840 2668
1157 895 864 869 875 878 904 2668
1138 873 834 835 841 844 902 2667
7番ピンにポテンショメータをつなぎ、残りのピンは解放してあるので、乱雑な値が出ている。