ラベル RaspberryPi の投稿を表示しています。 すべての投稿を表示
ラベル RaspberryPi の投稿を表示しています。 すべての投稿を表示

2016年4月27日水曜日

ラズパイ2BのAP化~続き

ちょっと前に説明したAP化ですが、どうやら不安定なので対策することにしました。できればログインしたと同時にAP立てたいし。

なにが問題かというと、起動してすぐに
sudo hostapd /etc/hostapd/hostapd.conf
を実行しても
nl80211: could not configure driver mode
nl80211: deinit ifname=(interface name) disabled_11b_rates=0
nl80211: driver initialization failed.
みたいなこと言ってきて立ち上がりません。 この状態からアダプタを脱着すればちゃんとAP化できるので、これまではそれで誤魔化していましたが、実戦投入するに当たってこれは不都合なので対策を打つことにしました。

http://askubuntu.com/questions/472794/hostapd-error-nl80211-could-not-configure-driver-mode

ここにある回答の通りです。
sudo nmcli nm wifi off (←もしダメならsudo nmcli radio wifi off)
sudo rfkill unblock wlan

sudo ifconfig wlan0 10.15.0.1/24 up
sleep 1 (←bashで実装する場合に1秒待機させるためと思われる)
sudo service isc-dhcp-server restart
sudo service hostapd restart
最後から2番目はDHCPサーバーの再起動なので、DHCP使わない場合は省略します。それで、sleep 1ってのがあるので、どうみてもbashスクリプト向けだからやってみました。問題はservice hostapd restartで、これそのままスクリプトに入れるとエラーが返されます。そこで直接サービスが再起動できるように、http://www.ksknet.net/linux/post_57.htmlを参考に
sudo /etc/init.d/hostpapd restart
としました。

他にもhostapdを入れ替える手段があるそうです。
http://qiita.com/arc279/items/21a3cda14f7dfdb267ca

http://ftp.ubuntu.com/ubuntu/pool/universe/w/wpa/

2016年4月14日木曜日

wiringPiでGPIOをsudoなしで実行する

別端末から接続しようとするとsudoがネックになる。特に別端末側でもラズパイを走らせて、そっち側のGPIOの入力によって(具体的にはスイッチでHigh, Low切り替えてHighになったときに)元の端末のGPIO出力を変える(スクリプトなりプログラムを実行する)というのが難しい(sudoのパスワード入力が問題になる)。そこでsudoなしでGPIOをいじれるようにしたい。

キーワードでいうと「gpio without sudo」とか「raspberry pi gpio without sudo」ってやつ。GPIOをwiringPiを使ってC言語によって操作したい時は通常sudoが必要(以下はsudoが必要としているサイト)

https://learn.sparkfun.com/tutorials/raspberry-gpio/c-wiringpi-example
sudo ./blinker
http://kaiware007.hatenablog.jp/entry/2015/07/07/024930
実行はroot権限が必要だった。
http://make.bcde.jp/raspberry-pi/gpio%e3%81%a7led%e3%81%ae%e7%82%b9%e6%bb%85python/
 sudoで実行するのは、GPIOの制御は、rootにのみ権限があるためです。
https://tool-lab.com/2013/12/raspi-gpio-controlling-command-2/
コンパイルした実行ファイルはpiユーザとして(一般ユーザ権限で)実行されますので、sudoをつけます。

しかしこれは不便!
【解決策】
前回の例にあったwiringPiSetup()またはwiringPiSetupGPIO()の代替としてwiringPiSetupSys ()を使ってバイナリを作成。また本体起動後、バイナリ実行前に
gpio export #port out
を実行する。

参考→https://www.raspberrypi.org/forums/viewtopic.php?f=33&t=16897

スクリプトでgpio export 17 outとかすればOKだし、ついでにそのスクリプトにバイナリ実行する部分も含めちゃえばお手軽。

なおwiringPiSetup()を使っていた場合はポート番号が変わる点に注意。たとえばGPIO 17の場合のポート番号は、wiringPiSetup()なら0だけどwiringPiSetupSys ()なら17を指定する。

たしかにwiringpi.comのリファレンスを見ると
  • wiringPiSetup (void) ;
This initialises wiringPi and assumes that the calling program is going to be using the wiringPi pin numbering scheme. This is a simplified numbering scheme which provides a mapping from virtual pin numbers 0 through 16 to the real underlying Broadcom GPIO pin numbers. See the pins page for a table which maps thewiringPi pin number to the Broadcom GPIO pin number to the physical location on the edge connector.
This function needs to be called with root privileges.
  • wiringPiSetupGpio (void) ;
This is identical to above, however it allows the calling programs to use the Broadcom GPIO pin numbers directly with no re-mapping.
As above, this function needs to be called with root privileges, and note that some pins are different from revision 1 to revision 2 boards.
これら2つはthis function needs to be called with root privilegesとあるので、これがsudoとしなければならない理由です。ところがwiringPiSetupSysは
  • wiringPiSetupSys (void) ;
