背景
IoT界隈に私のようなWEB系エンジニアが入り込みやすい時代になりました。
パッケージ化された電子工作部品がどんどん出回り始め、ライブラリなども増えてきたおかげで、PythonやNode.jsを使った電子回路の制御がお手軽に出来るようになってきています。必要なパーツはほとんどAmazonで揃いますし、秋月電子通商やスイッチサイエンスなどの通販サイトを探せば使いやすいパーツがデータシートのリンク付きで数多く掲載されています。今回取り扱うRaspberry PiではRaspbianにPython3 IDLE(Pythonの開発環境)が最初から入っていたり、Node.jsもNPMを探せば各種モジュールを扱うためのパッケージが転がっているので、それらを使えば簡単に入門することができます。
今回はそんなIoT界隈に、電子工作経験に乏しいWEBアプリケーションエンジニアの私がうっかり入門するために、「RaspberryPi 3B+で感圧センサーの値を、A/Dコンバーターを経由してI2CでNode.jsを使って取得」してみたいと思います。
回路の作成
今回、既に先人がいたので、下記サイトを参考に回路図を設計していきます。下記サイトと異なる点として、今回はMCP3002を使ったSPI通信ではなく、ADS1115を使ったI2C通信で試してみたいと思います。
Raspberry Piで感圧センサー(ALPHA-MF02-N-221-A01 )の情報取得するところまで
https://yomon.hatenablog.com/entry/2018/09/raspimf02n221a01
必要なものの準備
必要なものは下記です。参考までに購入元リンクも置いておきます。
- Raspberry Pi 3B+
- 感圧センサー
- A/Dコンバーター(ADS1115)
- ブレッドボード・ジャンパーワイヤー
- (あると便利)ワニ口クリップ
ブレッドボードとワニ口クリップは適当なものを使ってます。ちなみにラズパイ側のGPIOがオスなので、オスメスのジャンパーワイヤーがあると便利です。
ELEGOO 50 PCS オスメスジャンパーワイヤ200mm (無料 170 タイポイント ブレッドボード)
https://www.amazon.co.jp/gp/product/B06ZZXH4XT/
Fritzingで配線図・回路図の作成
ブレッドボードの配線図や回路図の作成にFritzingを使います。
Fritzing Download
http://fritzing.org/download/
Fritzingでパーツ作成(ADS1115)
FritzingにはADS1115のパーツが見つからなかったので今回適当に作成しました。適当なのでかなり手抜きで荒いです。本当はブレッドボードに直接配置出来るようにしたかったのですが、サイズを間違えたのかうまくいかず・・・。ただ、今回のざっくり設計には十分なのでこれをそのまま使おうと思います。
ちなみにパーツ作成は下記サイトを参考にしました。適当で良ければ手元にあるAdobe illustrator CS5.1でも割と簡単に作れたので、なかったらどんどん作ると良さそうです。
Fritzing カスタムパーツの作り方
https://jumbleat.com/wp-content/cache/all/2017/01/18/making_custom_parts_fritzing//index.html
完成したブレッドボード配線図と回路図
※FritzingにRaspberry Piの3B+がなかったので、3Bをそのまま使ってます。
※ちなみにケースは下記のものを使ってます。結構冷えてそう。
Raspberry Pi 2B/ 3B/ 3B+ ラズベリーパイ 金属ケース ラズパイ ケース アルミニウム合金 高速冷却 デュアル冷却ファン付き 放射線防護および防錆 RPI2B/3B/ 3B+用
https://www.amazon.co.jp/gp/product/B07LGHZF8W/
A/DコンバーターとI2C通信(ADS1115)について
配線についてですが、今回把握しておく必要があるのがA/DコンバーターとI2C通信です。
A/Dコンバーター(ADC)はアナログ信号をデジタル信号に変換する回路で、今回使用する感圧センサーのアナログ信号をRaspberry Piに送れるようにデジタル信号に変換します。
I2C通信は2本の信号線で複数の端末と通信するための方式です。今回だと下記のような構成が可能で、4×4=16個のセンサーを2本の信号線でぶら下げることができそうです。
- Raspberry Pi
- ADS1115
- 感圧センサー
- ADS1115(0x48~0x4Bの最大4つ)
- (A0~A3の最大4つ)
- ADS1115
ADS1115の各インターフェースについて
ADS1115の各インターフェースについて簡単に記載しておきます。
- VDD:プラス電源
- GND:信号グラウンド
- SCL、SDA:I2C通信の信号線
- ADDR:I2C通信をする際のアドレスを決めるために使われる。繋げる先で下記のようにアドレスが変わる
- GND:0x48
- VDD:0x49
- SDA:0x4A
- SCL:0x4B
- ALRT:入力電圧が閾値を超えた時にアラートのデジタル信号を出す
- A0~A3:各アナログ信号の入力
ADDRは今回GNDに繋げることで0x48のアドレスでI2C通信を行うように設定しています。
感圧センサーについて
感圧センサーですが、実際には圧がかかった際に抵抗値が変わる可変抵抗器と考えると分かりやすいと思います。つまみ回す代わりに圧をかけるイメージ。ですので、感圧センサーの代わりに可変抵抗器入れてもOKです。
参考サイト
5ドル!ラズパイ・ゼロ(Raspberry pi Zero)でIoT (5) A-Dコンバータの利用2 ADS1115
https://www.denshi.club/pc/raspi/5raspberry-pi-zeroiot4a-d1-1.html
Adafruit 4-Channel ADC Breakouts
https://cdn-learn.adafruit.com/downloads/pdf/adafruit-4-channel-adc-breakouts.pdf
ADS1115のデータシート
https://cdn-shop.adafruit.com/datasheets/ads1115.pdf
I2C通信の使い方
http://www.picfun.com/c15.html
Raspberry Pi 3 B+側のセットアップ
Raspberry Pi 3 B+を動かすために、まずOSであるRaspbianをSDカードかUSBメモリにセットアップします。
USBメモリにRaspbianをセットアップ
今回、うっかり手元にmicro SDカードがありませんでした。しかし以前のRaspberry Piとは異なり、Raspberry Pi 3 Model B+からはUSBブートが標準対応となっているとのこと。そのため、今回は手元のUSB3.0、8GBのUSBメモリを使ってRaspbianをセットアップしていきます。
まずは手元のPCに下記サイトから最新のRaspbianとWin32DiskImagerをダウンロード・解凍し、Win32DiskImagerでRaspbianをUSBメモリに書き込みます。
Raspbian ダウンロード
https://www.raspberrypi.org/downloads/raspbian/
Win32DiskImager
https://ja.osdn.net/projects/sfnet_win32diskimager/
結構時間がかかるのですが、手元だと10~20分くらいで完了しました。
完了したらRaspberry PiにUSBメモリを入れてRaspberry Piの電源を入れればOKです。
参考サイト
最新の「Raspberry Pi 3 Model B+」で標準対応になったUSBブートを試してみた。
https://dev.classmethod.jp/hardware/raspberry-pi-3-model-b-plus-usb-boot/
Raspberry Pi 3 Model B+ の USBメモリからのブート
https://qiita.com/miyamoto_lex/items/9a1867ffa27361d01937
Raspberry PiでI2C通信が出来るように設定する
ターミナルでraspi-config叩いても良いのですが、せっかくなのでGUI上から設定します。ちなみに私はやりやすいようにVNC有効にして手元のPCからRaspberry Piを操作していますが、今回は必須ではありません。
スタートメニュー>設定>Raspberry Piの設定をクリックします。
Node.jsのraspi-kit-ads1x15パッケージを使って、A/DコンバーターとI2C通信する
さて、I2C通信が出来るようになりました。後は具体的なプログラムを用意して、実際にA/Dコンバーターと通信してみます。
今回使用するのはraspi-kit-ads1x15パッケージですが、これが無くともi2c-busで通信することは可能です。ただ、i2c-busは一般的なi2cの通信をするだけのものなので、これだけではADS1115との通信について全て1から書く必要があります。raspi-kit-ads1x15パッケージであれば、この辺りは抽象化されて呼び出せばすぐに分かりやすく情報を手に入れることができます。
ADS1x15 Interface over I2C
https://www.npmjs.com/package/raspi-kit-ads1x15
i2c-busでの通信については下記サイトを参考にしました。
Node.jsでraspberry piのハードウェアを叩く7つの方法
https://qiita.com/ksksue@github/items/d0f02675f11ab38c190c#4-i2c%E9%80%9A%E4%BF%A1%E3%81%99%E3%82%8B
Node.jsのインストール
まず最初にNode.jsをインストールします。
# アップデートしておきます。
sudo apt-get update
# nodeのバージョン管理のため、NodeBrewをセットアップします。
curl -L git.io/nodebrew | perl - setup
# 現時点で最新のNode.jsをインストールしておきます。
nodebrew install-binary v10.16.0
nodebrew use v10.16.0
パッケージの取得
# 続いて、npmで必要なパッケージを取ってきます。
mkdir ~/Desktop/pressure-sensors
cd ~/Desktop/pressure-sensors
npm init
npm install raspi raspi-i2c raspi-kit-ads1x15 --save-dev
これで準備が整いました。後はここにスクリプトを書いて置いていくだけです。
A/Dコンバーターとの通信用サンプルスクリプト
下記サイトにサンプルがあるのですが、これだとADS1015用なので一部書き換えて使います。nanoかvmでindex.jsとして保存します。
ADS1x15 Interface over I2C
https://www.npmjs.com/package/raspi-kit-ads1x15
"use strict";
const Raspi = require('raspi');
const I2C = require('raspi-i2c').I2C;
const ADS1x15 = require('raspi-kit-ads1x15');
// Init Raspi
Raspi.init(() => {
// Init Raspi-I2c
const i2c = new I2C();
// Init the ADC
const adc = new ADS1x15({
i2c, // i2c interface
//chip: ADS1x15.chips.IC_ADS1015, // chip model
chip: ADS1x15.chips.IC_ADS1115, // ここをADS1115に修正します。
address: ADS1x15.address.ADDRESS_0x48, // i2c address on the bus
// Defaults for future readings
pga: ADS1x15.pga.PGA_4_096V, // power-gain-amplifier range
sps: ADS1x15.spsADS1015.SPS_250 // data rate (samples per second)
});
// Get a single-ended reading from channel-0 and display the results
adc.readChannel(ADS1x15.channel.CHANNEL_0, (err, value, volts) => {
if (err) {
console.error('Failed to fetch value from ADC', err);
process.exit(1);
} else {
console.log('Channel 0');
console.log(' * Value:', value); // will be a 11 or 15 bit integer depending on chip
console.log(' * Volts:', volts); // voltage reading factoring in the PGA
process.exit(0);
}
});
});
I2Cの情報を取得
さぁ、実際に通信してみましょう。
# index.jsを起動
$ cd ~/Desktop/pressure-sensors
$ node index.js
Channel 0
* Value: -4
* Volts: -0.0005
# 感圧センサーを指でつまみながら実行
$ node index.js
Channel 0
* Value: 3607
* Volts: 0.45088876003295997
現在のValueとVoltsが表示されました。
続編
書きました。取得したデータをブラウザ上で表示させています。
Raspberry piから送信したセンサーの値をGoのWEBサーバーで受け止め、three.jsで立体的に連続表示させる