Skocz do zawartości

Pomiar prędkości z czujnikiem odległości HC-SR04


Adder

Pomocna odpowiedź

Dzisiaj dokonałem pomiaru prędkości przy użyciu detektora odległości, ale uwaga, nie obiektu poruszającego się prostopadle do czujnika, ale równolegle do niego. Jak dla mnie było to trochę trudne, ale program działa, chociaż nie do końca jestem z niego zadowolony.  Generalnie można byłoby tak zmodyfikować program, aby badał prędkość obiektu poruszającego się w dowolnym kierunku i pod dowolnym kątem do czujnika poprzez składanie prędkości równoległej z prostopadłą. Co o tym sądzicie?

#define trigPin 12
#define echoPin 11

bool ObjectCheckRun=0;
unsigned long checkStartTime=0;
unsigned long checkEndTime=0;
float ObjectLenght=2; // długość obiektu w cm
 
void setup() {
  Serial.begin (9600);
  pinMode(trigPin, OUTPUT); 
  pinMode(echoPin, INPUT); 

 
}
 
void loop() {  



  if (ObjectDetected()) {
    
    if (ObjectCheckRun) {checkEndTime=millis();Serial.print("Check End: "); Serial.println(checkEndTime);}
    
    else {
      ObjectCheckRun=true;
      checkStartTime=millis(); 
      Serial.print("Check Start: "); Serial.println(checkStartTime);
      

    }
  
  } else {
    ObjectCheckRun=false;
    if (checkEndTime!=0&&checkStartTime!=0) {Serial.print("Time: "); Serial.print(checkEndTime-checkStartTime);Serial.print("ms / ");Serial.print(ObjectSpeed(checkEndTime,checkStartTime));Serial.println(" KM/H");}
    checkEndTime=0;
    checkStartTime=0;
    
  }
}


bool ObjectDetected() {

unsigned long echoPulse;
long distanceObject=0;


  
  digitalWrite(trigPin, LOW);
  delayMicroseconds(2);
  digitalWrite(trigPin, HIGH);
  delayMicroseconds(10);
  digitalWrite(trigPin, LOW);
  
  
  echoPulse = pulseIn(echoPin, HIGH);
  distanceObject = echoPulse/58*(echoPulse/58<30); // eliminacja "tła"

  if (distanceObject != 0) {return 1;} else return 0;
}

float ObjectSpeed(unsigned long EndTime,unsigned long StartTime) {

float Speed=0;

Speed=(1000/(EndTime-StartTime)*3600)*ObjectLenght/100000;
return Speed;
  
}

 

Link do komentarza
Share on other sites

Wydzieliłem z tematu:

Fajnie, że ambitnie podchodzisz do sprawy 🙂 

Masz może możliwość porównania poprawności pomiarów? Nie zgłębiałem tego tematu ale widze tu kilka utrudnień:

  • detekcja nie następuje idealnie prostopadle lecz tak jak fala trafi,
  •  nadajnik i odbiornik są przesunięte względem siebie,
  • opóźnienia wprowadza Serial.println więc lepiej zapamiętaj czas start/stop i wypisz po zakończonym pomiarze.
  • i tu chyba największa, sama obsługa czujnika zabija pomiary:
  digitalWrite(trigPin, LOW);
  delayMicroseconds(2);
  digitalWrite(trigPin, HIGH);
  delayMicroseconds(10);
  digitalWrite(trigPin, LOW);

Ale świat się nie zawalił, poczytaj o efekcie Doplera, na tym bazuje pomiar prędkości 😉 

  • Lubię! 1
Link do komentarza
Share on other sites

12 godzin temu, Gieneq napisał:

Wydzieliłem z tematu:

 

