文書の過去の版を表示しています。
タッチセンサーユニット
概要
私の場合には、このユニットをどんな用途に使っているかと言いますと...
朝が早いので、その時に暗い玄関で靴を履くときに使います。
先ず、センサーにタッチするとLEDが点灯します。
その間に玄関の蛍光灯を消灯して靴を素早く履いて鍵をかけます。
暫くすると自動的にLEDが消灯します。
如何ですか?省エネ用に...
応用としては、無線機のPTT(送信)スイッチの代わりにも使えると思いますよ。
用途はいろいろ考えられると思います。{^_^}!
動作原理
我々の周りにはノイズ(主には商用電源のノイズ)が一杯です。
人体もこのノイズを通す媒体となりますので、これを検出してLEDをコントロールしようというものです。
指でセンサー(1cm角の銅板)に触った時のノイズをアンプで増幅します。
そしてタッチ前のノイズ量とタッチ後のノイズ量の差によりタッチしたか否かを判断します。
回路図
処理説明
- センサーにタッチする前のノイズ(主には商用電源のノイズ)を検出する。(これを基準値(offset)とする)
- 感度を上げるためにPICの前段に2SK241によるアンプを入れる。
- ノイズの量は、10回サンプリングしてその間の最大値と最小値の差としています。
- タッチした時の値(ad0)と基準値(offset)を比較する。
- もしもoffset値よりもad0の値が大幅に大きければタッチしたものとみなす。
- タッチしていれば一定時間(10秒程度)LEDをONする。
- タッチしたことをブザー音で知らせる。
※夜だけ動作させるために光センサーも追加したいのですが、現時点では考慮していません。
ソースコード
- TouchSensor.c
//********************************************************************** /* <タッチセンサー> 2006.12.30 ・ノイズ(主には商用電源のノイズ)を検出する。 ・タッチ前のデータ(offset)とタッチ後のデータ(ad0)を比較する。 ・もしもoffset値よりもad0の値が大幅に大きければタッチしたものとみなす。 ・タッチしていれば一定時間(10秒程度)LEDをONする。 ・タッチしたことをブザー音で知らせる。 ・感度を上げるためにPICの前段に2SK241によるアンプを入れる。 ※夜だけ動作させるために光センサー(ad1)も追加したいが、現時点では考慮しない。 */ //********************************************************************** unsigned short lightOnCnt; void interrupt() { if (PIR1.TMR1IF == 1) { PIR1.TMR1IF = 0; if (lightOnCnt > 0) { lightOnCnt--; GPIO.F4 = 1; } else { GPIO.F4 = 0; } // GPIO.F5 = ~GPIO.F5; } } //********************************************************************** void Pwm_Change_DutyEx(unsigned int duty_ratio) { CCPR1L = duty_ratio >> 2; CCP1CON.F6 = duty_ratio & 0b00000001; CCP1CON.F7 = (duty_ratio & 0b00000010) >> 1; } //********************************************************************** void main() { static unsigned int min, max, ad0, offset, temp, cnt; // OSCCON = 0b01000000; // クロックは1Mhz CMCON0 = 0b00000111; // コンパレータは使用しない。 ANSEL = 0b00000001; // AN0を使用する。 TRISIO = 0b00001011; GPIO = 0b00000000; OPTION_REG = 0b10000000; PIE1.TMR1IE = 1; PIR1.TMR1IF = 0; T1CON = 0b00000001; INTCON = 0b01000000; // Pwm_Init(3000); // 3Khz Pwm_Change_DutyEx((PR2 * 4) / 2); // lightOnCnt = 0; // Delay_ms(2000); // min = 1024; max = 0; for (cnt = 0; cnt < 16; cnt++) { // 基準値(MAX-MIN)を設定する。 temp = Adc_Read(0); if (min > temp) min = temp; if (max < temp) max = temp; Delay_us(1000); } offset = max - min; // for (cnt = 0; cnt < 5; cnt++) { Pwm_Start(); Delay_ms(100); Pwm_Stop(); Delay_ms(100); } // INTCON.GIE = 1; // これ以降の処理で割り込みを許可する。 // while (1) { min = 1024; max = 0; for (cnt = 0; cnt < 16; cnt++) { // 現在値(MAX-MIN)を取り込む。 temp = Adc_Read(0); if (min > temp) min = temp; if (max < temp) max = temp; Delay_us(1000); } ad0 = max - min; // if (ad0 > (offset + 30)) { // 基準値(+30)と現在値を比較する。 lightOnCnt = 10; Pwm_Start(); Delay_ms(100); Pwm_Stop(); } } } //**********************************************************************




