チーム2057

課題名

キッチンタイマー

研究者名

Motoki Sugita
Kazuki Shio

概要

キーボード入力で指定された秒数をはかることができるタイマー。
キーボードの、a,s,d,f,g,hで時間を10秒、30秒、60秒、90秒、120秒、180秒から選べる。
キーボードのlで一時停止、再開ができる。
LCDにリアルタイムで秒数が表示される。終了したら音が鳴る。

timer_pwm_2のクローンを原型とし、timer16などのモジュールを追加して割り込み処理ができるようにした。
細かいソースコードやアルゴリズムは主にチーム2015、チーム2049のものを参考にした。

使用器具

PSoC 基板(1つ)
PSoC MiniProg(1つ)
スピーカー(1つ)
ジャンパ線(2つ)

配線・パラメータ・ソースコード

画像
Chip_2057.pngGlobal_2057.png
Counter8_2057.pngPWM16_2057.png
UART_2057.pngTimer16_2057.png
コード
#include <m8c.h> // part specific constants and macros
#include <stdlib.h>
#include "PSoCAPI.h" // PSoC API definitions for all User Modules
#pragma interrupt_handler myISR
int PW=125; // Pulse Width
int SILENT=0, D=229, L=204, M=182, F=172, S=153, R=136, C=121, DD=115; //Scale
int state = -1;
int TC = 0;
int k = -1;
char p[10];

void myISR(void) {
  TC += 1;
   
   if (state == 1) {
       if (TC%6 == 0 && k != 0)
           k--;
       if (k < 10) {
           p[0] = k + '0';
           p[1] = 0;
           LCD_Start();
           LCD_PrCString("0:0");
           LCD_PrString(p);
       }
       else if (10 <= k && k < 60) {
           p[0] = k / 10 + '0';
           p[1] = k % 10 + '0';
           p[2] = 0;
           LCD_Start();
           LCD_PrCString("0:");
           LCD_PrString(p);
       }
       else if (60 <= k && k < 70) {
           p[0] = (k - 60) % 10 + '0';
           p[1] = 0;
           LCD_Start();
           LCD_PrCString("1:0");
           LCD_PrString(p);
       }
       else if (70 <= k && k < 120) {
           p[0] = (k - 60) % 100 / 10 + '0';
           p[1] = (k - 60) % 100 % 10 + '0';
           p[2] = 0;
           LCD_Start();
           LCD_PrCString("1:");
           LCD_PrString(p);
       }
       else if (k <= 120 && k < 130) {
           p[0] = (k - 120) % 100 % 10 + '0';
           p[1] = 0;
           LCD_Start();
           LCD_PrCString("2:0");
           LCD_PrString(p);
       }
       else if (130 <= k && k < 180) {
           p[0] = (k - 120) % 100 / 10 + '0';
           p[1] = (k - 120) % 100 % 10 + '0';
           p[2] = 0;
           LCD_Start();
           LCD_PrCString("2:");
           LCD_PrString(p);
       }
       else if (k <= 180 && k < 190) {
           p[0] = (k - 180) % 100 % 10 + '0';
           p[1] = 0;
           LCD_Start();
           LCD_PrCString("3:0");
           LCD_PrString(p);
       }
       if (k == 0) {
           PWM16_1_WritePeriod(DD);
           UART_CPutString("時間です。\n");
           state = 2;
       }
   }
}

void main(void)
{
  char * strPtr; // Parameter pointer
   UART_CmdReset(); // Initialize receiver/cmd buffer
   UART_IntCntl(UART_ENABLE_RX_INT); // Enable RX interrupts
   Counter8_WritePeriod(155); // Set up baud rate generator
   Counter8_WriteCompareValue(77);
   Counter8_Start(); // Turn on baud rate generator
   UART_Start(UART_PARITY_NONE); // Enable UART
   M8C_EnableGInt ; // Turn on interrupts
   PWM16_1_Start();
   Timer16_1_EnableInt();
   Timer16_1_Start();
   PWM16_1_WritePulseWidth(PW);
   
   UART_CPutString("\r\nPSoC timer03 \r\n");
   UART_CPutString("選択可能時間・コマンド \r\n");
   UART_CPutString("\r\na:10秒");
   UART_CPutString("\r\ns:30秒");
   UART_CPutString("\r\nd:60秒");
   UART_CPutString("\r\nf:90秒");
   UART_CPutString("\r\ng:120秒");
   UART_CPutString("\r\nh:180秒");
   UART_CPutString("\r\nl:一時停止,再開,タイマー終了");

  while(1) {
       if(UART_bCmdCheck()) { // Wait for command
           if(strPtr = UART_szGetParam()) { // More than delimiter?
               UART_CPutString("\r\n");
               UART_PutString(strPtr); // Print out command
               UART_CPutString("\n"); 
               if (*strPtr=='a'){
                   LCD_Start();
                   TC = 0;
                   state = 1;
                   k = 10;
                   UART_CPutString("10秒で計測を開始します。\n");
               }
               else if (*strPtr=='s'){
                   LCD_Start();
                   TC = 0;
                   state = 1;
                   k = 30;
                   UART_CPutString("30秒で計測を開始します。\n");
               }
               else if (*strPtr=='d'){
                   LCD_Start();
                   TC = 0;
                   state = 1;
                   k = 60;
                   UART_CPutString("60秒で計測を開始します。\n");
               }
               else if (*strPtr=='f'){
                   LCD_Start();
                   TC = 0;
                   state = 1;
                   k = 90;
                   UART_CPutString("90秒で計測を開始します。\n");
               }
               else if (*strPtr=='g'){
                   LCD_Start();
                   TC = 0;
                   state = 1;
                   k = 120;
                   UART_CPutString("120秒で計測を開始します。\n");
               }
               else if (*strPtr=='h'){
                   LCD_Start();
                   TC = 0;
                   state = 1;
                   k = 180;
                   UART_CPutString("180秒で計測を開始します。\n");
               }
               else if (*strPtr=='l' && state != -1){
                   if (state == 1) {
                       state = 0;
                       UART_CPutString("一時停止\n");
                   }
                   else if (state == 0) {
                       state = 1;
                       UART_CPutString("再開\n");
                   }
                   else if (state == 2) {
                       UART_CPutString("終了\n");
                   }
                   PWM16_1_WritePeriod(SILENT);
               }
           }
           UART_CmdReset(); // Reset command buffer
       } 
   }
}

考察

・工夫した点
LCDになるべくリアルタイムで時間が表示されるよう、割り込み処理を使って設計した。
端末上に選択肢を表示して使用する側がわかりやすいようにした。
計測時間はコードを少し書き換えるだけで簡単に変更ができるようにした。
計測途中でも別の計測に簡単に移れるようにした。
計測途中で一時停止、再開ができるようにした。

・改善点
キーボードの入力をもう少し細かいパターンで見れれば機能を拡張できる。
具体的には、選択肢ではなく秒単位で入力ができればもっと便利になると思った。

  • 最終更新:2020-11-24 16:21:41

このWIKIを編集するにはパスワード入力が必要です

認証パスワード