チーム1351

課題名

加速度センサーによる音程と速度の変化

研究者名

青木 修平
赤柴 剛史

概要

加速度センサーを傾けることで、流している曲の音程と速度をずらして演奏させる。
IMG_0101.JPG



使用部品

PSoC
ジャンパー線
加速度センサー
スピーカー

ソースリスト


#include <m8c.h> // part specific constants and macros
#include "PSoCAPI.h" // PSoC API definitions for all User Modules
#pragma interrupt_handler myISR

long int speed = 600; //演奏速度を管理する
int bias = 0; //音程をずらさせる
int gakuhu[] = {10,12,7,4,9,11,9,8,10,8,7}; //gakuhu[0]は音符の数.-1が無音,0から12が4cから5cに対応
int timing[] = {120,2,2,2,1,1,1,1,1,1,20}; //timing[0]はbpm.16分を何度繰り返すかで長さを決める

void main(void)
{
  // Insert your main routine code here.
   int adc1_data,adc2_data;            //adcの値を入れる
   
   M8C_EnableGInt;                     //割り込みを許可
   Timer16_Start();                    //Timer16を起動
   Timer16_EnableInt();                //Timer16による割り込みを許可
   PWM16_Start();                        //PWM起動.このモジュールを使用して音を出す
   LCD_Start();                        //LCD起動
   PGA_1_Start(PGA_1_HIGHPOWER);        //PGA起動
   PGA_2_Start(PGA_2_HIGHPOWER);        //PGA起動
   DUALADC_Start(DUALADC_HIGHPOWER);    //ADC起動
   DUALADC_GetSamples(0);                //ADC逐一動作
   
   for(;;){    //メインのループ

      while(DUALADC_fIsDataAvailable() == 0);        //AD変換終了待ち
       adc1_data = DUALADC_iGetData1();            //AD変換値を取得.3軸センサのx
       adc2_data = DUALADC_iGetData2ClearFlag();    //AD変換値を取得.3軸センサのy
       bias = adc1_data/100;                        //3軸センサの値をもとに音程を変化
       speed = 600+adc2_data/10;                    //3軸センサの値をもとに速度を変化
       
       //パラメータの表示
       LCD_Position(0,0);
       LCD_PrCString("bias:");
       LCD_PrHexInt(bias);
       LCD_Position(1,0);
       LCD_PrCString("speed:");
       LCD_PrHexInt(speed);
   }
   
}
void setOnpu(int count){
  //4cから5cに対応
   static WORD onpu[] = {229,217,204,193,182,172,162,153,145,136,129,121,115};
   //-1は無音
   if(count == -1){
       PWM16_WritePeriod(0);
       PWM16_WritePulseWidth(0);
   }else{
       PWM16_WritePeriod(onpu[count] + bias);
       PWM16_WritePulseWidth(onpu[count]/2 + bias/2);
   }
}
void myISR(void){
  static long int i = 0;        //時間を数える変数
   static int count = 0;        //譜面(gakuhu[])を数える変数
   static int tim_count = 0;    //音を伸ばす長さ(timing[count]の数値)を数える変数
   int max = gakuhu[0];        //譜面の長さ
   int bpm = timing[0];        //曲の速さ
   
   if(i<speed/(bpm*4)){    //bpmの速さにおいて16分ごとに音を変えるチャンスを得る
       i++;
   }else{
       setOnpu(gakuhu[count+1]);            //音を変える
       if(tim_count >= timing[count+1]){    //音の長さを処理する
           count = (count+1)%max;
           tim_count = -1;
       }
       tim_count++;    
       i=0;
   }
}
  

考察


 最初の構成はTRIADC、PWM16、Timer8であった。Timer16でないのはブロックが足りなかったからである。このTimer8の割り込み頻度を1ms毎に設定したところ、メインのループが実行されなかった。これは割り込み頻度が高いから常に割り込みが発生しているという現象が発生したと思われる。Timer16を使用し割り込みを発生させるためにTRIADCをDUALADCに変更しTimer16を配置した。これを使用し割り込みを100ms毎に発生させることによってこの問題を解決した。割り込みの頻度に注意が必要であることがわかった。
 現状のモジュールではマシンがフリーズしてしまうことがある。これは恐らくAD変換終了フラグ関連の割り込みとタイマ割り込みとの多重割り込みの処理が原因だと思われる。恐らく多重割り込みが許可されていないのでそれを許可すればフリーズしないのではないかと思われる。

  • 最終更新:2013-11-19 16:03:11

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

認証パスワード