Micom Car Rally NET
MCR - Micom Car Rally
2015大会 マイコンカーラリーとは? 今から始めるマイコンカーラリー 技術情報 大会記録 MCRファン倶楽部 お問い合せ
マイコンカーラリートップへ マイコンカーラリートップへ
技術情報 >> R8C/M12A 技術情報
技術情報
アプリケーション
R8C/M12A 技術情報
上位入賞マイコンカー
参加者レポート
よくある質問(FAQ)
ダウンロード
R8C/M12A 技術情報
液晶を使った温度計(電圧補正版)

内容
液晶を使った温度計」は、電源電圧(Vcc)によって、プログラムの計算式が変わります。毎回、電源電圧を測ってプログラムを修正するのは大変なので、NJM1431Aという、常に一定の電圧(今回は、2.465V±1%)を出力する素子を基準として使い、電源電圧が変わっても自動的に電圧補正するように工夫します。

ワークスペース

r8cm12a_lcd_temperature_vref_100.zip
ファイルを解凍し、フォルダを「c:\worksapce」に入れてください。

回路
回路を下図に示します。

回路図
※液晶の1ピンと2ピンのVcc、GNDは、液晶によって違うことがあります。必ず付属の説明書を参照してください。

ブレッドボード実装図
ブレッドボードの実装を下図に示します。
ブレッドボード実装図

※液晶の1ピンと2ピンのVcc、GNDは、液晶によって違うことがあります。必ず付属の説明書を参照してください。

追加する部品
液晶を使った温度計」の他に追加する部品を下表に示します。

部品
番号
名称、メーカ 数量
U4 可変シャントレギュレーター
NJM1431A 新日本無線(株)
販売先:(株)秋月電子通商など
1
R6 抵抗100Ω 1

シャントレギュレータ(基準電圧源)IC

今回使用するシャントレギュレータ(基準電圧源)IC

今回は、(株)秋月電子通商などで販売されている新日本無線(株)製の可変シャントレギュレーターNJM1431Aを使用して、電源電圧の補正処理として使います。
NJM1431Aは、アノード、カソード、リファレンスの各端子がある3端子型のICで、カソード−アノード間に+2.5〜+37Vの電圧を加えると、2.465V±1%の電圧を出力します。リファレンス端子はカソードにつなぎます。

LM60

出力電圧

抵抗を介して+2.5〜+37Vを加えると、2.465V±1%(2.44035〜2.48965V)の電圧を出力します。±1%の誤差がありますので、精度の高いテスターで、R8C/M12Aの17ピン(P1_3端子)の電圧を測って実際の電圧を確認しておきましょう。以下、2.465V(または2465mV)の部分は、実際に計った電圧にして各自計算してください。

仕組み

この電圧を、R8C/M12AのA/D変換器で取り込みます。電源電圧(Vcc)とA/D変換値の関係を下表に示します。

電源電圧(Vcc) 2.465VのAD値
4.5 2.465/4.5*1023=560
4.6 2.465/4.6*1023=548
4.7 2.465/4.7*1023=536
4.8 2.465/4.8*1023=525
4.9 2.465/4.9*1023=514
5.0 2.465/5.0*1023=504
5.5 2.465/5.5*1023=458

例えば、2.465VのA/D変換値が560なら、電源電圧は4.5Vと分かります。2.465VのA/D変換値を使って電源電圧を求め、LM60から出力されるA/D変換値を電圧に変換します。LM60の出力は「電圧=温度」なので、電圧が求まれば温度も分かります。変換方法を説明します。

温度は、下記の式で求めます。

温度=(LM60の出力電圧 - 0℃の時の電圧)/(100℃の時の電圧 - 0℃の時の電圧)

LM60の出力電圧は、
LM60の出力電圧 = LM60のA/D変換値 / 1023 × 電源電圧
で求めることができます。今回、電源電圧は5000[mV]ではないので、まずは電源電圧を求めます。

●電源電圧を求める

※LM60の出力は、「液晶を使った温度計」と同様にオペアンプで5.7倍の電圧にしたときの計算です。

計算の基準となる電源電圧vccを計算します。NJM1431のA/D変換値=2.465Vなので比率で電源電圧が分かります。

電源電圧 : 1023 = NJM1431の電圧 : NJM1431のA/D変換値

電源電圧を求める式に変えます。

電源電圧(vcc) = 1023 * NJM1431の電圧 / NJM1431のA/D変換値

NJM1431の電圧は2465mVです。例えば、NJM1431のA/D変換値が560の場合、電源電圧は、
電源電圧(vcc) = 1023 * 2465 / 560 = 4503[mV]
となります。小数点は扱えないので、[mV]単位とします。

●LM60の出力電圧を求める

LM60の出力電圧は、次の式で求まります。
LM60の出力電圧(vtmp) = A/D変換値 / 1023 * 電源電圧(vcc)

今回、LM60の出力電圧を平均化するため、100回分の電圧を取得します。vtmpは、100回分の電圧になります。

●温度を求める

