Jeszcze w połowie 2014 roku szukałem czujnika, który pozwoli mi na pomiar odległości człowieka i sterowanie za jego pomocą oświetleniem w postaci taśm LED. Do czego potrzebne mi takie urządzenie? Wystarczy wyobrazić sobie sytuację, kiedy wracamy do domu wieczorem i nie sposób zlokalizować zamka do drzwi. Oczywiście można wykorzystać do tego celu wszelkie czujniki PIR. Jednak one wykrywają ruch, a nie określają odległość. Zależało mi na tym, żeby odczyt odległości był przekładany na odpowiedniej wartości sygnał PWM. Czyli im bliżej do drzwi, tym jaśniej.
Na początku wykorzystałem standardowy czujnik ultradźwiękowy, który dostałem w którymś z KITów Arduino. Niestety, ale okazał się całkowitą porażką przy detekcji człowieka. O ile sprawdził się dobrze przy weryfikacji odległości od płaskiej, prostopadłej przeszkody, o tyle przy detekcji człowieka dostawał czkawki. Objawiało się to tym, że odczyty były zupełnie nierówne i nie potrafiłem wyselekcjonować z nich właściwych wartości.
Po poszukiwaniach i założeniu wątku na Forum Majsterkowo, dotarłem w końcu do urządzenia, które co prawda jest dużo droższe, ale znacznie dokładniejsze. Sprawdza się świetnie w pomiarze odległości od/do człowieka. Przy zastosowaniu, które tu opiszę nie ma nawet większej potrzeby filtrowania odczytów, jednak ze względu na charakter edukacyjny – warto o tym wspomnieć. Urządzenie to LV-MaxSonar-EZ0 MB1000. To czujnik o najszerszej wiązce pomiarowej i zasięgu ok. 5-6 m. W polskiej dystrybucji jest dostępny w sklepie Nettigo.pl i szczerze mówiąc, nie znalazłem go nigdzie indziej. Cena na początku mnie odstraszyła, więc pogrzebałem trochę na stronach zachodnich (i wschodnich) sprzedawców, ale nie znalazłem tańszych odpowiedników. A dokładnie ten sam model był oferowany w zbliżonej, a czasami nawet wyższej cenie.
Na koniec wstępu warto zaznaczyć, że pomimo iż projekt chciałem zrealizować latem, wciąż jest na płytce prototypowej. A to dlatego, że ciągle znajduję nowe zastosowania czujnika i je testuję.
Niezbędnik
W założeniu projekt był przewidziany do montażu w wejściu do szeregówki, gdzie prowadzą proste schody ze spocznikami. Dlatego wybrałem czujnik o najszerszym dostępnym zakresie. W przypadku aplikacji w innych zastosowaniach, należy dobrać parametry na podstawie wykresów producenta.
Do montażu będziemy potrzebować:
- czujnik LV-MaxSonar-EZ0 MB1000 [link]
- płytkę Arduino [właściwie zadziała każde dostępne]
- taśmę LED 12V (tu 60 LED 3528/mb)
- MOSFET IRF540
- rezystor 10-30k [np. 10k, 22k]
- zasilacz 12V o mocy dobranej do taśmy LED [ja wykorzystam ATX DIY]
W przypadku prototypowania przydadzą się ponadto:
Schemat
Schemat wygląda banalnie:
- Czujnik LV-MaxSonar-EZ0 MB1000 posiada 7 punktów na przewody lub goldpiny. Zdecydowałem się na wlutowanie goldpinów i prowadzenie przewodów żeńsko-męskich. Do złącza GND wpinamy GND z Arduino lub zasilacza, do 5V (VCC) podłączamy pin 5V z Arduino, pin PW podłączamy do 2. pinu cyfrowego Arduino (D2).
- Bramkę MOSFETu IRF540 łączymy z pinem 3. cyfrowym Arduino (D3). Do drenu “minus” taśmy ledowej, a do źródła “minus”/GND zasilacza.
- Pomiędzy bramkę, a źródło montujemy rezystor. Zwykle stosowałem rezystory 10k, jednak w tym wypadku zadziałał dopiero 30k.
- +12V z zasilacza podłączamy do pinu VIN Arduino. Podobnie “minus”/GND zasilacza do GND Arduino.
- “Plus” taśmy LED podłączamy do +12V zasilacza.
Program
Zdawałoby się, że kod nie będzie niczym wyjątkowym. A jednak w sytuacji, gdy wykorzystujemy odczyt niemal ciągły, nasz zasilacz lubi się zgubić i podać dziwną wartość. Dlatego w programie dodana jest funkcja wybierania mediany spośród 7 pomierzonych próbek. Być może w odpowiednich warunkach czujnik będzie podawał właściwe wartości, jednak w przypadku tego projektu zdarzało mu się podawać odczyty, które robiły dyskotekę.
Pominąłem zmianę odczytu na cale/centymetry, bo nie ma tu zastosowania. Jednak, gdyby ktoś potrzebował takiej funkcji, zapraszam do przejrzenia bibliografii na dole projektu.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 |
#define SENSOR_PIN 2 #define led_PIN 3 #define array_SIZE 7 int distR; int dist[array_SIZE]; void setup() { Serial.begin(9600); // komunikację przez Serial wykorzystujemy do poznania min/max odczytów i ew. debugowania pinMode(SENSOR_PIN, INPUT); pinMode(led_PIN, OUTPUT); } void loop() { // wykonaj odczyt "array_SIZE" razy for (int i = 0; i < array_SIZE; i++) { dist[i] = pulseIn(SENSOR_PIN, HIGH); } // wywołanie funkcji sortującej tabelę sort(dist, array_SIZE); // wyświetlenie posortowanej tablicy dla łatwiejszego określenia wartości min/max Serial.print("Posortowane: "); for (int i = 0; i < array_SIZE; i++) { Serial.print(dist[i], DEC); Serial.print (" "); } Serial.println(); // wybór środkowego pola z tablicy distR = dist[array_SIZE/2]; // minimalny odczyt mojego czujnika wynosił 826 // maksymalny 9033, stąd te wartości int pwm = map(distR, 826, 9033, 255, 0); // podanie sygnału PWM na pin "led_PIN" o wartości PWM analogWrite(led_PIN, pwm); // odrobina opóźnienia pomiędzy pętlami // w przypadku odczytów min/max warto zwiększyć wartość do ok. 5000, // żeby mieć czas na odczytanie delay(50); } // sortowanie odczytów void sort(int *a, int n) { for (int i = 1; i < n; ++i) { int j = a[i]; int k; for (k = i - 1; (k >= 0) && (j < a[k]); k--) { a[k + 1] = a[k]; } a[k + 1] = j; } } |
Efekty zmagań
Moja karta pamięci nie lubi się z aparatem i czasami po prostu nie nagrywa filmów. Mam nadzieję, że zdjęcia wystarczą. Zdjęcia zrobiłem na manualnej ekspozycji, żeby było widać, jaka jest różnica w oświetleniu. Zakresu miałem tyle, ile kabla w pilocie.
Sam układ na płytce prototypowej wygląda, jak na zdjęciu poniżej. Jak widać i tym razem trzecia ręka ze statywów kulkowych (z poprzedniego projektu) się przydała :)
Napisy końcowe
Oczywiście zdaję sobie sprawę z faktu, że zamiast Arduino można było wykorzystać tranzystor mocy do sterowania przez wyjście analogowe. Mój wybór padł jednak na uC ze względu na niski koszt (Nano to ok. $2-3 z Dalekiego Wschodu). Poza tym, mikrokontroler pozwala nam na filtrowanie wyników. A czujnik pomimo, że najdokładniejszy, jaki znalazłem, miewa “humory” i potrafi odczytać wartość zupełnie losową.
Poza tym, można mieć wątpliwości, czy zastosowanie tak drogiego czujnika ma w ogóle sens. Przecież za ułamek ceny można mieć najzwyczajniejszy naświetlacz halogenowy z czujnikiem PIR, podłączyć go pod 230V i mieć problem z głowy. To wszystko prawda. Pamiętajcie tylko, że zakładałem na początku użycie taniego czujnika odbiciowego z KITa. A jak ten pomysł nie wypalił, za mocno wciągnąłem się w projekt, żeby go po prostu zostawić.
Czujnika używałem też do innych prób i sprawdzałem jego możliwości. Co się nauczyłem i popsułem po drodze to moje. Jak się okazało, jest to naprawdę przemyślany układ, dla którego można znaleźć wiele zastosowań. I to właśnie jego możliwości spowodowały, że projekt jest wciąż w powijakach, a nie na framudze :)
Teraz używam tego czujnika wraz z Processingiem, ale największym problemem pozostaje stabilność odczytów. Już przy 24 fps niewłaściwy odczyt stanowi problem, a przy 60 fps właściwie niszczy cały zamierzony efekt. Czas pokaże, jaki będzie ciąg dalszy przygody z pomiarem odległości…
Bibliografia
Podczas pracy nad tym projektem korzystałem z różnych źródeł. M.in.:
- problemy z odczytami czujnika, skąd się biorą i metody eliminacji: http://forum.arduino.cc/index.php/topic,20920.0.html
- wyczerpujący opis wszystkich możliwości odczytu danych z czujnika (analog, PWM, serial): http://starter-kit.nettigo.pl/2010/05/sonar/
- przydatne opisy algorytmów, może i podstawy, ale znać warto: http://edu.i-lo.tarnow.pl/inf/alg/001_search/0042.php
- jeszcze raz, porównanie sensorów: https://nettigo.pl/articles/maxbotix
Fajne i efektowne (4/5), ale na razie zastosowania są trochę małe.
Pomyśl nad zrobieniem alarmu (jeszcze jakaś syrena) i będzie o wiele więcej zastosowań. ;)
Dzięki za dobre słowo :)
Zależało mi głównie na prezentacji możliwości czujnika, bo sporo czasu, testów i kasy mi zeszło zanim trafiłem na ten właściwy. A jak już trafiłem, to zacząłem się męczyć z tym filtrowaniem odczytów, które w Processingu są wręcz niezbędne.
O alarmie nawet nie pomyślałem, a pomysł interesujący. Trzeba by tylko sprawdzić, czy wyłapie kota ;)
Jeśli chcemy uniknąć używania takiego czujnika to można by spróbować ustawić kilka czujników ruchu tak, by zrobić kilka stref odległości. Ale pewnie nie wyjdzie to już dużo taniej ;)
Myślałem o tym, ale odrzuciłem ten pomysł z innego powodu – ciągnięcie kabli. W wypadku odczytu odległości można wszystko zamknąć w jednej eleganckiej puszce i nie martwić się o przewody. W przypadku sieci PIRów trzeba by zatroszczyć się dodatkowo o ukrycie przewodów (VCC, GND i sygnał do każdego punktu). No i pytanie, gdzie montować czujniki, gdy nie mamy “dachu nad głową”, a czynniki atmosferyczne jednak mogą im zaszkodzić.
Ale muszę przyznać, że dałeś mi do myślenia. Tak się składa, że zamówiłem kiedyś większą ilość PIRów do Arduino, ale nie wykorzystałem ze względu na ich rozmiar. Może to być dobra opcja do aplikacji w pomieszczeniach :)
Fajny pomysł i wykonanie. Jedna tylko sprawa – ja bym zrobił chyba odwrotnie. Jeśli to ma działać w ciemności, to po wykryciu ludzia z maksymalnej odległości, rozjaśniłbym na maksa (by nie było zaskoczenia, można rozjaśniać stopniowo, ale w krótkim czasie), by oświetlało drogę do drzwi i potem w miarę zbliżania się obniżał jasność, by nie dawało po oczach jak będę celował kluczem :)
też pomyślałem o odwrotnym działaniu. jak daleko to jasno a potem by nie raziło ściemniało się w miarę zmniejszenia odległości. ale pomysł fajny, piąteczka
Moim zdaniem takie “tutoriale” są po to, żeby je rozwijać. Akurat zmiana na odwrotne świecenie to bardzo prosta rzeczy. Wystarczy zmienić granice mapowania zmiennej pwm, czyli zakutalizować wiersz:
int pwm = map(distR, 826, 9033, 255, 0);
na:
int pwm = map(distR, 826, 9033, 0, 255);
I już będzie świecić dokładnie tak, jak o tym piszecie :)
nie wszyscy posiadają aż taką wiedzę, ale masz w stu procentach rację. każdy projekt można rozwinąć
na wish nano mozna kupic doslownie za 4 zl(zamowilem juz 6 xD), wiec wydaje mi sie ze nie ma potrzeby uzywac golej atmegi do takich projektow :) Bez problemu takie arduino mozna sobie wlutowac/zrobic wejsc.
Sam uzylem nano do motoru i sprawuje sie swietnie :)
Podoba mi się pomysł z świecącą ościeżnicą! Ja jednak podkradając kod, wykorzystam to do podświetlenia szafek wiszących w kuchni, czujnik oczywiście byłby z tych o mniejszym zakresie (małe mieszkanie). Chciałbym jednak poprosić o radę dotyczącą klonów arduino z aliexpress lub innych chinszczyzn – jako pierwsze arduino, można śmiało zamawiać klon za kilka $? Czy raczej na początek zainwestować 90zł w oryginał? (moj budżet na hobby został ograniczony ostatnio przez regenerację turbiny w samochodzie :/ )
Ja używam klonów i to w wielu wersjach. Mam po jednym Mega ADK, UNO i Leonardo do prób, a gotowe projekty lecą na Nano albo MicroPro w zależności od potrzeb edytowania w przyszłości.
Jeżeli projekt jest zainstalowany w terenie, wolę Nano, bo podłączam się łatwo przez USB i jest mniejsza szansa, że się coś posypie i zostanę na lodzie.
Póki co – żadnych problemów z klonami nie miałem. Usmażyłem jedną Atmegę8A, ale to zupełnie inna historia ;)
Minus tylko taki, że obecnie dolar mocno poszedł w górę.
No i rozpocząłem zabawę. Nurtuje mnie jedna rzecz – czy w Twoim korytarzu, oprócz zbliżającego się człowieka – są inne przeszkody które sonar wykryje i – w rezultacie – włączą się LED’y? Czy też przykładowy korytarz musi być absolutnie pusty? Zastanawiam sie nad czujnikiem o bardzo wąskim promieniu, tak aby ‘oczekiwał’ obietu jedynie w framudze drzwi kuchennych, w przeciwnym wypadku wykryje chyba wszytsko: lodówkę, szafki, kwiaty doniczkowe, kota i co tam wejdzie w obszar. Bawię się w tej chwli standardowym czujnikiem HC-SR04 i szlag mnie trochę trafia jak to ustrojstwo jest kapryśne.
Wybacz opóźnienie w odpowiedzi.
HC jest faktycznie beznadziejny. Kiedyś trafiłem na okazję i zamówiłem od razu 7-8 sztuk. Niestety okazało się, że wykorzystanie jest bardzo ograniczone i nadają się tylko do prostopadłych przeszkód. Inaczej z odczytów mamy dyskotekę.
Co do czujników w korytarzu, to faktycznie fragment, który powinienem rozwinąć. Zamówiłem kilka innych wersji z różnymi kątami odczytu i niestety jeszcze nie miałem okazji ich przetestować. O ile dobrze pamiętam w/w układ był filtrowany w programie albo tak się złożyło, że sam usuwał niewłaściwe odczyty przeszkód. Ale faktem jest, że trzeba to samemu przetestować. Na początku musiałem sporo się nakombinować, zanim odkryłem, że przeszkody lubią mieszać w odczytach.
Te układy są dokładne. Czasami chciałoby się, żeby wykrywały trochę większe przeszkody niż każdą drobnostkę, którą spotkają.