HOME
  Security
   Software
    Hardware
  
FPGA
  CPU
   Android
    Raspberry Pi
  
nLite
  Xcode
   etc.
    ALL
  
LINK
BACK
 

2017/08/17

Raspberry Pi 3の Nodejs blenoで BLE接続して GPIOで Lチカ制御やボタン状態を読み取る Raspberry Pi 3の Nodejs blenoで BLE接続して GPIOで Lチカ制御やボタン状態を読み取る

(ラズパイ3と Node.js blenoで BLEの周辺機器機能を実装する GPIO編)

Tags: [Raspberry Pi], [電子工作]





● Raspberry Pi 3 Model Bを遂に購入

 Raspberry Pi3 Model B RPI2 RPI3

 大人気の CPUボードの Raspberry Piに WiFiと Bluetoothが搭載されたモデルが新発売となりました。
 以前から Raspberry Pi 2を買おうかどうか迷っていましたが、Raspberry Pi 3 Model Bの発売を機に購入を決意してラズベリアンになる事にしました。

 ※ ラズパイの OS Raspbianはバージョンが上がる毎に過去の版と OSの内部の作りが変わり、過去に書かれた製作記事(例えば Raspbian Wheezyの時代の記事)がそのままではエラーが出たりして動かない事が有ります。
 ※ 当方のホームページのラズパイ記事は全て Raspberry Pi 3 Model Bと Raspbian Jessieの組み合わせで動作確認をしております。
(ただし、将来的に新しい Raspbian OSが出た場合に、当方の Raspbian Jessieを基にした内容がそのままでは動かない可能性が有ります。)
 ※ 2017/08/16から Raspbian OSは Raspbian Jessieから Raspbian Stretchに変わりました。
 ※ 2019/06/20から Raspbian OSは Raspbian Stretchから Raspbian Busterに変わりました。

Download Raspbian for Raspberry Pi

ちなみに、歴代のバージョンと名称は
Debianコードネーム年月備考(参考)Ubuntuでの該当名称
Debian 11Bullseye2021/08/14~2021/11からラズパイにリリースFocal Fossa 20.04 LTS ?
Debian 10Buster2019/06/20~2019/06からラズパイ4対応Bionic 18.04 LTS
Debian 9Stretch2017/08/16~2018/03からラズパイ3B+対応Xenial 16.04 LTS
Debian 8Jessie2015~2016/02からラズパイ3対応Trusty 14.04 LTS
Debian 7Wheezy2013~2016
Debian 6.0Squeeze2011~2014
Debian GNU/Linux 5.0Lenny2009~2012


●ラズパイ3 + Node.js blenoで Bluetooth BLEのペリフェラルを作成する

 ラズパイ3の BLE + Node.jsで擬似環境を作成する必要性が出てきました。
 ここでは BLEや Node.jsに慣れる為にサンプルを動かして BLEと Node.jsに対して免疫をつけていきます。

 ラズパイで BLEをプログラムから自由に扱う手段としては Node.jsを使う方法が一般的な様です。
 ここでも Node.jsを使って Bluetooth BLEのペリフェラルを作成します。

 BLE = Bluetooth Low Energy
 bleno = BLE Peripheral(スレーブ、周辺機器側)
sandeepmistry/bleno - A Node.js module for implementing BLE (Bluetooth Low Energy) peripherals



●ラズパイ3で Lチカの事前確認を行なう方法

 ラズパイのコマンドラインで手動で LED単体の点灯試験を行ないます。
 これをする事で、問題発生時の切り分けが簡単になります。

 下記の要領で LEDが点灯・消灯する事を確認します。

# GPIO5を使用する宣言
sudo echo 5 > /sys/class/gpio/export

# IN/OUTの設定。出力する場合はout
sudo echo out > /sys/class/gpio/gpio5/direction

# High = '1'にする(負論理の場合は LEDが消える)
sudo echo 1 > /sys/class/gpio/gpio5/value

# Low = '0'にする(負論理の場合は LEDが点灯する)
sudo echo 0 > /sys/class/gpio/gpio5/value

# GPIO5を使うのを終了する宣言
sudo echo 5 > /sys/class/gpio/unexport



●ラズパイ3に Node.jsをインストールする方法

# お約束の update
sudo apt-get update
# upgradeは不要
# sudo apt-get -y upgrade

