文書の表示以前のリビジョンバックリンクPDF の出力全て展開する/折り畳むODT 出力文書の先頭へ この文書は読取専用です。文書のソースを閲覧することは可能ですが、変更はできません。もし変更したい場合は管理者に連絡してください。 ====== 超音波距離計V2 ====== ===== 概要 ===== 以前にも超音波人体検出ユニットV1を製作しましたが、今回は、人体に特化せずに、超音波を反射する物体までの距離を測るユニットを製作しました。 <仕様> * 測定距離は、40cm~4mとする。 * 精度は、cm単位とする。 ===== 動作原理 ===== センサーには、日本セラミック社製の超音波センサ(送信:T40-16、受信:R40-16)を使用します。 【超音波センサの仕様】 * 中心周波数:40±7kHz * 音圧レベル:115dBmin * 感度特性:-64dB/V/μBARmin * 周波数帯域:6kHzmin * 静電容量:2400pF±25% * 外形寸法:16.2φ×12.2mm 【超音波センサの基板への実装例】 {{:imgpaste:202004:htmikan-20200430-100759.png?500}} 【全体の流れ】 - タイマーを開始する。 - PICのPWMモジュールを利用して、40kHzの超音波を約200usec間送信する。 - 送信時の影響を減らすために、受信部の倍電圧整流回路を約400usec間リセットする。 - 受信した超音波をLM386(2個)を利用して、約4000倍に増幅する。\\ LM386は、20倍から200倍まで、増幅率を設定できます。\\ 400倍=20倍×20倍\\ 4000倍=200倍×20倍\\ 4000倍=200倍×200倍 - 増幅した信号を、ダイオードを利用して、倍電圧整流する。 - PICのコンパレータ用の基準電圧モジュールで比較電圧を設定する。 - 比較電圧と倍電圧整流した電圧を比較する。 - 比較電圧<倍電圧整流した電圧であれば、割り込みを発せさせる。 - 割り込み処理の中で、タイマーを停止する。 - 1.~9.までを、100回繰り返す。 - 100回分のターマー値より、平均値を求め、反射物体までの距離を計算(cm単位)する。\\ タイマー値は、反射物体までの往復の値となるので、1/2にします。(T1)\\ 次に、タイマーの分解能を求めます。(T2)\\ →%%クロックを8MHz、プリスケーラを1/1にしたので、0.5usec((1÷8000000)×4)となります。%%\\ 往復にかかった時間を求めます。(T3)\\ %%→T1×T2%%\\ 音速より、反射物体までの距離を求めます。\\ %%→距離=T3×330m%% - 計算した値を、LCDに表示する。 - 1.へ戻る。 【全体のブロックダイアグラム】 {{:imgpaste:202004:htmikan-20200430-101222.png?500}} 【タイミングチャート】 {{:imgpaste:202004:htmikan-20200430-101231.png?500}} ===== 回路図 ===== {{:imgpaste:202004:htmikan-20200430-101244.png}} ===== ソースコード ===== <code c 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; } } //********************************************************************** </code> ===== 動作確認 ===== {{:imgpaste:202004:htmikan-20200430-101347.png?500}} 超音波センサー部です。 今回は、整流回路のリセット機能を搭載したので、特に送受のセンサーの間隔を広げる必要はありません。 {{:imgpaste:202004:htmikan-20200430-101355.png}}{{:imgpaste:202004:htmikan-20200430-101358.png}} 左側:センサー部です。 右側:LM386(2個)、ダイオード倍電圧整流、トランジスタ、LED、PICです。 {{:imgpaste:202004:htmikan-20200430-101403.png}}{{:imgpaste:202004:htmikan-20200430-101407.png}} リセット信号(40kHz/200usec含む)と反射波(倍電圧整流後)の波形です。(1msec/div) 撮影のために、リセット回路はオープン状態にしています。 左上:反射物までの距離<約30cm:1msec> 右上:反射物までの距離<約60cm:2msec> 左下:反射物までの距離<約170cm:5.5msec> {{:imgpaste:202004:htmikan-20200430-101415.png}}{{:imgpaste:202004:htmikan-20200430-101418.png}} {{:imgpaste:202004:htmikan-20200430-101426.png}} リセット回路を接続したときの波形です。 約1.8Vでコンパレータが働いています。そして割り込み処理の中で、リセット回路をONにしているので、反射波(倍電圧整流後)の波形が1.8Vを超えると、0Vにリセットされています。 {{:imgpaste:202004:htmikan-20200430-101437.png?500}} 椅子の上に置いて、天井までの距離を測定してみました。→172cm {{:imgpaste:202004:htmikan-20200430-101448.png}}{{:imgpaste:202004:htmikan-20200430-101451.png}} 8cmの高さのタッパーの上に置いて、天井までの距離を測定してみました。→164cm(172cm-8cm)) {{:imgpaste:202004:htmikan-20200430-101458.png}}{{:imgpaste:202004:htmikan-20200430-101502.png}} 如何ですか? 思った以上に精度は高いようですね! ^_^ ※アンプ部の増幅率を上げる(40000倍)と、更に距離を伸ばすことが出来ます。 <callout type="warning" title="著作権表示 copyright notice"> このページは稲崎様の閉鎖したHPのコピーで、著作権は稲崎様にあります。[[elechobby:picdic:picdic|詳細]] This page is a copy of Mr. Inasaki's closed website, and the copyright is held by him.[[elechobby:picdic:picdic|Details]] </callout> elechobby/picdic/pic16f88/113.txt 最終更新: 2025/10/17 14:29by 127.0.0.1