Skocz do zawartości

Instrukcja warunkowa i przedziały


Pomocna odpowiedź

Elvis, wiem czym to się różni 😋, dzięki za wskazanie błędu, napisałem tak odruchowo, możliwe że rozwiązałeś mój problem

Rozwiązałeś ale nie do końca 😋 robot cały czas wykrywa ruch 😃. Jakbyście znali jakiś prostszy sposób na zrobienie z fotorezystora czujnika ruchu to był bym wdzięczy za pomoc.

Czyli jak zwykle w takich wypadkach okazało się, że problem jest zupełnie inny niż tytuł i pierwsze pytanie wątku.

Jeżeli chcesz zrobić wykrywanie zmiany położenia (ruchu?) czujnika bazujące na oświetleniu, to najpierw zastanów się jaką cechę sygnału chcesz wykryć. Dobrze kombinujesz z tym porównywaniem wartości poprzedniej z aktualną, bo tak właśnie działają filtry górnoprzepustowe. Z definicji: zmiana jest różnicą między tym co mamy a tym co było. Jeżeli jednak ma to działać dobrze, trzeba jeszcze coś poprawić. Twój sygnał - z tego co napisałeś obarczony jest stosunkowo dużym szumem. Bez ruchu kolejne odczyty powinny być w miarę podobne do siebie. Nie wiem jakie zmiany oświetlenia chcesz wykrywać, ale już widać, że wiele z nich "utonie" w zakłóceniach czyli tych ±10 czy 15 o których pisałeś.

Ja bym najpierw pochylił się nad uzyskaniem stabilnych pomiarów. Szum ADC na takim poziomie może brać się z wielu źródeł. Pierwsza to sam sygnał czyli światło. Jeżeli doświadczenia robisz w pomieszczeniu z żarówkami, świetlówkami lub innymi energooszczędnymi wynalazkami, to te źródła mrugają 100 razy na sekundę. Ty tego nie widzisz, ale fotoopornik tak i w zależności od tego kiedy akurat Arduino wstrzeli się z pomiarem, taki masz wynik. Tego nie zwalczysz chyba, że czujnik ma działać tylko w dzień - Słońce jest dużo stabilniejszym źródłem, ale jego wadą są chmury, pogoda no i pory dnia.

Drugą przyczyną szumu pomiarowego może być sam układ. Wystarczy zasilać go z niestabilnego lub zakłóconego zasilania, a dokładnie to samo przejdzie do wyników. Opisz swój układ. Skąd bierzesz zasilanie, jak to wszystko jest podłączone, czy masz jakieś pracujące napędy itd. Najlepszy byłby schemat połączeń i tzw. real photo.

Poprawny układ i stabilne oświetlenie powinny zwracać odchyłki między kolejnymi pomiarami nie większe jak ±1-2 wartości.

A teraz sama obróbka danych. Ja bym przede wszystkim zrobił lepsze "przyzwyczajanie" się algorytmu do obecnych warunków. Jak często robisz te swoje pomiary? Spróbuj pamiętać historię ostatnich np. kilku sekund oświetlenia i dopiero uśrednioną za ten czas wartość traktować jako poziom odniesienia, np:

#define DLUGOSC_HISTORII 10
#define KANAL_FOTO 2
#define PROG_ZADZIALANIA 20

int pomiar;
int historia[DLUGOSC_HISTORII];
int licznik_zapisu = 0;
int srednia_z_historii;
int n;

while(1)
{
 srednia_z_historii = 0;
 for (n=0; n<DLUGOSC_HISTORII; n++)
   srednia_z_historii += historia[n];
 srednia_z_historii /= DLUGOSC_HISTORII;

 pomiar = analogRead(KANAL_FOTO);

 if (abs(srednia_z_historii - pomiar) > PROG_ZADZIALANIA)
   wykryto_ruch();

 historia[licznik_zapisu++] = pomiar;
 if (licznik_zapisu >= DLUGOSC_HISTORII)
   licznik_zapisu = 0;

 delay(500);

}

Zbierane w tablicy historia[] wyniki najpierw są sumowane a potem dzielone przez ich liczbę więc w dostajemy średnią za okres całej zgromadzonej historii. Z tą średnią porównuję aktualny pomiar i jeśli różnica jest większa niż zadany próg, wywołuję funkcję alarm(). Potem trzeba jeszcze wstawić najnowszy pomiar do historii nadpisując najstarszy zapamiętany wynik. W tej pętli co pół sekundy będziesz wykonywał nowy pomiar a ponieważ historia zawiera 10 pomiarów, masz uśrednianie oświetlenia za 5 ostatnich sekund. Możesz dowolnie regulować te parametry i eksperymentować, wypisując np. poszczególne zmienne przez port szeregowy.

Problemem może być to, że dopóki historia nie napełni się sensownymi wynikami, na początku ma same zera i wtedy każdy pomiar wywołuje alarm. Możesz to rozwiązać poprzez wpisanie na początku (przed while) prostej pętli robiącej jeden odczyt czujnika i wpisujący to samo do całej historii. Wtedy już "pierwszy strzał" wypełnia całą historię i liczona za chwilę średnia od razu ma jakiś sens.

Powyższy kod nie zajmuje się w ogóle problemem szumu w pomiarach więc nadal zostaje strefa nieczułości związana z przypadkowo mierzonymi fluktuacjami sygnału a PROG_ZADZIALANIA musi być w oczywisty sposób od tego szumu większy. Możesz to poprawić (jeżeli jest to rzeczywiście szum losowy a nie zakłócenia od żarówek) robiąc zamiast jednego pomiaru od razu kilka i biorąc jako ostateczny wynik pomiaru ich średnią.

Bądź aktywny - zaloguj się lub utwórz konto!

Tylko zarejestrowani użytkownicy mogą komentować zawartość tej strony

Utwórz konto w ~20 sekund!

Zarejestruj nowe konto, to proste!

Zarejestruj się »

Zaloguj się

Posiadasz własne konto? Użyj go!

Zaloguj się »
×
×
  • Utwórz nowe...