チーム1648

課題名

Piano×2

研究者名

Tsuneo Otsuka
Hiro Okubo

概要

timer_pwm2とpwm_uart_2を元に構成した。

timer_pwm2はタイマー割込みを使用してPWMで音楽を演奏するというもので、
pwm_uart_2はシリアルポート経由の外部コマンドでPWM音源の音階発生させるというものであった。

主に、pwm_uart_2を元に改良した本プログラムの仕様は、シリアルポート経由の外部コマンドで入力された、音階を連続的にかつ2つのスピーカーを用いて発生させるというものである。

コマンドは、a,s,d,f,g,h,j,k とlの9文字を使用し,それぞれがド,レ,ミ,ファ,ソ,ラ,シ,ドと無音に対応する。
さらに w,e,t,y,u,i,o,p,8,9,- はド♯,レ♯,ファ♯,ソ♯,ラ♯,レ,ミ,ファ,ド♯,レ♯,ファ♯に対応する

コマンドを入力した後にエンターを入力すれば、スペースキーを挟んで2つずつ入力されたコマンドに指定されている音階が一定の周期でそれぞれ2つのスピーカーから鳴る。

具体的に説明すれば、「as d gl」と入力し最後にエンターを入力すれば、
一方のスピーカーからド、もう一方からレ、次に一方のスピーカーからミ、もう一方からは何も鳴らない、次に一方のスピーカーからソ、もう一方は何も鳴らない、というようになる。
この例からわかるように、一方のスピーカーからしか音を出したくなければ、コマンドを1つ入力したのちにスペースキーを挟むか、無音のコマンドの「l」を使えばよい。

使用機材

PSoC評価基板
CY3210 EVAL1等(Miniprog書き込み器,29466デバイス, USB巻き取り式延長ケーブル付)
ジャンパ線×2
スピーカー×2
USBシリアル変換ケーブル(PC-PSoC間通信)

ソースコード


#include <m8c.h> // part specific constants and macros
#include "PSoCAPI.h" // PSoC API definitions for all User Modules
#pragma interrupt_handler myISR
int PW=125;
int SILENT=0,D=229,L=204,M=182,F=172,S=153,R=136,C=121,DD=115,LL=102,MM=91,FF=86;
int Ds=217,Ls=193,Fs=162,Ss=145,Rs=129,DDs=108,LLs=96,FFs=81;//#
int TC=0;
char *strPtr; //Parameter pointer

