チーム1718

課題名

距離センサによる任意音階発生装置

研究者名

Yokota Raimu
Yukawa Kota

概要

距離センサで物体との距離によって音階を発生させる。
スイッチを押すと音階がでる。
スイッチを押している間LCDには出力されている音階の種類が表示される。
また、LCDには常時物体との距離を表している。
そして、Processingによって距離に応じて出力される音階の種類が確認できる。

使用した機器

・ジャンパ線
・PSoC基盤
・MiniProg
・ストレート通信ケーブル
・スピーカー
・距離センサ
基盤1718.png

モジュールの配置

チップ.png

ソースコード

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);
}

画面の挙動

距離音階画面.png

考察

距離センサで測定できる範囲を上手く音階ごとに分け、距離次第で音階の出力と画面に音階の種類の出力をした。
Processingでは距離の判定を文字としてPSoCから受け取り、それを元にboolean変数に真偽値を代入してディスプレイの出力を行った。
距離センサの精度の問題上、判定できる距離が限られたがその限定された距離をLCDの画面全体で表示できるように調整した。
常時音階が出力されないようにスイッチを用意したが、スイッチの条件のif文else文で同じ処理をする場所がありソースコードが長くなってしまった。

参考

チーム1364
チーム1447

  • 最終更新:2017-05-16 17:49:13

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

認証パスワード