niszetの日記

10年目エンジニアが最近勉強したことを忘れないようにメモをする

(R/Rcpp/WiringPi/RasPi3) R on ラズパイで Lチカする。完結編

ようやくこのシリーズも終わり

長い道のりでしたが、ラズパイ上のR/RcppでwiringPiを使用することで、Lチカを確認できました。
前回のwiringPiをRcppから呼び出せた時点でほぼ完了していたわけですが、まぁけじめとしてちゃんとLチカさせないとね…ということで。

本題

さて、cppのソースは以下の通り。

#include <Rcpp.h>
#include <wiringPi.h>

using namespace Rcpp;

// [[Rcpp::export]]
int l_chika(NumericVector v)
{
  wiringPiSetup();
  pinMode(pin, OUTPUT);

  int pin =15;
  int cnt = 0;

  while(cnt < 5){
    digitalWrite(pin, 1);
    delay(500);
    digitalWrite(pin, 0);
    delay(500);
    cnt++;
  }
  return(0);
}

今回、ピンの番号をwiringPiの使用している番号を示すためにwiringPiSetup();を入れています。これがないと他の指定方法になってしまいますので注意。15番は右列の上から4番目、GPIO14でありPIN番号8であり、TXD0であるピンのことを指しています。

回路図がないと意味不明ですが、このIOの出力とGNDとの間にLEDと電流制限用の抵抗を入れています。GNDは右列三番目、PIN番号06を使用しています(20とか14とかでももちろんOKです)

これで500ms毎にLEDが光ったり消えたりをします。while(1)でも良かったのですが抜けられないと怖いのでまた適当にカウンタ回しています。引数のvは例のようにダミーの引数。今回はこれを秒に変えても良かったですね。

ここまで書いて気づきましたが、プログラム側だけではなんだかよくわかりませんね。最低限ハード側の接続や説明がないとなんのことやら…。

動画か、回路図か何かがないといけない…という課題を残しつつも、ひとまずこれにてラズパイ上でRを動かしてハードウェアの制御をおこなう部分については一旦区切りとします~

とはいえ、まだこれは入り口に過ぎないので、少しずつ何かやっていきます。

さて、次は何をしようかな。

Rcppを活用すれば、Rでもラズパイ使っていろいろ出来ることが伝わればいいなと思います。

Enjoy!!

(R/Rcpp/WiringPi/RasPi3) RからWiringPiを使ってみる

Lチカまであと一歩

さて、トランジスタ技術2016年3月号の付録、「全ラズパイ対応! 楽々I/O関数セットWiring Pi虎の巻」を読んでいるのですが、これは必携ですね…。すっきりとまとまっていて持ち運びしやすい。ラズパイでGPIOをいじってみたい人がもう一歩前に進むために必要な、wiringPiを使うために必要な情報がかなり網羅されていると思います。

2016年3月号

CD-ROM版には残念ながら付録の内容は含まれないのですよね。もったいない…。

WiringPiについて

こちらは付録に記載されていたパスですが、説明を見るとミラーサイト的な扱いぽいですね、こちら。 github.com

本家はこちら。 wiringpi.com

git cloneして./buildで導入完了というかなり導入が簡単なツールとなっています。
詳しくはこちらや

l-w-i.net

こちらなどを参考にしてください。

www.feijoa.jp

gpio -v

でバージョン情報が得られればOKです。

Rcppを使ってwiringPiをRから呼び出す

さて本題。まずはC++のコード(Rcpp仕様)です。

#include <Rcpp.h>
#include <wiringPi.h>

using namespace Rcpp;

// [[Rcpp::export]]
int get_boardrev(NumericVector v)
{
  int pbr; 
  pbr = piBoardRev();
  return(pbr);
}

#include <Rcpp.h>, using namespace Rcpp;, // [[Rcpp::export]]はRcppのおまじないですね。
詳しくはteuderさんの「みんなのRcpp」をご参照ください。

teuder.github.io

じぶんのRcpp力のなさの関係で、関数にはダミーの引数vを与えています。これをとると動かない。voidとかも書けない。デフォルト値も与え方がわかってないので、とりあえず動くものを…ということでご勘弁。