void myISR(void){
   TC+=1;
   if(TC%2==0){
       if(strPtr=UART_szGetParam()){
           UART_CPutString("Found valid command\r\nCommand=>");
           UART_PutString(strPtr);
           UART_CPutString("<\r\nParamaters:\r\n");
               
           if(*strPtr=='a')
               PWM16_1_WritePeriod(D);
           else if(*strPtr=='w')
               PWM16_1_WritePeriod(Ds);
           else if(*strPtr=='s')
               PWM16_1_WritePeriod(L);
           else if(*strPtr=='e')
               PWM16_1_WritePeriod(Ls);
           else if(*strPtr=='d')
               PWM16_1_WritePeriod(M);
           else if(*strPtr=='f')
               PWM16_1_WritePeriod(F);
           else if(*strPtr=='t')
               PWM16_1_WritePeriod(Fs);
           else if(*strPtr=='g')
               PWM16_1_WritePeriod(S);
           else if(*strPtr=='y')
               PWM16_1_WritePeriod(Ss);
           else if(*strPtr=='h')
               PWM16_1_WritePeriod(R);
           else if(*strPtr=='u')
               PWM16_1_WritePeriod(Rs);
           else if(*strPtr=='j')
               PWM16_1_WritePeriod(C);
           else if(*strPtr=='k')
               PWM16_1_WritePeriod(DD);
           else if(*strPtr=='8')
               PWM16_1_WritePeriod(DDs);
           else if(*strPtr=='i')
               PWM16_1_WritePeriod(LL);
           else if(*strPtr=='9')
               PWM16_1_WritePeriod(LLs);
           else if(*strPtr=='o')
               PWM16_1_WritePeriod(MM);
           else if(*strPtr=='p')
               PWM16_1_WritePeriod(FF);
           else if(*strPtr=='-')
               PWM16_1_WritePeriod(FFs);
           else if(*strPtr=='l')
               PWM16_1_WritePeriod(SILENT);
               
           if(*(strPtr+1)=='a')
               PWM16_2_WritePeriod(D);
           else if(*(strPtr+1)=='w')
               PWM16_2_WritePeriod(Ds);
           else if(*(strPtr+1)=='s')
               PWM16_2_WritePeriod(L);
           else if(*(strPtr+1)=='e')
               PWM16_2_WritePeriod(Ls);
           else if(*(strPtr+1)=='d')
               PWM16_2_WritePeriod(M);
           else if(*(strPtr+1)=='f')
               PWM16_2_WritePeriod(F);
           else if(*(strPtr+1)=='t')
               PWM16_2_WritePeriod(Fs);
           else if(*(strPtr+1)=='g')
               PWM16_2_WritePeriod(S);
           else if(*(strPtr+1)=='y')
               PWM16_2_WritePeriod(Ss);
           else if(*(strPtr+1)=='h')
               PWM16_2_WritePeriod(R);
           else if(*(strPtr+1)=='u')
               PWM16_2_WritePeriod(Rs);
           else if(*(strPtr+1)=='j')
               PWM16_2_WritePeriod(C);
           else if(*(strPtr+1)=='k')
               PWM16_2_WritePeriod(DD);
           else if(*(strPtr+1)=='8')
               PWM16_2_WritePeriod(DDs);
           else if(*(strPtr+1)=='i')
               PWM16_2_WritePeriod(LL);
           else if(*(strPtr+1)=='9')
               PWM16_2_WritePeriod(LLs);
           else if(*(strPtr+1)=='o')
               PWM16_2_WritePeriod(MM);
           else if(*(strPtr+1)=='p')
               PWM16_2_WritePeriod(FF);
           else if(*(strPtr+1)=='-')
               PWM16_2_WritePeriod(FFs);
           else if(*(strPtr+1)=='l')
               PWM16_2_WritePeriod(SILENT);
       }
       else{//end of buffer
           PWM16_1_WritePeriod(SILENT);
           PWM16_2_WritePeriod(SILENT);
           UART_CmdReset();
           Timer16_1_Stop();
       }
   }
}

void main(void)
{
  // M8C_EnableGInt ; // Uncomment this line to enable Global Interrupts
   // Insert your main routine code here.
   
   UART_CmdReset();
   UART_IntCntl(UART_ENABLE_RX_INT);
   
   Counter8_WritePeriod(155);
   Counter8_WriteCompareValue(77);
   Counter8_Start();
   
   UART_Start(UART_PARITY_NONE);
   
   M8C_EnableGInt;
   
   PWM16_1_Start();
   PWM16_2_Start();
   Timer16_1_EnableInt();
   
   UART_CPutString("\r\nWelcome to PSoC UART test program.V1.1\r\n");
   
   while(1){
       if(UART_bCmdCheck()){
           Timer16_1_Start();
       }
   }
}


考察

スピーカーを2つにして、それぞれから別々な音を出すためにはPWMが2つ必要となる。
実習で使っていた27443デバイスでは処理能力が足りないため、性能の高い29466デバイスを使用した。

工夫した点は主に2つである。
1つは、入力文字の区切りごとの初めの1文字だけを読み込んでいたラボ「pwm_yart_2」を改良して、
区切りごとの初めの2文字までを読み込めるようにしたことである。1文字目はスピーカー1から、2文字目は
(あれば)スピーカー2からの音に対応する。
もう1つは、いったん演奏が終わるとTimer16を停止させることで、基盤がキーボードからの入力待ち状態に
移行する事である。こうすることで次回以降の入力も、エンターキーを押すことで演奏を始められるようになる。

さらなる改造案としては、
・出力できる音域の幅を広げる
・スピーカーを増やす
・より短い音を演奏できるようにする
などが考えられる。3つ目に関しては、演奏前にユーザーに入力させて自由に変更可能にするのがよいだろう。

また、今回はキーボードからの入力だったが、この入力を何かしらのセンサーを使って行うというのも面白いかもしれない
たとえば、基盤の傾き方で出る音が変わる等。ただ、正確な演奏には向かないだろう。

  • 最終更新:2016-10-18 15:49:32

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

認証パスワード