Masz może możliwość porównania poprawności pomiarów? Nie zgłębiałem tego tematu ale widze tu kilka utrudnień:

  • detekcja nie następuje idealnie prostopadle lecz tak jak fala trafi,
  •  nadajnik i odbiornik są przesunięte względem siebie,
  • opóźnienia wprowadza Serial.println więc lepiej zapamiętaj czas start/stop i wypisz po zakończonym pomiarze.
  • i tu chyba największa, sama obsługa czujnika zabija pomiary:

  digitalWrite(trigPin, LOW);
  delayMicroseconds(2);
  digitalWrite(trigPin, HIGH);
  delayMicroseconds(10);
  digitalWrite(trigPin, LOW);

Ale świat się nie zawalił, poczytaj o efekcie Doplera, na tym bazuje pomiar prędkości 😉 

Dobry wieczór!

Dziękuję za zainteresowanie się moim tematem. 

Wszystkie uwagi chętnie przyjmuję. Faktycznie! Korzystanie z fali dźwiękowej niesie wiele ograniczeń (jest powolna i szybko się rozprasza), ale też niesie duuużo ciekawych możliwości. Kwestię przesunięć nadajnika i odbiornika rozważałem przez chwilę, ale uznałem, że nie będą istotnie wpływały na wynik pomiaru. Znowu, zapomniałem, o tym, że mamy do czynienia z falą dźwiękową, a nie świetlną. Co do opóźnień wprowadzanych przez Serial.print - ohh... z tym mam wiele kłopotów. Ogólnie opóźnienia poprawiają dokładność działania programu w obecnej postaci, co było dla mnie sporym zaskoczeniem i męką. 😆 Co do samej rzetelności pomiarów, trudno mi się wypowiedzieć, brak punktu odniesienia. Jednak biorąc pod uwagę, że są wyrażone w km/h, a nie w nanometrach na mikrosekundy, wydają się być zaskakująco dokładne jak na tę skalę. Nawet byłem zadowolony. Więcej problemów mam raczej ze "ślepymi" pomiarami - typu różne "wyskoki" prędkości, w różnych kierunkach oraz "dziury" w pomiarach. Trudno to okiełznać przy moim, kiepskim (szkolnym) przyznaję, warsztacie programistycznym i nikłej wiedzy o zachowywaniu się tego czujnika.

Na koniec Doppler. Uważam, że sugestia jest GENIALNA. W środowisku fal akustycznych to naprawdę może pozwolić wyjść na wyższy poziom pomiarów. Musze się przyjrzeć temu co robi pulseIn. Trochę poobserwować wyniki i może... uda się zrobić uniwersalny miernik prędkości z detektora dystansu? Dziękuję za podpowiedzi i przepraszam za pasożytnictwo. Takie zielonki jak ja długo pasożytują na wiedzy innych zanim same coś dadzą z siebie. 😉

Pozdrowienia

 

 

Link do komentarza
Share on other sites

Tu masz pogadankę na temat wzoru:

 

Wygląda to dość prosto, pewnie trzeba napisać bardziej wyrafinowaną funkcję nadawania i odbierania fali odbitej przy pomocy timerów i może z tego wyjść ciekawy projekt.

  • Lubię! 1
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

9 godzin temu, Gieneq napisał:

Wygląda to dość prosto, pewnie trzeba napisać bardziej wyrafinowaną funkcję nadawania i odbierania fali odbitej przy pomocy timerów i może z tego wyjść ciekawy projekt.

👍 Rzeczywiście, jasno i zrozumiale. Ale, jak wycisnąć poziom zmiany częstotliwości fali odbitej z funkcji pulseIn albo odbiornika(czyli, wyrafinowaną funkcję nadawania i odbierania fali odbitej przy pomocy timerów)? Oto jest pytanie!😅😅 Biorę się do pracy... :))👍

 

