google-site-verification: google3bd66dd162ef54c7.html

ArduinoにSDメモリーカードを接続する実験

 最近は無線LANでデーターを飛ばして適当なサーバーに保存するのが流行っています。確かに便利ですが、SDメモリーカードにデーターを保存して、自己完結型にするのも悪くない方法だと思います。

 実はこの間から取り組んでいる電力量計の測定結果をロギングする方法について検討中ですが、SDメモリーカードにデーターを保存するのが使い易いかなと思っています。実は以前気圧ロガーを作った時にSDメモリーカードを使いましたが、この時はとにかく動かすことを優先したので、作り込みがちょっと甘いところがあって気になっていました。

 そんなことで、インタフェイスレベルからもう一度確認していくことにします。

 SDカードの接続コネクタはいろいろありますが、今回は秋月で売っているSDカードスロットDIP化モジュールを使うことにしました。

▼秋月のSDカードアダプタ
秋月のSDカードアダプタ
 標準サイズのSDカード用のアダプタです。なお東芝のSDメモリーカードが挿さった状態です。

▼SDカードアダプタの回路図 (秋月の資料から抜粋)
秋月のSDカード接続アダプタ
 ボード上に3.3Vのレギュレータが実装されているので使い易いです。当然J1を接続して使います。すべての信号線が10kΩでプルアップされています。

 Arduino UNOは5Vで動いているので信号を3.3Vに変換する必要があります。10kΩの抵抗はそのままにして数百Ωの抵抗で分圧する方法が判り易いですが、ネットを調べると抵抗はそのままでダイオードを使った事例がありました。ちなみに以前私が分圧抵抗方式で動かした時の記事はこちら。

▼ダーオードを使ったレベル変換回路
5V to 3.3Vレベル変換回路
 ダイオードを直列に入れるだけの簡単な回路です。プルアップ抵抗(Rp)はアダプタ内蔵の物を使うと10kΩになります。これでSDのサンプルプログラムは動いたのですが、いくらなんでも10kΩでは高すぎると思うので波形を見てみました。

▼SDの信号波形調査中
ArduinoへSDカード接続テスト

▼Rp=10kΩの場合の波形
10kΩ
 写真が見づらいですが、上がSDA、下がクロックで、縦軸は1V/Div.です。

 案の定立ち上がりがものすごくなまっていて十分なレベルに達していません。プログラムを走らせながらプロービングすると、ハングアップすることがあるので全くマージンが無い状態です。これではダメです。