#include <wiringPi.h> は wiringPiを使用するために必要な、ヘッダファイルのインクルードです。
これとコンパイル時の-lwiringPiの指定がRcppからwiringPiを使うために必要(後述)です

処理の中身は、ラズパイの基板のリビジョンを得て(piBoardRev()の部分)、それを返却するというものです。初代は1、ラズパイ2は2が返ってくると付録には書かれていて、今回はラズパイ3を使用しましたがラズパイ2と同じく2が返ってきました。

wiringPiやこのあたりの関数については、先の付録が詳しいです。ネット上の良い資料はまだ探していません(付録で満足)

R側の記述は以下のようになります。

Sys.setenv("PKG_LIBS"="-lwiringPi")
library(Rcpp)
sourceCpp("test.cpp")

test.cppは先のcppのファイル名を入れてあげてください。
Rcppを使用するためlibrary(Rcpp)あるいはlibrary(“Rcpp”)が必要ですが、それとともにSys.setenv("PKG_LIBS"="-lwiringPi")が必要です。これは通常のC/Cppのビルド時に-lwiringPiとしている部分が必要なためです。

下記のように以前苦しんだことが役に立った…

niszet.hatenablog.com

このリンクの指定はパッケージ開発時はMakevarsなどに記載するものだと思いますが、sourceCpp()だとたぶん指定できないはず…。これ以外に方法ある!って知ってる方、ぜひ教えてください…。

これらを実行して、何も問題がなければ何も出力されずにRが入力待ちにもどります。sourceCppにenvironmentを指定しなければ、globalにget_boardrevの関数がいるはずです。引数に適当な整数を与えて実行すると…

get_boardrev(1)
# [1] 2

と、2が返ってくる(ラズパイ2,3の場合)と思います。
これで、RからRcppを使用してwiringPiの関数を実行して値の取得が出来ることが確認できました。(IO自体を見ているわけではないですけどね)

おわりに

さて、とりあえずこれでRからRcppを介してwiringPiの関数を呼び出せることが確認できました。
あとは、特定のGPIOに対してH/Lの制御を行い、LEDに電流を流してチカチカさせれば真の意味での「RでLチカ」の完成です。
さすがにRcpp部分をCで書いて…は今風ではないと思いますのでやりません。

今回も意外となんとかなりました。RでLチカまであともう少し!

Enjoy!!

(R/Py3/RP3) Rからpythonを呼び出してラズベリーパイ3とRainbowHATでLチカする

できた。

超遠回りですが、一応「RでLチカ」、略して「Rチカ」が出来ましたので、ご連絡。

一応ご注意を。

今回のコードを実行しても特に危険はないと思いますが、ハードウェアを操作する場合は色々と気を付ける必要があります(電圧レベルとか電流値とか、いろいろ)
なので、色々調べて理解してトライしてください。
調べたことはほぼ書いたりリンク貼ったりしているので、大体解決できるはず…(抜けているものもあると思いますが…)
まぁ、ネットにある情報を使って何かするのは基本的に自己責任なんだけど。

構成など

環境:

Raspberry Pi 3 Model B
OS : 2017-07-05-raspbian-jessie

R : sessioninfo

> sessionInfo()
R version 3.4.1 (2017-06-30)
Platform: armv7l-unknown-linux-gnueabihf (32-bit)
Running under: Raspbian GNU/Linux 8 (jessie)

Matrix products: default
BLAS: /usr/local/lib/R/lib/libRblas.so
LAPACK: /usr/local/lib/R/lib/libRlapack.so

locale:
 [1] LC_CTYPE=en_GB.UTF-8       LC_NUMERIC=C              
 [3] LC_TIME=en_GB.UTF-8        LC_COLLATE=en_GB.UTF-8    
 [5] LC_MONETARY=en_GB.UTF-8    LC_MESSAGES=en_GB.UTF-8   
 [7] LC_PAPER=en_GB.UTF-8       LC_NAME=C                 
 [9] LC_ADDRESS=C               LC_TELEPHONE=C            
[11] LC_MEASUREMENT=en_GB.UTF-8 LC_IDENTIFICATION=C       

