前からせこせこと、イメージしていたロゴを考え中。
もっと、ラフにしないとPCB とかにプリントしたとき消えちゃうし。ロゴって難しいですね。
友達のデザイナーに暇なときに、作ってもらおう。やっぱりプロがやるとクオリティーがぜんぜん違うし。
前からせこせこと、イメージしていたロゴを考え中。
もっと、ラフにしないとPCB とかにプリントしたとき消えちゃうし。ロゴって難しいですね。
友達のデザイナーに暇なときに、作ってもらおう。やっぱりプロがやるとクオリティーがぜんぜん違うし。
途中で、仕事が忙しくなって部屋の模様替えやらなんやらで、途中で作業が止まっていた ESP13 (ESP-WROOM-02)のBackBoost 電源回路のモジュールの再開です。
このシリーズは、PCBのプリント基板を作って BackBoost 回路に TPS63000 を使い、さらにリチウム電池の充電機能と放電保護を入れた ESP-WROOM-02 のモジュールを作るコンセプトです。
とりあえず、前回はESP8266 を動かすところまでは行かず、電源回路の半田付け不良とかで止まっていました。QFN パッケージのTPS63000 も何個かつぶして、練習すること数台目、やっと動作するものができました。
LEDが裏側についているのでわかりにくいですが、2つビルトインで付いているグリーンとブルーのLED を点滅しています。
1セルのリチウム充電回路と保護回路も付いています。充電しながらの動作も対応です。
とりあえず、もうひとつ同じものを作り、各種電圧、電流などを測定してチェックしてみたいです。そもそも、そういう用途に作ったものですので。
ケースにも入れて、とりあえずこのネタを再開できそうです。
今、チェックしているのは、プログラム書き込みを自動化する回路を組み込んであるのですが、IDE の設定なのかこれが動作せずです。
ハードが悪いのか、ソフトの設定なのかをとりあえず分けたいところです。IDE のバージョンが1.6.9 まで上がって ESP8266 の Community のバージョンも 2.3.0 まで進化しました。
久しぶりだったので、この進化にまだ追いつけず。
https://github.com/esp8266/Arduino
汎用を選ぶとリセット方法も選択できるようです。
とりあえず、模索中です。
まとめ、というかやることリスト
・ESP8266 の BackBoost 回路付きの開発ボードが出来た
・QFN パッケージは慣れれば楽。5個くらい練習で潰れましたが、、、、
・リセットボタンの半田面のサイズが小さく、次回はもう少し幅を取りたい。
・リセット方法をNodeMCU のようにするにはどうすれば?
・12K と 200KΩの 0603 サイズを追加注文。12K は消費個数が多く、200KΩはとりあえず手元になかった。(表記はあるが、実測値が違っていた)
・オリジナル基板は楽しい反面、どっかおかしいところを見つけるのが難しい。ハードの問題(部品含む)なのか設計か、半田付け不良か、ソフトウェア的な問題なのか、などなど。
・とりあえず、おかしな動きが取れたらケースに入れたい。
INA226 と arduino の I2C 信号をロジックアナライザで見てみました。
コードは前回と同じものです。1秒ごとに4つのデータをゲットしています。
トリガは、SDA にかけました。Hi から Low になって信号が行くようです。
まず、I2C アドレス0x40 のレジスタ 0x02 を投げて、値が帰ってくる流れが見えます。読み出しには、1.7ms ほどかかっていることがわかりました。ビットの信号は、4us 程度のようです。SDAでビットが立っているのを判別しているようです。
たとえば、最初は INA226_REG_BUSVOLTAGE (0x02) を読み出しているようで、値は16進数で 0x0E9E が帰ってきています。10進数では、3742 でこれに1.25 を掛けたものが mV になるので、4677.5 mV = 4.6775V ということですね。精度は、0.1mV ということです。
I2C のリアルタイムな生データを見るのは今回が初めてです。なかなか、IC同士で通話している感じがおもしろいですね。
1000分の1,2秒で、データを読み取っていて、0 と 1 の Hi と Low の信号のやり取りでそれをやっているというのが目で見えてわかりやすいです。ロジックアナライザって偉い存在ですね。
▼まとめ
・INA226 と arduino の I2C 信号を見てみた
・SDA の LOW にトリガーをかけて採取。
・スレーブアドレス+データ領域を指定すると、対応するスレーブから値が帰ってくる
・SCL にビットデータが流れ、SDA にデータ流れる感じ。両方ともHi になった部分が ビットが立つ感じ。
・ビット のHi になる時間は、4us ほど。
・1つのレジスタの読み出しには、1.7ms ほどかかる。
・呼び出しから応答までの間隔は、1ms ほど。0.7ms でデータをやり取りしている。合計で1.7ms
・安物のロジックアナライザでも十分現象を観察できた。
もう1月も終わりですね。なんだか速く月日が経つような気がします。
さて、今日は 先日作った INA226 の電流電圧センサーを I2C で arduino nano クローンにて計測してみました。
前回の調査で見つけた、ポーランドのサイトにいいチュートリアルがありました。
Korneliusz Jarzębskiのサイト
Dwukierunkowy cyfrowy czujnik prądu/mocy INA226github
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 に入れます。あとは、負荷を電流計測にハイサイド側に付ける感じです。
シリアル通信を開くと、以下のようになっています。
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
・とりあえず、十分な精度です。
PCB が組みあがったのですが、これを RasPi で i2c するサンプルをググってみたら、いくつかありました。
RasPi は、i2c が使えるようにモジュールをロードしておきました。RasPi でi2c は初めて使います。無事に出来るでしょうか?
# lsmod Module Size Used by ★i2c_dev 6027 0 cfg80211 386508 0 rfkill 16651 1 cfg80211 rpcsec_gss_krb5 20958 0 nfsd 263569 2 snd_bcm2835 18649 0 snd_pcm 73475 1 snd_bcm2835 snd_seq 53078 0 snd_seq_device 5628 1 snd_seq snd_timer 17784 2 snd_pcm,snd_seq snd 51038 5 snd_bcm2835,snd_timer,snd_pcm,snd_seq,snd_seq_device ★i2c_bcm2708 4990 0 joydev 8879 0 spi_bcm2708 5137 0 evdev 9950 2 uio_pdrv_genirq 2958 0 uio 8119 1 uio_pdrv_genirq
先輩たちがサンプルコードは書いているはずなので、探したところ、python でやるのとか、ruby でやるのとかがすぐ見つかりました。
とりあえず、動作確認したいので以下のサイトのコードを参考に必要な部分だけ使わせてもらいました。
Rabbit Note
BeagleBone Black で作るロギング機能付き電力計 (ソフト編)
BeagleBone Black(BBBと略するようです)での環境ですが、大変参考になりました。
使わせていただいたコードは最下部に付けておきます。で、配線は写真のようにちょっと雑ですが配線。負荷には、ちっさいファンをつけてみました。
スレーブアドレスは、何も設定しないと、0x40 が設定されるようです。
# i2cdetect -y 1
0 1 2 3 4 5 6 7 8 9 a b c d e f
00: -- -- -- -- -- -- -- -- -- -- -- -- --
10: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
20: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
30: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
40: 40 -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
50: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
60: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
70: -- -- -- -- -- -- -- --
プログラムを起動すると、以下のようになります。
# ./test.ruby --------- 2016/01/25, 01:33:22 4.78125 V 151 mA 0.29 W --------- 2016/01/25, 01:33:22 4.78125 V 151 mA 0.289 W --------- 2016/01/25, 01:33:23 4.78875 V 152 mA 0.291 W --------- 2016/01/25, 01:33:23 4.7875 V 151 mA 0.29 W --------- 2016/01/25, 01:33:24 4.7875 V 150 mA 0.289 W --------- 2016/01/25, 01:33:24 4.7875 V 151 mA 0.29 W --------- 2016/01/25, 01:33:25 4.79 V 152 mA 0.292 W
負荷にLED を点けてみると、以下のようです。
# ./test.ruby --------- 2016/01/25, 01:35:31 4.88 V 2 mA 0.005 W --------- 2016/01/25, 01:35:31 4.88 V 2 mA 0.005 W --------- 2016/01/25, 01:35:31 4.9125 V 2 mA 0.005 W --------- 2016/01/25, 01:35:32 4.91375 V 2 mA 0.005 W --------- 2016/01/25, 01:35:32 4.91375 V 2 mA 0.005 W
まだあまりちゃんと理解していませんが、内部のレジスタの ox05 に、キャリブレーションする設定値を入れるようです。
以下の C のサンプルコードから、シャント抵抗に0.025R を使っている場合は、以下のように計算した16進数を入れればよいようです。書き込むとき、以下のコードでは、リトルエンディアンに変換していました。
https://github.com/jarzebski/Arduino-INA226/blob/master/INA226.cpp
0.025Ω = 0.00512/(0.025*0.0001)=2048 = 0x08 0x00
0x05 の補正レジスタを見てみると、
# i2cget -y 1 0x40 0x05 w
0x0008
という値が帰ってきました。
さて、そんな感じでとりあえずコードは以下のようにしてみました。
#!/usr/bin/env ruby
# -*- coding: utf-8 -*-
IOCTL_I2C_SLAVE = 0x0703
# Script for power meter using the following parts
# - Power Meter module (IC: INA226)
# # i2cdetect -y 1
# 0 1 2 3 4 5 6 7 8 9 a b c d e f
# 00: -- -- -- -- -- -- -- -- -- -- -- -- --
# 10: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
# 20: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
# 30: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
# 40: 40 -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
# 50: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
# 60: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
# 70: -- -- -- -- -- -- -- --
class PowerSenseor
def initialize(i2c_bus=1, dev_addr=0x40)
@i2c = File.open(sprintf('/dev/i2c-%d', i2c_bus), 'rb+')
@i2c.ioctl(IOCTL_I2C_SLAVE, dev_addr)
@dev_addr = dev_addr
@v_val = 0
@c_val = 0
@p_val = 0
# shunt resistor = 0.002Ω = 0.00512/(0.002*0.001)=2560 = 0x0a 0x00
# 0.025Ω = 0.00512/(0.025*0.0001)=2048 = 0x08 0x00
# 内部レジスタ[0x04] (Current) = 内部レジスタ[0x01]×内部レジスタ[0x05] / 2048
exec_cmd("i2cset -y 1 0x#{dev_addr.to_s(16)} 0x05 0x08 0x00 i")
# conversion time = 332us, number of average = 16
exec_cmd("i2cset -y 1 0x#{dev_addr.to_s(16)} 0x00 0x04 0x97 i")
end
def sense
# i2cset/i2cget は 10ms オーダーの時間を消費するのでここでは使用しない
@i2c.write(0x02)
@v_val = conver_signed(@i2c.read(2))
# 0x04 電流レジスタ
@i2c.write(0x04)
@c_val = conver_signed(@i2c.read(2))
# 0x03 Powerレジスタ
@i2c.write(0x03)
@p_val = conver_signed(@i2c.read(2))
end
def conver_signed(bytes)
# convert endian
return bytes.unpack('n').pack('S').unpack('s')[0].abs
end
def get_voltage
return calc_voltage(@v_val)
end
def get_current
return calc_current(@c_val)
end
def get_power
return calc_power(@p_val)
end
def exec_cmd(cmd)
val=`#{cmd} 2> /dev/null`
raise StandardError, "FAIL: #{cmd}" unless $?.success?
return val
end
def calc_voltage(v_val)
return v_val * 1.25 / 1000.0
end
# 0x04 電流レジスタ
def calc_current(c_val)
return c_val / 10
end
# 0x03 Powerレジスタ
def calc_power(p_val)
# return p_val * 0.025
return p_val * 0.001
end
end
require 'optparse'
params = ARGV.getopts('lq')
data_list = []
Signal.trap(:INT){
if params['l'] then
printf("time,voltage,current,power\n")
data_list.each{|data|
printf("%10d,%.3f,%.3f,%.3f\n", data[0], data[1], data[2], data[3])
}
end
exit(0)
}
sensor = PowerSenseor.new
require "date"
start_time = Time.now
i = 0
while true
sensor.sense
v = sensor.get_voltage
c = sensor.get_current
p = sensor.get_power
dt = DateTime.now
print "--------- "
print(dt.strftime("%Y/%m/%d, %H:%M:%S"), "\n")
print v
print " V\n"
print c
print " mA\n"
print p
print " W\n"
if ((i & 0x7F) == 0) then
else
sleep 0.5
end
i = (i & 0xff) + 1
end
▼まとめ
・0x05 にシャント抵抗値を入れた補正値を書き込む
・書き込む最は、16進をリトルエンディアンにして書き込む
・0x04 はPowerレジスタで、0x04 は電流レジスタ。
・LSB ってなに?
・ちっこい今使っているファンは、150mA くらい使っていて0.3W ほど
・c のサンプルはすぐに見つからなかったけども、どうんな感じになるんだろう?
・自分で作ったハードが動いてうれしぃ!
・レジスタって、どういう回路なの? どういう仕組みで覚えているんだろう?
小さな部品も大きく見えるようになって、作業しやすくなったのでPCB の半田付けを再開しました。
今回は、電流センサーの INA226 です。
回路図は、チュートリアルを参考に上記のようにしました。
ブレッドボードをまたぐ4ピッチ幅にしてあります。プリントに出すPCB のあまり部分に無理やり作ったので少し窮屈です。
こんな感じでテープで固定しつつ半田付け。小さいですが、モニターで見れるので問題なしです。
以下、作業ステップ。
半田小手の先にちょっと半田を付けて位置決め。ブリッジしても気にしない。 ![]()
シャント抵抗もつけて、ピンヘッダーを付けてとりあえず本日終了。
裏側も小さな抵抗とコンデンサーを付けています。
かなりマイクロスコープがあるおかげで作業がしやすくなりました。必須ですね。これは。
300円のmicroSD の 8GB も来たのでラズパイで I2C してみます。品質はどうでしょうかね?
こんなに、ぼやけた印字でしたっけ?なんか偽造品の臭いがしますが、、、、
あとで、手持ちの本物と比べてみますか。
|
|