Arduino - zliczanie impulsów

Ja po prośbie do doświadczonych bardziej niż ja...

Otóż próbuję zliczać obroty koła.

Pomiar 1 (jeden impuls/1 obrót koła): Czujnik IR TCRT5000 osłonięty po bokach, w odległości ok 10-15mm od odbijającej powierzchni koła, na której przylepiona jest czarna taśma o długości ok 10cm. Pomiar na analogowym pinie pokazuje ok 400 gdy przed czujnikiem jest powierzchnia odbijająca i ok 27 gdy przed czujnikiem jest taśma.

Pomiar 2 (10 impulsów na 1 obrót koła): na kole umocowanych jest 10 silnych magnesów (10mm średnica, 5mm wysokość, materiał N52) odległość miedzy magnesami ok 10cm. CZujnik - miniaturowy kontaktron. Odległość od magnesu do kontaktronu 3-4mm (sprawdzone - kontaktron zwiera się już przy odległości ok 15mm od magnesu).

Pomiar 3: jak pomiar 2 ale zamiast kontaktronu jest czujnik Halla - odległość od magnesu ok 4-5mm.

pomiar 4 i 5 tak jak 2 i 3, ale ilość magnesów zredukowana do 5

Płytka Arduino UNO R3 ATmega328P (CH340T), nieoryginalne, skrypty bądź z podręcznika Arduino bądź z instrukcji do czujnika Halla.

Spostrzeżenie - przy wolnych obrotach wszystko działa jak powinno i impulsy zliczane są poprawnie. Jednak przy nieco większej szybkości w każdej z powyższych konfiguracji "gubione" są impulsy, czyli zliczonych jest mniej niż powinno być. Prędkość przy której impulsy zaczynają być gubione szacuję na 15-20km/h.

Gdyby impulsów zliczane było więcej niż powinno, to w przypadku kontaktronu zwaliłbym to na wibrację styków... ale tu nie ma znaczenia jaki czujnik jest zastosowany. Ja tego nie rozumiem - przecież częstotliwość pracy Arduino jest o wiele wyższa niż częstotliwość zliczanych impulsów. Czy możliwe jest że płytka Arduino nie działa poprawnie? A jeśli to nie to, to w czym jest problem?

Z góry dziękuję za jakiekolwiek sugestie.

Reply to
Michal M. Lechanski
Loading thread data ...

Kup za 20 zlotych licznik do roweru. Bedzie dzialal i jeszcze bedzie mial bezcenna czesc. Bedzie mial ladna obudowe.

Reply to
Zenek Kapelinder

W dniu 07/07/2017 o 11:05, Zenek Kapelinder pisze:

Już kupiłem. Nadal jednak próbuję to zrozumieć.

Reply to
Michal M. Lechanski

Żadnych przerwań. "Kod" dla czujnika IR jak poniżej. Dla innych czujników poziom "skomplikowania" taki sam.

#include <LiquidCrystal.h>

LiquidCrystal lcd(12, 11, 5, 4, 3, 2);

int val0; int irPin0 = 1; int licznik;

void setup() { lcd.begin(16, 2); licznik=0; val0=0; lcd.clear(); lcd.setCursor(0, 0); lcd.print("val0 = "); lcd.setCursor(0, 1); lcd.print("licznik = "); }

void loop() { val0 = analogRead(irPin0); if (val0 > 100) { licznik++; } lcd.setCursor(8, 0); lcd.print(val0); lcd.setCursor(10, 1); lcd.print(licznik); }

P.S. Przepraszam - w pierwszym poście powinno być: "Pomiar na analogowym pinie pokazuje ok 27 gdy przed czujnikiem jest powierzchnia odbijająca i ok 400 gdy przed czujnikiem jest taśma."

Reply to
Michal M. Lechanski

W dniu 07.07.2017 o 12:24, Michal M. Lechanski pisze:

Witam. Czas konwersji wartości analogowej na cyfrową w Atmedze 328 może sięgać