attached base packages:
[1] stats     graphics  grDevices utils     datasets  methods   base     

other attached packages:
[1] PythonInR_0.1-3

loaded via a namespace (and not attached):
[1] compiler_3.4.1 R6_2.2.2       tools_3.4.1    pack_0.1-1   

Python : Python 2.7.9

RainbowHAT

実行

先にpython側でLチカを確認します。Rが悪いのかpyが悪いのかわからなくなるので。
今回は手元にRainbowHATがあって、ラズパイに刺さったままだったのでそれを使っていますが、ブレッドボードにLEDをつなげて~でももちろん出来ると思います(いずれやりますか…)

コードはこんな感じ。7つのLEDが0.1秒ごとに赤く光ります。結構綺麗。

import rainbowhat as rh
import time

ct = 0
while ct < 100:
    for pixel in range(7):
        rh.rainbow.clear()
        rh.rainbow.set_pixel(pixel, 255, 0, 0)
        rh.rainbow.show()
        time.sleep(0.1)
        ct = ct + 1

rh.rainbow.clear()
rh.rainbow.show()

最後にclearしないとLEDが消えないのでループ後に入れています。
Python単体だと、while True: でループしてEscで抜けても良いのですが(そのときLEDは消えた)、Rだとどうなるかわからないので適当な時間ループさせて抜けさせています。(whileじゃなくてfor使えよ)

RainbowHATについては以前の記事を参照してください。これを試すためにわざわざ買う必要はないですが、色々試すには便利といえば便利で面白い

さて、R側ですがpythonを呼ぶだけです。下記の通り。

# install.packages("PythonInR") # 入っていなければ
library(PythonInR)
PythonInR::pyExecfile("r_py_rainbow.py")

これだけ。pythonの方で完結しているので、Rからは呼び出すだけです。
結果はpythonと同じくLEDが綺麗に光るのでした。やったぜ

pyExecfileは指定したpythonスクリプトを実行するので、ファイル名やパスは適当に設定してください。
ラズパイ上でライブラリをインストールする(w/o RStudio)がちょっとなれなかったけどとくに難しさはなかったです。

参考リンク集

RからPythonを呼ぶ

探していて一番最初に見つけました。 RからPythonを使う諸々(のリンク集)kitayamalab.wordpress.com

PythonInRの実際のつかいかたはこちらを参考にしました。

qiita.com

ただ、上にあるようにpythonスクリプト自体を呼べるし、内部でimportしていればそれらの設定も不要、pythonで実行を確認してからRで動かすと思うので、実際に使うときはファイルをそのまま読む方法になるのかな、と。
こちらはR内で完結させている紹介記事だからですね。

このライブラリ、関数が結構多いので使いこなすには時間がかかるかも

RainbowHATの紹介

learn.pimoroni.com

雑多なこと

これと関係なく、SSHで接続できないことに気づいたのですが、デフォルトでSSHはinactiveになっているようです。

qiita.com

確かに、リンク先のこちらにも書かれていてその後特に変更なさそうです。というか、時期によって結構色々違うかも?ネットで情報探す場合はご注意。結局オリジナルを見る以外にないという話か。

http://downloads.raspberrypi.org/raspbian/release_notes.txt

今回、この記事の対応方法ではなく、単純にsshdを起動させました。

www.obenri.com

のとおり、

/etc/init.d/sshd status

で寝てることを確認したのち、

/etc/init.d/sshd start 

したらSSH接続できました。

課題

RainbowHATのライブラリを入れるときにミスったようでpython2系でしか動いていない(本当は3でも動くはず)ので、それは改善したい。 RのビルドはPC側でやってから転送したい、などなど。もうちょっと賢い方法が全体的にあるはずです。マサカリ待ってます。

結論

Rでもラズパイを使ってLチカできる!(実質python頼み)

でした。

次は

このあたりですね。

一方で、からあげさんの

karaage.hatenadiary.jp

の記事のとおり、GPIOライブラリではなくWiringPiライブラリを使っていく必要があるのかも。

まぁ、それも追々です。

