【Part1】BluePillを使ったPZEM-004T電力計ロガーにRTCとSDカード組込み | トドお父さん通信

トドお父さん通信

北部九州在住 高BMI中高年のオタク趣味の活動記録

みなさんこんにちは。 トドお父さんです。

 

l ブレッドボードでの確認です

 

PZEM-004Tを使った電力計 前回でBluePill対応での作成完了しましたが、宿題が残っていました。

>あとは内蔵のRTCを動かして、SD Card基板を追加し、FatFsでSDカードに記録する処理を入れる

>ことができれば完璧なんですが、なにしろケースが小さいのでムリゲーそうです。

 

今回、なんとかSTM32F103 BuePillでの対応が終わりましたので報告しますね。

今回はPart1ということで、ブレッドボードで作成したプログラムの説明をします。

前回説明したプログラムから、今回 RTCとSDカード対応で変更した部分の説明をしますね。

 

まずはRTC対応から始めましょう。

STM32F103にはRTC機能が入っていて、BluePill基板には32.768kHzの水晶も実装されています。

SDカードでのログ書き込み機能を実装するなら、RTCでタイムスタンプも入れたいですよね。

まぁ、BAT端子に3V電源が必要ですから、CR2032ボタン電池などを付ける必要がありますが。

 

てなわけで、バッテリバックアップがついたRTC機能の検討です。

STM32duno対応のRTCライブラリとサンプルプログラムはここから持って来ました。

 

 

 

 

 

 

Simple RTCサンプルの先頭部です。

頭にあるのは、PCからコンパイル時に年月と時間情報をゲットするマクロです。

// RTC Initial data from PC  
static const char* mydate = __DATE__;
static const char* mytime = __TIME__;

 

RTCにこの時間を設定するための関数を作ります。 initDateTime()で下記設定を行います。

void initDateTime(void) {
  // コンパイル時のPC日時を解析して設定 (2000年基準)
  year = conv2d(mydate + 9); // 年
    // Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec
  switch (mydate[0]) {
    case 'J': month = (mydate[1] == 'a') ? 1 : ((mydate[2] == 'n') ? 6 : 7); break;
    case 'F': month = 2; break;
    case 'A': month = mydate[2] == 'r' ? 4 : 8; break;
    case 'M': month = mydate[2] == 'r' ? 3 : 5; break;
    case 'S': month = 9; break;
    case 'O': month = 10; break;
    case 'N': month = 11; break;
    case 'D': month = 12; break;
  }
  day = conv2d(mydate + 4); // 日
  hours = conv2d(mytime);   // 時
  minutes = conv2d(mytime + 3); // 分
  seconds = conv2d(mytime + 6); // 秒
}

 

これで、無事にRTCの設定が読みだされました。

 

バッテリバックアップされてないので、電源を切るとまたコンパイル時の日時が

 

RTCにロードされますが、バックアップしていると切ってもRTCで保持されます。
 

 
これで、RTCはOKです。あとひとつ、BluePillでの32.768KHzの発振がおかしくて日時が
ずれる現象が発生しました。
 オシロで見ると発振が不安定
 
BLuePillの回路図の発振回路は下記のようになっています。
 
C9とC12が32.768KHz用の帰還CはC9とC12 20PFです。
外して容量を見ると回路図通り20pFになっていました。なぜ発振がおかしくなるのでしょうか?
パチ品の水晶のC0と負荷容量CLのマッチングが取れてないのでしょう。 
8PFに変更すると正しい周波数で発振するようになりました。ここはツッコミなしでお願いします💦
 
 
さて、RTCの実装試験が終わったので、次はSDカード読み書きの実装試験ですね。
Arduinoでは、SD.h かSDFat.hを使ってSDカード読み書きを実装することが一般的のようです。
STM32coreでは、この辺のライブラリはSTM32の仕様にあわせてラッパーで処理しているようです。
つまり、どれがちゃんと動くかやってみないとわからないようです。
こちらのサイトの情報で、まずSDFat.hを使った試験をやってみました。
情報が詳細なので、勉強にはなりますがなぜか動かないようです。
 
