チーム1958

課題名

電子ミニピアノ

研究者名

2-14-17 Riku Kambara
2-14-34 Motonami Nishiyama


使用した機器

・PSoC              1個
・PSoC基盤            1個
・MiniProg             1個
・スピーカー            1個
・16個ボタン基盤(KEYPAD-16X16) 1個

モジュール等[#z06ef467]

psoc_pianopiano.png

ソースコード(main.c)[#v525b1bc]

#include <m8c.h>
#include "PSoCAPI.h"

int PW=125,i=1,j=0;
int SILENT=0, D=229, L=204, M=182, F=172, S=153, R=136, C=121, DD=115;
int LD=462,LL=411,LM=364,LF=343,LS=306,LR=273,LC=243,LDD=229;
int HD=115,HL=102,HM=91,HF=86,HS=77,HR=68,HC=61,HDD=57;
static const keypad_LUT[256] =
 {/*   0     1     2     3     4     5     6     7      8     9     A     B     C     D     E     F  */
  /*0*/0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
  /*1*/0x20,  ' ',  ' ', 0x20,  ' ', 0x20, 0x20, 0x20,  ' ', 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
  /*2*/0x20,  'L',  'M', 0x20,  'H', 0x20, 0x20, 0x20,  'A', 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 
  /*3*/0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 
  /*4*/0x20,  '4',  '5', 0x20,  '6', 0x20, 0x20, 0x20,  '7', 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 
  /*5*/0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 
  /*6*/0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 
  /*7*/0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 
  /*8*/0x20,  '0',  '1', 0x20,  '2', 0x20, 0x20, 0x20,  '3', 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 
  /*9*/0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 
  /*A*/0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 
  /*B*/0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 
  /*C*/0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 
  /*D*/0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 
  /*E*/0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 
  /*F*/0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
 };
 
 BYTE rows,cols;
 unsigned char key[2] = {0x20,0};
 unsigned char keypad_scan(void);
 void InitModules(void);
 void GPIOInterrupt(void);
 
 void main(void)
 {  
 InitModules();
 M8C_EnableGInt;
 while(1)
 {
   key[0] = keypad_scan();
    if(key[0] != 0x20){

       LCD_1_Position(1,7);      
         switch (key[0]){
         case 'L':
          i=0;
          LCD_1_PrCString("Low   ");
          break;
          
         case 'M':
          i=1;
          LCD_1_PrCString("Middle");
          break;
          
         case 'H':
         i=2;
         LCD_1_PrCString("High  ");
         break;
         
         
         }
         
         LCD_1_Position(1,14);
         switch (key[0]){
         case 'A':
         if(j==0) j=1;
         else if(j==1) j=0;
         if(j==1) LCD_1_PrCString("ON");
         else if(j==0) LCD_1_PrCString("  ");
         break;
         }
         
         LCD_1_Position(0,6);   
         if(i==0){
         switch(key[0]){
         case '0':
         if(j==1){
         PWM16_1_WritePeriod(LD-24);
         LCD_1_PrCString("C#");
         }
         else{
         PWM16_1_WritePeriod(LD);
         LCD_1_PrCString("C ");
         }
         break;           
         case '1':
         if(j==1){
         PWM16_1_WritePeriod(LL-22);
         LCD_1_PrCString("D#");
         }
         else{
         PWM16_1_WritePeriod(LL);
         LCD_1_PrCString("D ");
         }
         break;           
         case '2':         
         PWM16_1_WritePeriod(LM);
         LCD_1_PrCString("E ");
         break;       
         case '3':
         if(j==1){
         PWM16_1_WritePeriod(LF-20);
         LCD_1_PrCString("F#");
         }
         else{
         PWM16_1_WritePeriod(LF);
         LCD_1_PrCString("F");
         }
         break;           
         case '4': 
         if(j==1){
         PWM16_1_WritePeriod(LS-16);
         LCD_1_PrCString("G#");
         }
         else{
         PWM16_1_WritePeriod(LS);
         LCD_1_PrCString("G ");
         }
         break;           
         case '5':
         if(j==1){
         PWM16_1_WritePeriod(LR-14);
         LCD_1_PrCString("A#");
         }
         else{
         PWM16_1_WritePeriod(LR);
         LCD_1_PrCString("A ");
         }
         break;           
         case '6':
         PWM16_1_WritePeriod(LC);
         LCD_1_PrCString("B ");
         break;           
         case '7':
         if(j==1){
         PWM16_1_WritePeriod(LDD-12);
         LCD_1_PrCString("CC#");
         }
         else{
         PWM16_1_WritePeriod(LDD);
         LCD_1_PrCString("CC ");
         }
         }
         
         }else if(i==1){
         switch(key[0]){
         case '0':  
         if(j==1)  {
         PWM16_1_WritePeriod(D-12);
         LCD_1_PrCString("C#");
         }
         else {
         PWM16_1_WritePeriod(D);
         LCD_1_PrCString("C ");
         }
         break;           
         case '1':
         if(j==1){
         PWM16_1_WritePeriod(L-11);
         LCD_1_PrCString("D#");
         }
         else {
         PWM16_1_WritePeriod(L);
         LCD_1_PrCString("D ");
         }
         break;           
         case '2':
         PWM16_1_WritePeriod(M);
         LCD_1_PrCString("E ");
         break;       
         case '3':
         if(j==1){
         PWM16_1_WritePeriod(F-10);
         LCD_1_PrCString("F#");
         }
         else{
         PWM16_1_WritePeriod(F);
         LCD_1_PrCString("F ");
         }
         break;           
         case '4':
         if(j==1) { 
         PWM16_1_WritePeriod(S-8);
         LCD_1_PrCString("G#");
         }
         else {
         PWM16_1_WritePeriod(S);
         LCD_1_PrCString("G ");
         }
         break;           
         case '5':
         if(j==1){
         PWM16_1_WritePeriod(R-7);
         LCD_1_PrCString("A#");
         }
         else{ 
         PWM16_1_WritePeriod(R);
         LCD_1_PrCString("A ");
         }
         break;           
         case '6':
         PWM16_1_WritePeriod(C);
         LCD_1_PrCString("B ");
         break;           
         case '7':
         if(j==1){
         PWM16_1_WritePeriod(DD-6);
         LCD_1_PrCString("CC#");
         }
         else {
         PWM16_1_WritePeriod(DD);
         LCD_1_PrCString("CC ");
         }
         }
         
         
         }else if(i==2){
         switch(key[0]){
         case '0':  
         if(j==1){
         PWM16_1_WritePeriod(HD-6);
         LCD_1_PrCString("C#");
         }
         else{
         PWM16_1_WritePeriod(HD);
         LCD_1_PrCString("C ");
         }
         break;           
         case '1': 
         if(j==1){
         PWM16_1_WritePeriod(HL-5);
         LCD_1_PrCString("D#");
         }
         else{
         PWM16_1_WritePeriod(HL);
         LCD_1_PrCString("D ");
         }
         break;           
         case '2':         
         PWM16_1_WritePeriod(HM);
         LCD_1_PrCString("E ");
         break;       
         case '3': 
         if(j==1){
         PWM16_1_WritePeriod(HF-5);
         LCD_1_PrCString("F#");
         }
         else{
         PWM16_1_WritePeriod(HF);
         LCD_1_PrCString("F ");
         }
         break;           
         case '4': 
         if(j==1){
         PWM16_1_WritePeriod(HS-4);
         LCD_1_PrCString("G#");
         }
         else{
         PWM16_1_WritePeriod(HS);
         LCD_1_PrCString("G ");
         }
         break;           
         case '5':
         if(j==1){
         PWM16_1_WritePeriod(HR-3);
         LCD_1_PrCString("A#");
         }
         else{
         PWM16_1_WritePeriod(HR);
         LCD_1_PrCString("A ");
         }
         break;           
         case '6':
         PWM16_1_WritePeriod(HC);
         LCD_1_PrCString("B ");
         break;           
         case '7':
         if(j==1){
         PWM16_1_WritePeriod(HDD-3);
         LCD_1_PrCString("CC#");
         }
         else{
         PWM16_1_WritePeriod(HDD);
         LCD_1_PrCString("CC ");
         }
         }
        
         }
         
         
         
 }else{
      PWM16_1_WritePeriod(SILENT);
      LCD_1_Position(0,6); 
      LCD_1_PrCString("   ");
       }
 }
 }
 
 void InitModules(void)
 {
 PWM16_1_Start();
 LCD_1_Start();
 LCD_1_Position(0,0);
 LCD_1_PrCString("Scale:");
 LCD_1_Position(1,0);
 LCD_1_PrCString("Octave:MIddle");      
 INT_MSK0|=0x20;       
 PRT0DR|=0xF0;
 }
 
 
 unsigned char keypad_scan(void)
 {
 BYTE key_result;
 
 PRT0DR = 0x0F;
 
 rows = PRT0DR;
 
 PRT0DR = 0xF0;
 
 cols = PRT0DR;
 
 key_result = rows & cols;
     
 return(keypad_LUT[key_result]);
 }
 
 
 #pragma interrupt_handler GPIOInterrupt
 void GPIOInterrupt(void)
 {
 INT_MSK0&=~0x20;    
 }

考察

今回は、チーム1827を参考に電子ピアノを作成した。
仕様としては、16個ボタン基盤を用いて
・ドレミを鳴らすスイッチ(8個)
・オクターブ切り替えスイッチ(3個)
・#音切り替えスイッチ(1個)
上記のように割り当てている。参考元の作品はスイッチが5か所余っていたので、そのうちの1つを#音のON/OFFの切り替えにあてた。また、#音がONかOFFかをLCDに「 」または「ON」で視覚的にわかるように工夫している。
1オクターブ下がるとその周波数は1/2倍になり、上がると2倍になることを利用し、3オクターブ分の#音を実装している。
音の発生を外部入力を利用し発生させ、割り込みやポーリングなどは使用せずすべてmain.cの記述で実装した。
ボタンはまだ4か所余っているので、本物のピアノに備わっている、鳴らした音を響かせる足のペダルなども実装できるのではないかと考えた。

  • 最終更新:2019-12-03 17:51:32

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

認証パスワード