というわけで、RからPythonで書かれたLチカコードを呼び出してラズパイ上でRainbow HATのLEDをチカチカさせる試み、一応の成功です。

Enjoy!!

(R/RP3) ラズベリーパイにRを入れる…(ちょっと加筆修正)

Rからpythonを呼び、pythonでGPIOを叩いてLチカするまでの長い道のりの一歩目

pythonからGPIOを経由して、外部のセンサやLEDをいじることが出来ましたので、今度はRでやっていこうと思います。

とはいえ、RむけのGPIOライブラリはおそらくなく、そもそもデフォルトの状態でR入っていないのでまずはRを導入するところから。

apt-getで楽する場合

こちらを参考にしました。

www.limemo.net

以下のコマンドを実行するだけです

sudo apt-get install r-base

ただし、この記事と同じ、R3.1.1が入ります。古っ。 とりあえず起動して

mean(1:10)

でちゃんと計算されることくらいにチェックは留め、R3.4.1を入れることにしました。

/etc/apt/source.listを見ると、mirrordirector.raspbian.orgとかになっていて、バイナリで得る方法は期待できないなということで。

ソースからビルドして頑張る場合

こちらから、欲しいバージョンを選んで落としてきます。 Index of /src/base/R-3

やることはこちらの、「Linuxでソースからのビルド」のような感じです。 www.okadajp.org

今回はこんな感じ。作業ディレクトリは適当に~/work/にして、ダウンロードしています。

wget https://cran.r-project.org/src/base/R-3/R-3.4.1.tar.gz

tar xvfz R-3.4.1.tar.gz

これで~/work/R-3.4.1/に解凍したファイルが出てくるので、

mv R-3.4.1
./configure
make
sudo make install

で入れました。configureは./configureにしないとデフォルト環境では実行されませんね。

configureでコケる

…が、configureで一度こけました。Rのcurlパッケージがlibcurlを要求していて、それが入っていないことが原因ぽい。

こちらで、 CRAN - Package curl

SystemRequirements:  libcurl: libcurl-devel (rpm) or libcurl4-openssl-dev (deb).

の記述からlibcurl4-openssl-devが必要と判断。

sudo apt-get install libcurl4-openssl-dev

で入れたらconfigureはパスしました。
これ以外にもパッケージごとに外部のライブラリに依存しているものがあるはずで、大体は検索すればどのパッケージかはわかるはずです。今回も検索したら一番上にcranのページが来た

今回、それっぽいライブラリは

apt-cache search ^libcurl

の方法でもみたのですが、多過ぎ…。ちゃんと確認した方が良いと思いまする。

今回、これを試す前に結構apt-getで入れているので、素のraspbian+Rだとあれもこれも入れろと言われると思います。頑張りましょう。

入れたものは、前回の記事、 niszet.hatenablog.com

のリンク先の、

Raspberry PiでのPython 3.5環境構築 | MUDAなことをしよう。

に書いてあるものからいくつかと、あといくつか…いずれ追加します。

それでもconfigureでwarningが出る

今回は無視してすっ飛ばしましたが、htmlとかpdfとかbuild出来ないよ、というwarningが出ます。

こちらに記事があったのですが

stackoverflow.com

…試していません。 texは結構ファイルサイズ的に重いのと、おそらくこっちで開発あまりしないので…。

いずれ、試したらどこかで書きます。

makeは時間がかかる

約1時間かかりました。のんびりお茶でも飲むか、寝る前にしかけて朝結果を見るとか。

と思っていたら、こんなお言葉をいただく。ありがたや…

わぁしまった、思いつかなかった…。
ちゃんと動くかどうかも含めて試してみようと思います。

make installはsudoで

まぁこれはいいか。

PATHを設定しないと、デフォルトでは/usr/local/bin/R 下に入るのでターミナル上でRと打っても実行されません。

パスの追加はこちらを参考に。 パスを追加したい〜.bashrc編〜 - ITmedia エンタープライズ

私の環境だとapt-getで入れたRがそのまま残っているので、~/.bashrcのPATHを

export PATH="/usr/local/lib/R/bin/R:$PATH"

に書き換え(先に自分が入れたRが見える)て、R –versionで3.4.1になることを確認、

