08.7
                                   林 正幸

「電源・デジタル表示装置」の製作

 これまで、電源とミリアンメーターを備えた「電源・メーター装置」を作っておいて、
必要に応じて検出部を製作して搭載し、利用してきた。アナログ表示は私には馴染みやす
く、メリットもある。
 しかし時代の流れの中で、メーターをデジタル表示に換えようと思った。これなら単位
も表示できるし、電流目盛りを読み替える必要もない。より現実的には圧力計を量産する
必要があり、ゲージ圧でなく絶対圧力を表示した方が分かりやすいと考えた。
 このためにはマイコンを搭載してAD変換をし、それを液晶表示する必要がある。また
単位や設定をテンキーで入力する必要がある。当然プログラム開発も付いてくる。このア
イデアを話したところ、幸い田中 英二さんが全面的に協力してくれることになり、PI
Cマイコンを採用して具体化に向けて動き出した(08.2)。

A.装置の概要

[1]装置は、マイコン部、テンキー部、電源部(これらの略号はPWDD)、そして今
回の検出部の圧力計を含む。また容器は安価で加工しやすいのでタッパーウエアである。
 マイコン部は、マイコンはPIC16F876Aで(始めはF873Aを使ったが、プ
ログラムが大きくなり、培容量のものに切り換えた)クロックは20MHzである。AD
変換は10ビットで5V、1024段階である(AN0ピンを使用)。液晶は16文字2
行のSC1602BS*Bであり、4ビット送信方式にする(Bポートを使用)。テンキ
ー部(Cポートを使用)や検出部との接続には10ピンのコネクターを使う。他に電源
(切り換え)スイッチ、リセットボタンを備える。
 なおAD変換入力に過大電圧が掛からないようにツェナーダイオードを使ったが、何故
か5.1Vでは駄目で、6.2Vのものにした。
[2]テンキー部は、装置を量産する場合(私は7台製作した)でも1,2台で十分であ
る。テンキーは0から9までと*および#の12キーである。#はエンターキーにし、*
はマイナス(−)とバックスペース(BS)に使い分ける。計測時には不要なので外して
おく。
[3]電源部は、9V1AのアダプターL.T.E.である。2つ使って±9Vを実現し、マ
イコン部を通して検出部に送り、オペアンプにも対応する。なおマイコン部に5Vの3端
子レギュレーターを付けてマイコンなどに送る。アダプターは容器側面に固定するトリプ
ルタップに差し込み、飛び出すプラグに延長コードを接続する。なお補助用に9V電池
(006P)を切り換えて使えるようにする。
[4]検出部の圧力計は、すでに開発が済んでいるが、最大5Vに出力するように手直し
した。
参考:「圧力計の製作と実験(改訂)」
   http://www.water.sannet.ne.jp/masasuma/masa/ne20.htm
[5]なお圧力計をデジタル表示するメリットは
@ゲージ圧でなく、絶対圧力で表示できる。
Aより精密な計測も可能になる。

                  - 1 -




                  - 2 -




                  - 3 -

B読み取りが簡単である。
C圧力センサーを外すときに、ミリアンメーターのスイッチを入り切りする必要がない。
などである。

B.回路図

 マイコン部(電源部を含む)、検出部(圧力計)の回路図は前ページのようである。

C.プログラムの概要

[1]液晶表示とテンキー入力の部分はすでに経験がある田中さんに全面的におんぶした。
 設定と計測の基本的な考え方は次のようである。
 単位は、数字しか入力できないので、1文字ずつ(8文字まで)アスキーコードを10
進数を使って入力し、アスキーコードに直してマイコン内蔵のeeprom(256バイ
ト)に記憶する。カタカナなども使える。
[2]レンジの最小値(min)と最大値(max)は、必要ならマイナスも加え、4桁までの
数値を入力する(小数点を除いて)。数値は桁毎に数字に直してeepromに記憶する
(5バイトずつ使う)。小数点はこれとは別にその位置を入力する。このように分離する
のはやっかいに見えるが、こうしないと記憶ができないし、プログラムも却って複雑化す
る。
[3]設定を記憶する領域は0〜5の6つであり、その場で設定して使うことも、予め設
定しておいて利用することもできる。ちなみにテンキーを接続しないで電源を入れるとそ
れを検出して、領域0で前の設定を使っていきなり計測できるようになっている。
 なお領域4,5では、補正することもできるようになっているが、これについては「F.
使用法」の「補正関数を使用する場合」を見てほしい。
[4]液晶表示は、1行目に計測数値(4桁まで それとは別にマイナス符号も)と単位
を、2行目にレンジ(最小値と最大値)を書く。
 AD変換の両端をレンジに合わせると、はみ出した部分が分からないので実際の調節が
できなくなる。つまり最小値と最大値をすこし超える領域も表示する必要がある。そこで
表示数値(hyouji)は、AD変換値(ad)から次の式で計算する。
  hyouji = koubai×(hyouji−42) + min
ただし
  koubai = (max−min)/940
これでAD変換値が42で最小値に、982で最大値になるので、数%のゆとりができる。
 計測は見やすいため、0.2秒に1回とする。
[5]計算式で戸惑ったのは、char や int の変数を使って答が256以上になるかけ算
すると(答−256)になり、正しい計算は long int 変数を使うとできるようになった。
た。
 プログラム(C言語)は最後に添付する。

D.部品表

    品  名                          単価(目安)
マイコン部
感光基板                               250円
PICマイコン(16F876A)                   900円
セラミック発振子(20MHz)                     50円

                  - 4 -

ソケット(28P スリムタイプ)                    20円
液晶表示器(16文字、2行 バックライトなし SC1602BS*B) 550円
レギュレータ(5V,1A)                       50円
ツェナーダイオード(6.2V)                      20円
可変抵抗(10k 小型)                        60円
抵抗 10k  ×5
   2k  ×2
コンデンサー 10μ  ×2                      20円
       0.1μ(積層)  ×4                  30円
LED(φ3)                             20円
トグルスイッチ(6p 中立 基板型)                 180円
プッシュスイッチ(小型)                        40円
めすコネクター(10P たて型 みぞあり つめあり)         150円
おすコネクター(10P みぞあり)                  130円
フラットケーブル(10本 8cm カラーコード)
ビス(φ2 15mm)、ナット、ばねワッシャ、平ワッシャ  ×2
ビス(φ3 20mm)、ナット  ×4
平ワッシャ(φ3)  ×7
スペーサ(10mm ねじなし)  ×6                 20円

