2013-01-11

Czujnik odległości

Kolejnym moim testem jest ultradźwiękowy czujnik odległości - model HC - SR04.




Dane techniczne:

  • Zasilanie: DC 5 V
  • Częstotliwość: 40Hz
  • Max zasięg: 4m
  • Min zasięg: 2cm
  • Kąt działania: 15º 
  • Wymiary: 45*20*15mm
  • Waga: 90 gr
Dokumentacja TUTAJ, koszt takiego urządzenia to około 3 euro. Jak być może widać na rysunku czujnik posiada 4 piny: 5V, OUTPUT, TRIGGER, GND.


Sposób działania:

W stanie nieaktywnym na pinie OUTPUT jest zawsze 0V. Żeby aktywować czujnik (czyli, żeby wygenerowany został impuls ultradźwiękowy - a dokładniej 8 takich impulsów) wysyłany jest sygnał (co najmniej 10us) na port TRIGGER. Na porcie OUTPUT pojawia się wtedy stan wysoki (+5V) i pozostaje on w tym stanie dopóki sygnał ultradźwiękowy nie powróci do czujnika (czyli po odbiciu się od badanego obiektu). Żeby wyznaczyć odległość musimy zmierzyć ten czas, wziąść pod uwagę prędkość dźwięku i podzielić na 2 (bo droga jest do obiektu i z powrotem).
Tu niestety należy zwrócić uwagę na spore ograniczenie tego zestawu - czyli dużą niedokładność mierzenia czasu na RPI/Linuxie... Tak naprawdę powinniśmy zastosować dodatkowy hardware (albo wykorzystać np. Arduino), zapewniający nam dokładniejsze wyliczenia czasu. Dla zainteresowanych szczegółami proponuje poszukać zagadnienia "non realtime os".


OSTRZEŻENIE !
Przy podłączaniu wszelkich kabelków należy zachować ostrożność, gdyż może zakończyć się to uszkodzeniem sprzętu lub uszczerbkiem na zdrowiu. Robisz to na własną odpowiedzialność.


Układ:

Od razu zaznaczę, że tym razem znalazłem gotowe rozwiązanie i niezbyt wysilałem się intelektualnie. Za układ i kod możemy podziękować autorowi tej strony:

Jak możemy wyczytać na powyższej stronce - problemem tego czujnika (w przypadku współpracy z Malinką) jest fakt, że pracuje z napięciem 5V. Jak już wiemy (np. STĄD) porty GPIO mogą pracować z napięciem 3.3V, więc musimy wykorzystać prostą sztuczkę z rezystorami.

tak więc układ:

+5V - pin 2 w RPI
GND -  pin 6 w RPI
Trigger - GPIO 23
Echo - rezystor 330 Ω (lub 1K) -> GPIO 24 -> rezystor 470 Ω (lub 1K5) -> GND

Źródło: raspberrypi-spy.co.uk

wartości rezystorów mogą być oczywiście inne - tak jak zaleca autor - muszą spełniać zależność :
R1 < R2 < 2*R1

Przydałoby się jednak kupić kolorowe kabelki ;)

Kod:

kod wrzucam również w oryginale (szacunek dla autora), mimo, że ja go nieco zmodyfikowałem (np. wrzuciłem pętle, żeby odległość sprawdzana była co parę sekund - w ten sposób wygodniej mi było testować ;) ).

#!/usr/bin/python
#+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
#|R|a|s|p|b|e|r|r|y|P|i|-|S|p|y|.|c|o|.|u|k|
#+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
#
# ultrasonic_1.py
# Measure distance using an ultrasonic module
#
# Author : Matt Hawkins
# Date   : 09/01/2013

# Import required Python libraries
import time
import RPi.GPIO as GPIO

# Use BCM GPIO references
# instead of physical pin numbers
GPIO.setmode(GPIO.BCM)

# Define GPIO to use on Pi
GPIO_TRIGGER = 23
GPIO_ECHO = 24

print "Ultrasonic Measurement"

# Set pins as output and input
GPIO.setup(GPIO_TRIGGER,GPIO.OUT)  # Trigger
GPIO.setup(GPIO_ECHO,GPIO.IN)      # Echo

# Set trigger to False (Low)
GPIO.output(GPIO_TRIGGER, False)

# Allow module to settle
time.sleep(0.5)

# Send 10us pulse to trigger
GPIO.output(GPIO_TRIGGER, True)
time.sleep(0.00001)
GPIO.output(GPIO_TRIGGER, False)
start = time.time()

while GPIO.input(GPIO_ECHO)==0:
  start = time.time()

while GPIO.input(GPIO_ECHO)==1:
  stop = time.time()

# Calculate pulse length
elapsed = stop-start

# Distance pulse travelled in that time is time
# multiplied by the speed of sound (cm/s)
distance = elapsed * 34300

# That was the distance there and back so halve the value
distance = distance / 2

print "Distance : %.1f" % distance

# Reset GPIO settings
GPIO.cleanup()

A to mój profesjonalny zestaw do badań skuteczności czujnika ;) czyli pusta przestrzeń, miarka oraz ciemny przedmiot z prostym kształtem. 



Wg moich badań precyzja jest naprawdę dobra. Powtarzalność wyników jest bardzo dobra (nie skacze np o parę centymetrów), dokładność również całkiem niezła. Dla prostych zastosowań zdecydowanie wystarczająca.  
Zbadałem też układ z innymi przedmiotami i wyniki również są obiecujące. Ultradźwięk to jednak dobra opcja.

Podsumowując, mimo swoich ograniczeń czujnik + RPI to ciekawy zestaw. Jeśli w naszym projekcie niezbędna jest duża precyzja to zapewne warto poszukać innego rozwiązania, jeśli możemy przymknąć na to nieco oko - zdecydowanie polecam.

To już chyba mój ostatni czujnik na tą chwilę. Pora się zabrać za jakiś konkretny projekt. Mam pomysł (mam nadzieję, że starczy mi chęci i umiejętności) - ale do jego realizacji jeszcze dłuuuuga droga. W międzyczasie będę starał się wrzucać kolejne posty dotyczące RPI.    

12 komentarzy:

  1. Witam, mam do Pana sprawę dotyczącą czujnika opisanego na tym blogu. Jeśli jest taka możliwość to proszę o kontakt, kop8g@op.pl

    OdpowiedzUsuń
  2. Bardzo interesujacy projekt. Jestem ciekawy kolejnych.

    OdpowiedzUsuń
  3. Witam,dzięki za przykład. Funkcję obliczającą odległość można skrócić najpierw jest mnożenie przez 34300 a potem dzielenie przez 2 (2 * 4 /2 = 2* 2) więc można dać tylko samo dzielenie przez 17150.

    Skopiowałem sobie kod ale

    OdpowiedzUsuń
  4. Witam czy bez rezystorów też będzie działał czujnik jak podepnę go bezpośrednio do płytki?

    OdpowiedzUsuń
  5. Wpis zawiera bardzo ciekawe informacje

    OdpowiedzUsuń
  6. Wydaję mi się że takie urządzenie może być bardzo przydatne

    OdpowiedzUsuń
  7. Podoba mi się ta recenzja. Ciekawy produkt godny uwagi.

    OdpowiedzUsuń