気ままにIoTメモ

色々なこと備忘録

圧力センサ(2)

引き続きFSRのメモ。

f:id:htn_hs:20170121215445j:plain
重り(75g)×2+台(68g)=218g 重りには釣りに使われるオモリを使っています。

重りを置いてからの抵抗値の変化を測定しました。

測定は250Hzで分圧値をArduinoのAD変換(10bit)により測定し、測定値から抵抗値を算出しました。
回路は圧力センサ(1)と同様の回路を使っています。

f:id:htn_hs:20170121220040p:plain
0.5秒もすれば十分収束するようです。

以下横軸対数
f:id:htn_hs:20170121215806p:plain
さらに長期的な変化を測定した所、0.5秒経過した後もじんわりと抵抗値が変化し続けてしまいました。
1秒の時点では1900Ωだった抵抗値が100秒の時点では1650Ωにまで変化してします。
感覚としては時定数が二段階ある感じ。

今回は0.5秒経過すれば収束、として重量を測定します。

f:id:htn_hs:20170121221025j:plain
重り(75g)×6+台(68g)=518g

今度はMCP3425で測定し、約4000Ωに収束することを確認しました。

抵抗値は力に反比例するので、
K/4000[Ω]=518[g]
K = 2072000

F[g] = 2072000/R[Ω]

75gの重りを一つずつ増やした結果
f:id:htn_hs:20170121224122p:plain
台の68g分を差し引いた値を出力しています。下の数字ははかりで測定した重さ。

±50gぐらいの精度で測定出来ました。
置く場所によっても値は上下するので、あくまで参考程度の測定しか出来ませんが、コンテストで使うモノがあるか・ないかを判断する程度には十分です。

iot_lab/10_fsr at master · hsgwa/iot_lab · GitHub

圧力センサ(1)

秋月で購入した圧力センサ(FSR:force-sensitive resistor)を使ったのでメモ。

抵抗値[Ω]∝1/力[F]という性質のあるセンサです。
日本語ではあまり資料は無いですが、英語で調べれば詳しい資料が多く出てきます。

センサ回路の製作 - 気ままにIoTメモ
以前の時点では組み込める形ではなかったのですが、丁度よいADコンバータがあったので簡単な回路に落ち着きました。

f:id:htn_hs:20170121161115j:plain
非反転増幅回路などを使っても良かったのですが、分圧であれば抵抗値が0~∞であっても出力電圧は0~2Vに収まるため、MCP3425で測定するには楽。
FSRを電源側に配置することにより、加えられている力が小さい(抵抗値が大きい)時に0V付近が出力され、MCP3425のPGAを8倍にできます。

センサ単体では面積が少ないため工夫します。

f:id:htn_hs:20170121161522j:plain
四つ角にセンサを配置し、並列接続します。 並列接続すれば一つのセンサとして取り扱えるのがミソ。

f:id:htn_hs:20170121161548j:plain
100均で買ってきた半球形のゴムクッションを使い、

f:id:htn_hs:20170121161619j:plain
厚めのアクリル(5mm)に取り付けることで、アクリル上であればセンサのみに力が加わるようになります。

f:id:htn_hs:20170121161711j:plain
乗せた様子はこのような感じ。

これで広い面積の荷重を測定することができるようになるはず。

I2C制御16bit ADC MCP3425(3)

前回に引き続き、ゲイン設定を自由にしてくれるプログラムを書いたのでメモ。

var Adc = require('./adc');

adc = new Adc({gain:1, accuracy:16});


adc.start();

var Vmax = [
    2.048,
    1.024,
    0.512,
    0.256
]

var gain = 8;

adc.on('complete', function(v){
    var idx = Math.log2(gain);

    if(gain > 1 && Vmax[idx] * 0.95 < Math.abs(v)) {
        gain /= 2;
    } else if(gain < 8 && Vmax[idx+1] * 0.95 > Math.abs(v)) {
        gain *= 2;
    } else {
        // 適切なゲインの測定結果
        console.log('gain:' + gain + '    ' + v);
    }

    adc.updateConfig({gain:gain});
    adc.start();
});

console.logの行ではゲインが適切に変えられた値を得ることが出来ます。

iot_lab/app.js at master · hsgwa/iot_lab · GitHub

I2C制御16bit ADC MCP3425(2)

I2C制御16bit ADCであるMCP3425用のライブラリを作ったので、使い方のメモ。

まずはモジュールのインストール

npm install i2c
npm install q
var Adc = require('./adc');

// adc = new Adc({gain:1, accuracy:16});

adc.updateConfig({gain:8});

adc.start();
adc.on('complete', function(v){
    console.log(v + '[V]');
    adc.start();
});