テンキー部
テンキー(12文字 小型)                      630円
ユニバーサル基板(ICB−93)                   290円
めすコネクター(10P L型 みぞあり つめあり)          150円
フラットケーブル(10本 10cm カラーコード)
アクリル板(1mm 97×74cm)
ビス、ナット、平ワッシャ、ばねワッシャ(φ2 12mm)  ×2
ビス、ナット、ばねワッシャ(φ2 10mm)  ×4
ビス、ナット、ばねワッシャ(φ3 15mm)  ×4
平ワッシャ(φ3)  ×8
スペーサ(5mm)  ×4                       15円

電 源
電源アダプター(DC9V,1.3A スイッチング L.T.E.)×2   600円
延長コード(おす&めすプラグ付き)                  470円
電池スナップ  ×2                          30円
乾電池(9V 006P)  ×2

容 器
プラ容器(1.3L フレッシュパック)                 105円
JTターミナル  ×4                         60円
トリプルタップ                            160円
平ビス、ナット(φ3 8mm) ×2                  30円
スペーサ(10mm ねじなし)  ×4                 20円

                  - 5 -


検出部(圧力計の場合)
  センサー部
圧力センサー(±1atm FMP−15PG Rタイプ)       1260円
  〃   (±0.5tm FMP−07PG Rタイプ)       1260円
ペットボトルのキャップとユニバーサル基板(切ったもの)  ×2
おすコネクター(10P みぞあり)  ×2              130円
フラットケーブル(10本 55cm カラーコード)  ×2
  回路部
感光基板(ユニバーサル基板ICB−93相当)             250円
オペアンプ(082)  ×2                      85円
ボリューム(可変抵抗)200Ω                    380円
    〃       50k                    380円
つまみ  ×2                             60円
抵抗 100k  ×5
   51k
   27k
   10k  ×2
   1k  ×2
   220Ω
   100Ω
コンデンサー 10μ  ×4                      20円
       0.1μ(積層)  ×4                  30円
トグルスイッチ(3p 基板型)                    160円
めすコネクター(10P たて型 みぞあり つめあり)         150円
おすコネクター(10P みぞあり)                  130円
フラットケーブル(10本 8cm カラーコード)            90円
ビス、ナット、ばねワッシャ(φ2 25mm)  ×4
平ワッシャ(φ2.5)  ×8

注意:フラットケーブルは切断位置に注意する。

E.製作

 マイコン部と検出部(圧力計)のプリント基板の製作は田中さんにお願いした。

容 器
@プラ容器のふたに、中心線を描き、それを基準に次ページの左図のように穴の中心と窓
の位置を描く。
窓はカッターで切り取り、穴は窓のある側がφ3.5mm、反対がφ6mmのドリルで開け
る。
AJTターミナルの足をペンチで切り、ふたに固定する。
Bトリプルタップのねじを外し本体側に、次ページの右上図のようにφ3mmのナットが
はまる余裕をとってφ3mmのドリルで穴を2つ開ける。そしてビスの邪魔になる金具を

                  - 6 -


  

すこし曲げておく。
Cプラ容器の長い側面(底に近い所)にタップの本体側を押し当てて、右下図のように新
しいねじ穴、元のねじ穴、プラグ用の穴(3つずつ)の位置を、現物合わせで描く。
 それぞれφ3.5,6,3mmのドリルで穴を開け、プラグ穴はニッパーで切ってプラグ
が通るようにする。
D本体側を差し込み、新しいねじ穴にφ3mmの平ビス・ナットで固定し、タップのカバ
ーを被せて元のねじで固定する。
E検出部の差し込みで使うスペーサ4つを入れておく。

テンキー部
 実際には、マイコン部のBで抵抗などの余剰線ができた段階で製作に入る。
@アクリル板をユニバーサル基板に合わせ、4隅にφ3.5mmのドリルで穴を開ける。基

  

                  - 7 -

板に対して、アクリル板の表裏、上下の位置関係を記しておく。
Aテンキーの基板に余剰線をはんだ付けしてピンを立てる。
Bピンをユニバーサル基板の30Iから30Pに差し込んではんだ付けする。
 またL型のめすコネクターを1Kから2Oに差し込んではんだ付けする。
前ページの左図の「テンキー部の実態配線図(部品面から見た図)」を参照する(以下同
じ)。
Cコネクター2つとテンキー4つの穴に合わせて、基板にφ2mmのドリルで穴を開け、
前ページの中図のようにビスなどで固定する。
D10cmのフラットケーブルを茶から紫色までの7本にする。
 はんだ面から(上下を正しくして見る 以下同じ)、テンキーのピンに茶色が右に来る
ようにはんだ付けする。ただし右端は接続しない。
 はんだ面から、ケーブルの他端をコネクターのピンに、茶が右端上、赤が右端下、橙が
茶の左、黄が赤の左というようにはんだ付けする。紫が左から2つ目の上になる。左端の
2つのピンもつなぐ。
備考:配線の都合でフラットケーブルの色(左)は、マイコン部の色(右)と次のように
   対応する。
     茶 → 赤  赤 → 茶  橙 → 黄  黄 → 橙  緑 → 青
     青 → 緑  紫 → 灰
Eマイコン部のGが確認できたら、アクリル板を前ページの右図のようにビス、スペーサ
などで固定する。

マイコン部
@マイコン部のプリント基板に次のようにドリルで穴を開ける。
  3端子レギュレーター  φ1mm(3つ)
  液晶表示器       φ2.5(2つ)
  四隅(基板固定)    φ3.5mm(4つ)
  残りすべて       φ0.8mm
資料の「マイコン部の実態配線図(部品面から見た図)」を参照する(以下同じ)。
A抵抗、コンデンサーをはんだ付けする。10μはプラマイに注意する。右の10μは寝
かせる。そして抵抗などの余剰線で3本のジャンパー線をはんだ付けする。
Bはんだ面から、電源配線部において余剰線で半円状の6つの端子をはんだ付けして作る。
Cおすコネクターに、▽印に茶色が来るように8cmのフラットケーブル(ゆ着部分の
方)を差し込んで、万力で締め、ケーブルを返してカバーを差し込む。
 はんだ面から、ケーブルの他端を右下部に、右側に茶色コードが来るようにはんだ付け
する。そしてコードをめっき線で固定する。
D部品面から(上下を正しくして見る 以下同じ)、LED(A(長い足)を左に向け
る)、ツェナーダイオード(K(黒帯)を左に向ける)、28pソケット(凹部は左に向
ける)、20MHz発振子(表示のある方を下に向ける)、可変抵抗、プッシュスイッチ
(端子の面を左右を向ける)、3端子レギュレーター(表示のある方を内側に向け、かつ
45°くらいに傾ける)、液晶附属のソケット、6pトグルスイッチ、めすコネクター
(みぞを外側に向ける)をはんだ付けする。
E液晶附属の14ピンの、短い方を液晶基板に裏から差し込んで、はんだ付けで固定する。
(まだソケットに差し込まない。)
F2つの電池スナップのコードを10cm延長し(はんだ部はビニールテープで巻く)、

                  - 8 -

