niszetの日記

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

(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!!