260us Do tego dochodzi komunikacja z wyświetlaczem. Może po prostu pomiar trafia przed i za czarną taśmą i stąd gubienie impulsów. Swoją drogą dziwię się, że przy wolnych obrotach nie zlicza po dwa, trzy i więcej impulsów na obrót.

Pozdrawiam.

Reply to
Nifhelm

W powyzszym kodzie jesli impuls przyjdzie podczas gdy piszesz do LCD, konsoli lub CPU wykonuje cokolwiek innego to zostanie pominięty.

c.

Reply to
Cezar

W dniu 2017-07-07 o 12:24, Michal M. Lechanski pisze:

Nigdy nic nie pisałem na mikrokontroler. Nie rozumiem tego programu. Jeśli to loop() jest jakoś wołane w pętli to przy zatrzymanym kole w pozycji gdy odczyt analogowy daje >100 licznik będzie ciągle wzrastał.

A zakładając, że to jednak jakoś działa to przypuszczam, że obsługa lcd zabiera dużo czasu.

Spróbuj wypisywać co 10-ty wynik i zobacz czy prędkość graniczna nie wzrośnie 10 razy. P.G.

Reply to
Piotr Gałka

W dniu 07/07/2017 o 11:40, Nifhelm pisze:

Taki efekt zaobserwowałem z magnesami i kontaktronem - zliczane były impulsy gdy kontaktron "najeżdzał" nad magnes i gdy się od magnesu oddalał. Czyli licznik zliczał dwa razy więcej impulsów niż było magnesów. Zmniejszenie odległości kontaktronu od magnesu usunęło ten efekt.

Reply to
Michal M. Lechanski

wyguglaj "arduino analog comparator interrupt count pulses" Kilka pierwszych stron da Ci gotowce.

c.

Reply to
Cezar

W dniu 07/07/2017 o 11:01, Michal M. Lechanski pisze:

Panowie, dziękuję bardzo - spróbuję najpierw wyeliminować wpływ opóźnień związanych z obsługą LCD.

Pozdrawiam

Reply to
Michal M. Lechanski

Ale w dalszym ciągu możesz dostać złe dane. Przez odsunięcie magnesów skróciłeś długośc impulsów. Musisz zliczać *zbocza* a nie stany.

c.

Reply to
Cezar

to jest (nie) rozwiązanie problemu od dupy strony :-)

c.

Reply to
Cezar

W dniu 07.07.2017 o 12:53, Michal M. Lechanski pisze:

Funkcja loop() wykonuje się ciągle od nowa. Za każdym przejściem dokonywane jest sprawdzenie wartości na pinie analogowym i za każdym razem gdy wykrywana jest taśma stan jest zwiększany. Przy każdym przejściu zapisywane są też dane d wyświetlacza LCD. Efektem jest długi czas przejścia pętli oraz to, że jeśli nastąpi dwukrotne sprawdzenie wejścia analogowego za jednym przejściem taśmy przed czujnikiem, to zliczone zostaną dwa impulsy. Po pierwsze zrezygnuj z pomiaru analogowego, bo jest zbyt wolny. Dodaj komparator i wynik na wejście cyfrowe. Po drugie zrezygnuj z zapisu LCD jeśli nie zmienia się wartość licznika. Po trzecie zastosuj wykrywanie przejścia z koła na taśmę, a nie wykrywanie taśmy (zmiana sygnału a nie jego stan). A najlepiej zastosuj przerwania. Pozdrawiam.

Reply to
Nifhelm

Do zliczania impulsów najprosciej skonfigurować licznik TCNT1 by zliczał z wejścia T1.

Osobiście jednak trzymam się z dala od kompilatorów typu Arduino, więc nie wiem jak to dokładnie się robi w tym czymś kompilatoropodobnym. Natomiast w dowolnym C robi się to bez problemu.

Reply to
Pcimol

Użytkownik "Michal M. Lechanski" napisał w wiadomości grup dyskusyjnych:ojnp7k$c2c$1$ snipped-for-privacy@news.chmurka.net... W dniu 07/07/2017 o 11:40, Nifhelm pisze:

