Skocz do zawartości

Język C sterowanie 2 czujnikami Hc-sr04


Pomocna odpowiedź

Twoja wizja brzmi prosto postaram zrobić tak jak mówisz, na 100 masz rację choćby ze względu na doświadczenie dlatego postaram się zastosować do twoich rad.

[ Dodano: 15-03-2016, 18:47 ]

Podsumowując

Najpierw

Włączanie, definicje

Inicjacja timerów

Inicjacja przerwań int0 i int1

While a w niej

Sygnał 10us

Start timer

Czekaj na echo

Jak echo wróci to zatrzymaj timer i zapamiętaj ile impulsów było

Koniec While

A potem trzeba wymyślić ja ten wynik przekształcić w odległość

O to chodziło bo nie wiem czy to dobrze zinterpretowałem?

W karcie katalogowej tego czujnika jest dziwny rysunek sugerujący to, że na tej samej linii wyzwalamy i otrzymujemy sygnał zwrotny. Oczywiście tak nie jest, na szczęście na stronie Botlandu znajduję samoobjaśniający się wykres:

Impuls wyjściowy może mieć od 150us do 38ms. Timer 2 ma 8 bitów więc przy podstawowym zegarze = 1MHz dostajemy przepełnienie po 256us. W stosunku do 38ms jest to 148 razy za krótko. Musimy więc odpalić timer z co najmniej takim podzielnikiem żeby liczył wolniej. Jedyny sensowny na liście dostępnych to 1/256, więc będziesz musiał taki ustawić. To oznacza, że timer będzie mierzył czas do 255*256us=65.28ms z rozdzielczością 256us. Taki kwant czasu to dla dźwięku droga 8.5cm. Ponieważ w sonarze dźwięk biegnie w dwie strony, oznacza to rozdzielczość pomiaru na poziomie 4.2cm. Taką odległość będzie wyznaczało pojedyncze tyknięcie timera. To tyle jeśli chodzi o fizykę zjawiska. Jeśli spodziewałeś się czegoś więcej, musisz użyć innego timera.

Z powyższego rysunku wprost wynika następujący algorytm obsługi czujnika:

1. Generujesz impuls sondujący 10us.

2. Czekasz na początek impulsu echa. Wystarczy proste while, które będzie się pętlić dopóki na wejściu z czujnika nie zacznie się impuls echa:

while ((PIND & 0x04) == 0) {};

3. Zerujesz timer i puszczasz go z podzielnikiem 1/256.

4. Znowu czekasz - tym razem pętląc się dopóki na wejściu z czujnika wciąż jest stan wysoki:

while ((PIND & 0x04) != 0) {};

5. Zatrzymujesz timer i odczytujesz jego zawartość. Dobrze byłoby ją wyświetlić by zweryfikować wyniki. Masz jakiś kontakt z tym procesorem? Podłączyłeś gdzieś UART?

6. Jeżeli chcesz, możesz wszystko powyższe 1-5 zamknąć w dużej pętli while(1) i obserwować jak różne przeszkody zmieniają wyniki z timera.

Pominąłem wszystkie wstępne ustawienia kierunków linii portów I/O itp.

Jeżeli wszystko będzie OK i wyświetlane liczby będą sensownie rosły wraz z odległością do przeszkody, możesz zacząć bawić się w przeliczanie na cm. Jeżeli jednak Twój program nie musi pokazywać nikomu odległości (np. na LCD lub przez UART) to wystarczy, by porównywał wprost odczyty timera z jakimś progiem i w zależności od tego odpalał silniki. Przecież to wszystko jedno czy wynik jest w cm czy w tyknięciach timera 2.

Co Ty na to?

W sumie racja nie ma znaczenia ale ty zrobiłeś to jeszcze prościej bez przerwań zewnętrznych tylko w zwykłym While faktycznie dużo prościej, a zasada działania ta sama więc jak dla mnie jest ok zastosuję się do tego. A co do uart to dopóki nie będe miał 2 laptopa z złączem rs232 to nawet się nie zabieram za to a do LCD jeszcze nie mam biblioteki.

Hm, czyli mamy kolejny przykład projektu który powstał bez chwili zastanowienia się "jak będę uruchamiał program?". Musisz mieć jakieś wyjście z procesora. Na początek zrób dzień dobroci dla siebie i podłącz chociaż jedną-dwie diodki LED do jakichś wolnych pinów. Za ich pomocą już wkrótce spróbujesz wysłać na zewnątrz wyniki pomiarów z timera 🙂 Przecież nie chcesz pracować na oślep, prawda?

Taki program już mam jest na rozwiązaniu 1 problemu i to jego będe modyfikował, zrobiłem prosty zestaw uruchomienowy coś jak

Arduino tyle że bez botloadera. Zabieram się do pracy.

Nie, w pierwszym programie pokazałeś zapalnie diodki w zależności od jakiegoś progu. Jak sobie wyobrażasz zbadanie tą metodą ilościowych wyników pomiarów? Przez skompilowanie 250 programów każdy z innym progiem? Do zabaw na biurku musisz mieć wyjście liczbowe. Każdy pomiar powinien być wyprowadzany nawet w formie mrugnięć diodką - jeśli już nie przewidziałeś czegoś wygodniejszego, teraz musisz się męczyć. W systemie gdzie mam mały procesor, wszystkie nóżki wykorzystane, tylko jeden sygnalizacyjny LED i jestem w desperacji piszę funkcję, która zamienia liczbę 8-bitową na trzy cyfry dziesiętne i każdą z nich "wyświetlam" za pomocą np. mrugnięć: długie to 5 (żeby było szybciej) a krótkie to 1. W tym systemie odczyt z timera równy 173 będzie wyglądał tak:

.

--- . .

. . .

Trochę upierdliwe, ale działa. Szybko się przyzwyczaisz do takiej rozmowy z procesorem. Nie wolno spraw zostawiać niesprawdzonymi. Jeżeli masz jakiekolwiek wypisywanie wyników (nawet takie dziwne) możesz w tym konkretnym wypadku sprawdzić maksymalny zasięg, czułość na małe przeszkody, rozrzut wyników w warunkach stabilnej odległości itd. Proste porównanie ze sztywnym progiem nic nie daje. Jeśli już coś robisz, zrób to porządnie i wyciągnij z lekcji z czujnikiem maksymalnie ile się da wiedzy. Inaczej szkoda czasu.

A nie lepiej zamiast 2 pętli While zrobić 1 if else bo wydaje mi się że tak będzie jeszcze lepiej?

Nie wiem co Ci się wydaje i jak mamy się odnosić do takich "gorących" postów. Przemyśl, napisz sobie kilka instrukcji na kartce, prześledź w głowie jak będą się wykonywały i czy będą robić to co chcesz - przecież algorytm pomiaru czasu jest trywialny.

Konstrukcja if nie jest pętlą, więc nie wiem jak za jej pomocą chcesz na coś czekać - a czekać musisz. Jeśli po teście myślowym, "na sucho" kod ma znamiona działania, pokaż go tutaj jeśli czegoś nie jesteś pewien. Skrytykujemy 😉 i będzie po sprawie. A tak to sobie można gdybać..

Bądź aktywny - zaloguj się lub utwórz konto!

Tylko zarejestrowani użytkownicy mogą komentować zawartość tej strony

Utwórz konto w ~20 sekund!

Zarejestruj nowe konto, to proste!

Zarejestruj się »

Zaloguj się

Posiadasz własne konto? Użyj go!

Zaloguj się »
×
×
  • Utwórz nowe...