mean(1:10)

でちゃんと計算されることも確認してとりあえずR3.4.1 on Raspberry Pi 3 の達成です。お疲れ様でした。

終わりに

どんどん答えから遠ざかっているような気が若干していますが、まぁいずれたどり着くと信じて進めていくのです。
次回はRからPythonを呼びますよ…

とりあえず、動きはしたもののこの辺りは苦手…。
間違いとかもっと良い方法とか、あれば教えてください…

(ラズパイ) 3を買ったので試してみる(追記あり2)

色々買い過ぎではないでしょうか?

そうですね…

とりあえず、OSを入れてみる。

特に気にせずにWin32DiskImagerを使い、RaspbianのisoファイルをmicroSDに書き込みました。

使い方はこちらを参考にさせていただきました。
itdecoboconikki.com

isoはこちらから。

www.raspberrypi.org

このDLが結構時間かかる…。そして、このファイルサイズから考えてmicroSDのサイズが小さすぎた気がする…。
まぁこれはいずれ考えよう。

必要なものを入れる。

実はここで書いたものは最終的に全く不要で、しかも別のやり方でやる(pythonを単体で、ソースからビルドして入れる)ことになったので、以下はあまりおすすめしません…。
記録のために書いてあります。

まずはpython3

なんと、標準ではpython2.7しか入っていないことがわかり(知ってた)、python3を入れることを決意。
しかし、pipとかpyenvとかあまり考えたくないなぁ…condaにしよ。minicondaでいいや…

その前に、一応apt-get系で必要そうなことをやっておく。こちらを参考にしていました(pythonを入れる前まで)

Raspberry PiでのPython 3.5環境構築 | MUDAなことをしよう。

こちらも参考にしていたので追記(2017/Aug/20) frontier-of-curiosity.org

ということでminicondaを入れることを試みた。Anacondaだと色々入って良くないという話もあるし、何よりファイルが多くて重い…
https://conda.io/miniconda.htmlconda.io

しかし、ここで表示されているLinuxのものではダメなんですねぇ…

Raspberry Pi 3はarmv7l(32-bit)、こちらのリンク先のモノでないとダメっぽいです。 www.continuum.io

latestってなっていますが、python3.4.3が入りました。今3.6.2なので悲しさがある…。

既にかなり古いバージョンになりつつあるので、やはり最新を入れるべきかなと思っています(これが3.5.xなら別にいいかという気になるのだけど)

Rainbow HAT を使ってみる

これもこの間買ったものの一つです。

こちらから購入可能です。 www.switch-science.com

温度やタッチセンサ、ブザーやLEDなど、なんか色々載せてあります。とりあえず試してみたいというときにあれこれ買うよりはお得…か?

英語版。というか本家。 Rainbow HATshop.pimoroni.com

さて、こちらを参考に実際にサンプルを動かしてみる… learn.pimoroni.com

まずはInstalling the softwareにあるコマンドを実行。

そして、ターミナル上でpythonを起動(condaを導入するとpythonはpython3になる)し、下記を直接入力…

import rainbowhat as rh
rh.rainbow.set_pixel(0, 255, 0, 0)

と書いたところでエラーに。rhというモジュールにrainbowなんてないよという。
いや、あるし…と思ったけど入力補完にも出ない…

もしやと思ってpython2で実行してみると…LEDが光った!

ということで、前半で四苦八苦したことはまるっきり無駄だったのです。
…と思ったら…

追記・修正

こちらのreadmeを読んでいたら、 github.com

sudo apt-get install python3-rainbowhat

で、py3のものが手に入るっぽい。なんと…試してみます。

ある程度感触がつかめたら、次はRで…となりますね。
あくまでも最終的にはRでIoT()なので…。先は長い。

(R…?) 昨日の続き。そしてHW色々…

昨日の続き。

昨日はconnectionまわりを見ていました。

niszet.hatenablog.com

通常のファイルからの読み込みの場合、ファイル名をfile_nameに入れておいたとして、

  con <- file(file_name, "rb")
  on.exit(close(con))

