RaspberryPi 3B+で感圧センサーの値を、A/Dコンバーターを経由してI2CでNode.jsを使って取得する



# 背景
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+
    - https://www.amazon.co.jp/gp/product/B07BFH96M3/
- 感圧センサー
    - https://www.switch-science.com/catalog/2614/
- A/Dコンバーター(ADS1115)
    - https://www.amazon.co.jp/gp/product/B0793J1YKP/
- ブレッドボード・ジャンパーワイヤー
- （あると便利）ワニ口クリップ

ブレッドボードとワニ口クリップは適当なものを使ってます。ちなみにラズパイ側の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のパーツが見つからなかったので今回適当に作成しました。適当なのでかなり手抜きで荒いです。本当はブレッドボードに直接配置出来るようにしたかったのですが、サイズを間違えたのかうまくいかず・・・。ただ、今回のざっくり設計には十分なのでこれをそのまま使おうと思います。

![![test回路2_回路図.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/280394/84e18693-a672-b2e3-0e21-c2a38aa9eab3.png)
ADS1115](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/280394/b5f8c43c-3183-ef22-0fd2-ab7a7e9eda91.png)

ちなみにパーツ作成は下記サイトを参考にしました。適当で良ければ手元にあるAdobe illustrator CS5.1でも割と簡単に作れたので、なかったらどんどん作ると良さそうです。

Fritzing カスタムパーツの作り方
https://jumbleat.com/wp-content/cache/all/2017/01/18/making_custom_parts_fritzing//index.html


### 完成したブレッドボード配線図と回路図


![ブレッドボード](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/280394/def53bd1-a519-9cdf-de9b-33937de665a3.png)

![回路図.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/280394/3982275f-7e27-b72f-0261-eb3cc03558b1.png)

![回路写真.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/280394/4fc4c346-21b6-e2e0-515e-5f0c8e088bf4.jpeg)


※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の各インターフェースについて簡単に記載しておきます。

- 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の設定をクリックします。
![Raspbianスタートメニュー](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/280394/e4abadd1-576e-2d54-6d9d-e67506656501.png)

インターフェースタブを選択し、I2Cを有効にします。
![Raspberry piの設定](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/280394/854bf76d-3fef-aa06-6e7e-a7d568526d0c.png)


# Node.jsのraspi-kit-ads1x15パッケージを使って、A/DコンバーターとI2C通信する

さて、I2C通信が出来るようになりました。後は具体的なプログラムを用意して、実際にA/Dコンバーターと通信してみます。
今回使用するのはraspi-kit-ads1x15パッケージですが、これが無くともi2c-busで通信することは可能です。ただ、i2c-busは一般的なi2cの通信をするだけのものなので、これだけではADS1115との通信について全て１から書く必要があります。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をインストールします。

``` shell
# アップデートしておきます。
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


``` JavaScript:index.js
"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の情報を取得

さぁ、実際に通信してみましょう。

```shell
# 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で立体的に連続表示させる](https://qiita.com/tobi50/items/74c578351d58c2457b86)