チーム2161

課題

ファミリーマート入店時のセンサー

研究者名

野口皓貴
平出陽一

概要

ファミリーマート入店時の音楽を再現する。
人が入店したことを距離センサーが感知→音楽を流す
LCDに距離を表示するようにする
音楽が流れると同時に、LCDに文章を表示

参考:lab3_abc, timer_pwm2, scale_freq.xls(音階周波数とPWMクロック計算用スプレッドシート)
   ファミリーマートの入店音[リンク:https://gourmet-note.jp/posts/1840 より参照]

使用機器

PSoC基板×1
PSoC MiniProg ×1
距離センサー×1
ジャンパー×1
スピーカー

配置

2161_Circuit.png

ソースコード

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

#pragma interrupt_handler myISR
int PW=125;
int SILENT=0, R=273, L=408, M=364, F=324;
int pitch = 1;
int TC=0;

char str[] = "Welcome! Welcome! Welcome! Welcome!";
int pos = 0;
int mp = 2;
int te = 31;
int d1 = 0, d2 = 0;

void myISR(void)
{
TC += 1;
PWM16_1_WritePulseWidth(PW);
if(TC == 1)
  PWM16_1_WritePeriod(F/pitch);
else if(TC == mp+1)
  PWM16_1_WritePeriod(L/pitch);
else if (TC == 2*mp+1)
  PWM16_1_WritePeriod(R*2/pitch);
else if(TC == 3*mp+1)
  PWM16_1_WritePeriod(L/pitch);
else if(TC == 4*mp+1)
  PWM16_1_WritePeriod(M/pitch);
else if (TC == 5*mp+1)
  PWM16_1_WritePeriod(R/pitch);
else if(TC == 8*mp+1)
  PWM16_1_WritePeriod(M/pitch);
else if (TC == 9*mp+1)
  PWM16_1_WritePeriod(F/pitch);
else if (TC == 10*mp+1)
  PWM16_1_WritePeriod(M/pitch);
else if (TC == 11*mp+1)
  PWM16_1_WritePeriod(R*2/pitch);
else if (TC == 12*mp+1)
  PWM16_1_WritePeriod(L/pitch);
else if(TC == 14*mp+1)
  PWM16_1_Stop();
else if(TC == te){
  LCD_Position(1, 0);
   LCD_PrCString("                 ");
   Timer16_1_Stop();
}
pos -= 1;
LCD_Position(1, pos*pitch/4);
LCD_PrString(str);
}

unsigned int HextoDec(unsigned int x)
{
  unsigned int result=0, buf;
   int i=0, j;
   
   while(x>0){
       buf = x%10;
       x /= 10;
       for(j=0;j<i;j++)
           buf *= 16;
       result += buf;
       i++;
   }
   return result;
}

void main(void)
{
  unsigned int adc_data;
   PGA_Start(PGA_HIGHPOWER);
   LCD_Start();
   LCD_InitBG(LCD_SOLID_BG);
   M8C_EnableGInt;
   Timer16_1_EnableInt();
   ADCINC_Start(ADCINC_HIGHPOWER);
   ADCINC_GetSamples(0);
   while(1){
       while(ADCINC_fIsDataAvailable() == 0);
       adc_data = ADCINC_wClearFlagGetData();
       d1 = d2;
       d2 = adc_data;
       if(adc_data > 2048){
           if(d2-d1 < 512){
               mp = 4;
               pitch = 1;
           }else if(d2-d1 < 2012 && d2-d1 >= 512){
               mp = 2;
               pitch = 2;
           }else{
               mp = 1;
               pitch = 4;
           }
           te = 15*mp+1;
           PWM16_1_Start();
           Timer16_1_Start();
           while(TC < te){};
           TC = 0;
           pos = 0;
       }
       LCD_Position(0,0);
       LCD_PrHexInt(HextoDec(adc_data));
       LCD_DrawBG(1,0,16, (adc_data/50));
   }
}

考察

主にtimer_pwm2,lab3_abcを組み合わせ、それにさらに新たな機能を持たせることで実現した。
音階の周波数やPWMのクロックの計算はスプレッドシートを活用した。

距離センサーでただ距離を観測するだけでなく、前回の読み込み時との差から距離の変化する速さも測定できるよう工夫した。
その測定結果である距離の変化する速さに応じて、変数を用いて音程の高さ、音楽の流れる速さ、LCDに表示した文字列の流れる速さを変化させた。

LCDに距離を表示する際、lab3_abcでは16進数で表示されていたが、10進数に変更した。しかし、距離が近づくにつれてその値が大きくなっていったことから、距離の長さを表している(距離センサーと物体の距離が1cmだったとき、0001と表示するような)値ではないことがわかった。この点は改良の余地があると考えられる。また10進数への変換は、もとの値の各桁を、10進数の場合10のn乗となるところを計算で16のn乗にすることで無理やり表示を10進数と同じにしているだけなので、ここをより良い方法を見つけられたら良いと考える。
またLCDに出力する文章は時間内は問題ないほどの長さのものを用意してそれを動かしているが、これを表示する範囲外になったら戻ってくるようにすればより無駄がないプログラムを作成できたと考える。

実際に音楽を流すときに、実際に流したい音楽とは異なる雑音のような音が発生してしまい、音を止めるのにPWMを停止させるという方法で対応するしかなかった。改善しようと試みたが、回路図やプログラムの誤りは発見できず改善することができなかった。接続障害や使用機器の障害も考えられるが、修正できるのであれば修正するべき点である。

今回は、LEDを使用することはなかった。距離が十分に近づいたらLEDを点滅させたり、距離に応じて点滅する速さを変更してみたりと、LEDを使用したさらなる改善も考えられる。

また、一般的なセンサーにはON、OFFを切り替えることができるセンサーが存在する。しかしこのセンサーはON、OFFの切り替えを操作することはできない。シリアル通信などを利用して、与えられたON、OFFの信号で自由にセンサーを操作できるよう改善できたらなおよい。

加えて、スピーカーに与える電圧をシリアル通信を使って外部から変更することで、自由に音量の調節ができるようにしたかったが、時間がなくできなかったのでここも改善できれば良いと考える。

  • 最終更新:2021-10-19 16:17:41

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

認証パスワード