Skocz do zawartości

"Elektroniczny patefon" na bazie czujnika odległości HC-SR04


Pomocna odpowiedź

@marek1707 Panie Marku, doczytałem o Fast PWM. Wydaje mi się, że zrozumiałem też, o czym Pan pisze. Mam teraz dylemat: robić po swojemu, czy korzystać z dobrej porady... Wydaje mi się, że zaczynam pojmować jak działają te rejestry. Chyba spróbuję zrobić po swojemu na jednym timerze, a potem po Twojemu. Może się czegoś nauczę, może nie. Największy problem mam w sumie, nie ze zrozumieniem jak one działają, ale z ustawianiem bitów i sprawdzaniem stanu flag.  Nie znam składni. W efekcie kopiuję wyrwane z kontekstu kody, które wydaje mi się, że pasują. Tasuję nimi jak małpa. Zaglądam też do dokumentacji. Ona nie jest dla laików. Ciężka sprawa. Zajmie kolejne 2 tygodnie.

Link to post
Share on other sites
(edytowany)

@marek1707 Melduję wykonanie zadania. Szpilka:

TCCR1A= (1<<COM1B1)+(1<<WGM11)+(1<<WGM10);
TCCR1B= (1<<WGM13)+(1<<WGM12)+(1<<CS10);
OCR1A=9999;
OCR1B=99;

Te dziewiątki odzwierciedlają mój nastrój....👹 

Brrr... Okropne. Jak teraz z kolei uporam się z Input Capture na tym timerze, poproszę już o inny zestaw zadań. 😉

Dużo się nauczyłem! Nie spodziewałem się takiej pojemności po moim mózgu.👍

Za wykonie tego zadania proszę moderatorów o zwiększenie mi reputacji. Mogę już uczyć znaczenia bitów kluczowych rejestrów timerów w podstawówce. 😅😅😅

Edytowano przez Adder
edycja
Link to post
Share on other sites
(edytowany)

@marek1707 W zasadzie jak się tak zastanawiam, to pozostała do zrobienia 1 linijka:

TIMSK1=(1<<ICIE1)

 A potem napisanie obsługi ISR (TIMER1_CAPT_vect), no ale zobaczymy co ranek przyniesie. Jestem steraaasznie zmęczony i mogę się mylić. 

Edytowano przez Adder
Link to post
Share on other sites
(edytowany)

Zamiast

(1<<COM1B1)

możesz używać makra BitValue, które "produkuje" taką przesuniętą o zadaną liczbę pozycji jedynkę:

_BV(COM1B1)

Moim zdaniem jest to bardziej czytelne i osobiście używam tej wersji, ale jak kto woli.

Jak rozumiem zdecydowałeś sie na wariant w którym Timer 1 obsłuży cały pomiar: generację impulsu sondującego i łapanie zboczy sygnału odpowiedzi. Przy zegarze 16MHz i prescalerze 1 dostajesz zatem szpilkę co 625us. To trochę często (1600Hz), nie uważasz? Nawet gdyby czujnik SR04 miał zerowe opóźnienie wysłania sygnału ultradźwiękowego, to sygnał akustyczny w tym czasie jest w stanie pokonać ok. 20cm. Zasięg pomiaru wynosi zatem jedynie 10cm a przecież musi być jeszcze zapas na wygenerowanie 8 impulsów 40kHz i wygaszenie drgań nadajnika. No chyba, że faktycznie w programie widzimy tylko Twoje emocje a liczby są od czapy. Czy z kolei szpilka wyzwalająca o długości ok. 6us jest wystarczająca dla czujnika? Nie pamiętam specyfikacji, ale pewnie to sprawdziłeś.

No tak, to teraz czas na zaprogramowanie funkcjonalności wejścia ICP1, oczekiwanie na pierwszy a potem drugi Input Capture, obliczenie różnicy i wypisanie wyniku. Pamiętaj, że licznik timera chodzicały czas w trybie PWM a więc modulo okres wpisany do OCR1A - to maksymalny wynikjaki możesz złapać. Musisz tak dobrać okres PWMa, by żadne ze złapanych zboczy odpowiedzi nigdy nie wyszło poza tę granicę, bo wynik będzie kompletnie błędny. Może na razie, w celach testowych zacznij od długich okresów, np. 65000? Dopiero gdy wyniki zaczną przychodzić sensowne, możesz zacząć podkręcać sample rate.

1 godzinę temu, Adder napisał:

Nie spodziewałem się takiej pojemności

Zostaw sobie trochę miejsca na a) pozostałe peryferia tego procesora, b) dużo ciekawsze timery np. w STM32 (i jeszcze więcej jeszcze ciekawszych peryferiów).

