とりあえず無線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ケーブル抜いて電源を入れなおす。
サクッとつながる。ケーブルがだらだらつながっていたのが減って、これはとてもいいなあ。
アナログ入力をしてみる
さて、今度はいろいろといじってみよう。
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円。
コッチは、同じくマイクロチップ・テクノロジー社の「MCP3208-CI/P」。こちらも8チャンネルだが、幅は12ビット。秋月電子でソケット付き、データシート付きで320円。
ついでにこの前壊したTLC5940NTも二つ買い込む。これも390円。
で、まずは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番ピンにポテンショメータをつなぎ、残りのピンは解放してあるので、乱雑な値が出ている。
私もこの件で3日悩んでいます(^_^;
SPI::sendRecN の if (ret < 0) のチェックで必ず引っかかり前に進みませんでしたので、当記事を参考にさせていただいたのですが、改善せずです。
Rasperry Pi 2 からドライバ関係のセットアップが rasp-config に変更になったため、まだあまり参考記事がなく困っています。
よろしければ、SPI::sendRecN の修正箇所を見つけた方法を教えていただけますでしょうか。
よろしくお願い致します。
すみません。
些細なところをミスっているのを発見して修正したら動きました(^_^;
非常に助かりました。
ありがとうございました。
返信する時間がなく、今日になりました。私が返信する前にうまく動いたとのことで、何よりです。
見つけた方法は、どなたかがyahoo知恵袋に次のように書いておられるのを見つけ……
http://note.chiebukuro.yahoo.co.jp/detail/n352937
そこで、念のため
/usr/include/linux/spi/spidev.h
……を開いて「spi_ioc_transfer」の定義を見ていきますと、問題のtx_bufとrx_bufは
struct spi_ioc_transfer {
__u64 tx_buf;
__u64 rx_buf;
・
・
・
……と定義されており、元のunsigned intは32ビットですから、大きさが違うな、ということを見て取った次第です。
ただし、修正版のunsigned longも32ビットですので、これも違うと言えば違うんですよね……(苦笑)。
ここからは実はよく確かめていないのですが、元のソースコードの配列の個数を1個から3個に増やしていることなどでなんとなく吸収しているのかな……などと思っています。
もし試すとすると、配列の個数を元に戻し、「#include <linux/types.h>」を足して、キャストを「(unsigned long)」から「(__u64)」にしてみる、などもあるかもしれません(私は試してません)。
お忙しいところ返信ありがとうございます。
配列数を3のままにして、unsigned intに戻しても無事通っているので、3で吸収できているような気もします。
また何かわかりましたらお知らせ致します。
当関数は通るようになったのですが、表示データがずっと”0″という現象に悩んでいます。
オシロスコープでSPI関連端子をモニターしたところ、SPI信号は皆無でした。
ポートがSPIモードになっていないのではないかと思っています。
lamod でモジュールを教示させると、
spi-bcm2835
i2c_bcm2708
この二つが表示されています。
あちこちのサイトにあるspidevは表示されていません。
佐藤様の環境ではspidevは表示されていますでしょうか?
よろしくお願い致します。
lamodではなくlsmodの間違いです。
失礼しました。
>Satoshi Higa 様
今、現に動いている最中の私の環境では、次のようになっております。
$ 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
evdev 10232 0
joydev 9047 0
i2c_bcm2708 5014 0
spi_bcm2835 7100 0
uio_pdrv_genirq 2966 0
uio 8235 1 uio_pdrv_genirq
8192cu 528485 0
この状態で、温度を測る試みができております。
実は、私も、コンパイルが通るようになってから、ゼロばかり出てくる、ということに悩まされまして、その時はソフトウェアではなく、結線ミスでした。
これもよく確かめていないのですが、結線ミスを2回やってしまいました。結局うまく動いたので、それで原因を確かめていないのです。2回同じ結線ミスをしたということは、参照しているどれかの資料が、一部間違っているのかな、と、今、急に思い至りました次第です。
ひょっとすると、私とSatoshi Higa様と、何か、同じ資料で、同じ結線ミスをしているのかもしれないな、と、今ちょっと思ったのです。
佐藤様、お忙しいところ有益なコメントありがとうございます。
加藤様のコメントをきっかけに、ハードウェアをとことんチェックしてみました。
まずADコンバータを造りこんだ拡張基板を外して、ピンヘッダを直接オシロスコープでモニターしたところ、SPI信号は正しく出力されていることが確認されました。
これでソフトウェアの問題はクリアとなりました。
そこで拡張基板上の回路を徹底的にチェックしたところ、配線は間違っていなかったのですが、3.3V→5Vのレベル変換チップが正しく動いていないことがわかりました。
明日新品の部品と取り換えて再度デバッグしてみます。
成功したらまたお知らせいたします。
すみません。
お名前間違えてしまいました。
申し訳ありませんでした。
全然大丈夫ッスw
多少なりともお役に立てたようなことで、何よりです。
こうして文字列を露出させておけば、正しい正しくないはさておき、似たようなことを試す多くの方が私たちの行動を参考にすると思いますので、有益なことと思います。
私としては、アナログの入力には少し知見を得ましたので、今度はRaspberry Piから、どうにかしてアナログの出力を得たいものと考えております。
無事解決しました!
レベルコンバータのイネーブルロジックを勘違いしていたのと、なんやかんやでADコンバータチップを壊してしまったようで、イネーブルロジックを反転してADコンバータを取り換えたところ、ちゃんと何らかのデータを出力するようになりました。
これまでお忙しい中ご協力ありがとうございました。
これでやっと次のステップへ進められます。
重ねてお礼申し上げます。
今回の回路の用途は特定用途のオシロスコープの試作機になります。佐藤様もアナログデータを扱われたいとのことですので、アナログ系で何らかの恩返しができればと思います。
なので引き続きブログをフォローさせていただきます。
※この一連のメッセージで救われる人がいれば何よりですね。
無事にご解決とのこと、なによりです。ADCが壊れていたとのこと。私は先日、LEDドライバICを壊しましたが、それは3端子レギュレータで定格電圧を印加してからArduinoでロジックを入れたところ、どうも順序の違いによるものでしょうか、あっさりと壊れてしまいました。私ももう少し精進したいと思っております。
特定用途のオシロスコープをご製作中とのこと、難しいものを手掛けておられて、驚き入るばかりです。
私は、アナログ出力を試して、それから、少年時代は別として、あまり「モーターで動くもの」をやっておりませんので、なにかそういうことをやってみようかな、と思っているところです。