I2Cのアドレスは0x68、ゲイン1倍、16bit精度がデフォルトになっています。 アドレスを変更したい時には直接ライブラリ内のアドレスを変える必要あり。 ワンショットの測定ですが、adc.on内で再度スタートさせて無限ループになっています。

gainは1/2/4/8、accuracyは12/14/16のいずれかに設定してください。

f:id:htn_hs:20170115153524p:plain

ゲインを8倍にすることで細かい電圧の測定ができます。

iot_lab/08_mcp3425 at master · hsgwa/iot_lab · GitHub

I2C制御16bit ADC MCP3425(1)

秋月に1個250円で売っているI2C制御16bit ADCのMCP3425に関するメモ。

特徴

  • 2.7V〜5.5V動作
  • 精度により測定周波数が変わる(16bit精度では15 SPS)
  • 内部に2.048V±0.05%(Vref)の基準電圧
  • ×1・×4・×8のPGA
  • Vin = (Vin+) - (Vin-)の 差動入力が測定可能
  • 測定範囲は-Vref <= Vin * PGA <= Vref

回路は端子の名前通りに繋ぐだけです。

f:id:htn_hs:20170115133548j:plain

今回はV-端子をGNDに接地させて、シングルエンド入力で使いました。
動作を見るだけなので今回だけパスコンは省略。

npm install q
npm install i2c
var Q = require('q');
var i2c = require('i2c');
var address = 0x68;
var wire = new i2c(address, {device: '/dev/i2c-1'});

Q.delay(10)
    .then(function(){
        wire.writeByte(0x88, function(err){
        })
    })
     .delay(70)
     .then(function(){
         wire.read(3, function(err, res){
             var int16value = res[0] << 8 | res[1];
             var voltage = 0.0000625 * int16value;
             console.log(int16value.toString(16) + ' -> ' + voltage + '[V]');
             console.log(res[2].toString(16));
         });
     });

16bit精度で測定するために、ワンショットの測定になっています。PGAは1倍にしたため、+2.048Vまでが測定範囲です。70msのディレイは1/15SPS=66mから計算しています。

f:id:htn_hs:20170115132555p:plain

テスタでの測定値は1.230Vだったので正しく動作しているようです。

共用体を使わないワード設定(C/C++)

MCP3425のArduino用ライブラリに使われている1ワードのデータを設定する方法が簡単だったのでメモ。

void getResult(int16_t *dataPtr) {
       ((char*)dataPtr)[1] = read();
       ((char*)dataPtr)[0] = read();
}

データの読み込みは1バイトずつで、測定データは2バイトと言う場合に使えそうです。

I2C接続小型キャラクタLCDモジュール(2)

I2Cで制御するLCD用のライブラリを作ったので、使い方のメモ。

回路図はI2C接続小型キャラクタLCDモジュール(1)を参考にしてください。

まずは使っているモジュールのインストール。

npm install i2c
npm install q

サンプルコード

var Lcd = require('./lcd');
// lcd = new Lcd({cols:16, rows:2, contrast: 35}); 
// lcd = new Lcd(); // デフォルト値は省略可
lcd = new Lcd({largeFont:true, rows:1});

lcd.on('ready', function(){
    lcd.print('Hello, world!');
});

I2Cのアドレスは0x3e、16文字2行、コントラストは35がデフォルトになっています。
アドレスを変更したい時には直接ライブラリ内のアドレスを変える必要あり。
カタカナは使う予定が無かったので、ASCIIコード内の文字しか表示できないようになっています。

2行分の文字を表示させる時にはlargeFontとrowsの両方が必要になります。

f:id:htn_hs:20170115004035j:plain

プログラムはこちら
iot_lab/07_i2c_lcd at master · hsgwa/iot_lab · GitHub

本当はCのマクロのようなビット演算

#define bitcheck(a,b) (a >> b) & 1
#define bitset(a,b)     a |= (1 << b)
#define bitunset(a,b)  a &= ~(1 << b)

のようなことをしたかったのですが、プリミティブ型は値渡しになってしまうので毎度丁寧にビット演算式を書いてます(Javascriptにビット操作は向かないのですね)。

今回、ライブラリの作成にはNode.js Hitachi HD44780 LCD driverを参考にさせていただきました。

参考:
aqm0802a-i2c-lcd by saraf
GitHub - fivdi/lcd: Node.js Hitachi HD44780 LCD driver
H8で学ぶマイコン開発入門(7):LCDに文字を表示させるプログラミング (1/3) - MONOist(モノイスト)
i2c
トリッキーなコード - bit演算マクロ
【Javascript】値渡しと参照渡しについてあらためてまとめてみる - Qiita