EDIT: Musisz łapać dwa zbocza: najpierw natastające a potem opadające. Nie musisz tego robić na przerwaniach.  Timer ma odpowiednie bity stanu i możesz je zwyczajnie czytać i na nie czekać. Tak się czasem prościej uruchamia, a przerwania to kolejny etap.

Edytowano przez marek1707
  • Lubię! 1
Link to post
Share on other sites
8 minut temu, marek1707 napisał:

No chyba, że faktycznie w programie widzimy tylko Twoje emocje a liczby są od czapy.

Liczby są od czapy. Ale eksperymentalnie doszedłem do pewnych wyników (dysfunkcja tabliczki mnożenia u mnie)

15 minut temu, marek1707 napisał:

Czy z kolei szpilka wyzwalająca o długości ok. 6us jest wystarczająca dla czujnika? Nie pamiętam specyfikacji, ale pewnie to sprawdziłeś.

Wystarcza nawet 2-3 uS. Dawno to sprawdziłem.

Wg. specyfikacji minimum to: 10 uS 

18 minut temu, marek1707 napisał:

Jak rozumiem zdecydowałeś sie na wariant w którym Timer 1 obsłuży cały pomiar

Tak. Idę po bandzie.

Link to post
Share on other sites
22 minuty temu, marek1707 napisał:

Pamiętaj, że licznik timera chodzicały czas w trybie PWM a więc modulo okres wpisany do OCR1A - to maksymalny wynikjaki możesz złapać. Musisz tak dobrać okres PWMa, by żadne ze złapanych zboczy odpowiedzi nigdy nie wyszło poza tę granicę,

Może z chwilą złapania zbocza wyłączyć PWM?

Link to post
Share on other sites

Ale po co? Przecież i tak nie możesz pobudzić czujnika dopóki nie przyjdzie opadające zbocze (czyli de facto echo) odpowiedzi. Okres musi być ustawiony tak, by echo zdążyło przyjść więc z definicji złapiesz odpowiedź do ICR1 z licznika Timera pracującego w PWM.

  • Lubię! 1
Link to post
Share on other sites
(edytowany)

Dzień dobry!

Ok. Część teorii mamy już za sobą:

Inicjalizacja:

  TCCR1A= (1<<COM1B1)+(1<<WGM11)+(1<<WGM10);
  TCCR1B= (1<<WGM13)+(1<<WGM12)+(1<<CS10);
  OCR1A=9999;
  OCR1B=99;
  TIMSK1=(1<<ICIE1);

Obsługa przerwania:

ISR (TIMER1_CAPT_vect) {                                                            
  
 static unsigned RisingEdgeTime = 0;                                                
 static unsigned FallingEdgeTime = 0;                                               

  if (TCCR1B & (1 << ICES1)) {                                                     
  RisingEdgeTime = ICR1;                                                        
  TCCR1B &= ~(1 << ICES1);                                                          
}
  else {                                                                                
  FallingEdgeTime = ICR1;                                                           
  echoPulseTime = FallingEdgeTime - RisingEdgeTime;                                 
  NewPulse=1;    
  TCCR1B &= ~(1 << ICES1); 
}
}

Sample są faktycznie od czapy. Ale są i jest ich dużo. Muszę się teraz zastanowić co tam siedzi w ICR1 i porobić przeliczenia. Arytmetyka nie jest niestety moją mocną stroną. 

Edytowano przez Adder
Link to post
Share on other sites
(edytowany)

