elechobby:picdic:pic16f88:113

超音波距離計V2

以前にも超音波人体検出ユニットV1を製作しましたが、今回は、人体に特化せずに、超音波を反射する物体までの距離を測るユニットを製作しました。

<仕様>

  • 測定距離は、40cm~4mとする。
  • 精度は、cm単位とする。

センサーには、日本セラミック社製の超音波センサ(送信:T40-16、受信:R40-16)を使用します。
【超音波センサの仕様】

  • 中心周波数:40±7kHz
  • 音圧レベル:115dBmin
  • 感度特性:-64dB/V/μBARmin
  • 周波数帯域:6kHzmin
  • 静電容量:2400pF±25%
  • 外形寸法:16.2φ×12.2mm

【超音波センサの基板への実装例】

【全体の流れ】

  1. タイマーを開始する。
  2. PICのPWMモジュールを利用して、40kHzの超音波を約200usec間送信する。
  3. 送信時の影響を減らすために、受信部の倍電圧整流回路を約400usec間リセットする。
  4. 受信した超音波をLM386(2個)を利用して、約4000倍に増幅する。
    LM386は、20倍から200倍まで、増幅率を設定できます。
    400倍=20倍×20倍
    4000倍=200倍×20倍
    4000倍=200倍×200倍
  5. 増幅した信号を、ダイオードを利用して、倍電圧整流する。
  6. PICのコンパレータ用の基準電圧モジュールで比較電圧を設定する。
  7. 比較電圧と倍電圧整流した電圧を比較する。
  8. 比較電圧<倍電圧整流した電圧であれば、割り込みを発せさせる。
  9. 割り込み処理の中で、タイマーを停止する。
  10. 1.~9.までを、100回繰り返す。
  11. 100回分のターマー値より、平均値を求め、反射物体までの距離を計算(cm単位)する。
    タイマー値は、反射物体までの往復の値となるので、1/2にします。(T1)
    次に、タイマーの分解能を求めます。(T2)
    →クロックを8MHz、プリスケーラを1/1にしたので、0.5usec((1÷8000000)×4)となります。
    往復にかかった時間を求めます。(T3)
    →T1×T2
    音速より、反射物体までの距離を求めます。
    →距離=T3×330m
  12. 計算した値を、LCDに表示する。
  13. 1.へ戻る。

【全体のブロックダイアグラム】

【タイミングチャート】

UltraSoundV3.c
//********************************************************************** 
/*
	<超音波距離計>
*/
//********************************************************************** 
 
#define		LED		PORTA.F7
#define		CLEAR	PORTA.F4
 
//********************************************************************** 
 
void	interrupt()
{
	if (PIR2.CMIF == 1) {
		PIE2.CMIE = 0;
		PIR2.CMIF = 0;
		//
		T1CON.TMR1ON = 0;
		CLEAR = 1;
	}
}
 
//********************************************************************** 
 
void	Pwm_Change_DutyEx(unsigned int duty_ratio)
{
    CCPR1L = duty_ratio >> 2;
    CCP1CON.F6 = duty_ratio & 0b00000001;
    CCP1CON.F7 = (duty_ratio & 0b00000010) >> 1; 
}
 
//********************************************************************** 
 
unsigned	int	measurement()
{
	static	unsigned	int	dat;
	//TIMER1の設定 
	TMR1H = 0;
	TMR1L = 0;
	PIR1.TMR1IF = 0;
	T1CON.TMR1ON = 1;
	//40kHz送信 
	CLEAR = 1;
	Pwm_Start();
	Delay_us(200);
	Pwm_Stop();
	Delay_us(200);
	CLEAR = 0;
	//割り込みの設定 
	PIR2.CMIF = 0;
	PIE2.CMIE = 1;
	//
	while ((T1CON.TMR1ON == 1) && (PIR1.TMR1IF == 0))
		;
	if (PIR1.TMR1IF == 1) {
		PIE2.CMIE = 0;
		return (-1);
	}
	//
	dat = TMR1H << 8;
	dat |= TMR1L;
	//
	return (dat);
}
 
//********************************************************************** 
 
