治具に役立つ RPi3 x node x I2C電子部品 3選

回路設計・ファーム開発担当のす〜(@ksksue)です。

技術を磨くな、治具を作れ

ということで今回は基板検査治具で役立った電子部品の話題です。

治具はざっくり以下のような構成をよく取ります。

  • Raspberry Pi 3 : 汎用性が高い、Webと親和性が高い、nodeが使える
  • nodejsでドライバ設計 : C/C++等に比べ圧倒的に開発スピード早い、Webと親和性が高い
  • センサは秋月・ストリナ・スイッチサイエンスなど市販モジュールを使用 : 入手性が良い、壊れてもすぐ交換/購入できる
    • 通信方式はなるべくI2C : SW側でインタフェース統一できる

開発スピード早く、組合せでさっと環境が整うのが良いです。

よく使っているI2C電子部品は以下の3つ

  • IOエキスパンダ
  • ADC
  • 電流センサ

それぞれ1つずつ紹介していきます。

IOエキスパンダ

f:id:photosynth-inc:20171210032702j:plain

16bit I2C I/Oエキスパンダー MCP23017: 半導体 秋月電子通商 電子部品 ネット通販

RPiのIOを使えばOKといえばOKなのですが

  1. RPiのIOピンだけだと足りない
  2. RPiのピン保護(故障した場合IO Expanderの交換でOK)

という理由でIO Expanderを使う場合があります。

16個のIOが増えるので重宝します。

ライブラリコードは以下

var i2c = require('i2c-bus');
var debug = require('debug')('IoEx');

const IOEX_ADDR = 0x20;
var self;

const IOEX_BANK_A_GPIO = 0x12;
const IOEX_BANK_B_GPIO = 0x13;

const IOEX_GPIO_HOGE_ON = 0x01;

function IoEx() {
  if(!(this instanceof IoEx)) {
    return new IoEx();
  }

  self = this;
  this._i2c = i2c.openSync(1);
  this._i2c.writeByteSync(IOEX_ADDR, 0x00, 0xFF); // BANK A 全て input
  this._i2c.writeByteSync(IOEX_ADDR, 0x01, 0x00); // BANK B 全て output
}

function setGpio(gpioVal) {
  let val = self._i2c.readByteSync(IOEX_ADDR, IOEX_BANK_B_GPIO);
  val = val | gpioVal;
  self._i2c.writeByteSync(IOEX_ADDR, IOEX_BANK_B_GPIO, val);
}

function clearGpio(gpioVal) {
  let val = self._i2c.readByteSync(IOEX_ADDR, IOEX_BANK_B_GPIO);
  val = val & (~gpioVal);
  self._i2c.writeByteSync(IOEX_ADDR, IOEX_BANK_B_GPIO, val);
}

function readGpio(gpioVal) {
  let val = self._i2c.readByteSync(IOEX_ADDR, IOEX_BANK_A_GPIO);
  val = val & gpioVal;
  if(val === 0) {
    return 0;
  } else {
    return 1;
  }
}

IoEx.prototype.setHoge = function() {
  setGpio(IOEX_GPIO_HOGE_ON);
}

IoEx.prototype.clearHoge = function() {
  clearGpio(IOEX_GPIO_HOGE_ON);
}

module.exports = new IoEx();

使う時

var ioex = require('./lib/IoEx');

// Hoge ピン ON
ioex.setHoge();

// Hoge ピン OFF
ioex.clearHoge();

ADC

このADCは12ビット4チャネルと精度そこそこでチャネル数が多いので汎用性が高いです。 npmにドライバがあります。

f:id:photosynth-inc:20171210040416j:plain

ADS1015使用12ビット4チャンネルADコンバータ(プログラマブルゲインアンプ付): 半導体 秋月電子通商 電子部品 ネット通販

先述したとおりnpmモジュールがあるのでインストール

npm i node-ads1x15 --save

それを使いやすくラップ

var ads1x15 = require('node-ads1x15');
var deasync = require('deasync');
var debug = require('debug')('Ads1015');

const CHANNEL_3_3V = 2;

const ADC_SAMPLES_PER_SECOND = '250';
const ADC_GAIN_AMP = '4096';

function Ads1015() {
  if(!(this instanceof Ads1015)) {
    return new Ads1015();
  }

  self = this;
  this._adc = new ads1x15(0); // 0 for ads1015, 1 for ads1115
  this._done = false;
  this._result = false;
}

function readAdc(channel, callback) {
  if(self._adc.busy) {
    return process.nextTick(function() { callback(new Error('ADC is busy')); });
  } else {
    self._adc.readADCSingleEnded(channel, ADC_GAIN_AMP, ADC_SAMPLES_PER_SECOND, function(err, data) {   
      if(err) {
        console.error(err);
        self._result = 0;
        self._done = true;
        if(callback) { callback(err); }
      } else { 
        debug('data : ' + data + ' mV');
        self._result = data;
        self._done = true;
        if(callback) { callback(null, data); }
      }
    });
  }
}

Ads1015.prototype.read3V = function(callback) {
  readAdc(CHANNEL_3_3V, callback);
}

Ads1015.prototype.readSync3V = function() {
  readAdc(CHANNEL_3_3V, null);
  deasync.loopWhile(function(){ return !self._done; });
  return self._result;
}

module.exports = new Ads1015();

使う時

var adc = require('./lib/Ads1015');
result = adc.readSync3V();
console.log(result + 'mV');

結果

3300mV

電流センサ

f:id:photosynth-inc:20171210044612j:plain

INA226PRC 【精密タイプ】I2Cディジタル電流・電圧・電力計モジュール - INA226PRC - ネット販売

0.1mAの分解能で電流値をセンシングすることができます。

電源ラインに流れる電流値の確認に使用しています。

詳細な使い方はストロベリーリナックスさんのモジュール説明書参照してもらうとして。。。

ライブラリコードは以下

var i2c = require('i2c-bus');
var debug = require('debug')('Ina226');

const INA226_ADDR = 0x41;

const MA_PER_LSB = 0.1; // 1 LSB 当たりの mA
const MV_PER_LSB = 1.25; // 1 LSB 当たりの mV

const INA226_CURRENT= 0x01;
const INA226_VOLT= 0x02;

var self;

function INA226() {
  if(!(this instanceof INA226)) {
    return new INA226();
  }

  self = this;
  this._i2c = i2c.openSync(1);
}

function i2cRead(cmd) {
  let buf = new Buffer(2);
  self._i2c.readI2cBlockSync(INA226_ADDR, cmd, 2, buf);
  debug(buf);
  return buf.readInt16BE();
}

INA226.prototype.readCurrentMa = function() {
  let val = i2cRead(INA226_CURRENT);
  debug('current raw : ' + val);
  return (val * MA_PER_LSB);
}

INA226.prototype.readVoltMv = function() {
  let val = i2cRead(INA226_VOLT);
  debug('volt raw : ' + val);
  return (val * MV_PER_LSB);
}

module.exports = new INA226();

使い方

var isense = require('./lib/Ina226');
result = isense.readCurrentMa();
console.log(result + ' mA');

結果

52.2 mA

配線

そういえばRPiとの繋ぎを描いてなかったので 以下の絵のように Raspberry Pi 3と繋ぐことで使えます。プルアップ抵抗描いてませんが適当(2.2k - 10k)な値のものを入れればOKかと。

I2Cで統一するとなにかとラクですね。

f:id:photosynth-inc:20171210044036p:plain

告知

フォトシンスではエンジニアを募集しています

www.wantedly.com