PDA

View Full Version : Cảm biến siêu âm


ahchu
17-11-2007, 01:17 AM
Chào mọi người,
Em đang làm mạch nhận biết vật cản. Mạch của em dùng PIC8F452 và PING))) ultrasonic sensor (http://www.lynxmotion.com/images/data/pingv1.2.pdf).

Hoạt động: nhận tín hiệu từ sensor sau đó sẽ điều khiển motor quay xuôi và quay ngược thông qua đặt giá trị cho 4 input của H-bridge. Mạch của em set up như hình vẽ dưới

Rất đơn giản!!! Thằng bạn em đang dở cái mạch này thì nó có chuyện phải đi một thời gian, giờ nó đi rồi nó kêu em test hộ nó cái mạch.

Sau khi em test thì mọi thứ đều ok cả, nếu không có vật cản thì output của H-bridge cho ra 12V (forward direction), cho vật cản trước sensor thì H-bridge cho ra -12V (reverse direction). Có điều khoảng cách nhận biết vật cản gần quá cỡ 40cm, mà nó cần nhận biết vật cản từ khoảng cách cỡ 1-2m. Nó quăng cho em cái C code mà em đọc xong chẳng hiểu gì cả. Giờ em muốn viết lại bằng ASM. Mọi người giúp em với, em quên sạch bách về con PIC này rồi.... :(. Đã từng dùng nó cách đây khoảng 2 năm, từ đó đến giờ kô đụng nữa nên quên hết.

Theo mọi người em nên đọc lại phần code của nó (phải bắt đầu học C) hay em nên viết lại code bằng assembly (em đã từng có kinh nghiệm viết Assembly)? Em cũng không rành về con cảm biến siêu âm này, đọc về phần hoạt động của con cảm biến này em vẫn chưa rõ làm thế nào để nâng khoảng cách nhận biết của nó? Mọi người giúp em với...lỡ ôm xô nhận lời giúp rồi....

falleaf
17-11-2007, 09:17 AM
Em nên gửi kèm code lên để mọi người xem giúp, cần viết chú thích đầy đủ, vì đọc code không có chú thích mệt lắm.

Chủ yếu là phần code tính toán khoảng cách siêu âm, đọc siêu âm.

Cảm biến này hoạt động giống với con SRF04, 05 của Devantech. Em có thể tham khảo cách hoạt động của nó được mô tả rất rõ, và có cả source code mẫu của Devantech.

Microchip cũng có một application note về đọc cảm biến siêu âm Polaroid với các nguyên lý tương tự.

Chúc vui

ahchu
23-11-2007, 12:10 AM
C code của bạn em đây ạ


/*

Filename: CC5G.c

Generate a PWM signal with 40% duty cycle

on pulse-width = 5us

off pulse-width = 20ms

on CCP1 (RC2 pin) compare

and configure CCP2 (RC1 pin) for capture

*/







#include <p18cxxx.h>

#include <p18f452.h>

#include <timers.h>

#include <capture.h>



#pragma config WDT = OFF



#define PER1_LIMIT 0x0E10

#define PER2_LIMIT 0x0E10





/*

Speed of sound in air = 1130 ft/sec

TMAX = 18.5ms; TMIN = 115us



FOSC = 8MHz; Processor Clock = 2MHz

CCP Clock = 1MHz

Period = Forward + Backward Trip time



0x0E10 -> 1.8ms

0x8CA0 -> 18ms



*/





unsigned int ov_cnt1, cap1_val1, cap1_val2;

unsigned int ov_cnt2, cap2_val1, cap2_val2;

unsigned int period1, period2; // 16-bit value

unsigned int count = 0; // counter used for waiting to turn relays ON

unsigned int count2 = 0; // counter used for waiting to turn relays ON





void high_ISR( void );

void low_ISR( void );



#pragma code high_vector = 0x08 // force the following statement to

void high_interrupt( void ) { // start at 0x08

_asm

goto high_ISR

_endasm

}



#pragma code low_vector = 0x18 // force the following statement to

void low_interrupt( void ) { // start at 0x18

_asm

goto low_ISR

_endasm

}



#pragma code

#pragma interrupt high_ISR

void high_ISR( void ) {

if( PIR2bits.TMR3IF ) {

PIR2bits.TMR3IF = 0;

ov_cnt2++;

}

if( PIR1bits.TMR1IF ) {

PIR1bits.TMR1IF = 0;

ov_cnt1++;

}





}



#pragma code

#pragma interrupt low_ISR

void low_ISR( void ) {

_asm

retfie 0

_endasm

}





void vDelay( void ) {



unsigned const int MAX = 45450;

unsigned int i = 0;



for( i=0; i<MAX; i++ ) ;



}



void vDelay10us( void ) {



unsigned int i = 0;





}



void vDelay5ms( void ) {



unsigned const int MAX = 1150;

unsigned int i = 0;



for( i=0; i<MAX; i++ ) ;



}





// Delay calculations based on 8MHz crystal, 1:1 prescalar for Timer3



void main( void ) {



unsigned int i = 0;

unsigned int odd = 0;

unsigned int flag = 1; // flag for determining boat direction

int num1 = 0;

int num2 = 1;





// Configure registers for Output Compare -- a 5us trigger pulse

TRISCbits.TRISC2 = 0; // configure CCP1 pin for output

T1CON = 0x81; // turn on Timer1 in 16-bit mode, prescalar = 1

// CCP1CON = 0x09; // configure CCP1 pin to set high initially but pull low on match

// CCPR1 = TMR1H + 0x0020; // start CCP1 compare with delay equals 10

// PIR1bits.CCP1IF = 0; // clear CCP1IF flag to prevent false interrupt



OpenTimer1( TIMER_INT_OFF &

T1_16BIT_RW &

T1_PS_1_1 &

T1_OSC1EN_OFF &

T1_SYNC_EXT_OFF &

T1_SOURCE_INT );





OpenTimer3( TIMER_INT_OFF &

T3_16BIT_RW &

T3_SOURCE_INT &

T3_PS_1_1 &

T3_SYNC_EXT_OFF &

T1_CCP1_T3_CCP2 );



T1CON = 0x81; // turn on Timer1 in 16-bit mode, prescalar = 1



TRISD = 0; // set PORTD for output

TRISCbits.TRISC1 = 1; // configure CCP2 pin for input

TRISCbits.TRISC2 = 1; // configure CCP1 pin for input

INTCONbits.GIE = 0; // Disable global interrupts

RCONbits.IPEN = 1; // enable priority interrupts

PIR2bits.TMR3IF = 0;

IPR2bits.TMR3IP = 1; // promote Timer1 rollover interrupt to high priority

INTCONbits.PEIE = 1; // enable preipheral interrupt

PIE2bits.TMR3IE = 0; // disable Timer3 rollover interrupt



PIR1bits.TMR1IF = 0;

IPR1bits.TMR1IP = 1;

PIE1bits.TMR1IE = 0;



TRISB = 0x00; // configure PORTB as output



while( 1 ) {



vDelay5ms();



// if( !odd )

PORTD = 0x01;

vDelay10us();

PORTD = 0x00;

// vDelay10us();











// PORTD = 0x00;



PIE2bits.CCP2IE = 0;

CCP2CON = 0x05;

PIE2bits.CCP2IE = 1;



// PORTD = 0x00;



PIE2bits.CCP2IE = 1; // disable CCP2 capture interrupt

PIR2bits.CCP2IF = 0;

IPR2bits.CCP2IP = 1; // high priority











while( !( PIR2bits.CCP2IF ) ) ;

cap2_val1 = ReadCapture2(); // save the first captured edge

PIR2bits.CCP2IF = 0;

PIR2bits.TMR3IF = 0;

PIE2bits.TMR3IE = 1; // enable Timer3 rollover interrupt



PIE2bits.CCP2IE = 0;

CCP2CON = 0x04;

PIE2bits.CCP2IE = 1;



PORTD = 0x00;



while( !( PIR2bits.CCP2IF ) ) ; // wait for interrupt

CloseCapture2(); // disable CCP2 capture

cap2_val2 = ReadCapture2();

PIR2bits.TMR3IF = 0;

PIE2bits.TMR3IE = 0; // disable Timer3 rollover interrupt



if( cap2_val2 < cap2_val1 ) { // if timer overflows, decrease overflow count by one

ov_cnt2--;

period2 = ov_cnt2*65536 + cap2_val2 + ( 65536 - cap2_val1 );

}

else {

period2 = ov_cnt2*65536 + cap2_val2 - cap2_val1;

}



ov_cnt2 = 0; // Reset overflow counter





// vDelay5ms();





PORTD = 0x02;

vDelay10us();

PORTD = 0x00;

vDelay10us();











// PORTD = 0x00;



PIE1bits.CCP1IE = 0;

CCP1CON = 0x05;

PIE1bits.CCP1IE = 1;



// PORTD = 0x00;



PIE1bits.CCP1IE = 1; // disable CCP2 capture interrupt

PIR1bits.CCP1IF = 0;

IPR1bits.CCP1IP = 1; // high priority











while( !( PIR1bits.CCP1IF ) ) ;

cap1_val1 = ReadCapture1(); // save the first captured edge

PIR1bits.CCP1IF = 0;

PIR1bits.TMR1IF = 0;

PIE1bits.TMR1IE = 1; // enable Timer3 rollover interrupt



PIE1bits.CCP1IE = 0;

CCP1CON = 0x04;

PIE1bits.CCP1IE = 1;







while( !( PIR1bits.CCP1IF ) ) ; // wait for interrupt

CloseCapture1(); // disable CCP2 capture

cap1_val2 = ReadCapture1();

PIR1bits.TMR1IF = 0;

PIE1bits.TMR1IE = 0; // disable Timer3 rollover interrupt



if( cap1_val2 < cap1_val1 ) { // if timer overflows, decrease overflow count by one

ov_cnt1--;

period1 = ov_cnt1*65536 + cap1_val2 + ( 65536 - cap1_val1 );

}

else {

period1 = ov_cnt1*65536 + cap1_val2 - cap1_val1;

}



ov_cnt1 = 0; // Reset overflow counter







if( period1 > PER1_LIMIT & period2 > PER2_LIMIT & flag ) {

count++;

count2 = 0;

num1 &= 0;

num2 = 0;

if( count > 20 ) {

PORTB = 0x0C; // Forward

}

}



if( period1 > PER1_LIMIT & period2 > PER2_LIMIT & !flag ) {

count++;

num2 = 0;

// num1 = 0;

count2 = 0;

if( count > 20 ) {

PORTB = 0x03; // Reverse

}

}



if( period1 > PER1_LIMIT & period2 < PER2_LIMIT ) {

PORTB = 0x00;

flag = 1;

count = 0;

count2++;

if( count2 > 20 )

PORTB = 0x0C; // Forward

}



if( period1 < PER1_LIMIT & period2 > PER2_LIMIT ) {

PORTB = 0x00;

flag = 0;

count = 0;

num2++;

num1+=num2;



if( num1 > 20 ) {

PORTB = 0x03; // Reverse

}

}



if( period1 < PER1_LIMIT & period2 < PER2_LIMIT ) {

PORTB = 0x00; // Shut down

count = 0;

count2 = 0;





}





}



}

nguyendinhtuan
23-11-2007, 10:36 AM
Bạn tham khảo trang web sau nhé:
http://embedded.olin.edu/ultrasonic/links.php

ahchu
28-11-2007, 03:44 AM
Em muốn làm lại cái cảm biến vật cản. Em định sẽ làm một cái mạch cảm biến bằng sóng âm, khi nào có vật cản trong khoảng từ 1-2m nó sẽ cho ra tín hiệu 1 khi nào không có vật cản trong đó sẽ cho ra tín hiệu 0, như mạch cảm biến hồng ngoại cho con line-following robot mà em đã làm hồi trước. Em không biết là có thể làm như vậy được không.

Hồi trước em dùng IR sensor để nhận biết vạch đen trên nền trắng và robot sẽ đi theo vạch đen ấy.
Hoạt động: IR sẽ bị hấp thụ bởi vạch đen và không phản xạ, điều đó làm đầu thu IR bị ngắt và tín hiệu sẽ là 0. Khi phản xạ lại, đầu thu được nối với nhau và sẽ có tín hiệu. Em nối đầu ra của đầu thu vào Hex-Schimitt trigger IC để nó có tín hiệu 1, 0 trước khi di qua PIC.

Em đang nghĩ làm thế nào để có thể áp dụng cách ấy cho ultrasonic sensor. Em muốn tín hiệu trước khi vào PIC (master micro processor) sẽ được xử lý thành 1, 0. Vì em sẽ phải dùng đến 6 con ultrasonic sensor để tránh vật cản. Mà trong khi đó nếu xử lý theo cách bạn em là dùng CCP1 và CCP2 để so sánh khoảng thời gian(rising edge và falling edge)->khoảng cách-> xử lý... thì sẽ phải dùng nhiều hơn 1 con PIC (PIC 18F452 chỉ có 2 chân compare: CCP1 và CCP2). Nếu dùng được như IR sensor trình bày ở trên thì chỉ cần dùng 1 con PIC để xử lý tín hiệu input 1, 0 từ mạch cảm biến (gồm 6 con ultrasonic sensor).

Mong mọi người cho em lời khuyên!!! Mọi người có thể cùng tham gia vào đề tài này cho vui. Em đang làm một cái thuyền để bơi dưới hồ, thuyền sẽ chạy vòng quanh hồ và tránh không bị mắc cạn, bằng cách nhận biết được khoảng cách từ thuyền đến thành hồ, nếu trong khoảng 2m thì thuyền sẽ quay ngược động cơ và đi lùi lại. Thật ra đề tài này của thằng bạn em, nó làm xong rồi, giờ em giúp nó test và định làm lại cái mạch cảm biến cho vui thôi!

Đây là bài về line-following robot của em làm năm ngoái
http://www.picvietnam.com/forum/showthread.php?t=345

và con robot của em (pin bị chết ngay hôm present nên phải cắm dây điện như dắt cún đi dạo vậy :)) )
http://youtube.com/watch?v=ErFmsQKkPy8