Skocz do zawartości

Ultradźwiękowy czujnik odległości do robota


Pomocna odpowiedź

Witam !

Zmajstrowałem ten układ na płytce ewaluacyjnej atmegi. Mam dla niego konkretne zadanie - chcę zrobić system zarządzania domem i ten układ ma służyć do automatycznego włączania wyświetlacza LCD centrali gdy się do niej podejdzie i wyłączania gdy sie odejdzie. Oprogramowanie napisałem do niego w C, używając przerwania timera 1 oraz przerwania układu komparatora. Zaprogramowałem też odstęp czasu pomiędzy impulsem a włączeniem odbioru aby układ nie wzbudzał się sam i nie trzeba było oddzielać nadajnika od odbiornika przegrodami. Na razie układ pokazuje info na 3 diodach: 1 - odebranie fali, 2 - wykrycie obiektu w polu detekcji (ok 100cm), 3 - status wyświetlacza LCD (hipotetycznego) 🙂. Załączenie wyświetlacza następuje po 3 detekcji obiektu a wyłączenie ok 5 sek po ostatniej detekcji.

Mam nadzieję że się to komuś przyda... Oprogramowanie jest pisane raczej na szybko zeby sprawdzić koncepcję - nie testowałem dokładnie. Użyty rezystor odbiornika to 100k.

Na razie działa chodź jeszcze czasem wariuje. Myślę jednak, że nada się doskonale do tego zastosowania.

#define F_CPU 16000000

#define WAVE_RETURNED_LED 0
#define OBJ_DETECTED_LED 1
#define LCD_ENABLE_PIN 7

#define WAVE_EMIT_TIME_MARK 120
#define WAVE_DETECT_TIME_MARK 200
#define WAVE_CYCLE_TIME_MARK 40000
#define WAVE_MAX_DETECT_TIME_MARK 5000
#define WAVE_OBJ_DETECT_TIME_MARK 600
#define LED_ENABLE_TIME 100

#define LCD_PULSES_REQUIRED 3
#define LCD_ENABLE_TIME 10

#define WAVE_STATUS_RETURNED 0
#define WAVE_STATUS_OBJ_DETECTED 1

#include <inttypes.h> 
#include <avr/io.h> 
#include <avr/interrupt.h> 
#include <avr/sleep.h> 
#include <util/delay.h> 

volatile uint16_t ledloop; 
volatile uint16_t main_sound_counter; 
volatile uint8_t lcd_pulses_remained; 
volatile uint16_t lcd_time_remained; 
volatile uint8_t wave_status; 

void delay_ms(unsigned int ms) 
{ 
       while(ms){ 
               _delay_ms(0.96); 
               ms--; 
       } 
} 

ISR (TIMER1_COMPA_vect) { 
if (main_sound_counter<WAVE_EMIT_TIME_MARK) { 
	if ((main_sound_counter%2)==0) PORTA = 0xFE; 
	else PORTA = 0xEF; 
} else if (main_sound_counter==WAVE_EMIT_TIME_MARK) { 
	PORTA = 0x00; 
} else if (main_sound_counter==WAVE_DETECT_TIME_MARK) { 
	wave_status = 0x00; 
	ACSR |= _BV(ACIE); 
} 
if (main_sound_counter==WAVE_MAX_DETECT_TIME_MARK+1) { 
	ACSR &= ~_BV(ACIE); 
	if (wave_status & _BV(WAVE_STATUS_RETURNED)) ledloop = LED_ENABLE_TIME; 
	if (wave_status & _BV(WAVE_STATUS_OBJ_DETECTED)) { 
		if (lcd_pulses_remained>0) { 
			lcd_pulses_remained--; 
			if (lcd_pulses_remained==0) { 
				lcd_time_remained = LCD_ENABLE_TIME; 
				PORTD |= _BV(LCD_ENABLE_PIN); 
			} 
		} else { 
			lcd_time_remained = LCD_ENABLE_TIME; 
		} 
	} else { 
		if (lcd_pulses_remained>0) lcd_pulses_remained = LCD_PULSES_REQUIRED; 
	} 
	if (lcd_time_remained>0) lcd_time_remained--; 
	else if (lcd_pulses_remained == 0) { 
		PORTD &= ~_BV(LCD_ENABLE_PIN); 
		lcd_pulses_remained = LCD_PULSES_REQUIRED; 
	} 
} 
if (main_sound_counter==WAVE_CYCLE_TIME_MARK) { 
	main_sound_counter=0; 
} 
main_sound_counter++; 
} 