# autoremove nodejsで既存の nodejsを削除する。
sudo apt-get -y autoremove nodejs

# setup Node.js v8
curl -sL https://deb.nodesource.com/setup_8.x | sudo -E bash -
# install Node.js v8
sudo apt-get -y install nodejs

# node -vでバージョンを確認する。
# $ node -v
# v8.4.0

# npm -vでバージョンを確認する。
# $ npm -v
# 5.3.0


●ラズパイ3に Node.jsの BLE blenoライブラリをインストールする方法

 下記の mfny2015-rpi-bleの npm installの時に blenoライブラリもインストールされるので不要。


● Androidスマホに BLEセントラルのアプリをインストールする

BLE Scanner: Read、Write、Notify - Bluepixel Technology LLP
com.macdom.ble.blescanner
アップデート 2017年3月17日
現在のバージョン 3.12

 BLE Scannerアプリを Androidスマホにインストールします。

・Android BLEセントラルのアプリ BLE Scanner
Android BLEセントラルのアプリ BLE Scanner


・Android BLEセントラルのアプリ BLE Scanner
Android BLEセントラルのアプリ BLE Scanner




●ラズパイ3で BLE blenoを使用した GPIO制御をする BLEペリフェラル実装のサンプル

Maker Faire NY Sept 27, 2015 - Bluetooth Low Energy with Raspberry Pi
 Bluetooth Low Energy with Raspberry Pi Maker Faire NY - Sept 27, 2015
 Don Coleman - Chariot Solutions @doncoleman

don/mfny2015-rpi-ble - Examples from Maker Faire 2015 Raspberry PI BLE presentation

 このサンプルでできる事。
 ・BLE接続してラズパイの GPIO出力を制御して LEDチカチカ(通称 Lチカ)
 ・BLE接続してラズパイの GPIO入力を監視してボタンの ON/OFFで Notify通知を送信

・元 blenoのサンプルプログラムで使用している GPIO
元 blenoのサンプルプログラムで使用している GPIO
 元 blenoのサンプルプログラムで使用している GPIO
・GPIO入力 GPIO 23 ボタン(負論理)
・GPIO出力 GPIO 18 LED(負論理)

・私のサンプルプログラムで使用している GPIO
私のサンプルプログラムで使用している GPIO
 私のサンプルプログラムで使用している GPIO
・GPIO入力 GPIO 25 ボタン(負論理)
・GPIO出力 GPIO 5 LED(負論理)

・Raspberry Pi 3の Nodejs blenoで BLE接続して GPIOで Lチカ制御やボタン状態を読み取る
Raspberry Pi 3の Nodejs blenoで BLE接続して GPIOで Lチカ制御やボタン状態を読み取る



●ラズパイ3で BLE blenoを使用した GPIO制御をする mfny2015-rpi-bleを動かす方法

# mfny2015-rpi-bleを gitからダウンロードする
cd
git clone https://github.com/don/mfny2015-rpi-ble

cd
cd ./mfny2015-rpi-ble

# peripheralのサンプルディレクトリに移動する
cd ./peripheral

# package.jsonの中身を見て必要なパッケージを自動でインストールしてくれる
npm install

# 途中で ERRのエラーが出るけど気にしない。
# node-pre-gyp ERR! Tried to download: https://github.com/tessel/node-usb/releases/download/1.2.0/usb_bindings-v1.2.0-node-v57-linux-arm.tar.gz
# node-pre-gyp ERR! Pre-built binaries not found for usb@1.2.0 and node@8.4.0 (node-v57 ABI) (falling back to source compile with node-gyp)

 使用する GPIOの端子が違うのでサンプルプログラム(jsファイル)の GPIO端子をしている箇所を書き換えます。
端子名mfny2015-rpi-bleのサンプル私の実験環境
LED出力GPIO 18GPIO 5
(0で点灯、負論理接続)
ボタン入力GPIO 23GPIO 25
(内蔵プルアップ必要、0で押下、負論理接続)


● BLE接続してラズパイの GPIO出力を制御して LEDチカチカ(通称 Lチカ)

 GPIO出力に LEDを接続して、セントラルから BLE経由で LEDのキャラクタリスティックに書き込み処理をします。
 ラズパイ側は書き込み内容に従って GPIO出力を変化させます。
 結果的に GPIOに接続している LEDが点灯・消灯するので Lチカ実験ができます。

