サーミスタの温度計算テンプレート

サーミスタの温度計算テンプレートを実装してみた。

このような簡単なテンプレートクラスを書くのは、程よい難しさもあり、パズル的
要素があって意外に楽しい。

クラスのプロトタイプは以下のようになっている。

//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++//
/*!
  @brief  NTCTH テンプレートクラス
  @param[in]  ADNUM A/D 変換値の量子化最大値
  @param[in]  THM   サーミスタの型
  @param[in]  REFR  分圧抵抗値
  @param[in]  thup  サーミスタが VCC 側の場合「true」、GND 側の場合「false」
*/
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++//
template <uint32_t ADNUM, thermistor THM, uint32_t REFR, bool thup>
class NTCTH {

使い方:

#include "chip/NTCTH.hpp"

・・・

// A/D: 12 bits, NT103, 分圧抵抗: 10K オーム、サーミスタ: VCC側
typedef chip::NTCTH<4095, chip::thermistor::HX103_3380, 10000, true> THERMISTOR;
THERMISTOR thermistor_;

・「NTCTH.hpp」をインクルードする。
・テンプレートパラメーターを typedef しておく。
※A/D 変換の分解能(この場合は12ビット)
※NT103 型サーミスタ(B定数などの定義は、「NTCTH.hpp」にある)
※分圧抵抗の値(10000オーム)
※サーミスタが、VCC側か、GND側にあるのか定義

auto v = get_adc(6);  // CH6
utils::format("温度: %5.2f [度]") % thermistor_(v);

クラスに、A/D変換値を入れて、呼ぶと温度が返ってくる。
※サーミスタの抵抗値が「0」になる場合は抵抗計算が成立しなくなるが、実際には、
そのようねケースは起こらないので、「良し」としとく。

テンプレート化している事で、不必要な比較的要素(サーミスタがVCC側かGND側)
かで別れる計算過程などがコンパイル時に決定されるので、条件分岐は無くなり、最適化
も十分行われる。

※対数計算があるので、数学ライブラリ「libm」をインクルードする必要がある。

※サーミスタは種類が多く特性が違うので、新たなサーミスタを使う場合は、テンプレー
トに定義を追加する必要がある。
・「thermistor」型の定義

//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++//
/*!
    @brief  サーミスタ型
*/
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++//
enum class thermistor {
    NT103_34G,  ///< THB:3435, TR25:10K
    NT103_41G,  ///< THB:4126, TR25:10K
    HX103_3380, ///< THB:3380, TR25:10K (25C to 50C)
};

・「パラメーターの取得関数」

static void get_para_(float& THB, float& TR25)
{
    switch(THM) {
    case thermistor::NT103_34G:
        THB  = 3435.0f;  ///< サーミスタB定数
        TR25 = 10e3;     ///< R25 サーミスタ25℃基準抵抗値
        break;
    case thermistor::NT103_41G:
        THB  = 4126.0f;  ///< サーミスタB定数
        TR25 = 10e3;     ///< R25 サーミスタ25℃基準抵抗値
        break;
    case thermistor::HX103_3380:
        THB  = 3380.0f;  ///< サーミスタB定数
        TR25 = 10e3;     ///< R25 サーミスタ25℃基準抵抗値
        break;
    default:
        break;
}

R8C/M120AN サーミスター・サンプル

-----
100円マイコン、R8Cでも、問題なく動作した。
・NTCサーミスタ(NCP18XH103F03RB)

※将来的にR8Cで温度制御に使う予定。

サーミスタの温度表示サンプル、R8Cでのバイナリーサイズ:
※log 計算や float の計算が含まれるので、確認

m32c-elf-size thm_sample.elf
   text    data     bss     dec     hex filename
  24580     296      76   24952    6178 thm_sample.elf

R8C/M120AN でのバイナリーサイズ

RX64M データフラッシュの操作

以前にRX24T用に、実装した事があるので、まぁ、同じようなものだろうと思った
が、全く違う仕様で、マニュアルを見ながら、チクチクと実装したので、それなりに時
間がかかった。
※「RX64Mグループ、RX71Mグループフラッシュメモリユーザーズマニュアル ハードウェア インタフェース編」
※リンクを開くには、ルネサスのアカウントが必要

RX64M、RX71Mは共通のようだが、基本的に、RX64Mは、フラッシュメモ
リーはEEPROM系では無い感じだ。

通常、EEPROMでは、イレースすると、データが「FF」になるが、RX64Mは
以前に書かれた値が維持されるようだ、しかしながら、イレースを発行したバンクには
新規に新しい値に変更ができるようになる。

なので、以前とは少し違った管理方法を考える必要がある。

それでも、R8C、RX24T、などと共通の仕様にしておく事は有益なので、そのよ
うな見た目を提供できるように実装を行った。
※単純にデータを保持する目的なら、I2Cで外部に接続したEEPROMの方が簡単
で汎用性が高いと思われる。
前から疑問なのだが、なぜ、こんなにも、面倒な操作が必要なのか理解に苦しむ。
※単純にメモリーが「主」のEEPROMをウェアハ上に作る場合と、一般的なロジッ
クが「主」のマイコンでは、製造過程におけるプロセスが随分違う為、マイコン内臓の
EEPROMの場合は、そう単純ではないのかもしれないが、単にデータフラッシュに
読み書きするだけなのに、毎回、仕様を見ながらシーケンスを作る手間は勘弁してほし
い、かと言って、「ル◎サ◎」が提供するソースコードの品質は極めて低いので使う気
にならないしで・・・

RX64Mのフラッシュが特殊な点は、フラッシュメモリーの操作は、内臓されたシー
ケンサーが行い、このシーケンサーにコマンドを送る事で二次的な操作で行う点だ。

初期化では、このシーケンサーにファームを転送して、起動する必要がある。
ファームは、RX64M内に置かれているので、単にデータの転送を行うだけなのだが、
特殊だと感じる。
※確かに、シーケンサーを動かすファームを書き換える事で、色々な仕様を網羅できる
のは後々便利なのだが・・

RX64Mのフラッシュで、とりあえず、駄目なところは、書き込みが4バイト単位で
しか行えない点だろう。
※当然書き込み先アドレスも4の倍数となる。
一度、データを書いたブロックは、イレースするまで更新ができない訳だから、バイト
単位でオーバラップするような操作は行えない事になる・・・
フラッシュの書き込みは、必ず4バイト(32ビット)単位で行うようにしなければな
らない。

とりあえず、「できた」レベルで、あまり詳細に検討していないがソースコードを、
Git に上げた。

flash_io.hpp

RX64M、GR-KAEDEのSPI、SDカードインターフェースの罠

GR-KAEDEにはRSPIを使った、SDカードインターフェースがある。

ところが、非常に不安定で、動作しない事が多かった。
実装はRX24Tでも実績のあるコードで、RX24Tでは何の問題も無く動作
しているものだった・・・

MMC/SDCの使い方
SDカードをSPIモードにするには、「DAT0」端子をプルアップしておく
必要があるのだが、回路図を観ると、GR-KAEDEには、プルアップが無い
ようだ、そこで、10Kでプルアップした。
しかし、全く効果は無かった。

電源ノイズによるものなのかとも思い、10uFをマイクロSDソケットの端子
に接続したが効果は無かった。

ソフト的に色々考えられる事を試したが、成果は無かった・・・

症状としては、初期化の段階で、SDカードをSPIモードに切り替える段階で
エラーになり、SPIモードにならないものだった。

SDカードの相性問題があるのかもしれず、試したが違うようだ(マイクロSD
を二種類しか持っていない)
※そもそも電気回路に「相性」のような不確定性があるハズも無い。
※ごく稀に動作する事もあるが、何かの拍子にすぐに不良になる。

約2日悩んだが、どうやら原因が判った。

RX64Mのデータシートを観ていて、気が付いた、何と、GR-KAEDEで
は、DAT0はPC7に接続している、しかも、この端子はリセット時にブート
モードを切り替えるMD端子でもある。
よくよく回路図を見ると、モード切替のDIP-SW付近で、4.7Kオームで
プルダウンされている。

あーーー、これだ・・・・・


そこで、1Kオーム位ででプルアップしたいが、それだと、ブート出来ない。
そこで、1KオームでPC3と接続しておき、SDカードの初期化時にPC3を
出力にして「H」を出力する事で、プルアップした状態を作る事にした。

この改修を行い、PC3の制御を足したら、当たり前だが、SDカードがSPI
接続出来るようになった。

-----
また、DAT0のプルアップは、必要無いカードもあり、状況を複雑にしている。

GR-KAEDEでSDカードを使っている人はどのように回避しているのだろ
うか?

追記:
ネットを調べたら、普通に情報があった(良く調べるべきだった・・・)
GR-KAEDEでSDカードにアクセスする場合について

RX64M、GR-KAEDEを試用してみた

GR-KAEDEを試用する機会があったので、少し内容に触れてみたい。

同時に、「RENESAS E1」も借りたので、それについても述べておく。

ルネサス関係のマイコンを集中して扱っているが、E1エミュレーターは、持って
いない。
理由として:
・値段が高い
・基本的に普段は詳細なデバッグを必要としない事が多い
※この理由が大きい、ターミナルデバッグで通常は十分
・ルネサスのIDEを使わない(購入するには高価すぎる)
・KPIT はフリーで使えるが、やはり、IDE が好きでは無いし、自分的には刺さらな

など、色々な理由がある、今回は、デバッガーとしてではなく、FlashROM
の書き換え時に、「Renesas Flash Programmer」でのみ利用した。
通常は、シリアルポートを使って書き込んでいるので、それに比較すると、書き込
み速度が速く、重宝した。

GR-KAEDEは、ハードとしては悪くは無いが、高すぎるので興味は無い。
※サポートや、色々考えると、まぁしょうがないのは理解できるが納得はできない。
※バッテリーバックアップ用の電池フォルダーくらいは付けて欲しかった。
・初期からSDRAMが載っているのは好印象。

GR-KAEDEに用意されているプロジェクトに関して:
とりあえず、WEBコンパイラで、簡単なコードを動かしてみて、動作確認し、自分
のシステムに、必要な部分を移植(主にイーサーネット関係のスタック)する為、
プロジェクト一式のソースコードを取得した。
※何故か、ビルドして出来た、mot ファイルをフラッシュに直接書いても動作しない。
スケッチとしてロードすると機能した、「まぁ、そういうものなのだろう」として
詳細な理由は調べなかった。

今まで、GR系のソースコードには触れていなかったのだが、開発期間が短いので、
色々調べたが、やはり既にある程度枯れているソースを再利用する事にした。

第一印象:
・CとC++のコードがあるが、どれも、品質がとても低い。
※ボードの価格に値しない、ソースコードの品質
・コーディング規約はほとんど守られていない。
※多分、会社内でコードレビューを行った事が無いのだろうな・・・
・関数名、クラス名、変数名のつけ方に一貫性がないのでわかり難い。
・C++のクラスがいくつかあるが、これはC++とは言えない(C+-だろうな)
※典型的な、C++を少しだけかじったCのプログラマーのコード
・色々なところに細かく罠とも思える実装依存が含まれている
※動作させるまでに、時間がかかった・・・
・設計が悪すぎで、典型的なスパゲッティーコードになっている。

そんなこんなで、動作させるまでに非常に時間がかかってしまったが、色々改修し
ながらコツコツを進めている・・・