Uhhh... Przeczytałem dokumentację tego czujnika. On wysyła falę o częstotliwości 40kHz i nie wiadomo, jakiej częstotliwości fali oczekuje. Pewnie, też o takiej samej (mniej więcej). Czyli czujnik zakłada, że obiekt się nie porusza. Oznacza to, że do mierzenia prędkości trzeba wykorzystać chyba czas upływający pomiędzy dwoma pomiarami, tak myślę. Tam jest jeszcze rozdzielczość równa 30mm. Co zdaje się sugerować, że zmiana odległości mniejsza niż ta wartość, może nie zostać rozpoznana, ale to drobiazg. Teoretycznie ograniczenie rozpoznawanej częstotliwości (wynikające z dokumentacji) czujnika dałoby się obejść badając empirycznie, przy jakiej prędkości obiektu czujnik przestaje rejestrować częstotliwość odbitej fali. Uzyskalibyśmy wtedy wiedzę jaka jest maksymalna prędkość prostopadła (oczywiście poprzez udany pomiar odległości) rejestrowana przez czujnik. Potem tę prędkość podzielić i uzyskalibyśmy miarkę do obliczania prędkości z pomiarów odległości podawanej przez czujnik. Coś w tym stylu, ale czuję, że nie tędy droga. 

 

A, to już chyba mam. Czas trwania pulsu (pulseIn) pierwszego i czas trwania pulsu drugiego. Z tego da się wyliczyć drogę, a potem prędkość.  A potem, ta cała matematyka wynikająca z ograniczeń sprzętu opóźnienia itd.. nienawidzę tego. Czyli, nie Doppler bo czujnik oczekuje stałych 40kHz na odbiorniku +/- tolerancja  i tylko w ramach tej tolerancji damy radę wyliczyć prędkość. Czy tak?

Jeśli tak, to współczuję sobie programowania. Ale co tam, pouczę się. 

Link do komentarza
Share on other sites

Nie podniecaj się tak. W czujniku SR04 nie masz wpływu na długość niczego. Wysyłasz impuls wyzwalający a mały mikrokontroler na pokładzie czujnika wykrywa to zdarzenie i wysyła w "eter" zawsze taką sama paczkę 8 impulsów 40kHz po czym wystawia stan wysoki na wyjście ECHO. Gdy przyjdzie to upragnione echo, wyjście jest zerowane i tyle. Możesz co najwyżej zmierzyć długość impulsu wyjściowego. A zjawisko Dopplera tu w ogóle nie ma znaczenia, bo selektywność toru odbiorczego jest mała. Po pierwsze sam przetwornik odbiornika ma pasmo grubo ponad 1kHz a po drugie filtr 40kHz jaki jest tam wstawiony jest tylko 2 rzędu. Zupełnie spokojnie możesz zatem odbierać i 38kHz i 42kHz. W stosunku do zasięgu tego czujnika to kosmos, bo 1m/s na 40kHz daje przesunięcie ok. 120Hz więc teoretycznie mógłbyś łapać cele o prędkościach ponad 10-krotnie wyższych, tylko że co z tego skoro nie masz żadnej informacji przesunięciu częstotliwości? Jeśli już chcesz się bawić w pomiary prędkości, to albo zrób sobie tor ultradźwiękowy samodzielnie albo kup równie tani czujnik mikrofalowy. Tam masz wyjście z mieszacza więc dostajesz wyłącznie zdudnienia. Nie złapiesz odległości, za to prędkość masz z definicji. No a jeśli chcesz złapać dwie sroki za ogon, to pozostaje radar FMCW albo właśnie własny moduł 40kHz. To nic trudnego, przynajmniej patrząc z daleka.. Jak juz się wprawisz, to możesz spróbować swoich sił w lokalizacji obiektów w polu 2D, oczywiście bez żadnego idiotycznego machania serwami. To też nic trudnego, choć stopień wyżej.

  • Lubię! 2
Link do komentarza
Share on other sites

19 godzin temu, marek1707 napisał:

Nie podniecaj się tak. 

🙂 🙂 🙂  Tak wiem... Po prostu niezmiernie mnie to bawi. Chciałbym, żeby to trwało jak najdłużej...