▼Rp=750Ωの場合 (正確には750//10k)
750Ω
 10kΩに並列に750Ωを入れた状態です。縦軸は2V/Div.です。
 やや立ち上がりが遅いのとLowレベルがダイオードの影響で少し持ち上がっていますが、この程度なら大丈夫でしょう。クロック 4MHzで動いていて、クロックの立ち上がりでデーターを読んでいるようです。

▼プルアップ抵抗追加方法
プルアップ抵抗を750Ωに改造
 チップ抵抗を持っていないのでラジアル部品をこの位置に取り付けて、内部の10kΩとパラにしました。

▼全体回路図
ArduinoにSDカード接続する回路
 Arduinoと接続する場合の全体回路図です。750Ωのプルアップ抵抗はCS, SDI, CLKに入れています。右下は使い勝手を良くするためのスイッチやLEDで、この後の記事で使います。

 この回路図の状態で、Arduino IDE のSDのサンプルプログラムは全て動かすことが出来ました。

◆まとめ
 ということでインターフェイス回路は大丈夫そうなので、次はSDメモリーカードロガーのプログラムを作っていきます。

 なお、いきなり電力ロガー専用のプログラムを作ると汎用性が無くなってしまうので、ある程度一般的なロガープログラムを先に作りたいと思います。こうしておくとプログラムの改造が楽になるので、どなたかがが応用プログラムを書いてくださるかも知れません。

RTCのバッテリーバックアップ回路

 マイコン工作で正確な時刻が必要な時に、リアルタイムクロック(RTC)は欠かせません。メイン電源が落ちていても時計を動かし続けるために、RTCの電源は電池でバックアップしますが、この回路の部品の選定について、電気の迷宮のFriendship 7さんが、バッテリーバックアップ回路のDiとRを厳密に選定というタイトルで詳しい解説記事を書かれています。

▼バッテリーバックアップに使うコイン電池とダイオード
コイン電池とダイオード
(この写真の電池はCR2025ですが、記事で使った電池はCR2032です)

 バッテリーバックアップ回路は、ダイオードで主電源と電池を切り替える方法が簡単です。これまで私はあまり深く考えないでショットキーバリアダイオード(SBD)を使っていましたが、Friendship 7さんの記事によると小信号用のスイッチングダイオードの方が良いそうです。

 実は2ケ月前にソーラータイマースイッチを作ったのですが、その時はSBDを使いました。良い機会なので、そのハードを使ってダイオードの違いで電池の充放電電流がどのように変わるか実測で確認することにしました。

◆測定準備
 測定する電流は10nAオーダーと微小です。テスターのテスト棒を手に持ってプロービングなどすると人体からの誘導などの影響でまともに測ることは出来ない可能性が高いです。とは言っても回路を切断して測定用の線を引っ張り出すのは面倒です。ということで、測定用に簡単な冶具を作りました。

▼電池電流測定アダプタ
電池電流測定アダプタ
 PETのシートの裏表に銅箔テープを貼り、そこに測定用のツイストペア線を接続しました。

▼使い方
電池に流れる電流測定
 電池ホルダーに入っている電池の上に測定アダプタを差し込んで電池電流を測ります。

▼電流計
バックアップ電流測定
 DMM(アドバンテスト TR6846)の電流レンジで測定しました。この写真は0.24μA(240nA)を表示中。このレベルの電流では配線を少し触っただけで値が変わるので、電流計のゼロ調(NULLセット)を頻繁に行う必要があります。なお、この写真の状態が最高感度で分解能は0.01μAですが、もうちょっと分解能の高い測定器が欲しいところです。

▼測定回路
RTCのバッテリーバックアップ回路図
 RTC-8564NBのバッテリーバックアップ関係の部分を切り出した回路図です。

◆測定結果
1) D1,D2にショットキーバリアダイオード(BAT43)を使った場合
 ・電源ON 時: Vcpu=5.19V, Vrtc=5.10V, Vbat=3.24V, iBat= -60nA
 ・電源OFF時: Vcpu=0.41V, Vrtc=3.16V, Vbat=3.25V, iBat= 240nA

2) D1,D2にスイッチングダイオード(1S4148)を使った場合
 ・電源ON 時: Vcpu=5.19V, Vrtc=4.95V, Vbat=3.25V, iBat= -10~0nA(ほぼゼロ)
 ・電源OFF時: Vcpu=0.40V, Vrtc=3.01V, Vbat=3.25V, iBat= 210nA

◆考察
・電池寿命
 電源OFF時の電池からの流れ出し電流は、BAT43を使った場合のiBat=240nAに対し1S4148を使った場合はiBat=210nAと30nA減っています。これはスイッチングダイオードにすることで、D1のリーク電流が減ったためだと思われます。なお、リーク電流が減ればその分だけ電池寿命が延びます。
 ちなみに、CR2032の容量が220mAhあるとして、BAT43を使った場合の電池寿命は 220/0.00024 = 917000h = 104年 で、全然余裕です。

・電池の充電電流
 電源ON時のiBatはBAT43を使った場合は-60nA(マイナスなので充電)です。これはSBDの逆リーク電流が大きいために電池が充電されていることになります。

 実はこうなるのは予想していて、充電されれば電池の消耗分の補給になるのでかえって好都合ではないかと思っていました。ところが、電池の充電量はライフを通じて電池の電力量の2%以内(1%、3%というSpec.もある)に抑えないといけないというスペックがあることを見逃していました。このルールを適用すると安全な期間は、(220 * 0.02)/0.00006 = 73333h = 8.4年となります。まあOKなんでしょうが、ちょっとマージンが足らない感じです。
 これが1S4148を使った場合は 充電電流は5nA程度なので、安全期間は10倍以上に伸びて全く問題無い領域になります。