Tu nam moze program to filtrowac. Wylapujemy pierwsze zwarcie, wyswietlamy cos na ekranie, czas mija, odczytujemy pin ponownie ... i z powodu minietego czasu drgan juz nie ma ..

J.

Reply to
J.F.

W sumie dość prosto. Trzeba podłączyć sygnał do wejścia D2 lub D3 w Arduino, uruchomić przerwania zewnętrzne na tym wejściu i napisać procedurę obsługi przerwania która będzie zwiększać wartość licznika o 1 o ile od poprzedniej zmiany minął określony czas (likwidacja drgań). I sprawa załatwiona. Pozdrawiam.

Reply to
Nifhelm

Ale wtedy bedzie wszystkie drgania zliczal.

I trzeba zmienic koncepcje, albo dodac na plytce uklad eliminujacy drgania :-)

Wiec zmieniajac watek ... no nie, tu sie z Piotrem zgodze, ze to zaden przyklad, bo o drganiach to w kazdej ksiazce pisza, wiec projektant powinien od poczatku dobrze zaprojektowac.

P.S. te optyczne uklady chyba maja jakas histereze ... wiec zachodzi potrzeba rozpoznania bojem czy wystarczajaca. Aaa ... tu mamy jakis "analogowy", to histerezy nie ma, a bój sie komplikuje :-)

Summa summarum - moze kolega dobrze zrobil, ze pod DAC podpial, tylko teraz trzeba bedzie dobry program napisac :-)

J.

Reply to
J.F.

Akurat Arduino to opakowany avr-gcc więcć trudno to nazwać kompilatoropodobnym...

Reply to
Marek

W dniu piątek, 7 lipca 2017 12:01:02 UTC+2 użytkownik Michal M. Lechanski napisał:

(...)

Zacząc nalezy od tego że wykrywasz poziom zamiast zmiany stanu.

Zmien program na dwa sposoby: po pierwsze wykrywaj zmiane stanu. Czyli jak czujnik przechodzi ze stanu 0 do 1 i odwrotnie to zliczaj te zmiany. Po drugie zmien program tak aby szybko ustalał jaki jest stan czujnika.

Po trzecie musisz pamietac że styki mogą podskakiwać więc musisz to też oprogramować.

Moja sugestia: Korzystaj z kontaktronu o ile tenże kontaktron pozwala na tak szybkie zmierzenie stanu. W przypadku koła o średnicy 28 cali masz obwód 223cm. Przy prędkości 30km/h (8m/sek) to daje około 4 obroty na sekunde. I do tego czas styku kontaktronu to pi*oko 1/100 z tej ćwiartki sekundy.

Musisz upewnic się że ten kontaktron potrafi sie otwoerać i zamykać te 5-10x na sekunde. Warto to zmierzyć np. przepuszczając przez niego sygnał dzwiekowy i nagrac przez karte muzyczna jesli nie masz oscyloskopu.

Tak zobaczysz czy ten kontaktron po pierwsze potrafi sie tak często rozłączać i łączyć oraz jak mocno mu styki podskakują.

Program napisz tak aby procedura działała na przerwaniach zegarowych. Odczytuj status kontaktronu około 500-1000-2000x na sekunde i wynik pomiaru wkładaj do zmiennej jako pojedynczy bit i przesuwaj bity w lewo (zwiekszasz wartośc zmiennej) w sytuacji kiedy masz w zmiennej odpowiednio wysoką wartość wiesz ze styk jest trwale zwarty. Zgodnie z tym ustawiasz sobie wartosci globalnych zmiennej w rodzaju "styk_zwarty".

Jest jeszcze pare alternatyw ale jak zrobisz powyższe to raczej będzie najprościej o ile całośc sie uda (kontaktron nadąży sie zamykać itp.).

Kolejny krok to zbudowac sobie układ z histerezą i nim wywoływać przerwanie.

Reply to
sczygiel

ElectronDepot website is not affiliated with any of the manufacturers or service providers discussed here. All logos and trade names are the property of their respective owners.