温度=(LM60の出力電圧 - 0℃の時の電圧)/(100℃の時の電圧 - 0℃の時の電圧)
温度=(LM60の出力電圧 - 2416.8)/(5979.3 - 2416.8)
LM60の出力電圧は、100回分の電圧を加えた値なので、
温度=(LM60の出力電圧(100回分) - 2416.8*100)/(5979.3*100 - 2416.8*100)
温度(tmp)=(vtmp - 241680)/356250

となります。tmp=1で100度なので、前回同様、1000倍してtmp=1000で100℃になるようにします。例えば、23.4℃ならtmp=234となります。最終的な計算は、次のようになります。
温度(tmp)=(vtmp - 241680)×1000/356250

プログラム「lcd_temperature_vref.c」の説明

「lcd_temperature_vref.c」で、電源電圧の取得、A/D変換値の取得、温度に変換、液晶に表示をしています。

シンボル定義

NJM1431からの出力電圧は2465[mV]±1%で、電圧の範囲は2440.35〜2489.65[mV]となります。R8C/M12AのP1_3端子に入力されている電圧をテスターで測定し、V_NJM1431定数の「2465」を実際に測定した電圧[mV]にします。

#define V_NJM1431 2465  /* NJM1431の出力電圧[mV]         */
                        /* 2465[mV]±1%                  */
                        /* → 2440.35〜2489.65[mV]の範囲 */

main関数

vccは電源電圧([mV]単位)、vtmpはLM60からの出力電圧(100回分)、temp変数は温度(100℃=1000)です。これらの変数をlong型で確保します。
また、液晶の(0,0)に「タダイマノオンドハ」と表示します。

※変数の型は、計算途中を含めて範囲以上にならないか必ず調べてください。今回のvtmp変数の最大は、「A/D値の最大1023×電源電圧5000mV×100回=511,500,000」です。long型の範囲(-2,147,483,648〜2,147,483,647)に収まっているので、使用可能です。

void main( void )
{
  long vcc, vtmp, temp;
  int i, j;

  init();               /* 初期化       */
  lcd_init();           /* 液晶初期化   */

  // 文字列の表示
  lcd_position( 0, 0 );
  lcd_put_str( "タダイマノオンドハ" );

NJM1431のA/D値を100回読み込む

まず、get_ad3関数でAN3(P1_3)端子の電圧を読み込み、NJM1431の電圧を読み込みます。NJM1431の電圧は2465mVと分かっているので、比率で電源電圧が分かります。電源電圧は、vcc変数に代入します。
次に、get_ad7関数でAN7(P1_7)端子の電圧を読み込み、vtmp変数に代入します。計算で使用する電源電圧は、vcc変数の値を使いますので、電源電圧に変動があっても大丈夫です。
この計算を100回行い、vtmp変数に100回分の電圧を保存します。これらの計算を100回実行しても数ms程度で終わってしまうので、約5msのウエイトを入れて、100回実行するのに約0.5秒かかるようにしています。

  while( 1 ) {
    // NJM1431電圧、温度計の電圧を100回取得
    vtmp = 0;
    for( i=0; i<100; i++ ) {
      // P1_3からVccを計算(vcc=5000なら5000mV)
      vcc = (long)1023 * V_NJM1431 / get_ad3();

      // P1_7から温度を計算(vtmp=5000なら5000mV)
      vtmp = vtmp + (long)get_ad7() * vcc / 1023;

      for( j=0; j<5000; j++ );     /* ウエイト 約5ms    */
    }

電圧を温度に変換

先の説明の通り次の計算を行い、電圧を温度に変換します。
電圧は100回分の値なので、その他の値も100倍します。
かけ算の「1000」は、100℃を1000に変換するための乗数です。

    // 温度変換(100℃のとき、1000に変換)
    temp = (vtmp - 241680) * 1000 / 356250;

A/D値の確認表示

A/D値を温度データに変換する前に、A/D値を確認するために、液晶に表示します。確認が不要なら、この部分は削除して構いません。

    // 確認用にA/D値を表示
    lcd_position( 9, 1 );
    lcd_put_str( "A/D=" );
    lcd_put_num( get_ad7(), 3 );

符号の表示

温度が0℃以下なら、液晶に表示する符号を「−」してtemp変数の値を正の数に変換します。温度が0℃以上なら、液晶に表示する符号を「+」にします。

    // 0℃以下か確認
    lcd_position( 0, 1 );
    if( temp < 0 ) {
      temp = -temp;
      lcd_put_str( "-" );
    } else {
      lcd_put_str( "+" );
    }

温度の表示

例えば23.4℃なら、temp変数の値は「234」になっています。
まず、値を10で割って整数部分を計算して3桁分表示します。temp変数が234なら「023」が表示されます。
次に、値を10で割った余りを計算して1桁分表示します。C言語で余りは「%」で求めることができます。temp変数が234なら、「4」が表示されます。

    // 上位3桁+"."+下位1桁表示
    lcd_put_num( temp / 10, 3 );
    lcd_put_str( "." );
    lcd_put_num( temp % 10, 1 );
    lcd_put_str( "゚C" );

温度が23.4℃のときの液晶への表示例を下記に示します。

0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
         
 

※電源電圧やNJU1431の出力電圧でA/D値は変わります。

温度をUART0でパソコンに出力したり、圧電サウンダーをつないで設定温度以上になったら音を鳴らすなど、いろいろと改造してみましょう!!


BACK