PIC16F1872への書き込みが成功したので、次は距離を取得してみたくなりました。
超音波センサーはHC-SR04を選択。
3V~5.5vで正常動作するっぽいです。
まずは回路図に超音波センサーを追記します。
コードを書いて通電した結果、予想とは違う結果となりました。
とりあえず超音波センサーの目前5cmの位置に障害物を置いて計測。
結果は5cmではなく5mmとなりました。
単三電池2本の3vで測っていたので電池を増やして4.5vで動作させてみましたが、結果は5mm。
ならば、単位が違うだけではないか計算式を確認してみる事にしました。
#define _XTAL_FREQ 8000000
unsigned int get_raw_distance(void);
int convert_to_mm(unsigned int raw_value);
void init(void) {
OSCCON = 0b01110000; //8MHz指定
PORTA = PORTB = 0;
TRISA = 0b00000100; // RA2を入力
TRISB = 0; // 全部出力(RB0はTrig用)
ANSELA = ANSELB = 0;// アナログ禁止
}
void main() {
init();
while(1) {
unsigned int raw = get_raw_distance(); // 距離取得
int mm = convert_to_mm(raw); // mm変換
}
}
unsigned int get_raw_distance(void) {
unsigned int count = 0;
LATBbits.LATB0 = 1;
__delay_us(10);
LATBbits.LATB0 = 0;
unsigned int timeout = 10000;
while(PORTAbits.RA2 == 0 && timeout > 0) timeout--;
while(PORTAbits.RA2 == 1) {
count++;
__delay_us(1);
if(count > 20000) break;
}
return count;
}
int convert_to_mm(unsigned int raw_value) {
// 音速 340,000mm/s * 0.000001s / 2 = 0.17
float mm = (float)raw_value * 0.17;
return mm;
}
ポイントはここ
// 音速 340,000mm/s * 0.000001s / 2 = 0.17
float mm = (float)raw_value * 0.17;
音は秒速340m。
プログラムでは count を1マイクロ秒(0.000001秒)ごとにカウントしてるから、1カウントあたりの進む距離は340,000×0.000001=0.34mm。
この結果は往復だから片道にするため半分を求めるので0.34÷2=0.17。
よって、超音波センサーから得た数値に0.17を掛ければmmを得られる筈。
数式は恐らく正しいと思うのです。
そもそもraw_value自体の値が小さいので、超音波センサーの結果が早すぎるようです。
この事から推測すると、トリガー信号を出した直後の残響を、反射波(Echo)だと誤検知している可能性があるかもしれません。
じゃあ、どうしたらいいのか?
trig信号を出してから少し待ち時間を設ければ誤検知が減るかも知れないし、セラミックコンデンサを追加してノイズを吸収させる事が検討できます。
今現在は田舎で電子部品調達が不可能なので、待ち時間を設ける事が現実的です。
今日はもう夜が遅いので、次回、プログラムを書き変えて再チャレンジしてみます。