±9Vが得られるように注意して、半円状端子のAグループにはんだ付けする。
 2つの電源アダプターのプラグコードを20および30cm残して切り落とし、コード
のプラマイをテスターで確認する。これをBグループにはんだ付けする。
 そしてこの段階でアダプターをトリプルタップに差し込み、延長コードでつないで電源
スイッチを入れ、基板に正しく±9Vが来ているか、そしてLEDが点灯するか点検する。
G電源スイッチを切り、プログラムを焼き込んだPIC16F876Aを凹部が左に来る
ように差し込み、液晶をソケットに差し込み(他端はそのまま)、おすコネクターをテン
キー部に差し込む。
 もう一度電源を入れ、液晶が表示されない場合は濃さを加減する可変抵抗を右に回す。
そして次の「使用法」のA,B,Cがうまく動作するか点検する。
Hラベルを貼り、液晶基板の他端を左図のようにビス、スペーサなどでプリント基板に固
定する。電源コードを容器のふたの穴から通し、基板をビス、スペーサなどで右図のよう
にプラ容器のふたに固定する。なお電池を使う場合は、両面テープで容器の底に固定する。

  


検出部(圧力計)
・センサー部
@圧力センサーを切ったユニバーサル基板にはんだずけする。
Aおすコネクターに、▽印に茶色が来るように55cmのフラットケーブル(ゆ着部分の
方)を裏から差し込んで、万力で締め、ケーブルを返してカバーを差し込み、穴を開けた
ペットボトルのキャップを通す(穴がコネクター側に向くように)。
Bケーブルの他端を、2本ずつ撚ってはんだづけし、茶赤を圧力センサーの1番ピン、橙
黄を2番ピン、緑青を3番ピン、紫灰を5番ピン、白黒を6番ピンにはんだづけする。
備考:圧力センサーのピン番は、円筒部を下にしみぞを左にして、左下が1番、そして右
   上が4番になる。
C次ページの左図のように、基板をビニールテープでキャップに固定する。

・回路部
@マイコン部のプリント基板に次のようにドリルで穴を開ける。
  四隅(基板固定)    φ2.5mm(4つ)
  ボリューム       φ4mm(2つ)
  残りすべて       φ0.8mm
ボリュームの穴はリーマで軸が通るように拡げる(ボリュームはまだ固定しない)。
資料の「検出部(圧力計)の実態配線図(部品面から見た図)」を参照する(以下同じ)。
A抵抗、コンデンサーをはんだ付けする。10μはプラマイに注意する。そして余剰線で
1本のジャンパー線をはんだ付けする。
Bはんだ面から、中央上部に余剰線で半円状の5つの端子をはんだ付けして作る。
Cおすコネクターに、▽印に黒色が来るように8cmのフラットケーブル(ゆ着部分の

                  - 9 -

方)を裏から差し込んで、万力で締め、ケーブルを返してカバーを差し込む。
 はんだ面から、ケーブルの他端を中央上部に、左に茶赤コードが来るようにして、半円
状端子に2本ずつはんだ付けする。そしてコードをめっき線で固定する。
 ちなみに5つの端子は部品面から見て右から左に次のように並んでいる。
  SIGNAL(AD変換のための電圧)、GRD、+9V、GRD、−9V
Dオペアンプ(2つとも丸印が左下に来るように)、めすコネクター(みぞを外側に向け
る)、3pトグルスイッチをはんだ付けする。
Eボリュームを固定し、余剰線で5本の配線をする。そして6角レンチでつまみを付ける。
このときつまみの向きが見やすいように注意する。
Fテンキー部を含めてマイコン部を準備し、検出部(圧力計)のおすコネクターを差し込
み、電源を入れる。オペアンプアは熱くならないか。
 続いて圧力センサー部のおすコネクターを検出部に差し込む。それぞれのセンサーが発
熱していないか。
G次に使用法に従って、センサーに合わせてテンキーで設定し、うまく調節できるか点検
する。
参考:「0点調節」を回しても最小値より小さくできないときは、200Ωボリュームと
   100Ωの間に数10Ωの抵抗を直列に入れたりするとよい。
Hラベルを貼り、基板にビスなどを右図のように固定し、スペーサを挟んでふたのJTタ
ーミナルに差し込む。センサーなどは容器に収納できる。

  

F.使用法

@検出部をコネクターで接続した装置に、テンキー部も接続して電源スイッチを入れる
(くり返し使う場合はリセットボタンを押す)。
A「リョウイキハ(0-5) ? 」と表示されるので、設定を記憶する領域を決めてその数字を入力し、
"#"キー(エンターキー)を押す。数字を間違えたときは"*"キー(バックスペースキ
ー)を押せばやり直せる。
B「アタラシク セッテイスル = 1
  マエノセッテイヲ ツカウ = 0」と表示されるので、どちらかの数字を入力する。すでに設定して
あるなら"0"を選んですぐに計測、あるいは調整して計測に進むことができる。
("1"を選んだとして)
C「タンイ アスキーコードデ」と表示されるので、1文字ずつ(8文字まで)次のようにアスキー
コードで入力していく。アスキーコードは次ページの表のようであり、16進数2桁で文
字を表す。
そこで上の桁を10進数2桁、下の桁を10進数2桁の合計4桁の数字で入力する。たと
えば
    a = 0601
    K = 0411

                  - 10 -


  

と、9以下の場合は0を加える。
 atmなら、010607040613と入力し、"#"キーを押す。ちなみに5文字目
からは数字が1行目に上書きされていく。途中で間違えたら"*"キーでやり直せる。なお
間違えて数字が4の倍数になっていないときは、自動的にやり直しになる。
D「[atm]
  OK '#' ヤリナオシ '1'」と表示されるので、"#"キーを押す。間違いに気付けば"1"キー
を押すとやり直せる。
E「ショウスウテンノ
  ケタ(ミギカラ)? = 」と表示される。ここからレンジの最小値と最大値を入力する。これら
および計測数値の表示は4桁までになっている。そのどの桁に小数点を付けるか、右から
数えて1〜4の数字を入力し、"#"キーを押す。数字を入力した時点なら"*"キーでやり
直せる。"#"キーを押してから間違いに気付いたら、リセットボタンを押して始めからや
り直す必要がある(以下同じ)。
F「ショウスウテンヲ ハブイテ
  サイショウ ? = 」と表示される。続いて最大値の入力があるので、合わせて説明する。
 たとえばレンジを−1.00〜1.00にしたいときは、
    小数点の桁は3とし
    最小値として*100を、最大値として100を入力する。
ここでは"*"キーはマイナス(−)である。この場合にレンジの段階は200となる。
 あるいはレンジを0.000〜1.000にしたいときは、
    小数点の桁は4とし
    最小値として0を、最大値として1000を入力する。
