● 実験テーマ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へ →