To, że efekt Dopplera nie będzie miał zastosowania przy HC-SR04 wydedukowałem dość szybko wczoraj wieczorem. Potrzeba by tu było czujnika, który zmierzy częstotliwość fali odbitej od obiektu, a jego nie ma w zestawie podstawowym. Odkryłem jak sobie poradzić inaczej z pomiarem prędkości. Po prostu obiekt wchodzi w wiązkę fal (strasznie szeroką swoją drogą) i z niej wychodzi. Jego prędkość można wyliczyć tylko na podstawie informacji o czasie wejścia i wyjścia z wiązki znając długość obiektu oraz szacowaną szerokość wiązki na wysokości wejścia i wyjścia (szerokość wiązki w wybranej odległości od czujnika zdradza pośrednio producent podając kąt propagacji fali = ok. 30 stopni). Można napisać zgrabny program, który to policzy i w ten sposób sięgnąć ideału w zadanych warunkach i to właśnie zamierzam osiągnąć. Chyba o to w tym wszystkim chodzi.. Zabawa, nauka, odskocznia od dnia codziennego... To mnie pociąga 🙂 

Link do komentarza
Share on other sites

Dobry wieczór, 

trochę się namęczyłem, ale udało mi się poprawić program mierzący prędkość za pomocą czujnika HC-SR04.

Niestety czujnik nie pozwala na obliczenie prędkości przy wykorzystaniu efektu Dopplera. Jest na to zbyt prosty. 

To co czujnik robi z emisją fal dźwiękowych przypomina mniej, więcej to:

Dlatego jedynym sposobem na obliczenie prędkości przy jego wykorzystaniu jest ustalenie drogi i czasu przejścia obiektu przez mało stabilną wiązkę "iskier". 

Pomijając dość szeroki margines błędu, bo "rozrzut" fal jest spory, da się to zrobić dość łatwo, a wyniki uznałbym za zadowalające. 🙂 🙂 🙂

Poniżej program:

#define trigPin 12 // Trigger na pinie 12
#define echoPin 11 // Echo na pinie 11

bool Measuring=false; 
unsigned long checkStartTime=0;
unsigned long checkEndTime=0;
float ObjectLenght=10; //w cm
int onexitDelay=10; 
int onentryDelay=5; 
float entryLevel=0; 
float exitLevel=0; 
float Level=0; 

 
void setup() {
  Serial.begin (9600);
  pinMode(trigPin, OUTPUT); 
  pinMode(echoPin, INPUT); 
}
 
void loop() {  

  if (IsDetected()) {
    
    if (Measuring) {
      checkEndTime=millis();
      exitLevel=Level;
    }
      else {
   
                                          checkStartTime=millis(); 
                                          Measuring=true;
                                          entryLevel=Level;
                                          delay(onentryDelay);
                                          }
  
                    } 
    else {              
          Measuring=false;
          if (checkEndTime!=0&&checkStartTime!=0) {
             Serial.print("Time: ");  
             Serial.print(checkEndTime-checkStartTime);
             Serial.print("ms / ");
             Serial.print(ObjectSpeed(checkEndTime,checkStartTime));
             Serial.print(" KM/H");
           
             Serial.print(" Distance in Cluster: ");
             Serial.print(ObjectLenght+Distance(exitLevel,entryLevel));
             Serial.println(" cm");
                                                                           }
             checkEndTime=0;
             checkStartTime=0;
             exitLevel=0;
             entryLevel=0;
             Level=0;
             
    }
}


bool IsDetected() {

float echoPulse;
float distanceObject=0;

  delay(ObjectLenght/10);
  digitalWrite(trigPin, HIGH);
  delayMicroseconds(10);
  digitalWrite(trigPin, LOW);
  
  echoPulse = pulseIn(echoPin, HIGH);
  distanceObject = echoPulse/58*(echoPulse/58<30); // eliminacja "tła"

  if (distanceObject != 0) {
    Level=distanceObject;
    return true;
    }
    else if (ExitApproval()) return false; else return true;
  }

bool ExitApproval(){

float echoPulse;
float distanceObject=0;
 
      delay(onexitDelay);
      digitalWrite(trigPin, HIGH);
      delayMicroseconds(10);
      digitalWrite(trigPin, LOW);

      echoPulse = pulseIn(echoPin, HIGH);
      distanceObject = echoPulse/58*(echoPulse/58<30); // eliminacja "tła"

      if (distanceObject!=0) { 
      Level=distanceObject;
      return false; 
      }
      else return true;
  
}

