motionを使ってRaspberryPiからUSBカメラの映像をストリーミングする方法
motionのインストール
sudo apt-get install motion
設定の変更
sudo vi /etc/motion/motion.conf ### USBカメラの設定をする(解像度やFramerate) 89 # Image width (pixels). Valid range: Camera dependent, default: 352 90 width 320 91 92 # Image height (pixels). Valid range: Camera dependent, default: 288 93 height 240 94 95 # Maximum number of frames to be captured per second. 96 # Valid range: 2-100. Default: 100 (almost no limit). 97 framerate 2 ### 画像ファイルとして保存する機能は今回はoffにする 250 output_pictures off ### Streamingの設定をする 473 # Maximum framerate for stream streams (default: 1) 474 stream_maxrate 2 475 476 # Restrict stream connections to localhost only (default: on) 477 stream_localhost off
motion起動
sudo motion -n
確認
以下のURLにアクセスして映像が確認できれば完了
http://{raspberryPiのIP}:8081
ただしMJPG-stremerに比べて3秒前後の遅延が発生する。
USBカメラの解像度等の情報を確認する方法
deviceの確認
まずはカメラを接続したらlsusbで認識されているか確認します
$ lsusb Bus 001 Device 005: ID 288c:0002 # <== これが追加された Bus 001 Device 007: ID 05ac:0222 Apple, Inc. Aluminum Keyboard (JIS) Bus 001 Device 006: ID 04ca:0061 Lite-On Technology Corp. Bus 001 Device 004: ID 05ac:1006 Apple, Inc. Hub in Aluminum Keyboard Bus 001 Device 003: ID 0424:ec00 Standard Microsystems Corp. SMSC9512/9514 Fast Ethernet Adapter 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 005にUSBカメラが設定されています。
このときカメラの製造元や会社の名前が出てくるときと出てこない場合があります
各項目の確認
概要確認
$ v4l2-ctl -d 0 --info Driver Info (not using libv4l2): Driver name : uvcvideo Card type : MS-M103HU Bus info : usb-3f980000.usb-1.5 Driver version: 4.4.11 Capabilities : 0x84200001 Video Capture Streaming Extended Pix Format Device Capabilities Device Caps : 0x04200001 Video Capture Streaming Extended Pix Format
全項目確認
$ v4l2-ctl -d 0 --all Driver Info (not using libv4l2): Driver name : uvcvideo Card type : MS-M103HU Bus info : usb-3f980000.usb-1.5 Driver version: 4.4.11 Capabilities : 0x84200001 Video Capture Streaming Extended Pix Format ・ ・ ・
対応解像度&FPS確認
$ v4l2-ctl -d 0 --list-formats-ext ioctl: VIDIOC_ENUM_FMT Index : 0 Type : Video Capture Pixel Format: 'YUYV' Name : YUYV 4:2:2 Size: Discrete 1280x720 Interval: Discrete 0.083s (12.000 fps) Index : 1 Type : Video Capture Pixel Format: 'MJPG' (compressed) Name : Motion-JPEG Size: Discrete 1280x720 Interval: Discrete 0.033s (30.000 fps)
lsusbでも確認できる
$ lsusb -s 001:005 -v | egrep "Width|Height" Couldn't open device, some information will be missing wWidth 1280 wHeight 720 wWidth( 0) 1280 wHeight( 0) 720 wWidth 1280 wHeight 720 wWidth( 0) 1280 wHeight( 0) 720
low voltage detected, date/time is not reliable.
エラー文
RaspberryPiでRTCから時刻合わせをしようとすると以下のようなエラーが出ることがある。
Jan 01 23:11:11 raspberrypi kernel: [ 131.098038] rtc-pcf8563 1-0051: low voltage detected, date/time is not reliable.
ちなみに使ったRTCはこちら
リアルタイムクロック(RTC)モジュール: 半導体 秋月電子通商 電子部品 ネット通販
エラーの意味としては『電圧低下が検知されたよ。だから今の時刻データは信頼できないよ。』って感じの警告だ。
調査
アプリケーションノートを読んでみると、RTCへの電源供給の電圧が一定以下になった場合、VLflag(Voltage Low Flag)が立つらしい。
対応
ちなみにこのVLフラグは秒数を管理しているメモリ区域で管理されている
なので上記のエラー文を出したくなければ、VLフラグを0クリアしてやればエラーは出なくなる。
RubyのThreadのステータスに関して
class Thread (Ruby 2.4.0)
instance method Thread#status (Ruby 2.4.0)
instance method Thread#alive? (Ruby 2.4.0)
Rubyのスレッドに関して各ケースのステータスまとめ
各項目がとる値
- thread object(thread.inspect)
- run
- sleep
- aborting
- dead
- thread.status
- run
- sleep
- false
- nil
- thread.alive?
- true
- false
調査
通常時(スレッドが生きているとき)
ソース
t1 = Thread.start{ loop do sleep 1 end } loop do p t1 # run, sleep, aborting, dead puts t1.status || t1.status.class # run, sleep, false, nil puts t1.alive? # true, false puts "--------------------------------" sleep 1 end
実行結果
#<Thread:0x55e80d30 sleep> run true -------------------------------- #<Thread:0x55e80d30 sleep> run true -------------------------------- #<Thread:0x55e80d30 sleep> run true --------------------------------
各ステータス
- thread object : (run), sleep
- thread.status : run, (sleep)
- thread.alive? : true
正常終了時
ソース
t1 = Thread.start{ 2.times{|n| sleep 1 puts n+1 } } loop do p t1 puts t1.status || t1.status.class # run, sleep, aborting, false, nil puts t1.alive? # true, false puts "--------------------------------" sleep 1 end
実行結果
#<Thread:0x566a0c48 run> sleep true -------------------------------- 1 #<Thread:0x566a0c48 sleep> sleep true -------------------------------- 2 #<Thread:0x566a0c48 dead> FalseClass false -------------------------------- #<Thread:0x566a0c48 dead> FalseClass false -------------------------------- #<Thread:0x566a0c48 dead> FalseClass false --------------------------------
各ステータス
- thread object : dead
- thread.status : false
- thread.alive? : false
異常終了時
ソース
t1 = Thread.start{ 2.times{|n| sleep 1 puts n+1 } raise } loop do p t1 puts t1.status || t1.status.class # run, sleep, aborting, false, nil puts t1.alive? # true, false puts "--------------------------------" sleep 1 end
実行結果
#<Thread:0x558e8bf0 run> sleep true -------------------------------- #<Thread:0x558e8bf0 run> sleep 1 true -------------------------------- #<Thread:0x558e8bf0 run> 2 sleep false -------------------------------- #<Thread:0x558e8bf0 dead> NilClass false -------------------------------- #<Thread:0x558e8bf0 dead> NilClass false
各ステータス
- thread object : dead
- thread.status : nil
- thread.alive? : false
まとめると
- thread.statusはスレッドが生きている間はrunかsleepで、正常終了するとfalseになり、異常終了するとnilになる
- thread.alive?はスレッドが生きている間はtrueで、終了すると正常・異常に関わらずfalseになる
- thread情報を直接見ると、スレッドが生きている場合はrunかsleepで、終了処理中はabortingになり、完全に終了するとdeadになる
raspberryPiでRTCを使おうとしたときにargument Errorになる
前提条件として、raspberryPiにはRTCがついていないため、シャットダウンしてしまうと時間を保持しておくことが出来ない。
なので通常は起動時にntpでシステムの時刻をあわせるのだが、当然インターネット環境がない場合はその時間合わせをすること自体が出来ない。
そういう場合などのために個別にRTCを取り付けることが出来るのだが、以下のようにエラーが出てRTCへアクセスが出来ないことがたまにある。
hwclock: ioctl(RTC_RD_TIME) to /dev/rtcX to read the time failed: Invalid argument
調べていくと割とメジャーなつまづきポイントらしい。
Raspberry Pi • View topic - Wierd RTC(ds1307) problem
調べていくとfake_hwclockというものが悪さをしているらしく、上の方でraspberryPiにはRTC(hwclock)はついていないといったのだが、その代わりにのっているのがfake_hwclockらしい。
これは何かというと、普通ならば時刻データを保持できないのでネット環境がない場合は起動するたびに初期値の1970年1月1日0時0分0秒になってしまうのだが、
このfake_hwclockというシステムが有効化されていると、起動している時間を定期的(shutdown時にも?)にtxtとして保存しておき、次回起動時にこの時間を現在時刻として
使おうという機能である。
今回は本物のhwclockであるRTCとこのfake_hwclockが競合してしまったために上記のエラーが出たものと思われる。
解決方法としてはこいつを無効化してやればよい。
sudo update-rc.d fake-hwclock disable
これで競合することはなくなり、上記のエラーが出ることもなくなった。
raspberryPi3のIPを固定する方法(static ip)
raspberryPiは通常自動でIPをアサインしてくれますが、それでは困る場合などに固定IPアドレスにする方法です。
raspbianのversion upに伴い、raspberryPi2の時とは方法が変わっているようです。
ちなみにversionは8.0です
$ cat /etc/debian_version 8.0
/etc/network/interfacesの確認
$ cat /etc/network/interfaces # interfaces(5) file used by ifup(8) and ifdown(8) # Please note that this file is written to be used with dhcpcd # For static IP, consult /etc/dhcpcd.conf and 'man dhcpcd.conf' # Include files from /etc/network/interfaces.d: source-directory /etc/network/interfaces.d auto lo iface lo inet loopback iface eth0 inet manual allow-hotplug wlan0 iface wlan0 inet manual wpa-conf /etc/wpa_supplicant/wpa_supplicant.conf allow-hotplug wlan1 iface wlan1 inet manual wpa-conf /etc/wpa_supplicant/wpa_supplicant.conf
上のほうのコメントを見ると、staticIPにするにはdhcpcd.confを編集すればよいことがわかります。
とりあえず書かれている通りにmanを見ます
$ man dhcpcd.conf static value Configures a static value. If you set ip_address then dhcpcd will not attempt to obtain a lease and just use the value for the address with an infinite lease time. Here is an example which configures a static address, routes and dns. interface eth0 static ip_address=192.168.0.10/24 static routers=192.168.0.1 static domain_name_servers=192.168.0.1 Here is an example for PPP which gives the destination a default route. It uses the special desti- nation keyword to insert the destination address into the value. interface ppp0 static ip_address= destination routers
staticで検索すると上記のような記入例が出てくるので、自分のIPに変更して実際に書き込みます
/etc/dhcpcd.confの編集
$ vi /etc/dhcpcd.conf ### ファイル末尾に追加 interface eth0 static ip_address=192.168.0.10/24 static routers=192.168.0.1 static domain_name_servers=192.168.0.1 ### wifi(wlan0)の場合は interface wlan0 . . .
これで完了です。
後はraspberryPiを再起動して設定したIPでアクセスできることが確認できればOKです。
raspberryPi3へWiringPiGPIOを設定する手順
GPIO:General Purpose Input/Output
$ git clone git://git.drogon.net/wiringPi Cloning into 'wiringPi'... . . . Checking connectivity... done. $ ls -l total 4 drwxr-xr-x 10 pi pi 4096 Nov 29 15:10 wiringPi $ cd wiringPi/ ./build wiringPi Build script . . . All Done. . . . $ gpio -v gpio version: 2.32 Copyright (c) 2012-2015 Gordon Henderson This is free software with ABSOLUTELY NO WARRANTY. For details type: gpio -warranty Raspberry Pi Details: Type: Pi 3, Revision: 02, Memory: 1024MB, Maker: Embest * Device tree is enabled. * This Raspberry Pi supports user-level GPIO access. -> See the man-page for more details -> ie. export WIRINGPI_GPIOMEM=1