・Vcpu と Vrtcの電位差
 実はこれが一番気になっていました、回路図のD1の部分です。このようにダイオードを一つ入れると普通は電圧が0.6V下がると考えます。つまりVrtc はVcpu より0.6V下がります。

 データーシートによるとRTCの入力信号(SCLやSDA)レベルはRTCの電源電圧 +0.5V までしか許容されません。ところが、CPUの電源電圧は0.6V高いのでハイレベルの信号は許容範囲を0.1V上回ることになります。たった0.1Vですが、絶対最大定格なのでちょっとでも上回ることは許されません。
 そんなことを考えて、私はD1に電圧降下が0.3Vで済むショットキーバリアダイオード使っていました。

 今回の測定結果を見ると、VcpuとVrtcの差は予想よりずっと小さくて、1S4148を使った時に0.24Vしかありません(BAT43の場合は0.09V)。これは電流が極めて少ないので、ダイオードの電圧降下も小さくて済んでいるということだと思います。これなら+0.5Vというスペックの範囲内なので安全です。

◆結論
・RTC-8564NBのバッテリーバックアップ回路に使うダイオードは、シリコンのスイッチングダイオードを使うのが正解です。SBDよりスイッチングダイオードの方が値段が安いのでSBDを使う理由は無いでしょう。

・もっと新しい設計のRTCはたぶん消費電流がもっと減っているでしょうから、この結論はたぶん変わらない気がします。

・D2がショートした場合の電池への充電電流を制限するために、抵抗を入れた方が良いそうです。アマチュアの工作なら省略してもかまわない気がしますが、判断はおまかせします。

 最後に、この件について詳しい解説記事を書いた下さった Frendship 7 さんに感謝します。とても勉強になりました。

電力量計の計量パルスをArduinoで読む(割込み版)

 電力量計の話の続きです。一つ前の記事でArduinoから電力の測定結果を読むプログラムを作りましたが、このプログラムで残念な点は、デ-ターはアラゴの円板の穴を検出したタイミングで出力されるということです。つまり電力の大きさによってデーターが出力される間隔が変化します。

 これでも、人間が値を読む場合はあまり問題は無いと思います。でもデーターをファイルに落としてPCでグラフ化して分析したい、などという場合は、一定の時間間隔のデーターでないと使い難いです。

 この対策として、タイマー割り込み(MsTimer2)を使って測定間隔を一定にするようにしました。あと、せっかくなので、円板の穴の検出も割り込みで行うようにしました。こうしておけば、後で別の機能を追加するのが楽になるはずです。

▼回路図
回路図
 円板の回転検出の表示用のLED(D1)をハードで点灯させるようにしました。同じことを割込みで動くプログラムでやろうとすると、ちょっとやっかいです。
 それと、C2はノイズ対策用に入れています。パルスの検出を割り込みでやっているので、ノイズが入ると誤動作するので注意が必要です。あと、回路図にはうまく表現出来ませんが、アナログ回路部分のノイズ対策はしっかりやる必要があります。

▼プログラム
// 電力ロガー
// 誘導型電力量計の円盤の回転を検出して電力表示
// (回転検出と測定間隔決定に割り込みを使用)
// 2018/8/26 ラジオペンチ http://radiopench.blog96.fc2.com/

#include <MsTimer2.h>

#define holeSigPin 2

volatile unsigned long tLast; // 前回のパルス時刻(ms)
volatile unsigned long tDiff; // パルス間隔
volatile unsigned long tNow; // 現在時刻
volatile unsigned long holeCount = 0; // 穴数カウンタ
volatile unsigned long NN = 0; // 累積時間カウンタ
volatile int timeUpFlag = 0; // タイムアップフラグ

float Watt = 0.0; // 電力
float Wh = 0.0; // 積算電力量

const float SFw = 1500.0; // (ScalFactor) 電力換算係数 SFw / パルス間隔(s) = W 
// 600rev/kWhで穴2個×2相合成で2400パルス/kWh → 1W = 1000*3600/2400=1500
const float SFe = 2.4; // 電力量換算係数 パルス数 * SFe = Wh