nano led.js
    led = new Gpio(18, 'out');
 を
    led = new Gpio(5, 'out');
 に変更する。

# led.jsを実行する
sudo node led.js
on -> stateChange: poweredOn
on -> advertisingStart: success
write request: 00 -> LEDが点灯する(負論理接続)
write request: 01 -> LEDが消灯する(負論理接続)
write request: 00 -> LEDが点灯する(負論理接続)
write request: 01 -> LEDが消灯する(負論理接続)

・BLE接続してラズパイの GPIO出力を制御して LEDチカチカ(通称 Lチカ)
BLE接続してラズパイの GPIO出力を制御して LEDチカチカ(通称 Lチカ)


・BLE接続してラズパイの GPIO出力を制御して LEDチカチカ(通称 Lチカ)
BLE接続してラズパイの GPIO出力を制御して LEDチカチカ(通称 Lチカ)


・BLE接続してラズパイの GPIO出力を制御して LEDチカチカ(通称 Lチカ)
BLE接続してラズパイの GPIO出力を制御して LEDチカチカ(通称 Lチカ)
 FF11の Wマークを押して、

・BLE接続してラズパイの GPIO出力を制御して LEDチカチカ(通称 Lチカ)
BLE接続してラズパイの GPIO出力を制御して LEDチカチカ(通称 Lチカ)
 Wtrite Valueに Byte Arrayを選択して 00を入力します。(= 0x00)
 負論理なので LEDが点灯します。

・BLE接続してラズパイの GPIO出力を制御して LEDチカチカ(通称 Lチカ)
BLE接続してラズパイの GPIO出力を制御して LEDチカチカ(通称 Lチカ)
 FF11の Wマークを押して、

・BLE接続してラズパイの GPIO出力を制御して LEDチカチカ(通称 Lチカ)
BLE接続してラズパイの GPIO出力を制御して LEDチカチカ(通称 Lチカ)
 Wtrite Valueに Byte Arrayを選択して 01を入力します。(= 0x01)
 負論理なので LEDが消灯します。


● BLE接続してラズパイの GPIO入力を監視してボタンの ON/OFFで Notify通知を送信

 GPIO入力にプッシュボタンを接続して、ボタンの ON/OFFのタイミングで Notify通知を送信する様にします。
 セントラル側はボタンキャラクタリスティックを購読登録します。
 ボタンを押したり離したりするタイミングで Notify通知をセントラルに対して送信します。
 ※ ボタンの状態に変化が有った時だけ(エッジトリガ)Notify通知が来るので、ボタンの状態を取得するのに、セントラル側で常にポーリング処理を行なう必要が有りません。

nano button.js
    button = new Gpio(23, 'in', 'both');
 を
    button = new Gpio(25, 'in', 'both');
 に変更する。

# button.jsを実行する
sudo node button.js
on -> stateChange: poweredOn
on -> advertisingStart: success
ButtonCharacteristic subscribe
button 0 <- ボタンを押した(負論理接続)
button 1 <- ボタンを離した(負論理接続)
button 0 <- ボタンを押した(負論理接続)
button 1 <- ボタンを離した(負論理接続)

・BLE接続してラズパイの GPIO入力を監視してボタンの ON/OFFで Notify通知を送信
BLE接続してラズパイの GPIO入力を監視してボタンの ON/OFFで Notify通知を送信


・BLE接続してラズパイの GPIO入力を監視してボタンの ON/OFFで Notify通知を送信
BLE接続してラズパイの GPIO入力を監視してボタンの ON/OFFで Notify通知を送信


・BLE接続してラズパイの GPIO入力を監視してボタンの ON/OFFで Notify通知を送信
BLE接続してラズパイの GPIO入力を監視してボタンの ON/OFFで Notify通知を送信
 FFE1の Nマークを押して、Notify通知を有効にします。

・BLE接続してラズパイの GPIO入力を監視してボタンの ON/OFFで Notify通知を送信
BLE接続してラズパイの GPIO入力を監視してボタンの ON/OFFで Notify通知を送信