ISR (ANA_COMP_vect) { 
if (main_sound_counter<WAVE_MAX_DETECT_TIME_MARK) wave_status |= _BV(WAVE_STATUS_RETURNED); 
if (main_sound_counter<WAVE_OBJ_DETECT_TIME_MARK) wave_status |= _BV(WAVE_STATUS_OBJ_DETECTED); 
ACSR &= ~_BV(ACIE); 
} 

int main (void) { 
TCCR1B = _BV(CS11) | _BV(WGM12); 

OCR1A = 0x0019; 
TIMSK |= _BV(OCIE1A); 

DDRA = 0xFF; 
PORTA = 0xFF; 

DDRD = 0xFF; 
PORTD = 0x00; 

ACSR &= ~_BV(ACIE); 

lcd_pulses_remained = LCD_PULSES_REQUIRED; 

sei(); 
for (;;) { 
	sleep_mode(); 
	if (ledloop>0) { 
		PORTD |= _BV(WAVE_RETURNED_LED); 
		while (ledloop>0) { 
			if (ledloop>0) 
			delay_ms(1); 
			if (wave_status & _BV(WAVE_STATUS_OBJ_DETECTED)) PORTD |= _BV(OBJ_DETECTED_LED); 
			else PORTD &= ~_BV(OBJ_DETECTED_LED); 
			ledloop--; 
		} 
		PORTD &= ~_BV(WAVE_RETURNED_LED); 
		PORTD &= ~_BV(OBJ_DETECTED_LED); 
	} 
} 
return (0); 
} 

Pozdrawiam i dzięki wszystkim za info tutaj, które pomogło mi rozwiązać mój problem.

Układ na płytce ewaluacyjnej:

Link do komentarza
Share on other sites

Witam

Mam takie malutkie pytanko. Chciałbym stworzyć układ na ultradźwiękach który będzie wykrywał przedmoty ale tylko takie które będą w ruchu. Czy układ od Drukarza można do tego wykorzystać zmieniając tylko softa czy trzeba całkowicie inny układ budować. Za wszystkie rady, porady i pomysły będę wdzięczny.

Link do komentarza
Share on other sites

Jeśli obiekt będzie się poruszać prostopadle do kierunku wysyłania sygnału, może być problem. Znacznie lepszym rozwiązaniem był by czujnik stereofoniczny (jeden nadajnik, dwa odbiorniki po bokach).

Link do komentarza
Share on other sites

Chce stworzyć układ który będzie sygnalizował że zbliża się do mnie. Mój układ też będzie w ruchu i teraz wszystko co się oddala lub ma taką samą prędkość jak ja to nie reaguje tylko jak ma większą prędkość odemnie. Tu raczej wchodzi w gre ruch równoległy.

Link do komentarza
Share on other sites

Zarejestruj się lub zaloguj, aby ukryć tę reklamę.
Zarejestruj się lub zaloguj, aby ukryć tę reklamę.

jlcpcb.jpg

jlcpcb.jpg

Produkcja i montaż PCB - wybierz sprawdzone PCBWay!
   • Darmowe płytki dla studentów i projektów non-profit
   • Tylko 5$ za 10 prototypów PCB w 24 godziny
   • Usługa projektowania PCB na zlecenie
   • Montaż PCB od 30$ + bezpłatna dostawa i szablony
   • Darmowe narzędzie do podglądu plików Gerber
Zobacz również » Film z fabryki PCBWay

No to można dobudować do programu funkcję mierzącą odległość w pewnych przedziałach czasu, następnie porównującą do odległości zmierzonej wcześniej (z uwzględnieniem dobranej tolerancji), co pozwoli na określenie ruchu względnego śledzonego obiektu (prędkość zerowa, dodatnia lub ujemna; spoczynek, zbliżanie lub oddalanie się od sensora). Nie jestem jednak przekonany, czy zaprezentowany w tym temacie układ jest wystarczająco czuły i odporny na ew. zakłócenia. Warto też wziąć pod uwagę możliwe zmiany kształtu przedmiotu i pośrednio kierunku propagacji odbitych fal dźwiękowych...ale pewnie tylko teoretyzuję 😉 Nic nie zastąpi złożenia układu, zaprogramowania go i przetestowania w praniu.

Powodzenia 🙂

Link do komentarza
Share on other sites

Chciałbym aby układ działał na jak największą odległość(tak do 10m) więc za odbiornikiem napewno musi być filtr aktywny kóry wszystkie szumy będzie niwelował. Tylko nie wiem czy musze wzmacniać sygnał wyjściowy też czy wystarczy tak jak jest.a jak trzeba wzmocnić to jak?