void setup() {
Serial.begin(9600);
pinMode(holeSigPin, INPUT_PULLUP); // クリーピング防止穴割り込み入力ピン

Serial.println();Serial.println("AC power logger start"); // 開始メッセージ
Serial.println("time(s), HoleCnt, Power(W), Enargy(Wh)");

// 割込み処理の設定
MsTimer2::set(1000, sensInterval); // 1000msごとにMsTimer2割込み
MsTimer2::start();
attachInterrupt(0, holeDetect, FALLING); // pin2(int0)のネガエッジで割込み
}

void loop() {
while (timeUpFlag == 0) { // タイマー割込みが入るのを待つ
}
timeUpFlag = 0;
if (holeCount >= 2) { // 2つ目以降の穴だったら電力計算
Watt = SFw / (tDiff / 1000.0); // 電力計算
Wh = (holeCount - 1) / SFe; // 累積電力量計算
}
logPrint(); // 測定結果をシリアル出力
Serial.flush(); // シリアル出力完了待ち
}

void logPrint() { // 測定結果室力
Serial.print(NN); Serial.print(", ");
Serial.print(holeCount); Serial.print(", ");
Serial.print(Watt); Serial.print(", "); Serial.println(Wh);
}

void sensInterval() { // Mstimet2の割り込み処理(タイマー割り込み)
timeUpFlag = 1; // タイムアップグフラグを立てる
NN++; // 累積時間インクリメント
}

void holeDetect() { // クリーピング防止ホール割り込み処理(ピン割り込み)
tNow = millis(); // 現在のシステム時刻取得
if ((tNow - tLast) > 30) { // 前回パルスから30ms以上経過している場合だけ計算(気休め)
tDiff = tNow - tLast; // 時間差計算 (50日でオーバーフローするので注意)
tLast = tNow; // 前回値として記録
holeCount++; // 穴数カウントアップ
}
}
 32~34行目が割り込み条件の設定です。55行目のsensInterval() がタイマー割り込み発生時の処理ルーチン。60行目のholeDetect() がアラゴの円盤の穴を検出した場合の処理ルーチンです。

 これ、二種類の割り込みを使っているので Arduino のプログラムとしてはちょっと高級な部類に入ると思います。でも、10行くらいの小さな関数の組み合わせで出来ているので、判り易いのではないかと思います。

▼出力例-1 (開始時)
出力リスト1
 開始直後の出力です。穴の数(HoleCnt)が2にならないと電力が計算できないので、最初はゼロになっています。

▼出力例-2 (測定中)
出力リスト1
 電力測定中のリストです。左から開始からの秒数、穴のカウント数、電力(W)、電力量(Wh)が表示されています。なお、電力の値は、円板から次のパルスが来るまで同じ値が連続して出力されます。

◆まとめ
 これで電力量計の測定結果が使い易いデーターとして取得出来るようになりました。

 この話はこれで終わりにしようかと思ったのですが、測定結果をSDカードに保存すると使い勝手がもっと良くなりそうです。以前気圧ロガーを作った時にSDカードを使いましたが、それ以来ずっとSDカードを使うプログラムを作っていません。

 そんなことで、久しぶりにSDカードへのデーターの記録をやってみたいと思います。ヤフオクで1500円で落とした電力量計ですが、これをネタにずいぶん楽しんでいるのですが、まだまだ遊べそうです。
カレンダー
08 | 2017/09 | 10
- - - - - 1 2
3 4 5 6 7 8 9
10 11 12 13 14 15 16
17 18 19 20 21 22 23
24 25 26 27 28 29 30
プロフィール

ラジオペンチ

Author:ラジオペンチ
電子工作を中心としたブログです。たまに近所(東京都稲城市)の話題など。60過ぎて視力や器用さの衰えを感じつつ日々挑戦!
コメントを入れる時にメールアドレスの記入は不要です。なお、非公開コメントは受け付けていません。

記事が気に入ったらクリックを!
最新記事
カテゴリ
最新コメント
リンク
FC2カウンター
検索フォーム
月別アーカイブ
RSSリンクの表示
QRコード
QRコード