レンジの段階は(見かけ上)1000となる。

                  - 11 -

 さらにレンジを1.000〜1.500にしたいときは
    小数点の桁は4とし
    最小値として1000を、最大値として1500を入力する。
レンジの段階は500となる。
G領域1以上を選ぶと、1段階の幅を選択できる。
「1 ダンカイノ
 ハバ(1,2,4) ? 」と表示されるので、3つのどれかのキーを押す。
 幅2を選べばレンジ幅の1/2、4を選べば1/4の段階に減少し、いたずらに数値が
ふらつくのを避けられる。
H最大値(や1段階の幅)も入力を終えると測定に入り、たとえば次のように表示され
「 [atm]
レンジ 0.000_1.000」
実際には単位の前に、符号や小数点を含めて数値が現れる。
 ここで検出部の「ゼロ点調節」(下側)と「振れ幅調節」(上側)の2つのボリューム
を加減して、最小値と最大値が正しい値になるように調整する。圧力計なら、圧力センサ
ーを50mL注射器につないで行う。そして「感度切り換えスイッチ」にも注意する。ち
なみに回路やレンジによって、2つのボリュームは連動することもある。その場合は調節
がやや難しくなる。
参考:圧力計の場合、耐寒透明チューブの内径は3mmであり、たとえば7cmなら0.5
   mLになる。これを考慮して調整した方が正確である。
Iあとは検出部の2つのボリュームに触れないように注意して、計測をする。
Jすでに領域0に設定が記憶されておれば、テンキーを接続せずに電源スイッチを入れる
かリセットボタンを押せば、いきなり計測、あるいは調整して計測に進むことができる。

補正関数を使用する場合
 「ゼロ点調節」と「振れ幅」の2つのボリュームで調整したとして、他の一点がしかる
べき数値からずれる場合を、2次関数で補正する。つまり
    aはaのまま、bもbのまま、そしてcがdになるように、2次関数
    y = sx2 + tx + u
の係数を求めると
    s = (d−c)/(c−a)(c−b)
    t = (c2 −ad−bd+ab)/(c−a)(c−b)
    u = ab(d−c)/(c−a)(c−b)
となるので、a,b,c,dを入力してこの2次関数で補正すればよい。
 これは領域4か5を選ぶと使用できるようになる。具体的には2つの段階を踏む。始め
は上のBで
 「アタラシク セッテイスル = 1
  マエノセッテイヲ ツカウ = 0」で1を選ぶと
・「イマ ホセイスル = 1
  アトデ ホセイスル = 0 」と表示されるので、0を選び、他の領域と同じように単位、最少・
最大値などを入力し、調節をすると、4つの数字(小数点は除く)が決まる。
 次にリセットし、再び「アタラシク セッテイスル = 1」を選び、「イマ ホセイスル = 1」を選ぶと
・「ホセイデータ ガアル = 1
  アトデ ホセイスル = 0」と表示されるので、1を選ぶ。0は、始めの段階で間違えて「イマ ホ

                  - 12 -

セイスル = 1」を選んだ場合の抜け道になっている。
・「ホセイ:カエナイ スウチ
  ヒトツメ ? 」と表示されるので、aの数値を入力する。
・「ホセイ:カエナイ スウチ
  フタツメ ? 」と表示されるので、bの数値を入力する。
・「ホセイ:カエル スウチ
  モト ? 」と表示されるので、cの数値を入力する。
・「ホセイ:カエル スウチ
  アト ? 」と表示されるので、dの数値を入力する。
 これで補正された数値が表示されるようになる。ちなみに後の段階を経ないかぎり、他
の領域と同じように補正されない表示が継続する。なお再び「アタラシク セッテイスル = 1」を選ぶ
と、現在の補正のための数値は消失する。

G.プログラムリスト

 プログラムはC言語で開発してコンパイルし、秋月の「PICプログラマ」でマイコン
に焼き込む。なお純正の「MPLAB」は日本語が使えないので、エディターには「秀
丸」を使った。
参考書:後閑「C言語によるPICプログラミング入門」(技術評論社)

(下に「追記」のプログラムがあるので、このバージョンは省略した。)



追 記(09.9)


 電源・デジタル表示装置(PWDDと略称)は、検出部にマイクロアンメーター、高抵
抗入力電圧計を加え、仲間からレベル表示も加えられないかという意見をもらった。さら
に高精度温度計を設計するにあたり、計測値表示のふらつきが問題になり、AD変換デー
タを平均してから表示してはどうかという示唆をもらった。

平 均
 これまでの計測は0.2sごとに表示しているので、20msごとに10回計測して平均
して表示するように、プログラムを改訂した。
 また新しいレベル表示は50msごとに表示することにしたので、5msごとに10回
計測して平均して表示するように、プログラムを改訂した。

レベル表示
 このため領域6,7を付け加える。
 0およびプラマイ7段階の合計15段階で表示する(液晶は1行が16文字)。0は
'0’で、プラス側は '+’の個数で、マイナス側は '−’の個数で表示する。
 AD変換された0〜1024までの数値(レンジよりすこし広い)を、リニア、中間
(0.75乗)、対数の3つの方法で変換する。
・リニア変換

                  - 13 -

    y= 0.01465x
・中間変換
    y = kx0.75
  対数をとって
    logy = logk + 0.75×logx
  実際には
    logy = −1.157 + 0.75×logx
・対数変換
    y = 2.768×logx
 計算は、yが0.5,1.5,2.5・・・7.5になるxを求め、0〜0.5が '0’レベ
ル、〜1.5が '+’レベル、〜2.5が '++’レベル・・・とする(これをマイナス側
にも拡げる)。実際には次のようにする。
   レベル     リニア       中間       対数
    −7   0〜  68   0〜  89   0〜 288
    −6      137      174      414
    −5      205      253      469
    −4      273      327      493
    −3      341      394      503
    −2      410      452      507*
    −1      478      498      509
     0      545      526      514
    +1      613      572      516*
    +2      682      630      520
    +3      750      697      530
    +4      818      771      554
    +5      886      850      609
    +6      955      935      735
    +7     1024     1024     1024
    (* 計算では507は508に、516は515になる。)

レベル表示の使い方
 予め領域0などで、検出部の調節を済ます。このとき正負両側の幅を同じにする。
 そして領域6か7を選ぶと
・「ヘンカンハ? リニア=1
  チュウカン=2 タイスウ=3」と表示されるので、どれかを選択する。
・続いて、単位、小数点の桁、最大値(最小値は入力しない)を入力する。
 これでレベルメーターになる。







                  - 14 -

改訂したプログラム