Z ciekawości możesz porobić jakieś obliczenia statystyczne, np. na złapanych kilkuset próbkach (tyle powinno się zmieścić w RAMie m328), ale nie ruszaj samych wartości. Przecież do późniejszej analizy dźwięku nie muszą być one wyrażone w żadnej sensownej jednostce. Muszą być tylko liniowo zależne od położenia membrany głośnika. Dalszy ciąg obliczeń może np. usuwać składową stałą, ale to wszystko. W audio jest ona niepotrzebna, ale to także trzeba umieć zrobić żeby kolejne bloki danych nie "pykały" na krawędziach zlepień. Niczego z wartościami nie kombinuj, a już na pewno żadne zmyślone "filtrowania" czy "poprawiania". Ciąg przetwarzania sygnałów cyfrowych przede wszystkim zakłada, że masz do czynienia z sygnałem nieskończonym. Podział takiego nieskończonego strumienia próbek na bloki często wynika z implementacji pewnych algorytmów, ale tak czy tak całość musi być tak zorganizowana, by mieć przepustowość równą częstotliwości próbkowania (a tak naprawdę nawet większą). Takie założenie powoduje, że nigdzie w torze nie masz wąskich gardeł, a te które są nie powodują spiętrzeń niemożliwych do zbuforowania. W przypadku procka tak lichego jak m328 i metody wejściowej jaką przyjąłeś możesz spróbować jeszcze prostej rzeczy: mała dynamika samego próbkowania sygnału być może umożliwi przeznaczenie jedynie jednego bajtu na próbkę. To daje dwukrotną oszczędność miejsca w stosunku do 16-bitowych intów, więc będziesz mógł w procesorze zmieścić z 1.5 tys. próbek. Możesz też polizać temat kompresji. W telekomunikacji szeroko stosowany jest standard kodowania tzw. A-law lub konkurencyjny u-law. Oba zamieniają kilkunastobitowy sygnał na bajt (i rzecz jasna odwrotnie). Algorytmy są znane i na pewno znajdzesz nawet gotową implementację w C. To by pozwoliło utrzymać dynamikę gdyby okazało się, że zdjęty sygnał wcale taki zasyfiony nie jest, przy jednoczesnej oszczędności miejsca w pamięci. No ale to tylko wtedy, gdy złapane próbki chcesz przesyłać dalej, bo bezpośrednio obliczeń na tak skompresowanych sygnałach robić się nie da. Napisz co chcesz z próbkami dalej robić, bo to jest kluczowe do wyznaczenia kierunku dalszych prac. Jeśli chcesz to przepychać do PC, to musisz zdecydować czy a) robisz prosty program gromadzący próbki aż do zapełnienia bufora w RAMie a potem wysyłający to do PC, czy b) robisz to od razu tak, by jedncześnie gromadzić próbki i wysyłać je do kompa. To drugie daje oczywiście szansę pracy na nieskończenie długich ciągach. Z drugiej strony wydaje mi się, że mimo swoich ograniczeń m328 jest w stanie odtworzyć i "odegrać" zgromadzone próbki na jakieś swoje wyjście audio. Potrzebny będzie projekt cyfrowego filtru rekonstrukcyjnego, który "wymyśli" brakujące próbki, które następnie będziesz mógł wysłać jako PWM na wyjście. Tam musisz zasadzić prosty filtr analogowy i wzmacniacz mocy sterujący głośnikiem. Miabyś wtedy (to jest trzecia droga) niezależny od PC samograj łapiący próbki i mogący je później odtwarzać. Oczywiście wzmacniacz i głośniki mogą być typowo komputerowe albo zamienione na słuchawki. Z filtrem rekonstrukcyjnym upsamplingującym (polskie nadpróbkującym też nie brzmi jakoś rewelacyjnie) do np. 8kHz ułomny arytmometr AVR powinien sobie mimo wszystko poradzić. Także zdecyduj co chcesz ze złapanym materiałem robić, czyli w jakim kierunku mają iść dalsze prace. Czy raczej jednorazowy strzał a jeśli tak, to co z próbkami:

  • samplowanie -> gromadzenie do zapełnienia bufora -> wysłanie do PC
  • samplowanie -> gromadzenie do zapełnienia bufora -> obróbka na miejscu -> odtwarzanie przez głośniczek

czy raczej proces ciągły:

  • samplowanie i równoczesne wysyłanie do PC aż do przerwania procesu, po drodze jakiś bufor kołowy (circular buffer) na wejściu i ze dwa bufory na tworzone i wysyłane ramki danych

UART pracujący na 115200 daje przepustowość 10kbajtów/s, czyli poradziłby sobie w czasie rzeczywistym nawet z przepychaniem pełnych intów bez żadnej obróbki.

EDIT: Gdy już program będzie działał stabilnie i będziesz w stanie buforować surowe próbki złapane nową metodą, zestaw stanowisko, złap trochę sygnału (tego samego co poprzednio, 40Hz sinewave) i wrzuć plik na Forum z informacją o przyjętej częstotliwości próbkowania. Zobaczymy co tam słychać.

Edytowano przez marek1707
  • Lubię! 1
Link to post
Share on other sites

@marek1707 Dziękuję. Tak zrobię. 

Wariant: Samplowanie i równoczesne wysyłanie do PC aż do przerwania procesu, po drodze jakiś bufor kołowy (circular buffer) na wejściu i ze dwa bufory na tworzone i wysyłane ramki danych

Link to post
Share on other sites
(edytowany)

Sampling: 771Hz

Sygnał: 40Hz

Zupełnie nie rozumiem co widzę. Teraz chyba dopiero to jest jakaś sieczka. Help!

ezyzip.zip

 

Jest jeszcze opcja, że nie umiem liczyć i przestałem rozumieć co się dzieje. Od kilku dni głowa mi puchnie od kalkulatora.

Program rozgrzebany do poziomu masakry... Coś czuję, że czeka mnie 10 kroków wstecz...

Edytowano przez Adder
edytowany
Link to post
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

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.