チーム1718
課題名
距離センサによる任意音階発生装置
研究者名
Yokota Raimu
Yukawa Kota
概要
距離センサで物体との距離によって音階を発生させる。
スイッチを押すと音階がでる。
スイッチを押している間LCDには出力されている音階の種類が表示される。
また、LCDには常時物体との距離を表している。
そして、Processingによって距離に応じて出力される音階の種類が確認できる。
使用した機器
・ジャンパ線
・PSoC基盤
・MiniProg
・ストレート通信ケーブル
・スピーカー
・距離センサ
モジュールの配置
ソースコード
PSoC
#include <m8c.h> // part specific constants and macros
#include "PSoCAPI.h" // PSoC API definitions for all User Modules
#include<stdlib.h>
int PW=125; // Pulse Width
int SILENT=0, D=229, L=204, M=182, F=172, S=153, R=136, C=121, DD=115;
#define SW 0b00010000
void main(void)
{
// M8C_EnableGInt ; // Uncomment this line to enable Global Interrupts // Insert your main routine code here. char buff[10]; int i; unsigned int adc_data; PGA_Start(PGA_HIGHPOWER); LCD_Start(); LCD_InitBG(LCD_SOLID_BG); M8C_EnableGInt; ADCINC_Start(ADCINC_HIGHPOWER); ADCINC_GetSamples(0); Counter8_WritePeriod(155); Counter8_WriteCompareValue(77); Counter8_Start(); UART_CmdReset(); UART_Start(UART_PARITY_NONE); UART_CPutString("\r\nUART start\r\n");
PWM16_1_Start(); PWM16_1_Stop(); PRT1DR &= (~SW); while(1){ while(ADCINC_fIsDataAvailable() == 0); adc_data = ADCINC_wClearFlagGetData(); if(PRT1DR & SW){ PWM16_1_Start(); LCD_Start(); // 音発生 PWM16_1_WritePulseWidth(PW); if(adc_data <= 1024){ UART_PutChar('D'); PWM16_1_WritePeriod(D); LCD_PrCString("D"); LCD_Position(1,0); LCD_PrCString("length:"); LCD_DrawBG(1,7,16,(adc_data/40)-20); } else if(adc_data > 1024 && adc_data <= 1280){ UART_PutChar('L'); PWM16_1_WritePeriod(L); LCD_PrCString("L"); LCD_Position(1,0); LCD_PrCString("length:"); LCD_DrawBG(1,7,16,(adc_data/40)-20); } else if(adc_data > 1280 && adc_data <= 1536){ UART_PutChar('M'); PWM16_1_WritePeriod(M); LCD_PrCString("M"); LCD_Position(1,0); LCD_PrCString("length:"); LCD_DrawBG(1,7,16,(adc_data/40)-20); } else if(adc_data > 1536 && adc_data <= 1792){ UART_PutChar('F'); PWM16_1_WritePeriod(F); LCD_PrCString("F"); LCD_Position(1,0); LCD_PrCString("length:"); LCD_DrawBG(1,7,16,(adc_data/40)-20); } else if(adc_data > 1792 && adc_data <= 2048){ UART_PutChar('S'); PWM16_1_WritePeriod(S); LCD_PrCString("S"); LCD_Position(1,0); LCD_PrCString("length:"); LCD_DrawBG(1,7,16,(adc_data/40)-20); } else if(adc_data > 2048 && adc_data <= 2304){ UART_PutChar('R'); PWM16_1_WritePeriod(R); LCD_PrCString("R"); LCD_Position(1,0); LCD_PrCString("length:"); LCD_DrawBG(1,7,16,(adc_data/40)-20); } else if(adc_data > 2304 && adc_data <= 2560){ UART_PutChar('C'); PWM16_1_WritePeriod(C); LCD_PrCString("C"); LCD_Position(1,0); LCD_PrCString("length:"); LCD_DrawBG(1,7,16,(adc_data/40)-20); } else if(adc_data > 2560 && adc_data <= 2816){ UART_PutChar('D'); PWM16_1_WritePeriod(DD); LCD_PrCString("DD"); LCD_Position(1,0); LCD_PrCString("length:"); LCD_DrawBG(1,7,16,(adc_data/40)-20); } PRT1DR &= (~SW); }else{ PWM16_1_Stop(); LCD_Start(); LCD_PrCString("PUSH SWITCH"); LCD_Position(1,0); LCD_PrCString("length:"); LCD_DrawBG(1,7,16,(adc_data/40)-20); PRT1DR &= (~SW); // if(adc_data <= 1024){ UART_PutChar('D'); } else if(adc_data > 1024 && adc_data <= 1280){ UART_PutChar('L'); } else if(adc_data > 1280 && adc_data <= 1536){ UART_PutChar('M'); } else if(adc_data > 1536 && adc_data <= 1792){ UART_PutChar('F'); } else if(adc_data > 1792 && adc_data <= 2048){ UART_PutChar('S'); } else if(adc_data > 2048 && adc_data <= 2304){ UART_PutChar('R'); } else if(adc_data > 2304 && adc_data <= 2560){ UART_PutChar('C'); } else if(adc_data > 2560 && adc_data <= 2816){ UART_PutChar('D'); } // } /*if(adc_data < 1479){//LEDがついていないときLED OFFとLCDに表示させる UART_PutChar('F'); }else{//LEDがついている間LCDにLED ONと表示させる UART_PutChar('T'); }*/ }}
Processing
import processing.serial.*;
Serial myPort;
boolean flg_d = false;
boolean flg_l = false;
boolean flg_m = false;
boolean flg_f = false;
boolean flg_s = false;
boolean flg_r = false;
boolean flg_c = false;
final int width=600;
final int height=600;
int dataCountT=0;
int s=0;
int r=100;
void setup(){
size(width,height); myPort = new Serial(this,"COM4",38400); frameRate(10); background(255);
}
void draw(){
noFill(); s++; dataCountT=dataCountT%300; fill(250,250,250,15); rect(0,0,600,600,15); stroke(random(255),random(255),random(255),100); textSize(80); int x,y; r=s*3; /* x=(int)(r*cos(s))+width/2; y=(int)(r*sin(s))+height/2; dx=(int)(r*cos(s+PI/2))+width/2; dy=(int)(r*sin(s+PI/2))+height/2; */ x=(int)random(520); y=(int)random(520)+60; fill(200,200,250); ellipse(x+30,y-30,100,100); fill(random(255),random(255),random(255)); if(flg_d) text("D",x,y); if(flg_l) text("L",x,y); if(flg_m) text("M",x,y); if(flg_f) text("F",x,y); if(flg_s) text("S",x,y); if(flg_r) text("R",x,y); if(flg_c) text("C",x,y); if(width<x| |height<y){ background(255); s=0; }
}
void serialEvent(Serial p){
char str; str = myPort.readChar(); //println(str); if(str=='D'){ dataCountT++; flg_d=true; flg_l=false; flg_m=false; flg_f=false; flg_s=false; flg_r=false; flg_c=false; } else if(str=='L'){ dataCountT++; flg_d=false; flg_l=true; flg_m=false; flg_f=false; flg_s=false; flg_r=false; flg_c=false; } else if(str=='M'){ dataCountT++; flg_d=false; flg_l=false; flg_m=true; flg_f=false; flg_s=false; flg_r=false; flg_c=false; } else if(str=='F'){ dataCountT++; flg_d=false; flg_l=false; flg_m=false; flg_f=true; flg_s=false; flg_r=false; flg_c=false; } else if(str=='S'){ dataCountT++; flg_d=false; flg_l=false; flg_m=false; flg_f=false; flg_s=true; flg_r=false; flg_c=false; } else if(str=='R'){ dataCountT++; flg_d=false; flg_l=false; flg_m=false; flg_f=false; flg_s=false; flg_r=true; flg_c=false; } else if(str=='C'){ dataCountT++; flg_d=false; flg_l=false; flg_m=false; flg_f=false; flg_s=false; flg_r=false; flg_c=true; } else{ dataCountT++; flg_d=false; flg_l=false; flg_m=false; flg_f=false; flg_s=false; flg_r=false; flg_c=false; } println("dataCountT:"+dataCountT);
}
画面の挙動
考察
距離センサで測定できる範囲を上手く音階ごとに分け、距離次第で音階の出力と画面に音階の種類の出力をした。
Processingでは距離の判定を文字としてPSoCから受け取り、それを元にboolean変数に真偽値を代入してディスプレイの出力を行った。
距離センサの精度の問題上、判定できる距離が限られたがその限定された距離をLCDの画面全体で表示できるように調整した。
常時音階が出力されないようにスイッチを用意したが、スイッチの条件のif文else文で同じ処理をする場所がありソースコードが長くなってしまった。
参考
チーム1364
チーム1447
- 最終更新:2017-05-16 17:49:13