float ObjectSpeed(unsigned long EndTime,unsigned long StartTime) {

float Speed=0;

Speed=(1000/(EndTime-StartTime)*3600)*(ObjectLenght+Distance(exitLevel,entryLevel))/100000;
return Speed;
  
}

float Distance(float End,float Start) {

float DistanceMade=0;

DistanceMade=sqrt(sq(Start)+sq(End)-2*Start*End*sqrt(3)/2);
return DistanceMade;
  
}

 

Link do komentarza
Share on other sites

Tylko że taka metoda, bazująca na prostej detekcji amplitudy (z ustalonym w czujniku progiem) bardzo zależy od kształtu, orientacji przestrzennej i materiału (współczynnika odbicia) obiektu. Dla ustalonych tych parametrów zadziała, choć z tragiczną dokładnością. No i trzeba wejść i wyjść z wiązki - dodatkowe utrudnienie. A ponieważ każdy mniejszy/większy, zaokrąglony/kanciasty, pochylony/prostopadły czy puchaty/metalowy przedmiot będzie później/wcześniej wchodził i wychodził z wiązki bo potrzebuje więcej/mniej energii aby tyle samo (bo próg detekcji jest stały) energii wróciło. I o jakich prędkościach mówimy, bo wiązka aż tak szeroka nie jest a pojedynczy pomiar trochę trwa. Fajnie, że dobrze się bawisz, nawet kupiłem chrupki, ale chyba przełączę kanał.

  • Lubię! 2
Link do komentarza
Share on other sites

@marek1707  No niestety, nic ponad to co zrobiłem tu się nie wymyśli, oprócz cyzelowania algorytmów wchodzenia i wychodzenia z wiązki w celu uzyskania precyzyjniejszych danych. Można byłoby jeszcze czujnik umieścić w jakimś tunelu dobrze dobijającym fale dźwiękowe, żeby skupić wiązkę i przesuwać obiekt na jego końcu. Kolejny skok precyzji. Itd, itp. Mimo wszystko uwazam, że i tak czujnik spełnił swoje nietypowe zadanie bardzo dobrze, biorac pod uwagę, ze producent pisze o najlepszych wynikach odczytu w kacie 15 stopni, pomimo, ze pojedyncze odczyty mozna złapać nawet przy kacie 30 stopni, a mimo, ze zalecana wielkość obiektu to 0,5m2 czujnik zliczy prędkość 2 centymetrowej linijki przesuwanej nad nim. 

Link do komentarza
Share on other sites

Dzień dobry!

Jak zwykle sen przyniósł olśnienie. Pomiar prędkości z jednym czujnikiem tego rodzaju będzie zawsze problematyczny i obarczony bliżej nieokreślonymi, grubymi błędami. Obiekt wpada w chaotyczną wiązkę fal i z niej wychodzi. To co się z nim dzieje w środku wiązki, a przede wszystkim to czy się rusza, czy nie rusza, jest tajemnicą, poza informacją o aktualnej odległości od czujnika. To za mało, a by obliczyć jego prędkość. Stosowanie niepewnych danych producenta o kącie rozwarcia wiązki do obliczeń jest niepewne, bo chmura fal "pływa", a producent chiński i ogólnikowy. Ale jest na to sposób. Drugi taki sam czujnik. Mając dwa czujniki ustawione pod znanym, precyzyjnie określonym kątem oraz znaną odległością między sobą, pozwolą na zbudowanie siatki współrzędnych X,Y i w cudowny sposób umożliwią pozyskanie wiedzy o położeniu obiektu w czasie przechodzenia przez chmurę. Dwa czujniki działające na przemian (aby nie zakłócać swoich wskazań) dadzą bardzo dobry wynik pomiaru prędkości w pewnym oczywiście zakresie, bo przy większej prędkości obiektu narastać będą błędy wynikające z opóźnień spowodowanych czasem upływającym pomiędzy pomiarem dokonywanym przez pierwszy i drugi czujnik. Voila! Chyba sobie zbuduję coś takiego. 🙂