次にSTM32向けSD.hを検討します。
まずSDfat.hを使おうと、こちらの記事を参考にします。

 

 

でも、SPI Started... から先に進みません。

STM32coreでの対応に何か問題がありそうです。

 

仕方がないので、SD.hの利用を考えます。
ArduinoのSD.hと違いSTM32での使用を考えて、SPIのピンはこちらのピン配置で設定しています。
 

SPI1に関して、
CSはPA4
SCLKはPA5
MISO(SDI)はPA6
MOSI(SDO)はPA7ですね
 
STM32F103でのSD.hのサンプルは、こちらのライブラリのCardInfoを利用します。

SDカードの情報を読み取って、serialで流すだけのプログラムです。

これがOKなら、読み書きもOKになると思います。

 

SDカードの情報が読み取れるようになりましたね。
こちらのライブラリでSDカードの読み書きを実装することにします。

実装する仕様は下記です。

SDカード基板はAdafruitのMicroSD card breakout boardを使います。

 

 

5V-3.3V 電圧レベル変換ICも入っていてちょっと大きいので、内蔵するにはこちらの基板を使います。

 

今回SPIを使うのでSDIOは使わないのですが、大きさがほどほどです。

 

新仕様として、下記を追加します。

① 起動時にENTキーを押していたら、パラメータ設定モードに入る

 

② 起動時にSELキーを押していたら、RTC設定モードに入る

 

③ PZEM004T測定データ表示中にSELキーを押すと、SDカードにログデータ記録を開始する
 (画面右上に小さくRECと表示)

 

④  PZEM004T測定データ表示中にENTキーを押すと、ログデータ記録を停止する

   ファイル名は、setting.txtにファイル名を入れていればその名前をBaseとして後ろに
  月、日と、01から始まる番号を追加する。ファイル名がなければLO030201.csvになる

   一旦記録を停止して、新たに記録を開始した場合、番号を+1したLO030202.csvを作り

  そのファイルにログを記録する。(8.3形式ファイル命名規則から、ファイル名は8文字とする)

 

⓹ 記録中でない時に、ENTキーを3秒以上長押しすると積算電力の値がが0クリアされる

 

⓺ sleep時間経過後に、焼き付き防止でsleep画面になった時は画面にランダムにドットが表示される

  SELキーまたはENTキーを押すとSleepが解除され通常表示モードに戻る

 (キーによる記録開始/停止は通常表示中でしか有効にならない)

 

といったところです。
大分使い勝手が改善したのではないでしょうか?
 
今回作成したプログラムはこちらのGoogleドライブに置いています。

 

コンパイルすると、Flashが73kB、RAMが7KB 強なので、実行速度も相まってArduino Nano等

では実装が困難だと思われます。(STM32F103C8 (128kB)でないとコンパイルエラーになります)

 

 

プログラムの説明ですが、今回は初めての試みとしてプログラム作成にChatGPTとXのGrokを

使いましたので、そのログを添付して手抜きの説明とさせていただきます。

 

ChatGPT

 

Grok

https://x.com/i/grok/share/mSsfThX3ekpRZBV12Ppy9OQS4

 

便利な世の中になったもんですね。

 

このソフトのコンソールでのログとCSVファイル名、それとCSVファイルの中身です。

 読み取りデータのログです

 

 

ファイル名

 

ログのCSVファイルの中身です。 Date Timeがちゃんと記録されています。

ここまで、プログラムのデバッグ用として、PZEM-004T電力計はつながず、ダミーデータです。
 
次回はハードウェア編として、実際にPZEM-004Tを接続して、SD Card基板とバックアップ用の
CR2032電池フォルダをケースに組み込む話をしますね。

それでは、皆さんおやすみなさい


関連記事