Link do komentarza
Share on other sites

Osiągnięcie 10m na zwykłych, tanich "piezakach" jest ciężko osiągalne, jeśli nie niemożliwe... Do tej spory spotykałem się z działającymi na 4-6m góra.

Żeby trochę wzmocnić działanie, możesz przyjrzeć się częstotliwości w jakiej pracują Twoje piezo (dokumentacja) i spróbować dokładniej dopasować częstotliwość emitowanych fal. Gdzieś na elektrodzie był też kiedyś temat o budowie tub i ekranów parabolicznych (odpowiednio do nadajnika i odbiornika); jeśli chce Ci się z tym bawić to zapraszam do szukania na tamtym forum:P

edit

Mały bonus 🙂

http://www.eres.alpha.pl/elektronika/readarticle.php?article_id=117

I wspomniany temat o tubach i czaszach

http://www.elektroda.pl/rtvforum/topic1028013.html

Link do komentarza
Share on other sites

Staram się zbudować sonar stereo, ale maksymalnie prosty - chodzi właściwie tylko o wykrycie obecności przeszkody, więc dokładność nie musi być duża. Dlatego rezygnuję z całego osprzętu (spójrzmy na sonar Konaru...), a nadajnik i odbiorniki chcę podłączyć tak jak w tym projekcie, bezpośrednio do uC.

I teraz pytanie o komparator. Z tego co zrozumiałem, w programie

// zwieramy nieodwracające wejście komparatora do masy

sbi(DDRD,PD7);

cbi(PORTD,PD7);

Więc jedno wejście komparatora mogę na stałe podłączyć do masy? Zależy mi na wolnych portach.

I drugie pytanie. Jak sprawowałby się w tym wypadku przetwornik AC w atmedze, zamiast komparatora ? Buduję sonar stereo, więc musiałbym użyć dodatkowego komparatora.

Hm, tak przeglądam datasheet atmegi - widze, że można ustawić wejście komparatora na dowolny port ADC. Sprawdziłoby się w praktyce ustawienie wejścia na port od jednego sonaru, odebranie sygnału, przestawienie wejścia na port od drugiego sonaru i ponowny pomiar?

Link do komentarza
Share on other sites

Zbudowałem ten sonar według schematu oraz wgrałem program, jednak (jak zwykle) nie działa tak jak trzeba...

Nie zamontowałem wyświetlaczy LED, ale podłączyłem diody pod PD2-PD5. Jednak sonar wciąż pokazuje odległość poniżej 3cm! Nawet jak wyjmę odbiornik i/lub nadajnik. Możliwe że przez odwrotne podłączenie przetworników mogło coś się stać? (odwrotne mam na myśli nóżka 1 nóżka dwa, bo w sumie to nie wiem która jest która...)

Programu nie modyfikowałem, próbowałem przemieszczać przetworniki bliżej/dalej od siebie, nawet jak je po prostu odłączę to wskazuje odległość poniżej 3cm...

Link do komentarza
Share on other sites

Siema na bazie tego projetku chcę napisać program do ATemga 16 - 16Mhz

w programi Code-Vision w C.

Mam J-tag'a i jak wykonuje krokowo program to niby działa i wyświetla przeszkode. Zależy mi głównie na tym ponieważ odległość nie jest istotna wystarczy że jest w jakiejś niezmiennej odległości. narazie zrobiłem coś takiego i jak wlewam program do procka to nic nie wyświetla. Nie działa. może widzicie jakiś błąd

#include <mega16.h>
#include <delay.h>

int odleglosc=0;
unsigned int zoom[6] = {8,14,20,26,32};
void sinus_40_khz(void);
// Declare your global variables here