This initialises wiringPi but uses the /sys/class/gpio interface rather than accessing the hardware directly. This can be called as a non-root user provided the GPIO pins have been exported before-hand using the gpio program. Pin numbering in this mode is the native Broadcom GPIO numbers – the same as wiringPiSetupGpio()
This can be called as a non-root userなのでsudoなしでOKということです。

そもそもなんでこんなことが必要になったかというと、前回に述べたとおりSSH経由でコマンド実行しようとしたためで、手入力でいいなら以下のように
http://qiita.com/yutaro1985/items/e01586c263fb16fec9ba

すればパスワードを入力することで実行可能
ssh -t username@IPaddress sudo ./program
だけどこれだと2回もパスワードを入力するよう(1回目はSSH接続のため、2回目はsudo実行のため)で手間

最初のSSHでログインするときのパスワードはRSA鍵で解決できる
http://ubuntu.u-aizu.ac.jp/004/index.html
http://kappa-bioinformatics.blogspot.ca/2014_03_01_archive.html

けど、sudoはどうやるか分からないのでググった

https://www.reddit.com/r/raspberry_pi/comments/3lo0gt/is_there_a_way_to_use_gpio_without_root/
http://askubuntu.com/questions/39281/how-to-run-an-application-using-sudo-without-a-password