////////////////////////////////////////////////////////////
/*    「電源・デジタル表示装置」のための
        DEJIHYOUJI
            Ver.3−2(11.9)
                林 正幸
             (協力:田中 英二)
*//////////////////////////////////////////////////////////

//宣言
#include <16f876a.h>                 //ヘッダーファイル
#fuses HS, NOWDT, NOPROTECT, PUT, BROWNOUT, NOLVP  //コンフィギュレーション
#device ADC=10                    //AD変換は10ビット
#use delay(CLOCK = 20000000)  //クロックは20MHz
#use fast_io(B)         //ポートB(液晶)の入出力は不変
#use fast_io(C)         //ポートC(テンキー)の入出力は不変
//液晶定義
#define output_x output_B
#define stb PIN_B3    //液晶の E
#define rs PIN_B2     //液晶の RS
//テンキー定義
#define R1 PIN_C4
#define R2 PIN_C5
#define R3 PIN_C6
#define R4 PIN_C7
#define C1 PIN_C0
#define C2 PIN_C1
#define C3 PIN_C2
#define SELECT PIN_C3  //PIN_C3はプルアップしている
//グローバル変数
char ryouiki = 0;  //eepromの記憶領域
char settei = 0;   //設定のフラグ
char hosei = 0;   //補正のフラグ
signed long suji[5];   //一時記憶 なぜかintなどでは駄目
signed long min, max;  //レンジの最小値、最大値
char keta, syo;  //数値の桁、小数点の桁
//その他の関数//
//液晶関係
//(データ出力)
void lcdout(char code, char flag)
{
  output_x(code & 0xF0);  //上4ビットのみ接続している
  if(flag == 0)       //0はコマンド、1は文字データ

                  - 15 -

    output_high(rs);
  else
    output_low(rs);
  delay_cycles(1);
  output_high(stb);  //書き込みトリガをON
  delay_cycles(2);
  output_low(stb);   //書き込みトリガをOFF
}
//(コマンド出力)
void lcdcmd(char cmd)
{
lcdout(cmd, 1);
lcdout(cmd<<4, 1);  //下4ビットを上に
delay_ms(2);
}
//(1文字表示)
void lcddat(char asci)
{
  lcdout(asci, 0);
  lcdout(asci<<4, 0);
  delay_us(50);
}
//(行・字指定)
void lcdyx(char gyo, char ji)
{
  char iti;
  if (gyo == 1)
    iti = 0x7F + ji;
  else
    iti = 0xBF + ji;
  lcdcmd(iti);
  delay_ms(2);
}
//(クリア)
void lcdclr(void)
{
  lcdcmd(0x01);
  delay_ms(15);
}
//(初期化)
void lcdsyokika(void)
{
  delay_ms(20);
  lcdout(0x30, 1);  //8ビットモード設定

                  - 16 -

  delay_ms(10);
  lcdout(0x30, 1);  //8ビットモード設定
  delay_ms(5);
  lcdout(0x30, 1);  //8ビットモード設定
  delay_ms(5);
  lcdout(0x20, 1);  //4ビットモード設定
  delay_ms(2);
  lcdcmd(0x28);    //ファンクション設定
  lcdcmd(0x0C);    //ディスプレイ設定
  lcdcmd(0x06);    //エントリー設定
}
//テンキー
char kiyomi(void)
{
  char atai;
  while(1)
  {
  //R1が1のとき
    output_low(R4); output_low(R3); output_low(R2); output_high(R1);
    if (input(C1) == 1)
    {
      atai = '1';
      while(input(C1));
      break;
    }
    if (input(C2) == 1)
    {
      atai = '2';
      while(input(C2));
      break;
    }
    if (input(C3) == 1)
    {
      atai = '3';
      while(input(C3));
      break;
    }
  //R2が1のとき
    output_low(R4); output_low(R3); output_high(R2); output_low(R1);
    if (input(C1) == 1)
    {
      atai = '4';
      while(input(C1));
      break;

                  - 17 -

    }
    if (input(C2) == 1)
    {
      atai = '5';
      while(input(C2));
      break;
    }
    if (input(C3) == 1)
    {
      atai = '6';
      while(input(C3));
      break;
    }
  //R3が1のとき
    output_low(R4); output_high(R3); output_low(R2); output_low(R1);
    if (input(C1) == 1)
    {
      atai = '7';
      while(input(C1));
      break;
    }
    if (input(C2) == 1)
    {
      atai = '8';
      while(input(C2));
      break;
    }
    if (input(C3) == 1)
    {
      atai = '9';
      while(input(C3));
      break;
    }
  //R4が1のとき
    output_high(R4); output_low(R3); output_low(R2); output_low(R1);
    if (input(C1) == 1)
    {
      atai = '*';
      while(input(C1));
      break;
    }
    if (input(C2) == 1)
    {
      atai = '0';

                  - 18 -

      while(input(C2));
      break;
    }
    if(input(C3) == 1){
      atai = '#';
      while(input(C3));
      break;
    }
  }
  return (atai);
}
//領域選択
void ryouikisenntaku(void)
{
//領域0:テンキーなしで表示。数値刻みは1
//領域1〜3:通常
//領域4,5:補正が可能
//領域6,7:レベル表示。正負は等幅。(調整は領域0などで済ませて)
  char i, ki;
  lcdclr();
  printf(lcddat, "リョウイキハ(0-7) ? ");
  lcdyx(2, 1);
  printf(lcddat, "4,5:ホセイ 6,7:レベル");
ryouikida:;
  ki = kiyomi();
  lcdyx(1, 15); lcddat(ki);
  ryouiki = ki - 0x30;
  if (ryouiki == 7)  //実際の領域に変更
    ryouiki = 9;
  if (ryouiki == 6)
    ryouiki = 8;
  if (ryouiki == 5)
    ryouiki = 6;
  ki = kiyomi();
  if (ki == '*')
  {
    lcdyx(1, 15); lcddat(' ');
    goto ryouikida;
  }
  lcdclr();
  printf(lcddat, "アタラシク セッテイスル = 1");
  lcdyx(2, 1); printf(lcddat, "マエノセッテイヲ ツカウ = 0");
  ki = kiyomi();
  if (ki == '1')

                  - 19 -

  {
    settei = 1;
    if (ryouiki == 4 || ryouiki == 6)  //領域4,5なら
    {
      lcdclr();
      printf(lcddat, "イマ ホセイスル = 1");
      lcdyx(2, 1); printf(lcddat, "アトデ ホセイスル = 0");
      ki = kiyomi();
      if (ki == '1')
      {
        lcdclr();
        printf(lcddat, "ホセイデータ ガアル = 1");
        lcdyx(2, 1); printf(lcddat, "アトデ ホセイスル = 0");
        ki = kiyomi();
        if (ki == '1')
          hosei = 1;
      }
      if (hosei == 0)
      {
        for (i = 0; i < 20; i++)
          write_eeprom(ryouiki*20 + 20 + i, ' ');
      }
    }
    if (ryouiki == 8 || ryouiki == 9)  //領域6,7なら
    {
      lcdclr();
      printf(lcddat, "ヘンカンハ? リニア=1");
      lcdyx(2, 1); printf(lcddat, "チュウカン=2 タイスウ=3");
      ki = kiyomi();
      write_eeprom(ryouiki*20 + 19, ki-0x30);
    }
  }
}
//単位設定
void tannisettei(void)
{
//アスキーコードは両方の桁を10進数表現で(Aは10 7は07)
//*はBS
//EEPROM
//0〜7番地  単位(8文字まで 領域6,7は7文字まで)  [ ]は除く
  char i, ki, jisu, asuki[34], moji[8];
tannida:;
  lcdclr();
  printf(lcddat,"タンイ アスキーコードデ");

                  - 20 -

  for(i = 1; i < 34; i++)
  {
  tanni:;
    asuki[i] = kiyomi();
    if (i%4 == 1 & asuki[i] == '#')  //入力終了なら
    {
      jisu = (i - 1)/4;
      if (jisu < 8)
        moji[jisu] = ')';     // )はこの前まで単位
      break;
    }
    if (i%4 != 1 & asuki[i] == '#')  //入力ミスでやり直し
      goto tannida;
    if (asuki[i] == '*')        //BSなら
    {
      if (i < 18)          //4字目までなら
      {
        lcdyx(2, -1 + i); lcddat(' ');
        lcdyx(2, -1 + i); i = i - 1;
      }
      else              //5字目からなら
      {
        lcdyx(1, -17 + i); lcddat(' ');
        lcdyx(1, -17 + i); i = i - 1;
      }
      goto tanni;
    }
    if (i < 17)                 //4字目までなら
    {
      lcdyx(2, i); lcddat(asuki[i]);     //アスキーコードを液晶表示
    }
    else                    //5字目からなら
    {
      lcdyx(1, -16 + i); lcddat(asuki[i]);  //アスキーコード液晶表示
    }
    asuki[i] = asuki[i] -0x30;  //数字に変換
  }
  lcdclr();
  lcddat('[');
  for(i = 0; i < jisu; i++)     //文字に翻訳して表示
  {
    moji[i] = asuki[4*i + 1]*160 + asuki[4*i + 2]*16 + asuki[4*i + 3]*10
      + asuki[4*i + 4];
    lcddat(moji[i]);

                  - 21 -

  }
  lcddat(']');
  lcdyx(2, 1); printf(lcddat, "OK '#' ヤリナオシ '1'");
  ki = kiyomi();
  if (ki == '1')
    goto tannida;
  for (i = 0; i < 8; i++)
    write_eeprom(ryouiki*20 + i, moji[i]);  //単位をEEPROMに
}
//数値書き込み
void kakikomi(char jisu, basyo)
{
  char i;
////符号
  suji[0] = kiyomi();
  if (suji[0] == '*') //−なら
  {
    suji[0] = '-';
    lcdyx(2, jisu); lcddat('-');
    write_eeprom(ryouiki*20 + basyo, '-');
  }
  else         //−でないなら、上1桁目を表示、記憶
  {
    write_eeprom(ryouiki*20 + basyo, ' ');
    lcdyx(2, jisu + 1); lcddat(suji[0]);
    suji[1] = suji[0];
  }
////数字
  for(i = 1; i < 6; i++)
  {
naoshi:;
    if (i == 1 && suji[0] != '-')  //−でないなら、2桁目に跳ぶ
      i = i + 1;
    suji[i] = kiyomi();
    if (suji[i] == '#')
    {
      if (i < 5)
        suji[i] = 'e';  //eはこの前まで数字
      break;
    }
    if (suji[i] == '*')
    {
      lcdyx(2, jisu - 1 + i); lcddat(' ');
      lcdyx(2, jisu - 1 + i); i = i - 1;

                  - 22 -

      goto naoshi;
    }
    lcdyx(2, jisu + i); lcddat(suji[i]);
  }
  for (i = 1; i < 5; i++)
    write_eeprom(ryouiki*20 + basyo + i, suji[i] -0x30);
}
//数値設定
void sutisettei(void)
{
//AD変換値0〜1023のうち、レンジ内は42〜982とする。
//EEPROM
//8番地   小数点の桁 右から1,2,3,4桁
//9     最小値の符号
//        (*は−にも利用)
//10〜13     数字(4桁まで)
//14    最大値の符号
//15〜18     数字(4桁まで)
//19    数値刻み(1,2,4)/領域1〜5の場合
//      変換の内容(リニア、中間(0.75乗)、対数)/領域6,7の場合
char i, syo, ki, haba;
//小数点の桁
  lcdclr();
  printf(lcddat, "ショウスウテンノ");
  lcdyx(2,1); printf(lcddat, "ケタ(ミギカラ)? = ");
syousu:;
  syo = kiyomi();
  lcdyx(2, 14); lcddat(syo);  //小数点の桁を液晶表示
  ki = kiyomi();
  if (ki == '*')  //BSなら
  {
    lcdyx(2, 14);lcddat(' ');
    goto syousu;
  }
  write_eeprom(ryouiki*20 + 8, syo - 0x30);  //数字に変換してEEPROMに
//最小値
  lcdclr();
  if (ryouiki < 7)
  {
    printf(lcddat,"ショウスウテンヲ ハブイテ");
    lcdyx(2, 1); printf(lcddat,"サイショウ ? = ");
    kakikomi(11, 9);
  }
//最大値

                  - 23 -

  lcdclr();
  printf(lcddat,"ショウスウテンヲ ハブイテ");
  lcdyx(2, 1);
  printf(lcddat,"サイダイ ? = ");
  kakikomi(11, 14);
//数値刻み
  if (ryouiki > 0 && ryouiki <7)  //領域1〜5以上なら
  {
    lcdclr();
    printf(lcddat, "スウチ キザミ");
    lcdyx(2, 1); printf(lcddat, " (1,2,4) ? ");
dannkai:;
    ki = kiyomi();
    lcdyx(2, 14); lcddat(ki);
    haba = ki - 0x30;
    ki = kiyomi();
    if (ki == '*')
    {
      lcdyx(2, 14); lcddat(' ');
      goto dannkai;
    }
    write_eeprom(ryouiki*20 + 19, haba);
  }
}
//補正設定
void hoseisettei(void)
{
//2次関数により補正する。
//EEPROM
//20番地   変えない1つ目の数値の符号
//21〜24          数字(4桁まで)
//25番地   変えない2つ目の数値の符号
//26〜29          数字(4桁まで)
//30     変える元の数値の符号
//31〜34          数字(4桁まで)
//35     変える後の数値の符号
//36〜39          数字(4桁まで)
  char i, ki, suuti[5];
//変えない1つ目の数値 aa
  lcdclr();
  printf(lcddat, "ホセイ:カエナイ スウチ");
  lcdyx(2, 1); printf(lcddat, "ヒトツメ ? ");
  kakikomi(8, 20);
//変えない2つ目の数値 bb

                  - 24 -

  lcdclr();
  printf(lcddat, "ホセイ:カエナイ スウチ");
  lcdyx(2, 1); printf(lcddat, "フタツメ ? ");
  kakikomi(8, 25);
//変える元の数値 cc
  lcdclr();
  printf(lcddat, "ホセイ:カエル スウチ");
  lcdyx(2, 1); printf(lcddat, "モト ? ");
  kakikomi(6, 30);
//変える後の数値 dd
  lcdclr();
  printf(lcddat, "ホセイ:カエル スウチ");
  lcdyx(2, 1); printf(lcddat, "アト ? ");
  kakikomi(6, 35);
}
//単位表示
void tannihyouji(void)
{
  char i, moji;
  lcdclr();
  if (ryouiki < 7)
    lcdyx(1, 7);
  else
    lcdyx(2, 8);
  lcddat('[');
  for (i = 0; i < 8; i++)
  {
    moji = read_eeprom(ryouiki*20 + i);
    if (moji == ')')
      break;
    lcddat(moji);  //単位を液晶表示
  }
  lcddat(']');
}
//数値読み出し
signed long yomidashi(char basyo)
{
  char i;
  signed long suti;
  keta = 4;
  for (i = 0; i < 4; i++)
  {
    suji[i] = read_eeprom(ryouiki*20 + basyo + 1 + i); //数値読み出し
    if (suji[i] == 'e' - 0x30)

                  - 25 -

    {
      keta = i; //数値の桁
      break;
    }
  }
  switch (keta) //桁数に応じて数値化
  {
    case 1:
      suti = suji[0];
      break;
    case 2:
      suti = suji[0]*10 + suji[1];
      break;
    case 3:
      suti = suji[0]*100 + suji[1]*10 + suji[2];
      break;
    case 4:
      suti = suji[0]*1000 + suji[1]*100 + suji[2]*10 + suji[3];
  }
  if (read_eeprom(ryouiki*20 + basyo) == '-')       //−なら
    suti = -suti;
  return (suti);
}
//レンジ表示
void rennjihyouji(void)
{
  char i;
  syo = read_eeprom(ryouiki*20 + 8);  //小数点の桁の読み出し
  if (ryouiki < 7)
  {
    min = yomidashi(9);  //最小値読み出し
    lcdyx(2, 1); printf(lcddat, "レンジ");  //レンジ表示
    if (min < 0)
    lcddat('-');
    if (syo == keta + 1)    //レンジ数値
    printf(lcddat, "0.");
    if (syo == keta + 2)
      printf(lcddat, "0.0");
    if (syo == keta + 3)
      printf(lcddat, "0.00");
    for (i = 0; i < keta; i++)
    {
      lcddat(suji[i] + 0x30);
      if (syo > 1 && syo == keta - i)

                  - 26 -

        lcddat('.');
    }
  }
  max = yomidashi(14);  //最大値読み出し
  if (ryouiki > 7)
  {
    lcdyx(2, 1);
    printf(lcddat, "+-");
  }
  else
  {
    lcddat('_');  //レンジ表示
    if (max < 0)
      lcddat('-');
  }
  if (syo == keta + 1)    //レンジ数値
    printf(lcddat, "0.");
  if (syo == keta + 2)
    printf(lcddat, "0.0");
  if (syo == keta + 3)
    printf(lcddat, "0.00");
  for (i = 0; i < keta; i++)
  {
    lcddat(suji[i] + 0x30);
    if (syo > 1 && syo == keta - i)
      lcddat('.');
  }
}
//測定1
void sokutei1(void)
{
//「数値設定」を読み出し、準備する。
  char i, haba;
  char hoseizumi = 0;
  signed long hyouji, ad, addat;
  signed int32 aa, bb, cc, dd;
  float koubai;
  float ee, ff, ss, tt, uu;
  koubai = (max - min)/940.0; //勾配の計算
  if (ryouiki > 0)
    haba = read_eeprom(ryouiki*20 + 19);  //数値刻みの読み出し
//補正データの読み出し
  if (ryouiki > 3 && read_eeprom(ryouiki*20 + 21) != ' ')
  {

                  - 27 -

    hoseizumi = 1;
    aa = yomidashi(20);  //変えない1つ目の数値
    bb = yomidashi(25);  //変えない2つ目の数値
    cc = yomidashi(30);  //変える元の数値
    dd = yomidashi(35);  //変える後の数値
//補正2次関数の係数
    ee = (cc - aa)*(cc - bb);
    ss = 1.0*(dd - cc)/ee;
    tt = cc*cc - aa*dd - bb*dd + aa*bb;
    tt = 1.0*tt/ee;
    uu = aa*bb*(dd - cc);
    uu = 1.0*uu/ee;
  }
//計測し、表示する(0.2秒間隔)。
  while(1)
  {
    addat=0;    //20ms間隔で10回計測して平均
for(i=0; i<10; i++)
    {
      set_adc_channel(0);
      delay_us(100);
      ad = read_adc();    //AD変換
      addat = addat+ad;
      delay_ms(20);
    }
    addat = addat/10;
    hyouji = koubai*(addat - 42) + min;  //数値化
    if (hoseizumi == 1)
    {
      ff = koubai*(addat - 42) + min;
      hyouji = ss*ff*ff + tt*ff + uu;  //補正する
    }
    lcdyx(1, 1); printf(lcddat,"   ");  //画面を整えて
    if (hyouji < 0)
    {
      lcdyx(1, 1); lcddat('-');
      hyouji = -hyouji;
    }
    if (ryouiki > 0)  //数値刻み幅にする
      switch(haba)
      {
        case 2:
          if (hyouji%2 == 1)

                  - 28 -

            hyouji = hyouji + 1;
          break;
        case 4:
          if (hyouji%4 == 1)
            hyouji = hyouji + 3;
          if (hyouji%4 == 2)
            hyouji = hyouji + 2;
          if (hyouji%4 == 3)
            hyouji = hyouji + 1;
      }
    keta = 4;    //数値の桁数
    if (hyouji <1000)
      keta = 3;
    if (hyouji <100)
      keta = 2;
    if (hyouji <10)
      keta = 1;
    lcdyx(1, 2);
    for (i = 0; i     {
      suji[i] = hyouji%10;
      hyouji = hyouji/10;
    }
    if (syo == keta + 1) //小数点が数値の上なら
    {
      if (keta == 1)
        printf(lcddat, " 0.");
      if (keta == 2)
        printf(lcddat, " 0.");
      if (keta == 3)
        printf(lcddat, "0.");
    }
    if (syo == keta + 2)
    {
      if (keta == 1)
        printf(lcddat, " 0.0");
      if (keta == 2)
        printf(lcddat, "0.0");
    }
    if (syo == keta + 3)
      printf(lcddat, "0.00");
    if (syo < 4 && keta == 3)  //数値が3桁以下なら
      lcddat(' ');
    if (syo < 3 && keta == 2)

                  - 29 -

      printf(lcddat, " ");
    if (syo < 2 && keta == 1)
      printf(lcddat, "  ");
    for (i = 0; i < keta; i++)    //数値などの表示
    {
      lcddat(suji[keta - 1 - i] + 0x30);
      if (syo > 1 && syo == keta - i)
        lcddat('.');
    }
  }
}
//測定2
void sokutei2(void)
{
//「数値設定」を読み出す。
  char i, henkan;
  signed long hyouji, ad, addat;
  henkan = read_eeprom(ryouiki*20 + 19);  //変換内容の読み出し
//計測し、表示する(0.05秒間隔)。
  while(1)
  {
    addat=0;      //5ms間隔で10回計測して平均
    for(i=0; i<10; i++)
    {
      set_adc_channel(0);
      delay_us(100);
      ad = read_adc(); //AD変換
      addat = addat+ad;
      delay_ms(5);
    }
    addat = addat/10;
    lcdyx(1, 1); printf(lcddat,"    0    ");  //画面を整えて
    switch (henkan)
    {
      case 1:  //リニア変換・表示
        if (addat > 545)
        {
          lcdyx(1, 9);lcddat('+');
        }
        if (addat > 613)
        {
          lcdyx(1, 10);lcddat('+');
        }
        if (addat > 682)

                  - 30 -

        {
          lcdyx(1, 11);lcddat('+');
        }
        if (addat > 750)
        {
          lcdyx(1, 12);lcddat('+');
        }
        if (addat > 818)
        {
          lcdyx(1, 13);lcddat('+');
        }
        if (addat > 886)
        {
          lcdyx(1, 14);lcddat('+');
        }
        if (addat > 955)
        {
          lcdyx(1, 15);lcddat('+');
        }
        if (addat < 479)
        {
          lcdyx(1, 7);lcddat('-');
        }
        if (addat < 411)
        {
          lcdyx(1, 6);lcddat('-');
        }
        if (addat < 342)
        {
          lcdyx(1, 5);lcddat('-');
        }
        if (addat < 274)
        {
          lcdyx(1, 4);lcddat('-');
        }
        if (addat < 206)
        {
          lcdyx(1, 3);lcddat('-');
        }
        if (addat < 138)
        {
          lcdyx(1, 2);lcddat('-');
        }
        if (addat < 69)

                  - 31 -

        {
          lcdyx(1, 1);lcddat('-');
        }
        break;
      case 2:  //中間(0.75乗)変換・表示
        if (addat > 526)
        {
          lcdyx(1, 9);lcddat('+');
        }
        if (addat > 572)
        {
          lcdyx(1, 10);lcddat('+');
        }
        if (addat > 630)
        {
          lcdyx(1, 11);lcddat('+');
        }
        if (addat > 697)
        {
          lcdyx(1, 12);lcddat('+');
        }
        if (addat > 771)
        {
        lcdyx(1, 13);lcddat('+');
        }
        if (addat > 850)
        {
          lcdyx(1, 14);lcddat('+');
        }
        if (addat > 935)
        {
          lcdyx(1, 15);lcddat('+');
        }
        if (addat < 499)
        {
          lcdyx(1, 7);lcddat('-');
        }
        if (addat < 453)
        {
          lcdyx(1, 6);lcddat('-');
        }
        if (addat < 395)
        {
          lcdyx(1, 5);lcddat('-');

                  - 32 -

        }
        if (addat < 328)
        {
          lcdyx(1, 4);lcddat('-');
        }
        if (addat < 254)
        {
          lcdyx(1, 3);lcddat('-');
        }
        if (addat < 175)
        {
          lcdyx(1, 2);lcddat('-');
        }
        if (addat < 90)
        {
          lcdyx(1, 1);lcddat('-');
        }
        break;
      case 3:  //対数変換・表示
        if (addat > 514)
        {
          lcdyx(1, 9);lcddat('+');
        }
        if (addat > 516)
        {
          lcdyx(1, 10);lcddat('+');
        }
        if (addat > 520)
        {
          lcdyx(1, 11);lcddat('+');
        }
        if (addat > 530)
        {
          lcdyx(1, 12);lcddat('+');
        }
        if (addat > 554)
        {
          lcdyx(1, 13);lcddat('+');
        }
        if (addat > 609)
        {
          lcdyx(1, 14);lcddat('+');
        }
        if (addat > 735)

                  - 33 -

        {
          lcdyx(1, 15);lcddat('+');
        }
        if (addat < 510)
        {
          lcdyx(1, 7);lcddat('-');
        }
        if (addat < 508)
        {
          lcdyx(1, 6);lcddat('-');
        }
        if (addat < 504)
        {
          lcdyx(1, 5);lcddat('-');
        }
        if (addat < 494)
        {
          lcdyx(1, 4);lcddat('-');
        }
        if (addat < 470)
        {
          lcdyx(1, 3);lcddat('-');
        }
        if (addat < 415)
        {
          lcdyx(1, 2);lcddat('-');
        }
        if (addat < 289)
        {
          lcdyx(1, 1);lcddat('-');
        }
    }
  }
}

//メイン関数
void main(void)
{
  set_tris_b(0);         //Bポート(液晶) 出力
  set_tris_c(0x0F);        //Cポート(テンキー) 上位出力 下位入力
  setup_adc(ADC_CLOCK_DIV_64);  //AD変換のクロック指定
  setup_adc_ports(0x8E);     //RA0をAD変換機能(AN0)に
  lcdsyokika();
  if(input(SELECT) == 0)  //テンキーがつながれていれば

                  - 34 -

  {
    ryouikisenntaku();
    if (settei == 1 && hosei == 0) //設定するなら
    {
      tannisettei();
      sutisettei();
    }
    if (settei == 1 && hosei == 1) //補正するなら
      hoseisettei();
  }
  tannihyouji();
  rennjihyouji();
  if (ryouiki < 7) //測定をくり返す
    sokutei1(); //数値表示
  else
    sokutei2(); //レベル表示
}

//以上



                  - 35 -




                  - 36 -




                  - 37,38 -




                  - 39,40 -


林 正幸と主万子の始めの ホームページ(to our initial Home Page) にもどる。