チーム1351
課題名
加速度センサーによる音程と速度の変化
研究者名
青木 修平
赤柴 剛史
概要
加速度センサーを傾けることで、流している曲の音程と速度をずらして演奏させる。
使用部品
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