● 実験テーマ7
「dsPIC30F_SDカード_温度ロガー」の顛末記
■ 2010.09.16
・実験テーマ2〜6で得た経験を活かし、その全ての要素(RTC+温度ロガー+EEPROM+SDカード)を使って
「SDカード_温度ロガー」を作ることにした。
<ソースの組立・変更案>
・ベースのソースは、「eeprom_temperature_logger_4013.c」とする。
・この時の保存ターゲットは、EEPROMだったが、それをSDカードに置き換える。
(参考になるソースは、「easy_sd_loger.c」)
・EEPROMは、ロギング条件設定値(interval値と、sample_set値)の保存のみに使う。
・大きく異なるのは、RTCとEEPROMのI2C制御を、I2Cモジュールではなく、ポート制御に変更することである。
(直近のソース「soft_i2c_****.c」を適用すればよいはず。)
・SDカードからの読出しは、UART経由でPCに転送することにする。
・SDアクセスのエラー処理は、とりあえず省略。
・全体的には、I2CとAD入力のポート割付を変更する必要あり。
<コンパイルに関しての注意事項>
・#include "stdio.h"として
#define EOF 0x1Aとすると、コンパイルエラーになる。
→ まず、FSIO.cで、"stdio.h"の中の、EOF定義を使用しているので、#include
"stdio.h"は必要。
何故エラーになるかと言うと、stdio.hで定義しているEOF(-1)と重なるからである。しかも定義している値
が異なる。
→ よって次のように修正
#define EOF_Code 0x1A
■ 2010.09.17
・今日から、ベースのソース「eeprom_temperature_logger_4013.c」の変更作業に入った。
・ハードI2C(I2Cモジュール使用)のルーチンをソフトI2Cに置き換え
・MAINルーチンのLEDポート割付変更及び、I2C初期化変更
・AD初期化にて、AN2→AN3に変更
■ 2010.09.18
・SDデファイン+変数定義追加
・テーブル宣言のEEPROMへの保存フォーマット名:logger_write_dataをSDへの保存フォーマット名:
SD_write_dataに変更
・I2C受信した時刻データをEEPROMへ転送する関数:forward_rec_data(void)中の、logger_write_dataを
SDへの保存フォーマット名:SD_write_dataに変更
■ 2010.09.19
・記録サービスルーチンの変更
・サンプル数:sample_setの意味合い変更
→ バイト数から、データ(パケット数)に変更:256→ 16,
8192→ 512
・EEPROMへ記録していた時は、記録場所はメモリ番地で管理されていたが、SDへの記録の場合は、
1パケット毎の管理になるので、変数:start_tmpを、Ixに変更する。
・REC:表示は、Ix+1の値を表示(logging_disp関数の引数start_tmp→Ix+1に変更))
■ 2010.09.20
・EEPROMへの保存と違って、SDへの保存或いは読出しは、その前に必ず、SDカードの実装チェックと
フォーマットチェック及び、それぞれのモードでファイルオープンを実行する必要があるので、そのように
変更
■ 2010.09.25
・本日からデバッグ開始
RTCとEEPROMを実装した状態で一応、時刻表示と温度表示するが、時刻表示が途中でおかしくなる。
(文字化けする。)また、EEPROMを抜くとRTCからの1Hz割込みが掛からなくなる。
→ このことから、温度のAD動作はOK、I2Cに関しては、単体ハードの時と比べてI2Cラインの長さが長く
なったせいで、タイミングに影響が出ているのか?
・RTCのみにし、単体チェックしてみるか?
(ハード上の違いは、I2Cポート割付を変更しただけ: SDA:RF2→
RF5/ SCL:RF3→ RF4)
■ 2010.09.26
・RTCのみにし、単体チェック
今までの、ソフトI2Cの実験でSCL側にプローブを接続するとACK受信できないことが判っているので
現状も配線容量が増えたことが影響していると想定する。
I2C_Write/Read関数共に、データ及びコマンド書込みの前に、40uSの遅延を入れてみたが症状
変わらず。
また、1Hz割込みが正常なことから、Writeは正常と想定して、Read関数のみに遅延を入れても同じ。
・チェックしやすくするため、最初の、RTCの年月日/時分秒リードでプログラムを止めてみる。
→ 正: 2010/06/15(TUE) 00:00:00が
誤: 2018/07/1?(WED) 00:00:00になる
・I2Cバスのプルアップ抵抗値を変えてみる。(2.2k→
1kとか)
→ 2.2kを並列接続して、1.1kにしてみたが同じ。
・10kまでSCLを落し、I2Cライト・リードのタイミングをソフト・オシロ2で確認したが一見問題なさそう。
■ 2010.09.27
・現実に、表示上リードミスしている、0x15をライト後、リードしてI2Cタイミング上では正しくリードできて
いるか確認してみる。
(もしLCD表示は正しく、I2Cでリードミスを起こしていれば、0x1Fがリードされているはずである。)
→ I2Cタイミング上では、正しくリードできていることを確認した。
・デバッグプログラムのメインループに、I2C読出し後、その1バイトデータをLCD表示するルーチンを追加
し、読み出して表示を確認してみる。
→ ループさせっぱなしの状態で"0:"を表示するが、I2Cタイミング上では、正しく0x15をリードできている。
■ 2010.09.28
・以前の実験で、同グループの隣り合った出力ポートビットを、PORT指定にすると、例えばLCDデータ
4bitの場合、RB12をアクセスすると、その前にビット確定したRB9〜RB11ば、Lowに固定してしまい
表示化けが起こっていた。
この時、LAT指定にすると解決した。
しかし今回の場合、LCD制御ポートビットと、I2Cポートビットは2bitばかり離れているし、LAT指定に
しているので、同グループビット間での干渉は起こらないはずだが、文字化けの原因を探るため次を試行。
・メインループにて、I2Cアクセスの前で、書込み値のLCD表示を行い、次にI2Cライト・リードを実行したとこ
ろでプログラムを停止し、表示化けしないか確認。
→ 表示化けしないことを確認した。
・
このことから、同グループビット間での干渉ではないことが判明。
ちなみに、I2Cで0x15ライト後、リードした結果をLCD表示すると、=?になる。
やはり配線長によるタイミングずれと思われる。
(ソフト・オシロ2では、転送速度を大幅に落さないとタイミング確認できないため、見た目正常に読込めて
いても、正規の100kでは、どうなっているかは、高速のハードオシロを持合わせてないので不明。
細かい所でタイミングがずれている可能性あり。)
・以前のソフトI2Cと同様のポートに接続しなおしても、現ハードの配線長では同様の症状が起きるか確認。
→ 予想に反して正常に動いている。
・以前のソフト(soft_i2c_rtc_check.c)と、現デバッグソフト(sd_logger_rtc_debug_4013.c)を目視比較
したが、ポート割付に伴う修正は間違い無さそう。
■ 2010.09.29
・昨日の結果で、配線長の問題はなさそうなので、やはりビット操作のバグが気になる。
そこで、SDAとSCLアクセスを、ビット操作でなく、AND/ORにて記述してみる。
→ 結果は同じであった。
・同じように、他のRFビット(RF0:LCD-E/
RF1:LCD-RS)についても、AND/ORで記述してみる。
→ 結果は同じであった。
・これで少なくとも、RFグループ内(LCD制御ビットとI2Cの2ビット)での干渉は無くなったはずなので話は
難解になってきた。
■ 2010.10.01
・I2Cアクセス中に、LCDアクセス有り無しで、読出しデータ化けを起こすと想定し実験
→ I2Cアクセス中に、LCDアクセス有り無しに関係なく読出し値がおかしい。
書込み時は、0x15をちゃんと送出している。これだけを見ると書込みタイミングは正常で読出し
タイミングに何か問題があるように思われる。
→ もう1つの疑問は、ソフト・オシロ2でのタイミング確認では、0x95を読込んでいるのに、LCD表示が、
"6:"となり、異なる値を表示している点である。
(これから見ると、読出しタイミングの他に、LCDアクセス中のポートのビット操作の不具合がまだある
のか?)
・I2CとLCD制御ポート(データポート含む)の全てを、ビット単位アクセスマクロを使用せず、AND/ORで記述
しても、全く症状変わらず。
→ ということは、LCDで表示されている値は正しいと思われる。
やはりI2Cタイミングが、微妙にマージン無くメモリに取り込む時点で、I2Cバス上のデータが化けた形で
取込まれている可能性あり。
・以下に、ソフトオシロ2でI2Cバスタイミングを確認した時の波形を示します。
■ 2010.10.02
・問題一応解決!!
i2c_read関数で、MSBから、SDA入力しながらビット毎のORをしているところの、SDA入力の前に、5uの
ウエイトを入れたら正常に時計データをリードするようになった。
(これまでいろいろ試行錯誤してきたが、結局はI2Cバスの配線長が長くなって浮遊容量が増した影響で
リードタイミングが微妙にずれていたのが原因だった。)
・ここからようやく本来のデバッグ開始
・SDに書込みを開始すると、ロギング表示の時計部分のコロン「:」が消える
→ SDロギング開始時に画面を切替え、コロンを消しているためで、割込み前に固定表示の「:」表示を追加
して解決
■ 2010.10.03
・SD読込みチェック開始
ファイルオープンしてから、リードが始まらない。
→ 書込みファイル名:「DAT.CSV」に対して、読込みファイル名が「DAT.DAT」になっていた為で、
「DAT.CSV」に変更しOKを確認。
・しかし、RS232C経由での読出し結果が、"ハ="のようにしかならず。
■ 2010.10.04
・RS232Cが悪いのか、それ以前のバッファ転送時点が問題なのかの切り分けを行う。
(232出力の前に、LCDにバッファの内容を表示して確認した。)
→ バッファ転送の時点で、SDのファイル内アスキーデータを正常に読めていまいことが判明した。
■ 2010.10.05
・マイクロチップ社のFAT16は、CSVファイルのライトはサポートしていてもリードはサポートしていないと想定
し、どちらも、.TXTに変更してみる。
→ 結果、リードは、"DT DT■■■■■■■"となってしまう。
・ファイルリードの時も、SDの初期化は必要なことが判明(ライトの時ににみ初期化していた。)
これでCSVファイルのリード時も正常に読込めた。
考えてみれば当然のことだが、リード時、初期化しないと、電源ON後、いきなりファイルリードの時、正常
に読込めないことになる。
■ 2010.10.06
・SDのエラー処理以外は、サンプル数:16/64パケット,
インターバル:1秒にて、全て考えた仕様通り動いた
ことを確認!!
※ とりあえず、エラー処理なし(後からエラー処理を追加できるように、N_Write
= f(x), N_Read = f(x)による
関数呼出記述のままにしておく。(それぞれの戻り値(書込み或いは読込み回数)が、0の場合、エラー
と見なす。))で動いているので、本件はこれで一時クローズとする。
以後の改善案としては、エラー処理の追加、任意のファイルネームを使用可とする、書込み中は、LED
点灯でなく点滅にする等を考えている。
<最終回路図>
・こちらから、どうぞ→ 「dsPIC30F_SDカード_温度ロガー回路図」
<最終ソース・ファイル>
・こちらから、どうぞ→ sd_card_rtc_temperature_logger_4013.c
← 実験テーマ1に戻る TOP PAGEに戻る 実験テーマ8へ →