・BLE接続してラズパイの GPIO入力を監視してボタンの ON/OFFで Notify通知を送信
BLE接続してラズパイの GPIO入力を監視してボタンの ON/OFFで Notify通知を送信
 ラズパイの GPIOに接続したボタンを押すと 0x00になります。(負論理接続)

・BLE接続してラズパイの GPIO入力を監視してボタンの ON/OFFで Notify通知を送信
BLE接続してラズパイの GPIO入力を監視してボタンの ON/OFFで Notify通知を送信
 ボタンを離すと 0x01になります。(負論理接続)



● GPIOのプルアップ設定を Device Tree Overlayと言う設定方法で指定する

 プルアップ抵抗を回路上に実装していなくて、ラズパイの内部プルアップ抵抗の設定が必要な場合。

 button.jsのサンプルで使用している fivdi/onoffの GPIOライブラリは GPIOを入力に設定した時のプルアップ、プルダウン指定ができません。
fivdi/onoff - GPIO access and interrupt detection with Node.js

 Device Tree Overlayと言う設定の方法を使って GPIO端子のプルアップ指定、プルダウン指定を行ないます。

Enabling Pullup and Pulldown Resistors on The Raspberry Pi

# device-tree-compiler dtcをインストールする
sudo apt-get install device-tree-compiler

# mygpio-overlay.dtsを作成する
# GPIO 16、GPIO 25、GPIO 27を入力で内蔵プルアップ有りに設定している
nano mygpio-overlay.dts
/dts-v1/;
/plugin/;

/ {
    compatible = "brcm,bcm2708";

    fragment@0 {
        target = <&gpio>;
        __overlay__ {
            pinctrl-names = "default";
            pinctrl-0 = <&my_pins>;

            my_pins: my_pins {
                brcm,pins = <16 25 27>;     /* gpio no. */
                brcm,function = <0 0 0>; /* 0:in, 1:out */
                brcm,pull = <2 2 2>;     /* 2:up 1:down 0:none */
            };
        };
    };
};

# dtcコマンドで dts設定ファイルを dtb設定ファイルに変換する
dtc -@ -I dts -O dtb -o mygpio-overlay.dtb mygpio-overlay.dts

# mygpio-overlay.dtbファイルを /boot/overlays/にコピーする
sudo cp mygpio-overlay.dtb /boot/overlays/

# /boot/config.txtに mygpio-overlay.dtbの設定内容の参照を追加する
sudo nano /boot/config.txt
device_tree_overlay=overlays/mygpio-overlay.dtb

# 再起動して設定内容を反映させる
sudo reboot


● GPIOライブラリを 'onoff'から 'pigpio'に切り替える

 pigpio版の GPIOライブラリは node.jsのプログラム上でプルアップ指定が可能です。
 (上記の Device Tree Overlayの設定が不要になります。)

fivdi/pigpio - Fast GPIO, PWM, servo control, state change notification and interrupt handling with Node.js on the Raspberry Pi

cd
cd ./mfny2015-rpi-ble

# peripheralのサンプルディレクトリに移動する
cd ./peripheral

# Error: Cannot find module 'pigpio'
# Install the pigpio Node.js package
npm install pigpio

# button2.jsを作成
cp button.js button2.js

# button2.jsを pigpio版に書き換え
nano button2.js

 GPIOの初期化設定と GPIOの割込み処理部分を pigpio版の記述方法に変更します。
var Gpio = require('pigpio').Gpio,
  button = new Gpio(25, {
    mode: Gpio.INPUT,
    pullUpDown: Gpio.PUD_UP,
    edge: Gpio.EITHER_EDGE
  });

var bleno = require('bleno');
var util = require('util');

var ButtonCharacteristic = function() {
    ButtonCharacteristic.super_.call(this, {
      uuid: 'ffe1',
      properties: ['notify'],
      descriptors: [
         new bleno.Descriptor({
           uuid: '2901',
           value: 'Button'
         })
      ]
    });
  };
util.inherits(ButtonCharacteristic, bleno.Characteristic);

ButtonCharacteristic.prototype.onSubscribe = function(maxValueSize, updateValueCallback) {
  console.log('ButtonCharacteristic subscribe');

button.on('interrupt', function (level) {
  console.log("button " + level);
  var data = new Buffer(1);
  data[0] = level;
  updateValueCallback(data);
});
};

