1
Lokalizator ultradźwiękowy
Arkadiusz Materek
7 czerwiec 2006
1. Cel projektu
Celem projektu było zapoznanie się z działaniem sonarów ultradźwiękowych
i ich własnościami, oraz zapoznaniu się z komunikacją miedzy
mikroprocesorami oraz miedzy komputerem PC a mikrokontrolerem.
2. Założenia projektowe
Urządzenie wyposażone będzie w trzy niezależne odbiorniki
ultradźwiękowe, każdy z nich wyposażony w mikrokontroler, główny
mikrokontroler odpowiedzialny za komunikację z odbiornikami i
komputerem PC, oraz sterowaniem nadajnikiem ultradźwiękowym.
Użytkownik obsługujący lokalizator z poziomu PC, będzie miał możliwość
wykonania pomiaru oraz odczytania wyników i na podstawie znajomości
położenia odbiorników określenia pozycji nadajnika.
3. Odbiornik ultradźwiękowy
Celem było zaprojektowanie prostego odbiornika. Do tego celu
wykorzystano mikrokontroler ATtiny12, mikrofon ultradźwiękowy, jeden
rezystor i kondensator.
Własności ATtini12:
- posiada komparator analogowy
-
wewnętrzny oscylator 1.2Mhz
- 32 rejestry ogólnego przeznaczenia
- 1KB FLASH
- 64 Bajty EEPROM
- Tirem/Licznik 8mi bitowy z programowalnym preskalerem
- Watchdog
2
Rysunek 1. Schemat odbiornika
Zasada działania odbiornika ultradźwiękowego:
Mikrofon podłączony jest bezpośrednio na wejścia komparatora
analogowego równolegle z rezystorem 470kΩ. Piny PB0 i PB1 (wejścia
komparatora), gdy nie wykonywany jest pomiar ustawione są jako wyjścia w
stanie niskim, co powoduje szybkie rozładowanie mikrofonu. Podczas
pomiaru przełączane są na wejścia w stanie wysokiej impedancji.
Mikrokontroler dokonuje pomiar czasu od momentu otrzymania impulsu
synchronizującego do momentu ustawienia bitu ACO w rejestrze ACSR (bit
odzwierciedla aktualny stan komparatora) lub przepełnienia licznika.
Czas od sygnał synchronizującego (zbocze opadające na PB2) do zliczania
czasu wynosi ok. 5μs. Stan komparatora sprawdzany jest co ok. 5μs, co przy
liczniku 8-bitowy daje pomiar czasu do 1,28ms (przy prędkości dźwięku 340
m/s odległość 43,52cm).
Kod w asemblerze realizujący wyżej opisaną procedurę:
Pomiar:
;czekamy na sygnal synchronizujacy
Pomiar2:
sbic PINB, Wire
rjmp Pomiar2
;przelaczenie pinow komparatora z wyjsc na wejscia
in
r16,
DDRB
andi
r16,
~((1<<PB0)|(1<<PB1))
out
DDRB,
r16
;pomiar czasu
clr
r20
Pomiar0:
sbic ACSR, ACO
rjmp
Pomiar1
nop
inc
r20
brne
Pomiar0
Pomiar1:
dec
r20
3
;przelaczenie pinow komparatora z wejsc na
;wyjscia w stanie niskim
in
r16,
DDRB
ori
r16,
((1<<PB0)|(1<<PB1))
out
DDRB,
r16
ret
4. Nadajnik ultradźwiękowy
Nadajnik jest zbudowany na układzie MAX232. Zadaniem tego układu jest
wytworzenie odpowiedniego dla poprawnego działania sonaru napięcia,
które powinno wynosić ok. 20V, co zapewnia wyżej wymieniony układ.
Rysunek 2. Schemat nadajnika
Na wejście T1IN podawany jest sygnał prostokątny 0-5V o częstotliwości
40kHz, a na wejście T2IM jego negacja, co daje różnice napięć na wyjściach
T1OUT i T2OUT ok. 20V. Tranzystor T1 oraz oporniki R1 i R2 tworzą
bramkę NOT.
5. Obwód głównego mikrokontrolera
Jako głównego mikrokontrolera użyto ATtini2312.
Własności ATtini2313:
- 2kB pamięci FLASH
- 128 bajtów pamięci EEPROM
- 128 bajtów RAM
- jeden tirem 8-bitowy z (2xPWM, 2xOC)
- jeden 16-bitowy (2xPWM, 2xOC, IC)
4
- USART
- USI
- Watchdog
Rysunek 3. Schemat głównego obwodu
Mikrokontroler jako źródła zegara używa zewnętrzny kwarc o częstotliwości
8Mhz. W tym celu należy odpowiednio ustawić bity konfiguracyjne (patrz
dokumentacja ATtini2313 str. 23 i 24).
a) Obsługa nadajnika
Do nadajnika podawany jest sygnał prostokątny o częstotliwości 40kHz
generowany przy pomocy funkcji Output Compare timera 0. Wycie OC
znajduje się na pinie 2 portu B.
Konfiguracja Timera 0 w trybie CTC z przerwaniem:
ldi
r16, (1<<COM0A0)|(1<<WGM01)
out TCCR0A,
r16
;PB2 – wyjcie OC
ldi
r16,
100
;stala przy ktorej licznik sie zeruje
out
OCR0A,
r16
ldi
r16,
(1<<OCIE0A)
;odblokowanie przerwania
out
TIMSK,
r16
Włączenie timera 0 taktowanego, co jeden takt zegara odbywa się przez
ustawienie bitu CS00 w rejestrze TCCR0B.
W funkcji obsługi przerwania dekrementowany jest licznik, a gdy
osiągnie wartość 0 to tirem zostaje wyłączony. Rozwiązanie takie
możliwość wysłania określonej liczby okresów fali.
5
Funkcja obsługi przerwania OC0
ObslugaOC0:
in
r3,
SREG
;zapamietanie resjestru flag
dec
r24
;zminiejszenie licznika
brne
ObslugaOC00
out
TCCR0B,
r24
;jesli r24==0 to wylaczamy timer
ObslugaOC00:
out
SREG,
r3
;przywrocenie rejestru flag
reti
Do poprawnego wykorzystania funkcji trzeba zainicjować rejestr r24
podwójną liczbą wysyłanych okresów fali oraz do rejestru licznika
TCNT0 wpisać wartość taka samą jak w rejestrze TCCR0A, aby wymusić
przerwanie zaraz po włączeniu timera.
b) Procedura pomiaru sonarem
Do wszystkich odbiorników jednocześnie wysyłana jest komenda
oczekiwania na sygnał synchronizujący, następnie wysyłana jest fala
ultradźwiękowa i zboczem opadającym synchronizowany pomiar czasu
przez odbiorniki (ta sama linia, co do magistrali 1-wire). Należy poczekać
na zakończenie pomiarów np. 5ms i odczytujemy kolejno z odbiorników
zmierzone wartości przez z magistrali 1-wire.
Przykładowa implementacja:
WykonajPomiary:
push
r16
push
r17
push
r18
cli
;zablokowanie przeran
ldi
r18,
0x00
;adres wszystkich urzadzen
rcall
wire_w
;wysylamy adres do sonarow
ldi
r18,
SonarPomiar
rcall
wire_w
;wysylamy komende do sonarow
sei
;odblokowanie przerwan
;wysylamy
fale
ldi
r24,
16
ldi
r17,
100
out
TCNT0,
r17
ldi
r17,
(1<<CS00)
out
TCCR0B,
r17
;wlaczenie timera
;czekamy na wyslanie fali
Pomiary2: tst
r24
brne Pomiary2
;zbocze
synchronizujace
cbi
PORTD,
PD6
delay
40
sbi
PORTD,
PD6
;czekamy
ok.
5ms
6
ldi
r17,
52
Pomiary0: delay 255
dec
r17
brne
Pomiary0
cli
;zablokowanie przeran
;pomiary juz sa wykonane, odczytujemy dane z sonarow
ldi
r18,
SonarAddr1
;odczyat z sonaru 1
rcall
wire_w
ldi
r18,
SonarWynik
;komenda wyslaniia wyniku
rcall
wire_w
;wyslanie komendy
rcall
wire_r
;wysylane zawsze do 1mastera
;nie
ma
potrzeby
sprawdzac
adresu
rcall
wire_r
;odebranie wyniku pomiaru
sts
Pomiary+0,
r18
;zapisanie wyniku w RAM
;
pomiary juz sa wykonane, odczytujemy dane z sonarow
ldi
r18,
SonarAddr2
;odczyat z sonaru 1
rcall
wire_w
ldi
r18,
SonarWynik
;komenda wyslaniia wyniku
rcall
wire_w
;wyslanie komendy
rcall
wire_r
;wysylane zawsze do 1mastera
;nie ma potrzeby sprawdzac adresu
rcall
wire_r
;odebranie wyniku pomiaru
sts
Pomiary+1,
r18
;zapisanie wyniku w RAM
;pomiary juz sa wykonane, odczytujemy dane z sonarow
ldi
r18,
SonarAddr3
;odczyat z sonaru 1
rcall
wire_w
ldi
r18,
SonarWynik
;komenda wyslaniia wyniku
rcall
wire_w
;wyslanie komendy
rcall
wire_r
;wysylane zawsze do 1mastera
;nie ma potrzeby sprawdzac adresu
rcall
wire_r
;odebranie wyniku pomiaru
sts
Pomiary+2,
r18
;zapisanie wyniku w RAM
sei
;odblokowanie przerwan
pop
r18
pop
r17
pop
r16
ret
c) Komunikacja z komputerem PC
Komunikacja z PC odbywa się interfejsem RS232. Mikrokontroler
ATtiny2313 ma sprzętową obsługę UART. Standard 0-5V jest
konwertowany na standard R232 za pomocą układu MAX232. Prędkość
transmisji ustalona została na 9600 bodów na sekundę. Format ramki to 8
bitów danych 2bity stopu i kontrola parzystości ODD.
;inicjowanie UART
clr
r16
out
UBRRH,
r16
ldi
r16, 51
;predkosc transmisji 9600 przy kwarcu 8Mhz
out
UBRRL,
r16
;wlaczenie odbiornika i nadajnik i odblokowanie przerwan
ldi
r16,
(1<<RXCIE)|(1<<RXEN)|(1<<TXEN)
7
out
UCSRB,
r16
Komputer PC wysyła do mikrokontrolera komendy, na które
mikrokontroler odpowiednio reaguje.
Zaimplementowane zostały komendy:
- wykonaj pomiar
- prześlij wynik pomiaru
- prześlij informacje o urządzeniu (ciąg znaków „Lokalizator
ultradzwiękowy”)
- sprawdzenie obecności urządzenia (wysyła bajt 0x07)
W przypadku wystąpienia błędów transmisji komenda zostaje odrzucona.
Komenda odbierana jest w przerwaniu URX.
ObslugaURX:
push
r16
in
r2,
SREG
;zapamietanie rejestru flag
in
r12,
UDR
;zapamietanie odebrabego bajtu
in
r16,
UCSRA
andi
r16,
(1<<FE)|(1<<UPE)
;czy wystapily blady
breq
ObslugaURX0
clr r12
;jesli tak to zerujemy odebrany bajt
ObslugaURX0:
out SREG, r2
;przywrocenie rejestru flag
pop
r16
reti
Proceura wysyłajaca wyniki pomoarów
;wyniki zapisane w tabli pomiary
WyslijWyniki:
push
r16
push
r17
ldi
r31,
HIGH(Pomiary
) ;ladujemy adres
ldi
r30,
LOW(Pomiary)
;pierwszego elementu tablicy
ldi
r17,
3+1
;licznik – wysylamy 3 bajty
WyslijWyniki0:
dec
r17
breq
WyslijWyniki2
WyslijWyniki1:
sbis UCSRA, UDRE
;czekamy na wolny bufor
rjmp
WyslijWyniki1
ld
r16,
Z+
;odczyt bajtu z ram
;z pod adresu w Z i zwieksz Z o 1
out
UDR,
r16
;wysylamy bajt
rjmp
WyslijWyniki0
WyslijWyniki2:
pop
r17
pop
r16
ret
Procedura wysyłająca informację o urządzeniu:
;dane zapisane są pamieci programu
WyslijInfo:
push
r16
ldi
r31,
HIGH(Info<<1
) ;ladujemy adres
ldi
r30,
LOW(Info<<1)
8
WyslijInfo0:
lpm
r16, Z+
;do r17 bajt z pamieci programu i
;inkrementacja rejestru indeksowego Z
tst
r16
breq
WyslijInfo2
;koniec gdy napotkamy znak 0
WyslijInfo1:
sbis UCSRA, UDRE
;czekamy na wolny bufor
rjmp
WyslijInfo1
out
UDR,
r16
;wysylamy bajt
rjmp
WyslijInfo0
WyslijInfo2:
pop
r16
ret
Procedura wysyłająca potwierdzenie obecności urządzenia:
ldi r16,
0x07
łtaki wzmzslone potwierdzenie
☺
loop: sbis UCSRA,
UDRE
;czekamy na wolny bufor
rjmp
loop
out UDR,
r16
;wysylamy bajt z rejestru r16
6. Komunikacja 1-wire
Komunikacja pomiędzy głównym mikrokontrolerem a odbiornikami odbywa
się za pomocą interfejsu 1-wire. W projekcie zmodyfikowano ramkę do
dwóch bajtów, pierwszy bajt oznacza adres urządzenia, a drugi dane. Jeżeli
urządzenie odbierze pakiet z adresem, który się nie zgadza z adresem
urządzenia to dane nie są ignorowane.
Przesyłanie bitów interfejsem 1-wire pokazuje rysunek 4.
Rysunek 4. Przesyłanie bitów
Rozpoznawanie przesyłanych bitów odbywa się przez pomiar czasu stanu
niskiego na magistrali. Układ master generuje zbocze opadające na
magistrali, co synchronizuje układy slave przy obieraniu i nadawaniu bitow.
9
Ważną rzeczą podczas wykorzystania software’owej implementacji 1-wire
jest, aby blokować przerwania na czas komunikacji przez magistrale, które
mogą wprowadzić przesunięcia czasowe sygnału na magistrali, co może
doprowadzić do błędów podczas przesyłania danych.
a) Odbiorniki (slave)
- Przykład implementacji odbierania bitu:
wire_r_b:
;czekamy na sygnal synchronizujacy
wrb0: sbic PINB, Wire
rjmp
wrb0
delay
8
;odczekanie ok 20us
sbic
PINB,
Wire
;odczytanie stanu magistrali
;(przeskocz jesli 0)
ori
r18,
0b10000000
delay
15
;odczekanie ok 45us
ret
Odebrany bit jest zapisywany jako najstarszy w rejestrze r18, ale przed
wywołaniem procedury mus być wyzerowany.
- Przykład implementacji nadawania bitu:
wire_w_b
;czekamy na sygnal synchronizujacy
wwb0: sbic PINB, Wire
rjmp wwb0
nop
nop
cbi
PORTB,
Wire
sbrc
r18,
0
;(przeskocz jesli 0)
sbi
PORTB,
Wire
sbi
DDRB,
Wire
;zapis na magistrale (PB2 - wyjscie)
delay
10
;czekamy
cbi
DDRB,
Wire
;przelaczenie pinu na wejscie
cbi
PORTB,
Wire
delay
6
ret
W tym przypadku nadawany jest najmłodszy bit rejestru r18.
- Przykład implementacji odbierania bajtu:
;procedura czyta bajt z magistrali 1-wire do rejestru r18
wire_r:
clr r18
;zerujemy wynik
ldi
R17,
8
;licznik do petli
wire_r_1:
;przed kazdym odczytaniu bitu
lsr r18
;przesuwamy ostatni odebrany w prawo
rcall wire_r_b
;odczyt bitu
dec
r17
;dekrementacja licznika
brne
wire_r_1
;jesli r17!=0 to powtarzamy czytanie bitu
ret
- Przykład implementacji wysyłania bajtu:
;procedura zapisuje bajt na magistrale 1-wire z rejestru r18
wire_w:
ldi
r17,
8
;licznik petli
10
wire_w_1: rcall wire_w_b
;wyslanie najmlodszego bitu bitu
lsr
r18
;pzesuniecie w lewo
dec
r17
brne
wire_w_1
;jesli r17!=0 to nadajemy nastepny
ret
b) Główny mikrokontroler (master)
- Przykład implementacji odbierania bitu:
wire_r_b:
cbi
PORTD,
PD6
;zbocze synchronizujacy
delay
14
;odczekanie 5us
cbi
DDRD,
PD6
;przelaczeny PD6 na wejscie
delay
39
sbic
PIND,
PD6
;odczytanie stanu magistrali
ori
r18,
0b10000000
delay
105
;odczekanie ok 45us
sbi
PORTD,
PD6
; stan wysoko na magistral
i
sbi
DDRD,
PD6
; przełac PD6 na wyjscie
ret
Odebrany bit jest zapisywany jako najstarszy w rejestrze r18, ale przed
wywołaniem procedury mus być wyzerowany.
- Przykład implementacji nadawania bitu:
wire_w_b:
cbi
PORTD,
PD6
;zbocze synchronizujace
delay
13
sbrc
r18,
0
;(przeskocz jesli 0)
sbi
PORTD,
PD6
delay
146
;czekamy
sbi
PORTD,
PD6
;stan wysoki na magistrale
ret
W tym przypadku nadawany jest najmłodszy bit rejestru r18.
- Przykład implementacji odbierania bajtu:
wire_r:
push
r16
push
r17
push
r2
in
r2,
SREG
clr r18
;zerujemy wynik
ldi
R17,
8
;licznik do petli
wire_r_1:
lsr
r18
;po kazdym odczytaniu bitu przesuwamy go w lewo
rcall wire_r_b
;odczyt bitu
delay
100
dec r17
;dekrementacja licznika
brne
wire_r_1
;jesli r17!=0 to powtarzamy
out SREG,
r2
pop
r2
pop
r17
pop
r16
ret
- Przykład implementacji wysyłania bajtu:
11
wire_w:
push
r16
push
r17
push
r2
in
r2,
SREG
ldi
r17,
8
;licznik pretli
wire_w_1: rcall wire_w_b
;wysylamy najmlodszy bit r18
lsr r18
;przygotwanie nastepnego bitu
delay
100
dec
r17
brne
wire_w_1
;jeli r17!=0 to powtarzamy wysylanie
out
SREG,
r2
pop
r2
pop
r17
pop
r16
ret
7. Wnioski
Urządzenie zostało zmontowane i przetestowane. Działanie jest poprawne.
Dobrym rozwiązaniem okazało się użycie zintegrowanego komparatora
analogowego w mikrokontrolerze. Jest on wystarczająco czuły, aby
wychwycić fale z nadajnika nawet z kilku metrów a jednocześnie dość
odporny na zakłócenia. Dodatkowo dokonuje pomiaru czasu bez obciążania
innego mikrokontroler, a wynik można w każdej chwili odczytać.
Napisany został również interfejs graficzny z wykorzystaniem biblioteki QT.
Do kompilacji programów w asemblerze użyto AVRSTudio 4.12.
8. Literatura
Dokumentacje producentów podzespołów elektronicznych.
Materiały internetowe:
http://konar.ict.pwr.wroc.pl/uploads/download/raporty/sonar.pdf