LoginSignup
65
65

More than 5 years have passed since last update.

Node.jsでRaspberryPiのGPIOを良しなにする方法

Last updated at Posted at 2014-12-11

Node.jsのAdvent Calendar 12日目です。

巷でIoTとか流行ってるので大学でちょっと電子工作(Arduino)をした時についでにRaspberryPiを買ってから早2ヶ月

Raspbianを入れてから放置したままだったので

これを機会にRasPiでGPIOやっていきたいと思います!

Q. 何故 Node.jsでやるのか?

A. JavaScriptが好きだからです!!

けど、構文そのものはすきではな開発効率のためCoffeeScriptを普段から使っているのでCoffeeScriptで書いていきます。

使うもの (環境)

  • 秋葉原で衝動買いしたRaspberryPi B+ - Raspbian GNU/Linux 7 (wheezy)
  • Amazonで買ったB+用のケーブルとブレッドボード
  • Arduinoと一緒に買ったLEDなどなど
  • Ethernetケーブルとアダプター(大学やカフェとかでも使えるように)

Node.jsのインストール

バージョン管理にはnodebrewを使います。

nodebrewのインストール

$ curl -L git.io/nodebrew | perl - setup

nodebrewからnodeのインストール

インストール方法は二通りあり

  • ソースコードをダウンロードしてコンパイル
  • バイナリをダウンロードして設置

一番手っ取り早いの後者のバイナリをダウンロードするタイプなんですが

新しいバージョンのだとRaspberryPi用のバイナリがなかったりします。

バイナリがない場合
$ nodebrew install-binary v0.11.14
v0.11.14 is not found

Can not fetched: http://nodejs.org/dist/v0.11.14/node-v0.11.14-linux-arm-pi.tar.gz

今回、自分がbinary installで動くのを確認したのはv0.10.28なので

バイナリインストールする場合は以下のコマンドでインストールします。

$ nodebrew install-binary v0.10.28

RaspberryPiのGPIOを操作する方法

プログラムからRaspberryPiのGPIOの操作方法は二通り
メモリに直接書き込む/sys/class/gpioをシェルから操作することでGPIOをON/OFFできます。

とりあえずシェルを使ってNode.js抜きで操作してみたいと思います。

回路は発光ダイオードを直接繋いだだけのシンプルなものでやってみます。

IMG_20141212_033412.jpg

(写真ですみません。回路図の画像を作れるWebサービスないかな...)

// GPIO24 を使うためのコマンド
$ echo 24 > /sys/class/gpio/export

// IN/OUTの設定 出力する場合はout
$ echo out > /sys/class/gpio/gpio24/direction

// 信号のON/OFFの切り替え ONは1 OFFは0
$ echo 1 > /sys/class/gpio/gpio24/value

// OFFにする
$ echo 0 > /sys/class/gpio/gpio24/value

// unexport
$ echo 24 > /sys/class/gpio/unexport

出力するだけならシンプルですね。

ちなみにメモリを直接操作する方法は Node.jsでどうやればいいのかよくわからないので今回は保留 (/dev/mem をあれやこれやするようですがまだよくわからないのでまた今度)

Node.jsからGPIOを操作する

/sys/class/gpio をNode.jsから操作する方法で行こうとお思います。

さっきの操作をNode.jsでやるにはFileSystemを使えばOKです。


fs = require 'fs'
path = require 'path'

dir = '/sys/class/gpio/'
pin = 24

# export
fs.writeFileSync path.join(dir, 'export'), pin

gpio24 = path.join dir, 'gpio' + pin

# directionの設定
fs.writeFileSync path.join(gpio24, 'direction'), 'out'

# 値の書き込み
fs.writeFileSync path.join(gpio24, 'value'), 1

# 3秒後に終了
setTimeout ->
  fs.writeFileSync path.join(gpio24, 'value'), 0
  fs.writeFileSync path.join(dir, 'unexport'), pin
, 3000

わかりやすくするため同期メソッドを使いましたが

JavaScript的には非同期がいいと思うのでasyncやPromiseなんかを使うといいと思います。

Lチカ

プログラミングの最初の一歩がHello Worldなら
電子工作の最初の一歩はLチカです。

Lチカとは「LEDチカチカ」の略です。

既に冒頭でやってしまってますがライブラリを使った もう少しちゃんとしたLチカをやりたいと思います。

ライブラリは覚えたての知識であるPromiseを活用したいのでPromise使ったライブラリないかなぁと思って探したんですが

なかったので作ったnode-pi-gpioを使いたいと思います。

回路は上の写真と同じです。

l_chika.coffee

GPIO = require 'node-pi-gpio'

pin = 24

time = 500

_loop = (gpio, val)->
  gpio.value val
  setTimeout _loop, time, gpio, (unless val then 1 else 0)

GPIO.open pin, 'out'
.then (gpio)->
  process.on 'SIGINT', ->
    gpio.value 0
    gpio.close()
    .then ->
      process.exit()
  _loop(gpio, 1)
  return
.catch (err)->
  console.log 'err', err.stack

実行するとLEDが0.5秒ごとにON/OFFが切り替わると思います。
終了するには Ctrl+c を入力して終了させます。

ボタンの入力を受け付ける

今度はボタンを使って入力を受けてみたいと思います。
ちなみにfs.watchでは変更をキャッチできないようです。orz

IMG_20141212_022913_2.jpg

回路は先程のLチカのやつに追加してます。

ボタンを橋渡しのようにつけてGRAND側に抵抗(10k)、ボタンと抵抗の間に線を繋ぎます。

繋ぐ先はGPIO25になってます。

button.coffee


GPIO = require 'node-pi-gpio'
Promise = require('es6-promise').Promise


led_pin = 24
button_pin = 25

Promise.all [GPIO.open(led_pin, 'out'), GPIO.open(button_pin, 'in')]
.then (res)->
  console.log 'open'
  [led, button] = res

  process.on 'SIGINT', ->
    led.value 0
    Promise.all [led.close(), button.close()]
    .then ->
      process.exit()

  button.on 'change', (val)->
    console.log 'change', val
    led.value val
.catch (err)->
    console.log 'err', err.stack

ボタンを押すとLEDが光るサンプルです。

Lチカとボタンのソースコードはgithubのexampleに入っています。

npmのスクリプトも設定しているので

npm installした後に

$ npm run example:l_chika
$ npm run example:button

で、すぐに実行できます。

まとめ

ネタかぶりを防ぐためにRaspberryPiを使おうとしたけど、参考文献少ないしライブラリも少ないしfs.watchは使えないし
自分でライブラリ書いてるしで想像より大変でした。

赤外線とかもうちょっとセンサー使ったあれこれも紹介したかったんですが長くなりそう(*1)なのでここではHelloWorld的なところまでにしておきます。

*1 文量ではなく作業量 orz

追記:
どうもrpio

Node.js Advent Calendar 2014 明日は@Wmrfreewさんが担当です!

65
65
3

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
65
65