計測時刻を表示できる様になったのは良いのですが、押しボタンで設定できないので、いちいち電源をいれる前に、ソースリストの時刻設定初期値を変更してコンパイルしてプログラムを書き込み、リセットを押したままで時計を見ながら「よーいドン!」でリセットを離さなければなりません。
それに、パソコンへのデータ送信情報に計測時刻を含めると云う本来の目的が達成できていません。
そこで、簡易的な一行分の日時設定画面用GUIを作って、グラフィックLCDと押しボタン3個を使って日時を変更できる様にしようと考えました。
まず押しボタンとのインターフェースの実験からはじめました。
いかなる押しボタンにもチャタリングを考慮しなくてはなりませんが、その処理を考え出すと深みにはまってしまい頭が痛くなるので、いままで避けて通ってきたのです・・
著名な後閑氏の執筆されたPIC24F書籍の中では、
「えー?そんな簡単な処理でまともに動くの?!」
と思う様な方法で処理していました。
実際に自分のPIC24Fの回路で、
後閑氏と同じ様に処理してみたら、
全く問題なく押しボタンでの数値の増減が処理できてしまいました。
いったい、
どうなっているのかと不安になり、
タクトスイッチによる電圧変化をデジタルオシロスコープで観測してみました。
(1)先ず、3.3Vへポート内蔵のプルアップ設定を行ったデジタルI//O入力を、
タクトスイッチでグランドへ短絡する事でLowレベル信号を入れた場合です。
しつこく、何度も繰り返してやっても、HighからLow信号への変化の場合は、
上記の様な波形以外は全く観測されませんでした。
2.6V(PIC24FでVdd3.3V駆動の場合は、デジタルI/OでのHighレベル値は、Vdd-0.7Vとなる)から過度現象しながら60ナノsec(0.06μSec)以内という非常に短い時間に0Vへ到達しています。
途中信号的にHighレベルに上がってしまう事は無い様です。
(2)今度は、LowからHighへの信号への変化を観測してみました。
300μSec以内に10回前後の明らかなチャタリングが発生しています。
今度は400μSecの間に発生してます。
今度は1500μSec(1.5mSec)間に発生しています。
これは
2700μSec(2.7mSec)間に発生しています。
8mSec間発生しました。
3mSec間発生しています。
押しボタンを解放する場合には、思いきりチャタリングが発生しています。
非常に稀ですが最大8mSecのノイズ発生とチャタリングを起こしました。
しつこく何回も何回もやりましたが、
8mSec以上の長いノイズやチャタリングは観測されませんでした。
実験方法にもよりますが、結論としては
タクトスイッチは、
押しボタンの「閉」ではチャタリングを起こし難く、
押しボタンの「開」では少なくとも10mSec前後のノイズやチャタリングが発生する可能性がある。
というところでしょうか・・
確かに、
トグルスイッチ等のメカニカルなスイッチと比べれば、
チャタリング時間が非常に短いと思われます。
そこで今回は、
(1)タクトスイッチの押しボタン開放状態からボタンを押し込んで、
信号がHighから1回でもLowになれば、
押されたと解釈してその時のやりたい事をさっさとやり、
その直後にwhileでポートがLowである間中捕まえます。
そして、ボタンが解放されてHighレベルに1回でもなれば、
そのルーチンを抜け出る。
その押しボタン処理の後に、
他の処理が多く有る場合はそれでおしまい。
(2)そのボタンの処理にすぐ戻ってくる様な全体の周期の短い場合や、ループ内では、
Highへのチャタリングを避ける為に、
10msecのディレイを入れておく。
上記の処理のしかたが、ベストだとは思いませんが、とりあえずタクトスイッチで、問題なくデータを+1、-1づつ増減する事が出来ました。
チャタリングが「開」でも、「閉」でも数百ミリSec単位で発生する様な押しボタンの場合には、上記の様な方法は使えません!
この実験で、なんとか日付や時刻の設定変更がポタンで出来そうです。
でも、どんな表示(GUI:グラフィックユーザーインターフェース)でやるかが最大の難点です。
プログラム次第でどうにでも出来るので、専用のGUIに凝り始めると、キリが有りません。
とりあえず、
3つの押しボタンの1つをモード切り替えに、残りの2つは一桁ずつの増加方向のみボタンにしました。
下桁は0から9まで増加して行き、9を超えると0、あるいは1に戻ります。
月の上桁は2を超えると0に戻ります。等・・
00月や13月は有りませんが・・どうしても00月や00日になってしまう場合があります。まだ改良の余地があります。(暫定ですので・・)
モードは、モードボタンを一回押す毎に変化し、0から1,2と増加して行き、12を超えると元の0に戻ります。
0:通常動作の計測、表示、データー送信モード。
1:現在の設定値(現在時刻では無い)を読み出して、「年」の設定値の変更モード(2桁独立設定)
2:?と「年」の設定値だけを表示して、3つ目の押しボタンが押された時には、年、月、日、時、分、秒の全設定値を現在値へ書き込んで変更する。
3:現在の設定値(現在時刻では無い)を読み出して、「月」の設定値の変更モード(2桁独立設定)
4:?と「月」の設定値だけを表示して、3つ目の押しボタンが押された時には、年、月、日、時、分、秒の全設定値を現在値へ書き込んで変更する。
** 以下 下記の「秒」の設定までモード5からモード10までモード値を増加させながら繰り返す **
11:現在の設定値(現在時刻では無い)を読み出して、「秒」の設定値の変更モード(2桁独立設定)
12:?と「秒」の設定値だけを表示して、3つ目の押しボタンが押された時には、年、月、日、時、分、秒の全設定値を現在値へ書き込んで変更する。
モード0へ戻る。
と云う事になりました。
もう、いつ変更するかは分かりませんが、とりあえずの暫定です。
これで、曲がりなりにも、電源を切った時にコンパイラーのお世話にならなくても、日時を正しく設定し直す事が出来る様になりました。
次に、RS232Cへの計測日時情報の送信ですが、元々RTCCから読み出される日時情報は、BCD(BCD、Binary-coded decimal:2進化10進数)です。0000から1001までの4ビットの2進数です。
始めはなぜなのだろうと思いましたが、ASCIIコード変換をして表示する場合には0x30を各桁に加えれば良い事、一桁づつに分ければそのまま数値データとしてすぐ利用できる事の2点を同時に兼ね備えているのです。
これは思ったよりも、簡単に出来ました。
部屋の温度が高いですが、そういう部屋なのです。決してセンサーの故障では有りません。
今回も後で、バッテリー駆動を行う場合に備えて、PICでの消費電流を押さえる為に、内部システムクロックを8MHzに設定しています。
I/O端子を最大限に使う為に、外付けの発振子を使わずに、内部のFRC発振(8MHz)を直接使用しています。FRC発振の場合には、これ以下の低い周波数を選定する事は出来ません。
内部システムクロックが8MHzの場合、遅延用delay_us()用の CLOCK 値は、「4」です。今回使用しているdelay関数では CLOCK にMIPS値を入れる様になっているからです。PIC24Fは2クロックで1サイクルですから、殆どの命令が1サイクルで処理されるので、内部システムクロックが8MHzならば、4MIPSの処理能力が有ります。
間違って倍の「8」を使用しないで下さい。
delay等で、どうしても机上計算等で納得のいかない場合は、MPLAB IDE 内の MPLAB SIM(シミュレーター)上でストップウォッチ機能を使ってdelay_ms(1000)の前後にブレイクを入れて、その長さを計ってみて下さい。それでも納得のいかない場合は、delay関数で1秒の長さを作って確かめてみれば明白です。2倍も違えば誰でも分かるでしょう。
また、内部システムクロック8MHzの場合、UARTモジュールのFcyも、「4」です。PIC24FJは2クロックで1cyだからです。
参考ですが、同じ16ビットPICのdisPIC30は4クロックで1cyです。
同一内部システムクロックならば、PIC24FはdisPIC30の2倍のMIPS値ですが、PIC24Fの最大内部システムクロックは32MHz(16MIPS)まで、disPIC30は120MHz(30MIPS)まで動作してDSP機能もで内蔵しています。
その代わりに消費電流はdisPIC30は同一電圧、同一MIPS値では、PIC24Fの約3倍の電流を消費します。
PIC24F64GA004 8MHz(4MIPS) 3.3V 4.1mA
disPIC30F401x 16MHz(4MIPS)3.3V 11mA
だからどうだという事は有りませんが、処理が早ければ良いと云うわけではなく、PIC12F、PIC16F、PIC18F、PIC18LF、PIC24F、disPIC30、PIC32MX等、色々な特徴を持ったPICがありますが、それぞれに良いところがあるので、適材適所でPICを選んで使いましょう。
事実、足が8ピンしか無い PIC12F で十分気圧センサーユニットを使ってRS232C通信で気圧、温度情報をパソコンに送る事が出来るのですがら。(パレットソフトさんの「気圧センサ SCP1000 (試食)」記事を参照)
下記に、サンプルソースをリンクしておきます。ハード回路図は前回(その5)と同じです。
このサンプルでも、内部システムクロックは FRC 8MHz を直接使っています。
|