PS. Tak oczywiście, zdaję sobie sprawę, że materiał, kształt, precyzja pomiaru itd, ale chodzi o to ile się da wycisnąć z tego co mamy. A myślę, że zaskakująco wiele. 👍

Link do komentarza
Share on other sites

Odkryłem, że aby zbudować urządzenie mierzące prędkość przy wykorzystaniu dwóch HC-SR04 z zadowalającą dokładnością, trzeba najpierw ustalić "soczewkę pomiaru". Geometrycznie nie jest to zadanie łatwe (jak rozstawić czujniki?). 

Założenia:

1. Mierzymy prędkość poruszającego się punktu (na odcinki, figury, hmmm...bryły przyjdzie czas)

2. Zakres odległości pomiaru od czujnika mieści się w stałych granicach. 

3. Wiarygodnego pomiaru odległości od czujnika można dokonać w wycinku 15 stopni od czujnika. Tak podaje producent i tak wskazuje doświadczenie.

Poniżej wizualizacja:

119887570_2HC-SR04-obszarpomiaru.thumb.png.6a1cdc037a272d9eea3adb502bb50514.png

"Soczewka" HJKL w tym przypadku, akurat w tym ustawieniu czujników, wygląda tak. Bardzo niepokojąco, powiedziałbym. W jej wnętrzu można dokonać wiarygodnego pomiaru drogi obiektu. Czyli, np tor wyścigowy, po którym porusza się samochodzik, którego prędkość chcemy w miarę dokładnie mierzyć musi przebiegać wewnątrz wyznaczonej figury (w odpowiedniej skali).

No i tutaj uświadomiłem sobie, że prędkości samochodu można zmierzyć 2 czujnikami, ale prędkość samolotu... tylko trzema!

Jak będzie wtedy wyglądała "soczewka"? Uhhh... Zaraz jakąś pracę magisterską stworzę, albo licencjat, a ja się chciałem nauczyć trochę elektroniki.. 🤣😂🤣

Link do komentarza
Share on other sites

@Adder w temat nie będę się zagłębiał, ale co do samego kształtu to nie jest trudne.

7 godzin temu, Adder napisał:

Jak będzie wtedy wyglądała "soczewka"?

Skoro tu dla 2D masz fragment koła wycięty innym kołem i część wspólna z podobnym tworem, to w 3D będzie to samo, tylko naniesione na sferę i wyciągnięte.

To w 2D możesz przybliżyć czworokątem, a to w 3D jakimś graniastosłupem.

Link do komentarza
Share on other sites

@Gieneq Tak, to prawda, ale wyobrażasz robie wtedy liczenie warunków dla czujnika do pomiarów wejścia i wyjścia z "soczewki"? Pierwiastkowanie argusów cotangensów to będzie na dzień dobry. 😱 Przy utrzymaniu soczewki o boku wycinka okręgu pomęczyć się trzeba będzie raz, przy ustawianiu czujników. Program natomiast będzie relatywnie prosty obliczeniowo. 

Wymyśliłem sobie nawet praktyczne zastosowanie dla mojego projektu: Tarcza treningowa do rzutów piłka basebolową. Podająca prędkość rzutu i jego celność. Forbocie, wysyłaj mi tu zaraz dwa dodatkowe czujniki 😀

Link do komentarza
Share on other sites

@Adder to wiesz co... może przejdźmy do działu programowanie i zacznij od symulacji. Bo na AVR to lepiej tego nie ruszaj, na STM pewnie, na RPi jak najbardziej, ale na start poćwicz w Pythonie i zobacz czy ugryziesz ten temat. Czujnik możesz sobie jakoś zamodelować kołem wewnątrz którego trafiają się punkty.

Oczywiście warto najpierw zapytać googla czy taki program już nie istnieje i coś z niego podpatrzeć.

Edytowano przez Gieneq
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.