Czujnik ruchu PIR HC-SR501

HC-SR501 to bardzo popularna i tania czujka PIR (passive infrared) pracująca w paśmie podczerwonym.

pir_000Jej zadaniem jest wykrywanie ruchu. Reaguje, gdy w jej polu widzenia – katalogowo do 7m – przemieści się jakiś obiekt.

Podłączenie

pir_005pir_001Do podłączenia HCSR-501 wystarczą 3 przewody:

  • VCC: zasilanie, od 4.5 – 20V (!), pobór prądu 50uA,
  • GND: masa,
  • OUT: wyjście logiki:
    • 3.3V (stan wysoki), gdy wykryto ruch;
    • GND (stan niski) – gdy jego brak.

Jeżeli w zasięgu czujki przemieści się jakiś obiekt – stan jej wyjścia OUT zmieni się z niskiego na wysoki.

Płytkę czujki wyposażono w dwa potencjometry pozwalające na  dostrojenie czasu trwania sygnału wysokiego i zasięgu.

pir_002Potencjometr Tx reguluje czas trwania sygnału wysokiego po wykryciu obiektu, w granicach od 5 – 200s. Dla mojego czujnika:

  • Pozycja skrajna: 5.8s;
  • Pozycja 90st: 16s.
    pir_007
  • Pozycja środkowa: 100s
  • Druga skrajna: 190s

Zasięg czujki to maksymalnie 7 m, kąt widzenia 100 stopni:

pir_006Zasięg ten możecie regulować za pomocą potencjometru Sx, w granicach 3 – 7m. W przypadku mojej czujki było to 2.8m – 7.6m.

Dodatkowa zworka MD pozwala na zmianę sposobu reakcji czujki na pobudzenie.

pir_003W zależności od jej ustawienia:

  • H: (stan domyślny) czujka utrzymuje stan wysoki na wyjściu dopóki wykrywa jakiś ruch w ciągu czasu ustawionego potencjometrem Tx (retriggering mode),
  • L: czujka sygnalizuje stanem wysokim każdy kolejny wykryty ruch; po wykryciu ruchu czujka przechodzi w stan wysoki, który trwa zgodnie z ustawieniem Tx, potem przechodzi w stan niski i po raz kolejny wejdzie w stan wysoki po wykryciu kolejnego ruchu.

Co ciekawe, możecie dostać dwie wersje tego czujnika: jedną z padami smd (zielona) – drugą z pinami wlutowanymi w miejscu MD:

pir_004

Podstawowy układ

Wyjście OUT czujki jest typu cyfrowego i pracuje z logiką 3.3v. Dzięki temu możecie tą czujkę podłączać bezpośrednio do Arduino lub Raspberry.

Dla Arduino podłączcie czujkę na przykład tak:

pir_008Gdy to zrobicie, pozostanie jedynie wykrycie momentu, w którym stan pinu OUT zmienia się z niskiego na wysoki. Dzieje się tak, gdy w polu widzenia czujki zachodzi jakaś zmiana – spowodowana np. poruszającym się przedmiotem.

Oczywiście możecie „poczekać” na sygnał wysoki na pinie D2:

Programik ten co 100ms sprawdza stan sygnału na pinie D2. Jeżeli pojawi się na nim sygnał wysoki (odczytany funkcją digitalRead()) – wywołuje funkcję alarm(), w której podejmowane są akcje związane z podniesiem larum.

Dodatkowe instrukcje Serial… wypisują na konsoli szeregowej kropki w pętli głównej lub napis „ALARM!” na czas trwania sygnału wysokiego (w funkcji alarm()).

Funkcja alarm() będzie wywoływana wielokrotnie, co 100ms tak długo, jak pin OUT czujki PIR będzie w stanie wysokim.

W praktyce możecie potrzebować jednak rozwiązania, gdzie kod reaguje nie na stan sygnału – ale jego zmianę.

Przerwania

W takim przypadku warto wypróbować mechanizm zwany przerwaniami. Przerwania to nic innego jak takie pobudzenia przychodzące od zewnętrznych układów – na przykład opisywanej  czujki PIR. Czujka przerywa działanie programu głównego. W ten sposób wymusza reakcję procesora na wykrycie ruchu.

Wodróżnieniu do przykładu przedstawionego powyżej – Arduino nie odpytuje co chwilę o stan czujki (digitalRead() w funkcji loop()). To czujka przerywa na chwilę pracę kontrolera Arduino.

Dla Arduino UNO mamy 2 piny, które obsługują zewnętrzne przerwania (a więc przychodzące z podłączonych do Arduino układów): D2 i D3.

Zmodyfikujemy nasz program:

Zauważcie, że w pętli głównej progamu loop(), funkcja alarm() wcale nie jest wywoływana! Program idzie swoją drogą – wysyłając na port szeregowy co 100ms napis „…….uczymy.edu.pl”.

Kluczową jest tu instrukcja „attachInterrupt()” umieszczona w funkcji setup(). Konfiguruje ona obsługę przerwań tak, że:

  • Przerwanie podłączone jest do pinu cyfrowego D2,
  • Przerwanie obsługiwane jest przez funkcję alarm() (ISR: interrupt service routine),
  • Funkcja alarm() będzie wywołana wtedy, gdy stan pinu D2 zmieni się z niskiego na wysoki (wyzwalanie zboczem rosnącym): RISING; dla Arduino UNO możecie też użyć:
    • FALLING: funkcja ISR jest wywoływana, gdy stan pinu zmienia się z wysokiego na niski (zbocze opadające),
    • CHANGE: RISING lub FALLING,
    • LOW: gdy stan pinu jest niski,
    • Dla UNO nie działa: HIGH.

Dla ustawienia RISING, gdy na pinie D2 sygnał zmieni się z niskiego na wysoki – procesor przerwie wykonywanie pętli głównej programu (loop()) i wskoczy do funkcji alarm().

Takie podejście ma jednak swoje konsekwencje:

  • Funkcja alarm() zostanie wywołana tylko raz, w momencie gdy czujka wykryje ruch,
  • Następny raz funkcja alarm() zostanie wywołana dopiero gdy czujka powróci do stanu niskiego i z powrotem zostanie wzbudzona,
  • Jako obsługa przerwania, funkcja alarm() może być przedmiotem pewnych ograniczeń związanych np. z użyciem zmiennych globalnych lub wykorzystaniem portu szeregowego (ale to temat na osobny tekst:))

Źródła

6 myśli w temacie “Czujnik ruchu PIR HC-SR501”

    1. Niestety nie. Długość sygnału wysokiego nie ma nic wspólnego z odległością od wykrytego obiektu. Poza tym – ta czujka działa w 3D:) Do sprawdzenia odległości od obiektu można użyć HC-SR04, czujek podczerwonych (np. opisywany TCRT5000) i podobnych.

  1. Pingback: -N/A-

Dodaj komentarz