それによるとsetuidという方法(http://www.cyberciti.biz/faq/unix-bsd-linux-setuid-file/を参照)の他に
sudo visudo
で例外指定すればいいという(ただしバイナリを直接指定する必要がある)のでやり方を調べる。

http://qiita.com/yuku_t/items/5f995bb0dfc894c9f2df
http://ryodotanaka.github.io/ubuntu/2015/02/09/ubuntu-without-passwd/

ちなみにsudo visudoで起動するのはviじゃなくてnano(なぜ?)なので操作性は問題ないけど、でも肝心のバイナリの指定が分からない。これはsudoが必要なのは、ソースの中でもwiringPiSetup()なりwiringPiSetupGPIO()だけなので、ソースを指定すればいいわけではないため。こんなのも見つかったけど、どうも動かない
https://dissectionbydavid.wordpress.com/2013/10/21/raspberry-pi-using-gpio-wiringpi-without-root-sudo-access/

グループが原因か?と思ってグループの追加方法(gpasswd)も調べた
http://qiita.com/orangain/items/056db6ffc16d765a8187
http://d.hatena.ne.jp/thegoodbadugly/20130116/1358316032
 % sudo usermod -G subversion user # ダメ!
だからこのサイトのような「usermod -G」は禁止

これらのページに沿ってgpioというグループに属させたけど、それでも動かなかった。そして最終的に先に述べた方法にたどり着いた。

ところでPythonで同じくやるにはどうすればいいんだろう。

ラズパイのGPIOを使ってカメラのレリーズをコントロールしよう

ひとまずはGPIOで2.5ミニピンジャックを制御していけばOK

目標はこんなの
https://www.zugyuuun.com/examples/io_relay.php

ひとまずはもっと簡便な構成にします。GPIOを使ったLED点灯がすべての基本。LEDで遊ぶ場合は必ず電流制限抵抗を入れるように!(うっかり忘れて1つ燃やした!!!)

手動でGPIOの動作チェック
https://tool-lab.com/2013/12/raspi-gpio-controlling-command-2/
http://mas-home.hatenablog.com/entry/2013/01/06/204616
 gpio -g mode 18 out
これで出力モードになるので、続けて
 gpio -g write 18 1
LED点灯するはず。そして
gpio -g write 18 0
で消灯。

次にC言語でちゃんとしたプログラムを書く(wiringPiをインストールする。gitとgccは入ってなかったらインストール)

http://mas-home.hatenablog.com/entry/2013/01/06/204616
http://make.bcde.jp/raspberry-pi/gpio%e3%81%a7led%e3%81%ae%e7%82%b9%e6%bb%85c%e8%a8%80%e8%aa%9e/
 gcc -o sample wiringpi_sample.c -lwiringPi
これで
sudo ./sample
でLED明滅が完成(sudo不要にする方法は次回)。wiringPiSetup()を使ったときに必要になる物理端子番号(左上が1で右下が40)とwiringPiにおける番号とGPIOの端子の番号の対応は、ここに掲載されている
http://blog.negativemind.com/2015/04/14/raspberry-pi-2-gpio-pin/
http://usicolog.nomaki.jp/engineering/raspberryPi/raspberryPi2_GPIO.html

このままだと端子の制御に使えないので、トランジスタで電子スイッチにする。
http://startelc.com/elc/elc_3_7Tr2sw.html

アイディアとしては、GPIOの出力を10 kΩ通してトランジスタのベースに入れる。このときGPIOがhighならトランジスタがONでlowならトランジスタがOFFになる。
http://www.onsemi.com/pub_link/Collateral/BC546-D.PDF

カメラの制御は一番の根元がGNDで真ん中が「半押し」でチップ(先端)が「全押し」になっているから、トランジスタのエミッタはラズパイのGNDかつカメラの「根元」にする。コレクタには真ん中 or チップを接続する。そうすればベースの電位が高いときにコレクタ→エミッタの電流が流れてショート状態になるからシャッターが切れる。

注意点は、全押しと半押しの両方がONじゃないとシャッターが切れないこと。手元のD810Aで見た限りだと全押しだけGNDに落としてもシャッターは切れなくて、半押しもGNDに落とさないといけない。ひとつの手法はコレクタに半押しと全押しの両方を同時に接続することで、もう一つの手法は、半押しに対応するトランジスタをONにしてから、そのまま続けて全押しに対応するトランジスタをONにする。

ここまでできれば制御そのものは完成したので、前に述べたようにしてAPを設置し、別の端末からSSHを通して接続し、コマンドを実行すればいいということになる。

次回に続く

ラズパイ2B+にUbuntu入れてAP化させる

OSはラズビアンが定番ですが、なんかWi-Fiが思い通りに動かなかったのでUbuntuにしました。15.10以降は簡単にインストールできるようになっていて、次期バージョンがLTSの16.04なので遊びが終わったら16.04にする予定。

https://ubuntu-mate.org/raspberry-pi/

micro SDHCは8 GBのを使いましたが、インストールが終わった時点だと4 GBしか使えない状態になっているので別のLinuxでGpartedによって8 GBフルに使えるようにします。

続いてAP化。作業に入る前にWi-FiアダプタがAP対応かチェック

http://askubuntu.com/questions/180733/how-to-setup-an-access-point-mode-wi-fi-hotspot

iwが入ってなければインストールしてから
iw list
を実行してこれで
Supported interface modes:
         * IBSS
         * managed
         * AP
         * AP/VLAN
         * monitor
         * mesh point
 が出ることを確認する。確認できたらインターフェース名をチェック
 nmcli dev status
ここで該当するデバイス名(通常だとwlan0とか簡単なのが出てくるはずなのに、どういうわけかwlx000ナントカってすごい長い名称だった)を記録する。ip aでも一覧が出せる。以降は

http://maruchan-shiro123.hatenablog.com/entry/2015/04/05/175257

を参考に
sudo systemctl stop network-manager
でnetwork-managerを無効化する。http://xmodulo.com/disable-network-manager-linux.htmlを見る限りだと、今回の手法はDebian 8以降の手法でUbuntuの手法ではないが、Ubuntuの手法が使えなかったので仕方ない。次にhostapdインストール
sudo apt-get install hostapd
さらに/etc/hostapd/hostapd.confを設定する。ドライバはnl80211で、インターフェースはテンプレのwlan0からさっきのに変更する。

設定が終わったら次はIPアドレスの設定
sudo ifconfig (iface) 192.168.xxx.xxx netmask 255.255.255.0

このIPアドレスは必ず既存のネットワークと異なるもの(既存が192.168.1.xなら192.168.2.xなど)を使うようにする。 どうやらこれだと毎回設定するようらしい(※未確認)ので、https://wiki.debian.org/NetworkConfigurationにあるように/etc/network/interfacesを設定

 あとはこれでAP化できる…はず
sudo /usr/sbin/hostapd /etc/hostapd/hostapd.conf
ひとまずクライアント側とサーバー側からpingが通るのをチェックするのが良い。

次回の課題はDHCPサーバーの設定だけど、今回のAPの設置目的はルーティングじゃないから、省略してもいいかな…
http://tmtms.hatenablog.com/entry/2012/11/17/002416
http://maruchan-shiro123.hatenablog.com/entry/2015/04/05/112530

そのほか参考になりそうなページ
http://karaage.hatenadiary.jp/entry/2015/11/04/073000
http://seriousbarbarian.blogspot.co.id/2013/08/raspberry-pi-ap_8.html
http://kkayataka.hatenablog.com/entry/2012/10/19/235609
http://d.hatena.ne.jp/penkoba/20130806/1375742819
http://qiita.com/kasei-san/items/087e5b33207c214c8db6
http://taker.hatenablog.jp/entry/2015/11/02/031218
http://herb.h.kobe-u.ac.jp/raspiinfo/raspiAP.html

AP設置して接続が不安定になったら読んでみようと思う(思うだけ)
https://community.netgear.com/t5/WiFi-Range-Extenders-Repeaters/WNAP320-Disconnects-clients-frequently/td-p/381449
http://forums.techarena.in/networking-security/1430491.htm