1950年に始まったデジタル革命は、既存のすべての機械的およびアナログ電子構造をデジタルコンピューターに変えます。デジタル電子機器の成長は指数関数的であるため、今日、人が電子機器の使用に抵抗することはほとんど不可能です。あなたを目覚めさせる目覚まし時計とあなたに朝食を提供するトースターから始めて、すべてはデジタル電子機器からの貢献です。これらすべてを考えると、PICマイクロコントローラーを使用してこのプロジェクトで構築する目覚まし時計のように、シンプルでありながら便利なタスクを実行できる独自のものをプログラムすることは本当にエキサイティングです。以前、他のマイクロコントローラーで目覚まし時計を作成しました。
- RTCモジュールDS1307を使用したRaspberryPi目覚まし時計
- アラーム付きArduinoベースのデジタル時計
- ATmega32マイクロコントローラーを使用した目覚まし時計
この目覚まし時計は、現在の時刻と設定時刻を表示する16x2LCDディスプレイを備えています。必要に応じて、いくつかのプッシュボタンを使用してアラーム時間を設定します。現在の時刻はDS3231RTCモジュールを使用して追跡され、IIC通信を使用してRTCモジュールからこれらの値を取得します。RTCモジュールとそれをPICとインターフェースする方法についてはすでに学びました。したがって、そのチュートリアルを一読することをお勧めします。このチュートリアルで説明されている情報のほとんどはスキップします。
必要な材料:
- ブレッドボード– 2Nos
- PIC16F877A
- 5V電源-電源モジュール
- 20MHzクリスタル
- 33pfコンデンサ– 2Nos
- DS3231RTCモジュール
- 16 * 2LCDディスプレイモジュール
- 10Kポット
- 10kおよび1K抵抗
- 押しボタン– 5Nos
- ブザー
- 接続線
前提条件:
このプロジェクトでは、PICマイクロコントローラーとそのプログラミング方法に関するいくつかの基本を知っている必要があります。このプロジェクトでは、GPIO、LCDディスプレイ、RTCモジュールを使用します。したがって、これらのモジュールの使用方法を事前に学習しておくことをお勧めします。次のリンクはあなたが同じことを学ぶのに役立ちます
- PICマイクロコントローラーで最初のプログラムを書く
- LCDとPICのインターフェース
- PICを使用したI2C通信
- PICとのDS3231RTCインターフェース
回路図:
このPICベースの目覚まし時計プロジェクトの回路図を以下に示します。これはプロテウスソフトウェアを使用して作成されたものです。このプロジェクトでは、シミュレーションにも使用されます。
5つの押しボタンは、必要な時間のアラームを設定するための入力として機能します。したがって、すべての押しボタンの一方の端はグランドに接続され、もう一方の端はPORTBピンに接続されます。これらのピンには、ピンが浮かないように内部プルアップ抵抗が使用されます。ブザーは出力として機能し、アラームがトリガーされてPORTSピンに接続されるとビープ音を鳴らします。現在の時刻は、PICがI2Cバスを介してデータを受信するDS3231 RTCモジュールによって常に追跡されるため、RTCモジュールのSCLピンとSDAピンはPICコントローラーのSCLピンとSDAピンに接続されます。 PICのPORTDにはLCDディスプレイが取り付けられており、現在時刻と設定時刻を表示します。 PICでのDS3231RTCモジュールの使用について詳しくは、こちらをご覧ください。
完全な回路はブレッドボード上に構築できます。接続するワイヤは数十本あるので、しばらくお待ちください。接続が正しいことを確認してください。接続が完了すると、ハードウェアのセットアップは次のようになります。
ブレッドボードモジュールと12Vアダプターを使用してモジュールに電力を供給しました。これが私の+ 5V電源電圧のソースです。また、回路をきれいに保つために2つのブレッドボードを使用する必要があります。より堅牢なプロジェクトを作成したい場合は、回路全体をパフォーマンスボードにはんだ付けすることもできます。
目覚まし時計のプログラミング:
この目覚まし時計プロジェクトの完全なPICプログラムは、このページの下部にあります。このプロジェクトには、PICでLCD、I2C、RTCを使用するための3つのライブラリも必要です。ヘッダーファイルを含む完全なコードは、ここのZIPファイルからダウンロードでき、抽出後にMPLABXを使用して開くことができます。以下では、メインのcファイルを小さなスニペットとして説明しています。ヘッダーファイルがどのように機能するかを知りたい場合は、上記のチュートリアルに戻ることができます。
メインプログラムに入る前に、使用したピンをより意味のある名前で定義する必要があります。このようにして、プログラミング中にそれらを簡単に使用できるようになります。プログラムで定義されているピンを以下に示します。
// LCDピンを定義します #defineRS RD2 // LCDのピンをリセットします#defineEN RD3 // LCDのピンを有効にします #defineD4 RD4 // LCDのデータビット0 #define D5 RD5 // LCDのデータビット1 #define D6 RD6 // LCDのデータビット2 #define D7 RD7 // LCDのデータビット3 //定義ボタン #defineMB RB1 //中央のボタン #defineLB RB0 //左ボタン #defineRB RB2 //右ボタン # define UB RB3 //上部ボタン #defineBB RB4 //下部ボタン // Define Buzz #define BUZZ RD1 //ブザーはRD1に接続されています
main 関数内で、入力ピンと出力ピンを宣言することから始めます。私たちのプロジェクトでは、PORTBは入力デバイスであるプッシュボタンに使用されるため、ピンを入力として設定し、PORTDはLCDとブザーに使用されるため、ピンを出力として設定します。また、ピンをフローティングのままにしないでください。I/ Oピンは常にグランドまたは+ 5V電圧に接続する必要があります。私たちのプッシュボタンの場合、ボタンが押されていないときはピンは何にも接続されないので、使用していないときにピンをHighに設定する内部プルアップ抵抗を使用します。これは、以下に示すように制御レジスタを使用して行われます。
TRISD = 0x00; //ポートDピンをLCDインターフェースの出力として作成TRISB = 0xFF; //スイッチは入力ピンとして宣言されていますOPTION_REG = 0b00000000; //スイッチのポートBでプルアップ抵抗を有効にするBUZZ = 0; //ブザーを鳴らします
LCDとI2Cヘッダーファイルがメインプログラムにリンクされているので、簡単な関数を呼び出すことでLCDの初期化を開始できます。I2Cの初期化についても同じことができます。ここでは、RTCモジュールが100kHzで動作するため、100kHzでI2C通信を開始しています。
Lcd_Start(); // LCDモジュールを初期化します I2C_Initialize(100); // 100KHzクロックでI2Cマスターを初期化します
以下の関数は、RTCモジュールの時刻と日付を設定するために使用されます。時刻と日付が設定されたら、この行を削除します。それ以外の場合は、プログラムを開始するたびに、日時が何度も設定されます
//時間と日付が初めて設定され たら、以下の行を削除します。Set_Time_Date(); // RTCモジュールに日時を設定します
プログラムが起動していることを示すために、以下に示すように、プロジェクトの名前とWebサイトの名前を表示する小さな紹介画面を表示します。
// LCDに紹介メッセージを表示します Lcd_Clear(); Lcd_Set_Cursor(1,1); Lcd_Print_String( "目覚まし時計"); Lcd_Set_Cursor(2,1); Lcd_Print_String( "-Circuit Digest"); __delay_ms(1500);
次に、 while ループ内で、RTCモジュールから現在の時刻と日付を読み取る必要があります。これは、以下の関数を呼び出すだけで実行できます。
Update_Current_Date_Time(); // RTCモジュールから現在の日付と時刻を読み取ります
上記の関数を呼び出すと、変数sec、min、hourが現在の値で更新されます。それらをLCD画面 に表示するには、以下のコードを使用してそれらを個々の文字に分割する必要があります。
//をcharに分割して、lcd に表示しますchar sec_0 = sec%10; char sec_1 =(sec / 10); char min_0 = min%10; char min_1 = min / 10; char hour_0 =時間%10; char hour_1 =時間/ 10;
次に、LCD画面で値を更新します。現在の時刻が1行目に表示され、アラームをトリガーする必要がある設定時刻が2行目に表示されます。同じことを行うコードを以下に示します。
//現在の時刻をLCD画面に表示します Lcd_Clear(); Lcd_Set_Cursor(1、1); Lcd_Print_String( "TIME:"); Lcd_Print_Char(hour_1 + '0'); Lcd_Print_Char(hour_0 + '0'); Lcd_Print_Char( ':'); Lcd_Print_Char(min_1 + '0'); Lcd_Print_Char(min_0 + '0'); Lcd_Print_Char( ':'); Lcd_Print_Char(sec_1 + '0'); Lcd_Print_Char(sec_0 + '0'); // LCD画面に日付を表示します Lcd_Set_Cursor(2、1); Lcd_Print_String( "アラーム:"); Lcd_Print_Char(alarm_val + '0'); Lcd_Print_Char(alarm_val + '0'); Lcd_Print_Char( ':'); Lcd_Print_Char(alarm_val + '0 '); Lcd_Print_Char(alarm_val + '0');
これで、時間と設定時刻がLCDに表示され、ユーザーがアラーム時刻を設定しようとしているかどうかを確認する必要があります。これを行うには、ユーザーが中央のボタンを押す必要があるため、中央のボタンが押されているかどうかを確認し、変数を切り替えてアラームセットモードに入ります。同じボタンをもう一度押して値が設定されていることを確認します。その場合は、アラーム設定モードを終了する必要があります。したがって、以下のコード行を使用して、変数 set_alarmの ステータスを変更します。
//中央のボタンを使用して、アラームを設定 する必要があるかどうかを確認しますif(MB == 0 && set_alarm == 0){//中央のボタンが押され、アラームがオンになっていない場合 (!MB); //ボタンが 離される まで待ちますset_alarm = 1; //アラーム値の設定を開始します} if(MB == 0 && set_alarm == 1){//中央のボタンが押され、アラームがオフになっていない場合 (!MB); //ボタンが 離される まで待ちますset_alarm = 0; //アラーム値の設定を停止します}
ユーザーが中央のボタンを押した場合、それは彼がアラーム時間を設定しようとしていることを意味します。この場合、プログラムは上記のコードを使用してアラームセットモードに入ります。アラーム設定モードでは、ユーザーが左または右のボタンを押すと、カーソルを左または右に移動する必要があります。これを行うには、カーソルを配置する必要のある位置の値をインクリメントするだけです。
if(LB == 0){//左ボタンが押された場合 (!LB); //ボタンが 離される まで待つpos--; //次にカーソルを左に移動します} if(RB == 0){//右ボタンが押された場合 (!RB); //ボタンが離されるまで待つ pos ++; //カーソルを右に移動します }
マイクロコントローラまたはマイクロプロセッサでプッシュボタンを使用する場合、取り組むべき一般的な問題が1つあります。この問題は、スイッチバウンスと呼ばれます。つまり、ボタンを押すと、MCU / MCUにノイズの多いパルスが発生し、複数のエントリに対してMCUを偽造する可能性があります。この問題は、スイッチの両端にコンデンサを追加するか、ボタンの押下が検出されるとすぐに遅延機能を使用することで解決できます。このタイプのソリューションは、デバウンスと呼ばれます。ここでは、 while ループを使用して、ボタンが離されるまでプログラムを所定の位置に保持しています。これは最良のデバウンスソリューションではありませんが、私たちにとっては問題なく機能します。
while(!RB);
左右のボタンと同様に、アラーム時間の値を増減するために使用できる上下のボタンもあります。同じことを行うためのコードを以下に示します。設定されたアラーム時間の各文字は、配列のインデックス値によってアドレス指定されていることに注意してください。これは、値を変更する必要がある必要な文字に簡単にアクセスできるためです。
if(UB == 0){//上ボタンが押された場合 (!UB); //ボタンが 離される まで待ちますalarm_val ++; //その特定の文字値を増やします} if(BB == 0){//下のボタンが押された場合 (!UB); //ボタンが 離される まで待ちますalarm_val--; //その特定のchar値を減らします}
アラーム時刻が設定されると、ユーザーは真ん中のボタンをもう一度押します。次に、現在の時刻と設定した時刻の比較を開始できます。現在時刻のすべての文字が設定時刻の文字と等しいかどうかをチェックすることによる比較。値が等しい場合は、 trigger_alarm 変数を設定してアラームをトリガーします。それ以外の場合は、等しくなるまで比較します。
//アラームが設定されている場合設定値が現在の値と等しいかどうかを確認します if(set_alarm == 0 && alarm_val == hour_1 && alarm_val == hour_0 && alarm_val == min_1 && alarm_val == min_0) trigger_alarm = 1; //値が一致する場合はトリガーをオンにします
アラームが設定されている場合は、ブザーを鳴らしてユーザーにアラームを警告する必要があります。これは、以下に示すように、定期的にブザーを切り替えるだけで実行できます。
if(trigger_alarm){//アラームがトリガーされた場合 //ブザーを鳴らします BUZZ = 1; __delay_ms(500); BUZZ = 0; __delay_ms(500); }
シミュレーション:
このプログラムは、プロテウスソフトウェアを使用してシミュレートすることもできます。上記の回路を再作成し、16進ファイルをPICにロードするだけです。このプロジェクトの16進コードは、ここにリンクされているZIPファイルにあります。シミュレーション中に撮影したスクリーンショットを以下に示します。
シミュレーションは、プロジェクトに新しい機能を追加しようとしているときに非常に役立ちます。I2Cデバッガモジュールを使用して、I2Cバスを介して送受信されるデータを確認することもできます。ボタンを押して、アラーム時刻を設定してみてください。設定時刻が現在時刻と同じになるとブザーが鳴ります。
PIC16F877Aを使用したデジタル目覚まし時計の動作:
ブレッドボード上に回路を構築し、ダウンロードリンクからコードを取得し、MplabXおよびXC8コンパイラを使用してコンパイルします。ここに記載されているZIPファイルからコードをダウンロードした場合は、ヘッダーファイルが既に添付されているため、問題なくコンパイルできます。
コンパイル後、PicKit3プログラマーを使用してプログラムをハードウェアにアップロードします。ピキットプログラマをPICICに接続するための接続も回路図に示されています。プログラムがアップロードされると、紹介画面が表示され、表示されている時刻が表示されます。次に、プッシュボタンを使用してアラーム時刻を設定できます。電源を入れたときのハードウェアのセットアップは次のようになります。
アラーム時刻が現在の時刻と一致すると、ブザーがビープ音を鳴らしてユーザーに警告します。完全な作業は、以下のビデオで見つけることができます。このプロジェクトには、構築するための多数のオプションがあります。RTCモジュールは任意の日時を追跡できるため、必要な任意の日時にスケジュールされたタスクを実行できます。ファンやライトなどのACアプライアンスを接続し、必要に応じてオンまたはオフにするようにスケジュールすることもできます。このプロジェクトに基づいて構築できるものはまだまだたくさんあります。このプロジェクトのアップグレードとしてどのようなアイデアが思い浮かびますか。ご連絡をお待ちしております。
プロジェクトを理解し、プロセスから何か役立つことを学んだことを願っています。このプロジェクトに疑問がある場合は、コメントセクションを使用して投稿するか、フォーラムを使用して技術的なヘルプを入手してください。
ヘッダーファイルを含む完全なPICコードはここにあります