第12回 ADコンバータ(6) 〜チャレンジ課題〜

今回はチャレンジ課題です。

目次

ADコンバータの設定を変えてみよう

ADコンバータの設定のところで、結果の値をADRESに右詰にするようにしました。

この設定を左詰にすると、プログラムをどのように変更すればよいか検討してみてください。左詰にする場合、ADCON1レジスタの設定を以下のように変更します。

ADCON1 = 0b00000000;  // 結果数値は左寄せ、ADコンバータクロックはFOSC/2、基準電圧はVDD

このように変更すると、ADRESHの値を8-bitの数値として見ることができます。判定する数値は8-bitになるので、判定範囲が変わりますよね。

時間表現方法を変える

これはADコンバータ機能とは関係ありませんが、タイマー時間を変更すると変更後のタイマー時間をLEDの点滅回数で表現していました。ただこの方法の場合、タイマー時間が長くなるとLEDの点滅回数が増えてしまいます。何十回も点滅する様子を見て正確に点滅回数を数えるのは、タイマーというより、そういうゲームですよね。

この点滅表現を、例えば、1を早い点滅1回、5をちょっと時間が長めの点灯1回、というように点滅回数が減るようにしてみてください。

プリセットタイマー時間から選択する

電源をONにした場合は、例えば5分タイマーとします。

この状態で、例えば黒のスイッチを1回押すと、3分、もう1回押すと1分というように、プリセット値から選択するようなスイッチに変更してみてください。

白いスイッチを押した場合は、7分、10分というように長い時間を選択するようにします。

今までは、黒のスイッチと白のスイッチはタイマー時間の値を増減する機能としていましたが、ここではプリセット値を選択するスイッチ、という機能にしてみてください。

次回から、EEPROMについて説明します。

更新履歴

日付 内容
2017.7.29 新規投稿
通知の設定
通知タイミング
guest
7 コメント
新しい準
古い順 一番投票が多い
本文中にフィードバック
全てのコメントを見る
jh3gpn
jh3gpn
6 年 前

温度・湿度・気圧だけで十分です。
壁掛けで実用になるような大きなディスプレイはないでしょうか?
この先を楽しみにしております。

管理者
管理者
6 年 前

wakazoさま、
プログラミングのご経験がどの程度あるかで、ヒントの内容が異なりますので回答が難しいところですが、以下の前提条件でご回答いたします。

[条件]
 ・以下の主要なC言語の文法は理解している
   -変数型、演算子
   -配列
   -繰り返し構文(while文、for文)
   -条件判断構文(if文、switch文)
   -2進数、16進数

[ヒント]
 ・ADコンバータの設定を変える
   今までADRESの16ビットレジスタを16ビットの変数として扱っていました。レジスタは16ビットですが、ADコンバータの値は10ビットですので、16ビットとしては0〜65535まで表現できますが、ADコンバータとしては0〜1023を使用していました。
   この10ビットの数字を16ビットレジスタに左詰にした場合、ADRSHは、ADコンバータの結果の10ビットのうち上位8ビットがセットされます。10ビットのうち、この上位8ビットは「ADRES >> 2;」とイコールになります。つまり、ADRESに左詰で10ビットをセットした場合、ADRESHはADコンバータの結果の値を4で割った値(2ビット右シフトした値)になっているわけです。0〜1023の値は、0〜255になります。
   ということは、0〜1023のADコンバータの値を例えば500以上で判定する場合、0〜255の値の場合は500の判定値はどうなるか、がポイントになります。

 ・時間表現方法を変える
   プログラム(アルゴリズム)を考える場合、自分が何をしているかじっくり考えるとどのようにプログラムすればわかって来ます。
   1を早い点滅1回、5を長めの点滅1回にしたい場合、具体例で自分がどのような処理をしているか考えてみます。
   例えばタイマーが7秒にセットされている場合、今までのプログラムでは、LEDを7回点滅させていました。では、1秒を早い点滅1回、5秒を長めの点滅1回にしたい場合、7秒はどのような点滅パターンになるかというと、

 1回の長い点滅 + 2回の短い点滅

 になる、というのはすぐにわかると思います。では次に、99秒の点滅バターンはどうなるでしょうか。7秒の場合は感覚的にわかると思いますが、99秒の場合は何か計算式を考える必要がありますよね。

 99秒 = 5秒が◯回 + 1秒が□回
 ※ただし、◯は一番大きい数字にする

 この計算をどうすればよいか考えてみる必要がありそうです。これがわかれば、あとは、

 for文で◯回長い点滅をしたあと、次のfor文で□回短い点滅を□回点滅させれば実現できます。

 ・プリセットタイマー時間から選択する
  今までは、タイマー時間をtimerValueという変数にセットしておき、スイッチが押されたらtimerValueを++したり–したりしていました。
  今回は、1回押されたらあらかじめ設定してあるプリセットの秒数にセットする必要があります。
  このようなケースで一番簡単なのは配列使って実現する方法です。例えば、プリセットの値として、

  presetValue[] = {1, 3, 5, 7, 10};

  などにセットしておき、デフォルトは5秒とすると、配列のインデックスをtimerIndexとすると、timerIndex = 2とすれば、

  presetValue[timerIndex]

  つまり、5がデフォルトの秒数になります。スイッチが押された場合、このtimerIndexを++したり–すればpresetValue[timerIndex]がプリセット値になります。ただし、timerIndexの上限下限がありますので、その範囲を超えないようにする必要もあります。

wakazo
wakazo
返信  管理者
6 年 前

ありがとうございます。
時間を見つけてこつこつやってみたいと思います。

プログラミング経験は、ほぼないです。が用語や文法や2進数、16進数の理解はしている状態なのかなと思います。ただ、今興味がどんどん出てきてはまり始めていると言った感じです。

claynets
claynets
返信  wakazo
6 年 前

wakazoさま、
C言語の文法や2進数、16進数がある程度わかれば、あとは練習あるのみだと思います。

C言語の文法がわかっていても、プログラミングはまた別物、と感じていらっしゃると思います。言葉と一緒で単語や文法を知っていても、言い回しがわからないと話をするのが難しいのと一緒で、プログラミングも色々な考え方を身につけていけば、絶対にオリジナルのプログラムが書けるようになります!

ぜひ色々とチャレンジされてみてください!

wakazo
wakazo
6 年 前

こんばんは、プログラムの経験不足すぎて少し課題がでただけで戸惑っています。もう少し考えかたのヒント、アドバイスがあれば教えて頂けるとありがたいです。よろしくお願いします。

目次