var buttonService = new bleno.PrimaryService({
  uuid: 'ffe0',
  characteristics: [
    new ButtonCharacteristic()
  ]
});

bleno.on('stateChange', function(state) {
  console.log('on -> stateChange: ' + state);

  if (state === 'poweredOn') {
    bleno.startAdvertising('Button', [buttonService.uuid]);
  } else {
    bleno.stopAdvertising();
  }
});

bleno.on('advertisingStart', function(error) {
  console.log('on -> advertisingStart: ' + (error ? 'error ' + error : 'success'));

  if (!error) {
    bleno.setServices([buttonService]);
  }
});

function exit() {
  process.exit();
}
process.on('SIGINT', exit);

sudo node button2.js
on -> stateChange: poweredOn
on -> advertisingStart: success
ButtonCharacteristic subscribe
button 0
button 1
button 0
button 1
# 問題無く動きました。


● GPIOライブラリを 'onoff'から 'pigpio'に切り替える

 下記のインストール手順でも動きました。(mfny2015-rpi-bleが不要)
# お約束の update
sudo apt-get update
# upgradeは不要
# sudo apt-get -y upgrade

# autoremove nodejsで既存の nodejsを削除する。
sudo apt-get -y autoremove nodejs

# setup Node.js v8
curl -sL https://deb.nodesource.com/setup_8.x | sudo -E bash -
# install Node.js v8
sudo apt-get -y install nodejs

npm install bleno
npm install pigpio



● GPIOライブラリを 'onoff'から 'pigpio'に切り替える

 led.jsの pigpio版
 単純に led.jsの onoffライブラリ部分を pigpioに置き換えました。
 (GPIO 5を使用)
 pigpioライブラリの digitalWrite関数は 0-1の範囲しか受付ないので & 0x01の演算処理をしています。
 (書き込みデータの下位 1bitが GPIOの設定値として有効です)

nano led2.js

# led2.jsを実行する
sudo node led2.js

led2.js
var Gpio = require('pigpio').Gpio,
  led = new Gpio(5, {mode: Gpio.OUTPUT});

var bleno = require('bleno');
var util = require('util');

var Characteristic = bleno.Characteristic;
var PrimaryService = bleno.PrimaryService;

var SwitchCharacteristic = function() {
    SwitchCharacteristic.super_.call(this, {
      uuid: 'ff11',
      properties: ['read', 'write'],
      descriptors: [
         new bleno.Descriptor({
           uuid: '2901',
           value: 'Switch'
         })
      ]
    });
  };
util.inherits(SwitchCharacteristic, Characteristic);

SwitchCharacteristic.prototype.onReadRequest = function(offset, callback) {
  console.log("read request");
  var data = new Buffer(1);
  data[0] = led.digitalRead();
  callback(this.RESULT_SUCCESS, data);
};

SwitchCharacteristic.prototype.onWriteRequest = function(data, offset, withoutResponse, callback) {
  console.log('write request: ' + data.toString('hex'));
  var level = (data[0] & 0x01);
  led.digitalWrite(level);
  callback(this.RESULT_SUCCESS);
}

var lightService = new PrimaryService({
  uuid: 'ff10',
  characteristics: [
    new SwitchCharacteristic()
  ]
});

bleno.on('stateChange', function(state) {
  console.log('on -> stateChange: ' + state);

  if (state === 'poweredOn') {
    bleno.startAdvertising('Light', [lightService.uuid]);
  } else {
    bleno.stopAdvertising();
  }
});

bleno.on('advertisingStart', function(error) {
  console.log('on -> advertisingStart: ' + (error ? 'error ' + error : 'success'));

  if (!error) {
    bleno.setServices([lightService]);
  }
});

function exit() {
  process.exit();
}
process.on('SIGINT', exit);



Tags: [Raspberry Pi], [電子工作]

●関連するコンテンツ(この記事を読んだ人は、次の記事も読んでいます)

TIの 8051マイコン内蔵の BLE CC2540/CC2541を使ってみる
TIの 8051マイコン内蔵の BLE CC2540/CC2541を使ってみる

  Bluetooth Low Energyの SensorTagや iBeacon、CC Debuggerの使い方など