void main()
{
	//変数の設定 
	static	short	cnt;
	static	double	dat;
	static	long	tmp;
	static	char	buf[10];
	//ポート関連の設定 
	TRISA = 0b00101100;
	TRISB = 0b00000000;
	OSCCON = 0b01110000;	// クロックを8Mhzに設定する。 
	ANSEL = 0b00000000;		// A/D変換は使用しない。
	//TIMER1の設定 
	T1CON.TMR1CS = 0;
	T1CON.T1CKPS0 = 0;
	T1CON.T1CKPS1 = 0;
	T1CON.TMR1ON = 0;
	TMR1H = 0;
	TMR1L = 0;
	PIE1.TMR1IE = 0;
	PIR1.TMR1IF = 0;
	//LCDの設定 
	Lcd_Custom_Config(&PORTB, 7, 6, 5, 4, &PORTB, 3, 2, 1);
	Lcd_Custom_Cmd(LCD_CURSOR_OFF);
	Lcd_Custom_Cmd(LCD_CLEAR);
	//
	for (cnt = 0; cnt < 16; cnt++) {
		Lcd_Custom_Chr(1, cnt + 1, 0xFF);
		Delay_ms(50);
	}
	for (cnt = 0; cnt < 16; cnt++) {
		Lcd_Custom_Chr(2, cnt + 1, 0xFF);
		Delay_ms(50);
	}
	Lcd_Custom_Cmd(LCD_CLEAR);
	//PWMの設定(40kHz) 
	Pwm_Init(40000);
	Pwm_Change_DutyEx((PR2 * 4) / 2);
	Pwm_Stop();
	//コンパレータ用の基準電圧の設定 
	CVRCON.CVREN = 1;
	CVRCON.CVR3 = 1;
	CVRCON.CVR2 = 0;
	CVRCON.CVR1 = 0;
	CVRCON.CVR0 = 0;
	CVRCON.CVRR = 1;
	//コンパレータの設定 
	CMCON.CM2 = 0;
	CMCON.CM1 = 1;
	CMCON.CM0 = 0;
	CMCON.CIS = 1;
	// 割り込み関連の設定 
	INTCON.PEIE = 1;
	INTCON.GIE = 1;
	//
	while (1) {
		//測定 
		dat = 0.0;
		for (cnt = 0; cnt < 100; cnt++) {
			tmp = measurement();
			if (tmp != -1) {
				dat += tmp;
			} else {
				cnt--;
			}
		}
		dat /= 100.0;
		//測定値の表示(換算前) 
		WordToStr(dat, buf);
		Lcd_Custom_Out(2, 1, buf);
		//測定値の表示(換算後) 
		dat = (dat / 2.0) * 0.0000005 * 330.0;
		WordToStr(dat * 100.0, buf);	// m -> cm
		Lcd_Custom_Out(1, 1, buf);
		Lcd_Custom_Out(1, 6, "cm");
		//
		LED = 1;
		Delay_ms(100);
		LED = 0;
	}
}
 
//**********************************************************************

超音波センサー部です。
今回は、整流回路のリセット機能を搭載したので、特に送受のセンサーの間隔を広げる必要はありません。

左側:センサー部です。
右側:LM386(2個)、ダイオード倍電圧整流、トランジスタ、LED、PICです。

リセット信号(40kHz/200usec含む)と反射波(倍電圧整流後)の波形です。(1msec/div)
撮影のために、リセット回路はオープン状態にしています。
左上:反射物までの距離<約30cm:1msec>
右上:反射物までの距離<約60cm:2msec>
左下:反射物までの距離<約170cm:5.5msec>

リセット回路を接続したときの波形です。
約1.8Vでコンパレータが働いています。そして割り込み処理の中で、リセット回路をONにしているので、反射波(倍電圧整流後)の波形が1.8Vを超えると、0Vにリセットされています。

椅子の上に置いて、天井までの距離を測定してみました。→172cm

8cmの高さのタッパーの上に置いて、天井までの距離を測定してみました。→164cm(172cm-8cm))

如何ですか?
思った以上に精度は高いようですね! ^_^

※アンプ部の増幅率を上げる(40000倍)と、更に距離を伸ばすことが出来ます。

著作権表示 copyright notice

このページは稲崎様の閉鎖したHPのコピーで、著作権は稲崎様にあります。詳細
This page is a copy of Mr. Inasaki's closed website, and the copyright is held by him.Details
  • elechobby/picdic/pic16f88/113.txt
  • 最終更新: 2025/10/17 14:29
  • by 127.0.0.1