sygnal(void)       // procedura wysyłania paczki ultradźwięków
{
   int echo=0;            // zmienna do bliczenia powrotu ultradźwięków
   sinus_40_khz();
   sinus_40_khz();
   sinus_40_khz();
   sinus_40_khz();
   sinus_40_khz();
   sinus_40_khz();
   sinus_40_khz();
sinus_40_khz();
sinus_40_khz();
sinus_40_khz();

// teraz trzeba wytłumić drgania przetwornika zwierając go do masy
PORTD=0x03;
delay_us(1);

// przetwornik wejściowy też zwieramy do masy w celu wytłumienia
DDRB=0xFF;
PORTB=0x40;
delay_us(1);


DDRB=0xDF;					// no i można go włączyć

for(echo=0;echo<36;echo++)	// i czekać na odbite dźwięki
{delay_us(1);
	if(ACSR==0x30)	// jeżeli bit ACO rejestru ACSR ustawiony
	{
		break;					// to przerwij
	}
}
return echo;					// zwróć wartość zmiennej
}
void sinus_40_khz(void)			// procedura sygnału 40kHz
{
DDRD=0x03;
   PORTD=0x01;
   PORTD=0x00;
}
void main(void)
{PORTA=0xFF;
DDRA=0xFF;

PORTB=0x80;
DDRB=0x80;

PORTC=0xFF;
DDRC=0xFF;

PORTD=0x00;
DDRD=0xFF;

TCCR0=0x00;
TCNT0=0x00;
OCR0=0x00;

TCCR1A=0x00;
TCCR1B=0x00;
TCNT1H=0x00;
TCNT1L=0x00;
ICR1H=0x00;
ICR1L=0x00;
OCR1AH=0x00;
OCR1AL=0x00;
OCR1BH=0x00;
OCR1BL=0x00;

ASSR=0x00;
TCCR2=0x00;
TCNT2=0x00;
OCR2=0x00;

MCUCR=0x00;
MCUCSR=0x00;

TIMSK=0x00;

ACSR=0x00;
SFIOR=0x00;

while(1)
{
ACSR=0x30;//zeruje rejest ACSR
 odleglosc=sygnal();

     if(odleglosc<zoom[0])	
{
   PORTA=0x0F;
}
else
if(odleglosc<zoom[1])
{          
   PORTA=0x2F;
}
else
if(odleglosc<zoom[2])
{
   PORTA=0xAF;
}
else
if(odleglosc<zoom[3])
{
   PORTA=0xEF;
}
else
if(odleglosc<zoom[4])
{
   PORTA=0xFF;
}
else
if(odleglosc>zoom[4])
{
   PORTA=0xFF;
}
   else
   PORTA=0xFF;                                                              
}

   }
Link do komentarza
Share on other sites

A jak wyglądałby schemat z użyciem LM311 jako komparatora? tak żeby można było wcisnąć kilka czujników na jedną atmegę? Szczególnie chodzi mi o to jak zrobić zwieranie odbiornika w celu wytłumienia.

Link do komentarza
Share on other sites

Witam, odświeżę troszkę temat. Próbuję przerobić program z pierwszego posta tak aby działał na atmedze 32. W programie zmieniłem porty odbiornika na PB2 i PB3 (ain0 i ain1). Po wgraniu do uC 3 diody się palą cały czas a jedna mruga i w rytm jej mrugania słychać delikatne piszczenie z ODBIORNIKA ultradźwięków, oczywiście nie ma żadnej reakcji na przeszkody. Dodam, że posiadam kwarc 16Mhz a z programowaniem dopiero zaczynam przygodę. Proszę o pomoc 🙂 i z góry dzięki za odpowiedzi.

Link do komentarza
Share on other sites

Jest też wada tego sonaru. Jeśli przedmiot jest umieszczony prostopadle to wykrywa go bez problemów. Nawet monetę 2zł wykrywa z odległości 30cm. Ale jeśli jest pod kątem 45° to już jest gorzej. Ale w przypadku odległości poniżej 10cm przedmiot i tak zostaje wykryty.

To nie jest wada, to zjawisko związane z prawami Fizyki, na którym opiera się międzyinnymi technologia maskowania Stealth, wykorzystując tę właściwość można zaprojektować tak kadłub, że zmniejszy się wykrywalność danego obiektu.

Link do komentarza
Share on other sites

Dołącz do dyskusji, napisz odpowiedź!

Jeśli masz już konto to zaloguj się teraz, aby opublikować wiadomość jako Ty. Możesz też napisać teraz i zarejestrować się później.
Uwaga: wgrywanie zdjęć i załączników dostępne jest po zalogowaniu!

Anonim
Dołącz do dyskusji! Kliknij i zacznij pisać...

×   Wklejony jako tekst z formatowaniem.   Przywróć formatowanie

  Dozwolonych jest tylko 75 emoji.

×   Twój link będzie automatycznie osadzony.   Wyświetlać jako link

×   Twoja poprzednia zawartość została przywrócona.   Wyczyść edytor

×   Nie możesz wkleić zdjęć bezpośrednio. Prześlij lub wstaw obrazy z adresu URL.

×
×
  • Utwórz nowe...

Ważne informacje

Ta strona używa ciasteczek (cookies), dzięki którym może działać lepiej. Więcej na ten temat znajdziesz w Polityce Prywatności.