INA226 を arduino nano で

もう1月も終わりですね。なんだか速く月日が経つような気がします。

さて、今日は 先日作った INA226 の電流電圧センサーを I2C で arduino nano クローンにて計測してみました。

前回の調査で見つけた、ポーランドのサイトにいいチュートリアルがありました。

Korneliusz Jarzębskiのサイト
Dwukierunkowy cyfrowy czujnik prądu/mocy INA226

github
Arduino-INA226
https://github.com/jarzebski/Arduino-INA226

このGitHub のsimple のソースにライブラリを配置し、

./INA226_simple
├── INA226.cpp
├── INA226.h
└── INA226_simple.ino

INA226.cpp の記述を以下に変更。25mR のシャント抵抗の設定をします。

#include "INA226.h"
::
void setup() 
{
::
  // Calibrate INA226. Rshunt = 0.025 ohm, Max excepted current = 4A
  ina.calibrate(0.025, 1);
::

配線は以下のようにしました。ちょっとわかりにくいですが、Arduino の A5(SCL) と A4(SDA) をつないで、GND と 3.3V を VSS に入れます。あとは、負荷を電流計測にハイサイド側に付ける感じです。

arduino_ina226

シリアル通信を開くと、以下のようになっています。

Initialize INA226
-----------------------------------------------
Mode:                  Shunt and Bus, Continuous
Samples average:       1 sample
Bus conversion time:   1.100ms
Shunt conversion time: 1.100ms
Max possible current:  3.28 A
Max current:           3.28 A
Max shunt voltage:     0.08 V
Max power:             117.96 W
-----------------------------------------------
Bus voltage:   4.67875 V
Bus power:     0.01250 W
Shunt voltage: 0.00007 V
Shunt current: 0.00300 A

Bus voltage:   4.68125 V
Bus power:     0.01250 W
Shunt voltage: 0.00007 V
Shunt current: 0.00300 A

Bus voltage:   4.67750 V
Bus power:     0.01250 W
Shunt voltage: 0.00007 V
Shunt current: 0.00300 A

PC からのUSB 電圧は4.67V 程度のようです。3mA で12.5mW ということがわかりました。ちゃんと計測できているようですね。

arduino だと装備からLCDなどに出す用途で使えそうですね。データをどこかに飛ばすものであれば、ESP8266 が良さそうです。

 

IC 回路の電圧は3.3V でも5V でもOKです。LEDの負荷を arduino の 3.3V から取って計測してみると以下のようになりました。

Initialize INA226
-----------------------------------------------
Mode:                  Shunt and Bus, Continuous
Samples average:       1 sample
Bus conversion time:   1.100ms
Shunt conversion time: 1.100ms
Max possible current:  3.28 A
Max current:           3.28 A
Max shunt voltage:     0.08 V
Max power:             117.96 W
-----------------------------------------------
Bus voltage:   3.26875 V
Bus power:     0.00500 W
Shunt voltage: 0.00004 V
Shunt current: 0.00150 A

Bus voltage:   3.27000 V
Bus power:     0.00500 W
Shunt voltage: 0.00004 V
Shunt current: 0.00150 A

Bus voltage:   3.26875 V
Bus power:     0.00500 W
Shunt voltage: 0.00004 V
Shunt current: 0.00160 A

 

ちょっとコードを追加して、レジスターの値を取ってみました。

Initialize INA226
-----------------------------------------------
Mode:                  Shunt and Bus, Continuous
Samples average:       1 sample
Bus conversion time:   1.100ms
Shunt conversion time: 1.100ms
Max possible current:  3.28 A
Max current:           3.28 A
Max shunt voltage:     0.08 V
Max power:             117.96 W
-----------------------------------------------
INA226_REG_CONFIG          (0x00):16679 ---
INA226_REG_SHUNTVOLTAGE    (0x01):30 ---
INA226_REG_BUSVOLTAGE      (0x02):3749 ---
INA226_REG_POWER           (0x03):5 ---
INA226_REG_CURRENT         (0x04):30 ---
INA226_REG_CALIBRATION     (0x05):2048 ---
-----------------------------------------------
Bus voltage:   4.68250 V
Bus power:     0.01250 W
Shunt voltage: 0.00007 V
Shunt current: 0.00300 A

レジスター値は10進です。アベレージの回数とかも定数があるので便利ですね。

精度は、0.1mA  のようですね。PCB のあまり部分で作ったモジュールでも結構遊べました。あと、小さなパーツの半田付けの練習にもなりました。

 

▼参考サイト

http://denshi-kousaku.fan.coocan.jp/report030.html

 

▼まとめ

・ライブラリ便利!

・INA226 モジュールを使って、arduino で i2c にて電流電圧を簡単に取れる

・精度は、シャント抵抗次第で、0.025R だと0.1mA(100μA) の精度になるようです

・GND はIC回路と共通で測定で、電圧を測定する場合は、IC の VBUS 8pin に計測電圧をかける

・LSB とは一般的には、最下位ビットのことで、least significant bit の頭文字。

・これの分解能力は16ビットなので、0.025R だと電流は0.1mA で電圧は 1.25mV

・とりあえず、十分な精度です。

1us Lチカ

2016年 謹賀新年、あけましておめでとうございます。おせち料理も31日と1日で食べつくしてしまいました。

さて、今年最初のブログですね。0.000001秒のLチカをロジックアナライザーでモニタリングして光らせてみました。

あと、オレンジパイで、8本のGPIO を使って安価なロジックアナライザーで採取できるかも確認してみました。

 

サンプルプログラムを採取したデータが以下です。8本分は取れていますが、速すぎるところは取りこぼしているようです。

1

矢印は500ns で光っている部分で採取に失敗し、取りこぼす事がありました。このあたりが2Mhz の限界なんですね。今のファームウェアとソフトウェアだとこれが限界のようです。

2

複数のLED は、blink ファンクションにて光らせていますが、呼び出しと初期化の処理で250us 程度使っているようです。

3

usleep 関数を使っても思ったより、処理に時間がかかるようです。1us を指定して光らせているんですが、実際は69us 光っています。nanosleep を使っても66us は使われてしまうようで、1us を光らせる為にwhile で調整してみました。

4

サンプルのプログラムは以下です。

/*
 *  +-----+-----+----------+------+---+--OrangePiPC--+---+------+---------+-----+--+
 *  | BCM | wPi |   Name   | Mode | V | Physical | V | Mode | Name     | wPi | BCM |
 *  +-----+-----+----------+------+---+----++----+---+------+----------+-----+-----+
 *  |     |     |     3.3v |      |   |  1 || 2  |   |      | 5v       |     |     |
 *  |   2 |  -1 |    SDA.0 |      |   |  3 || 4  |   |      | 5V       |     |     |
 *  |   3 |  -1 |    SCL.0 |      |   |  5 || 6  |   |      | 0v       |     |     |
 *  |   4 |   6 | IO6 PA06 |  OUT | 0 |  7 || 8  |   |      | TxD3     |     |     |
 *  |     |     |       0v |      |   |  9 || 10 |   |      | RxD3     |     |     |
 *  |  17 |  -1 |     RxD2 |      |   | 11 || 12 | 0 | OUT  | IO1 PD14 | 1   | 18  |
 *  |  27 |  -1 |     TxD2 |      |   | 13 || 14 |   |      | 0v       |     |     |
 *  |  22 |  -1 |     CTS2 |      |   | 15 || 16 | 0 | OUT  | IO4 PC04 | 4   | 23  |
 *  |     |     |     3.3v |      |   | 17 || 18 | 0 | OUT  | IO5 PC07 | 5   | 24  |
 *  |  10 |  -1 |     MOSI |      |   | 19 || 20 |   |      | 0v       |     |     |
 *  |   9 |  -1 |     MISO |      |   | 21 || 22 |   |      | RTS2     |     |     |
 *  |  11 |  -1 |     SCLK |      |   | 23 || 24 |   |      | SPI-CE0  |     |     |
 *  |     |     |       0v |      |   | 25 || 26 |   |      | CE1      |     |     |
 *  |   0 |  -1 |    SDA.1 |      |   | 27 || 28 |   |      | SCL.1    |     |     |
 *  |   5 |   7 |  IO7 PA7 |  OUT | 0 | 29 || 30 |   |      | 0v       |     |     |
 *  |   6 |   8 |  IO8 PA8 |  OUT | 0 | 31 || 32 | 0 | OUT  | IO9 PG08 | 9   | 12  |
 *  |  13 |  10 | IO10 PA9 |  OUT | 0 | 33 || 34 |   |      | 0v       |     |     |
 *  |  19 |  12 | IO12PA10 |  OUT | 0 | 35 || 36 | 0 | OUT  | IO13PG09 | 13  | 16  |
 *  |  26 |  14 | IO14PA20 | ALT3 | 0 | 37 || 38 | 0 | OUT  | IO15PG06 | 15  | 20  |
 *  |     |     |       0v |      |   | 39 || 40 | 0 | OUT  | IO16PG07 | 16  | 21  |
 *  +-----+-----+----------+------+---+----++----+---+------+----------+-----+-----+
 *  | BCM | wPi |   Name   | Mode | V | Physical | V | Mode | Name     | wPi | BCM |
 *  +-----+-----+----------+------+---+--OrangePIPC--+------+----------+-----+-----+
 *         ^^^^ Pin NO                                                   ^^^^ Pin NO
 * 1us LED blink.
 * building ex) gcc -lwiringPi -lpthread -I/usr/local/include -L/usr/local/lib -levent -o 2016blinkall 2016blinkall.c
 * 
 *
*/
#include <sys/time.h>
#include <time.h>
#include <unistd.h>
#include <stdio.h>
#include <wiringPi.h>

#define MSEC 1
#define USEC 33
#define NANOSEC 1000

int blink2(int led, int delay);

int main (void)
{
  int led;
  int i = 0;

  while (i < 3)
  {
    blink2(16, 1000);
      blink2(15, 1000); //Next blink 250 us
      blink2(13, 1000);
      blink2(9, 1000);
      blink2(5, 1000);
      blink2(4, 1000);
      blink2(1, 1000);
      blink2(6, 1000);

    i++;
  }

  delay (MSEC);
  return 0;
}

int blink2(int led, int delay){
    // unsigned int usecs;
    // usecs = delay;
    // sec = delay;
    led = led;
    int i = 0;

    // nano sec
    struct timespec nano;
    nano.tv_sec = 0;
    nano.tv_nsec = delay;

    wiringPiSetup () ;
    pinMode (led, OUTPUT) ;

    digitalWrite (led, HIGH) ;
    nanosleep(&nano, NULL); // 66us
    // usleep (usecs) ; // 66us
    // delay (delay);
    digitalWrite (led,  LOW) ;
    usleep (1);

    digitalWrite (led, HIGH) ;

    // 1us
    while (i < 100)
    {
        i++;
    }
    digitalWrite (led,  LOW) ;
    usleep (1); // 66us

    digitalWrite (led, HIGH) ;
    // 500 ns
    digitalWrite (led,  LOW) ;
}

GPIO の8本を同時に処理させるにはどうしたらいいんでしょうかね。マルチスレッド処理ですかね?シフトレジスタに投げて、一括処理とかですかね?

 

前ちょっと触ったイベント処理のlibevent とかを使うとどのくらいの精度になるんでしょうかね。いろいろ疑問がわいてきます。

E-ink を表示するためにはまだまだ超えないといけない山がたくさんあるようです。

なんとか、春までには表示したいんですが。こつこつとやっていきます。

Sigrok の Pulsview 0.3.0 動きました

とりあえず、なんとか動かしたいのでソースをコードも見ましたが、特に問題となりそうな部分もなく、ちょっと場を離れてから、brew版のをサイド入れてみることに。とりあえず、動作させることができました。

なんとか、今年中に出来たのですっきり。

 

0.3.0-git-5d73886 では、以下のようにトリガーが設定できて楽になりました。Runを押せばトリガーがでるまで、stop して採取されます。サンプル数を設定しておけば、採取されて停止します。ロジックアナライザーとしては基本機能だと思いますが、手持ちのハードでなんとか動いてよかったです。

7

拡大すると、500ns とか取れています。1us 単位くらいまでは見れそうということがわかりました。

8

サンプルレートは、2MHz 以上あげるとどうしても採取後にクルクル回って、操作を受け付けないスタック状態のような感じになります。コマンドライン版でドライバを指定してみると、以下のようです。

$ sigrok-cli --show --driver fx2lafw
Driver functions:
    Logic analyzer
Scan options:
    conn
sr: fx2lafw: Failed to get manufacturer string descriptor: LIBUSB_ERROR_OTHER.
sr: fx2lafw: Failed to get manufacturer string descriptor: LIBUSB_ERROR_OTHER.
sr: fx2lafw: Failed to get manufacturer string descriptor: LIBUSB_ERROR_OTHER.
sr: fx2lafw: Failed to get manufacturer string descriptor: LIBUSB_ERROR_OTHER.
sr: fx2lafw: Failed to get manufacturer string descriptor: LIBUSB_ERROR_OTHER.
sr: fx2lafw: Failed to get manufacturer string descriptor: LIBUSB_ERROR_OTHER.
fx2lafw:conn=28.2 - Saleae Logic with 8 channels: 0 1 2 3 4 5 6 7
Supported configuration options:
    continuous: 
    limit_samples: 0 (current)
    conn: 28.2 (current)
    samplerate - supported samplerates:
      20 kHz
      25 kHz
      50 kHz
      100 kHz
      200 kHz
      250 kHz
      500 kHz
      1 MHz
      2 MHz
      3 MHz
      4 MHz
      6 MHz
      8 MHz
      12 MHz
      16 MHz
      24 MHz
    Supported triggers: 0 1 r f e 
    captureratio: 0 (current)

ここに出ているサンプリング周波数は採取できるはずなんですが、なぜか2MHz までしかとれません。

まぁ、最初の一台ですし、これで勉強させてもらって、物足りなければまた考えることにします。

 

automator でシェルスクリプトを実行するものを作り、アイコンをつけて、app 化します。

6

python の環境変数を一度 unset して消去して、python3.4 とか3.x のをセットしてアプリをバックグランドで呼び出します。

unset PYTHONPATH
export PYTHONPATH="/usr/local/lib/python3.4/site-packages/:$PYTHONPATH"

/usr/local/Cellar/pulseview/HEAD/bin/pulseview >/dev/null 2>&1 &

 

配布用にするには、ライブラリのパスを全部書き換えないといけないので、やめました。このあたりのスキルは、もう少し勉強しないと嵌りそうです。

5

brew 版のインストールは、wiki に書いてあるとおりで以下のようです。

https://sigrok.org/wiki/Mac_OS_X

$ brew tap rene-dev/sigrok

$ brew install python3

$ brew install –HEAD libserialport

$ brew install –HEAD –with-libserialport libsigrok

$ brew install –HEAD libsigrokdecode

$ brew install –HEAD –with-libserialport sigrok-cli

$ brew install –HEAD pulseview

ポイントとしては、マニュアルビルドしてソースから入れたものは一度、綺麗に消して、brew docter で問題をクリアにしてからやることと、以下の libsigrokdecode が2つ出てくるのでbrew のを無効にすることくらいです。

$ brew install –HEAD libsigrokdecode

Error: Formulae found in multiple taps:

* homebrew/science/libsigrokdecode

* rene-dev/sigrok/libsigrokdecode

 

$ brew untap homebrew/science

$ brew tap –repair

$ brew update

 

あと、ファームウェアの格納場所は、デフォルトで

/usr/local/share/sigrok-firmware

になるので、ここにディレクトリを作成し、最新のファームウェアを入れておきます。これで最初のデバイスを見つけてファームがなくエラーになるのを迂回できます。エラーでも、落ちはしませんが。前回落ちたのは別の原因で、QT 関連のライブラリのパスが書き換わっていないのが原因でした。ltool で見ると、/usr 配下となっていました。そのほかの原因もあったとは思いますが、ライブラリの依存関係でおそらくは、brew 版のを見に行っていたのかもしれません。まぁ、詳細は不明です。

 

ということで、とりあえずは動いてよかったです。トリガーもかけられるようになったし、インターフェイスは少しよくなった感じ。ボタンの配置とか。

 

▼まとめ

・EZ-USB FX2LP CY7C68013A で、sigrok の pulsview は動作

・このハードは実質6ドルくらいなので、ロジックアナライザーとして最初の一台で遊ぶには十分

・0.3.0-git-f3697d3 は動作した

・トリガーがかけられるようになった

・少しインターフェイスがよくなった

・2Mhz サンプリングまでは出来ることを確認

・1チャンネル採取で500ns は採取できた。1us くらいが精度か?

・8チャンネル同時採取はまだやっていない

・ファームウェア格納場所は、/usr/local/share/sigrok-firmware

・brew 版で HEAD で入れているので、時期によっては動作しない場合もあるかも

・配布用に、ライブラリを書き換えるのはどうすれば楽になるのか?要研究