とするのが一般的だと思います。on.exit(close(con))で閉じておくようにしておくと良いです。コネクション開いた直後に。 arduinoとのシリアル通信でも同じじゃないかなぁと思っているのdすが、ちょっと準備に時間がかかりそうです。結果は確認でき次第。

Tinker board

実は、Maker Faire Tokyo 2017でTinker boardを入手していたのですが、すっかり放置…。
先ほど起動を確認しました。マニュアルにあるとおり、OSをmicroSDに書き込んであげれば特に難もなく起動できると思います。ケースに入れるのが一番苦労したような(microSD刺したままケースに入れるのは避けるべきです)
こちらも追々。

SPIとかI2Cとか

段々と趣旨が変わってきていることを感じていますが、Rでarduinoと通信したい。そのためにSPIとかI2Cの仕様を理解しよう、という流れになってきました。
SPIの説明はいたるところに書いてあるので、自分は特に書かないで良いよね。。。

こちらとか、参考にいたしました。 synapse.kyoto

SPIに限りませんが、Clockとdataを別々に送る場合、その遅延差、skewが気になるところです。
これがつき過ぎると受信側のセットアップ/ホールドのタイミングが発生する可能性があるためです。

しかし、SPIは精々数Mbps、送信側でClockとDataをタイミングマージン最大になるような位置、つまりデータの腹の位置にClockのエッジが来ているので、よほどの配線skewがない限りは問題にならないのでしょう。
SPIの、このあたりのゆるーい仕様による使いやすさが受けているのでしょうね。HW的なことをあまり意識しなくてよいという点はSW屋さんにとってはありがたいのだろうなと思います。
私は電気的特性やこのあたりのタイミング関係の記述が全然見つからないので逆に不安になるのですが…

ちなみに、I/O系のまとまった書籍でわかりやすいものってあまりないですよね。まぁ大体データシート読めって話になるのだとは思いますが。
そんななかで、こちら

www.shoeisha.co.jp

は珍しいI/Oについての本です。普段Cとか組み込みで使っている人に、HWのことを理解できるようにということで書かれたらしい、結構貴重な本だと思います。
もっと高速な、LSIの中に入っているような回路についてはCQの青い本のシリーズもありますが、あれは一般ユーザ向けではないですからね。

とはいえ、I2C/SPIについて、ページ数としては多くないので、もっと基礎から、割り込みとかまで踏み込みたい、とかいう方…やはり組み込み系の人向けかなぁ。
自分も必要な箇所だけ読んで積んでいたのですが、arduinoをいじり倒すためにももう一度読み直してみようと思います。

おススメの書籍等あれば、ご連絡ください(twitterでも)

しばらくHW寄りの話が多くなっていくと思いますが、Rもやっていきます。二足のワラジー

(R調べもの)connectionまわりのあれこれ(未解決)

とりあえずメモしておく。

Rでarduinoを制御したいな、と思いまして。以前調べていたものをもうちょっと調べることにしたのです。

過去の記事を掘り起こす…

まずはこれ。

d.hatena.ne.jp

その元になる記事、

notchained.hatenablog.com

こういう方もいらっしゃる(一番上の記事を参照している)

keachmurakami.github.io

そしてこれ。

stackoverflow.com

こまったときはヘルプをよむ。kazutan先生に教わったこと。

R: Functions to Manipulate Connections (Files, URLs, ...)

R: Read Data Values

yutaniさんに教えていただいた、

github.com

結局何?

何なんでしょう…。 おそらく、arduinoとの通信において、そのすべての値を取得しなくてはならないような状況でないのであれば問題にならないのではないかなと思っています。たとえば毎秒の値の取得であるとか。
センサーの読み取り値をarduinoで制御し、それをRで直接処理する、ロガー件リアルタイム分析マシンとかなら。

これが遅延だとかリアルタイムだとか同期だとかを考え始めると厄介なのかなぁと。

一応、ファイル等でなくてもreadBinは有効だったはず(connectionであればよかったはず)ので、scanでなくても良いし、fifoとかでも良いはず(使えれば)

ただ、実使用上では問題があるかもしれないのでその時はここに戻ってくること。

そのための足がかりとしてのメモでした(何も解決してなくてすみません…)