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
Rubyでシリアル通信する方法(serialport gem)
Rubyでシリアル通信する場合は、serialport gemを使うと簡単にできます。
install serial port
$ gem install serialport
How to Use
require 'serialport' sp = SerialPort.new('/dev/ttyS0', 115200, 8, 1, 0) # device, rate, data, stop, parity # 送信 sp.puts("foobar") # 受信 sp.gets sp.readline.chomp.strip # こっちだと空白とか余分な情報をそぎ落としてくれる
sinatraでhashデータをJSONとして返す方法
方法
require 'json' return #{hash}.to_json
例
require 'sinatra' require 'json' get '/top' do hash = { "key1" => 1, "key2" => 2, "key3" => 3, } return hash.to_json end