Raspberry Pi 3の Bluetooth BLEで TI SensorTagと接続してセンサーの測定値を読み取る方法
Raspberry Pi 3の Bluetooth BLEで TI SensorTagと接続してセンサーの測定値を読み取る方法

  ラズパイ3の BLEと Node.jsで、TIの SensorTag CC2541DKに接続してセンサーの状態を取得

Raspberry Pi 3の gatttoolのコマンドラインで TIの SensorTagを直接操作する方法
Raspberry Pi 3の gatttoolのコマンドラインで TIの SensorTagを直接操作する方法

  ラズパイ3と gatttoolのコマンドラインで TIの SensorTagに直接接続して gatttoolの使い方を覚える

Raspberry Pi 3に Nodejs blenoをインストールして Bluetooth BLEのペリフェラルを作成する
Raspberry Pi 3に Nodejs blenoをインストールして Bluetooth BLEのペリフェラルを作成する

  ラズパイ3と Node.js blenoで Bluetooth BLEの周辺機器機能を実装する

Raspberry Pi 3の Python BLE pygattlibライブラリで TIの SensorTagに接続して制御する方法
Raspberry Pi 3の Python BLE pygattlibライブラリで TIの SensorTagに接続して制御する方法

  ラズパイ3と Python BLE pygattlibで TIの SensorTagのセンサーの値を取得とボタン状態の通知を受信する

Raspberry Pi 3に Bluetooth BlueZ Version 5.42 BLE
Raspberry Pi 3に Bluetooth BlueZ Version 5.42 BLE

  ラズパイで Bluetooth 4.0の BLE gatt通信を行なう TIの SensorTagや iBeacon実験など

Amazon Dash Buttonをハックして IoTボタンとして使う方法を解説
Amazon Dash Buttonをハックして IoTボタンとして使う方法を解説

  Amazon Dash Buttonをハック。ARP要求を監視、DNSハック、IPアドレスハック等。

Raspberry Piで Amazon Dash Buttonを自在にハックする方法。node-dash-button方法
Raspberry Piで Amazon Dash Buttonを自在にハックする方法。node-dash-button方法

  ラズパイ + Node.jsで Amazon Dash Buttonをハックして IoTボタンとして使う方法を解説

Raspberry Piで Amazon Dash Buttonを自在にハックする方法。tcpdump libpcap方法
Raspberry Piで Amazon Dash Buttonを自在にハックする方法。tcpdump libpcap方法

  ラズパイ + libpcap Packet Capture libraryで Amazon Dash Buttonをハックして IoTする

Raspberry Piで Amazon Dash Buttonを自在にハックする方法。Python Scapyライブラリ方法
Raspberry Piで Amazon Dash Buttonを自在にハックする方法。Python Scapyライブラリ方法

  ラズパイ + Python Scapyライブラリで ARPパケット検出からの Amazon Dash Buttonをハック

Raspberry Piで Amazon Dash Buttonを自在にハックする方法。Node.js Dasher方法
Raspberry Piで Amazon Dash Buttonを自在にハックする方法。Node.js Dasher方法

  ラズパイ + Node.js Dasherライブラリで ARPパケット検出からの Amazon Dash Buttonをハック

Raspberry Pi 3で安定して使える相性の無い最適な microSDカードの種類のまとめ
Raspberry Pi 3で安定して使える相性の無い最適な microSDカードの種類のまとめ

  ラズパイ3で安定して使える microSDカードを購入する Teamと SanDiskは絶対に買わない

Raspberry Pi 3の Linuxコンソール上で使用する各種コマンドまとめ
Raspberry Pi 3の Linuxコンソール上で使用する各種コマンドまとめ

  ラズパイの Raspbian OSのコマンドラインで使用する便利コマンド、負荷試験や CPUシリアル番号の確認方法等も

Raspberry Pi 3で GPIO端子の I2C機能を有効化する方法
Raspberry Pi 3で GPIO端子の I2C機能を有効化する方法

  ラズパイ3の GPIO端子の I2C機能を有効にして各種センサーを繋げる方法まとめ




[HOME] | [BACK]
リンクフリー(連絡不要、ただしトップページ以外は Web構成の変更で移動する場合があります)
Copyright (c) 2017 FREE WING,Y.Sakamoto
Powered by 猫屋敷工房 & HTML Generator

http://www.neko.ne.jp/~freewing/raspberry_pi/raspberry_pi_nodejs_ble_bleno_gpio/