Skocz do zawartości

Mierzenie prędkości obrotowej za pomocą czujnika HONEYWELL 1GT101DC i Arduino.


Pomocna odpowiedź

Napisano

Witam, mam pytanie jak podłączyć czujnik HONEYWELL 1GT101DC i jak w takim wypadku ma wyglądać program na Arduino?

Próbowałem już wielu sposobów, ale nic nie zadziałało. Wpinałem wyjście czujnika zarówno pod pin analogowy jak i cyfrowy. Czujnik zasilam z Arduino. Projekt ma wyglądać w ten sposób, że d wałka przykręcam dwie śrubki, mierzę czas impulsów i z tego wyliczam obroty/min (po poprzednim podzieleniu wyniku na 2). Do dyspozycji mam ten czujnik i na nim musi to być zrobione.

Z góry dzięki za pomoc

Odpowiedz na każde z tych pytań:

1. Czy widziałeś ten dokument?

https://www.tme.eu/pl/Document/87cdfa44b324e586219728645eb6d16a/1gt101dc.pdf

2. Czy go przeczytałeś i czy jest jasny a jeśli nie, to w którym miejscu?

3. Czy podłączyłeś swój czujnik wg tego dokumentu (kolory kabelków)?

4. Czy rozumiesz co znaczy zdanie "Output is digital, current sinking (open collector)"?

5. Czy możesz pokazać schemat tego podłączenia?

6. Czy jakoś testowałeś działanie czujnika na tych swoich śrubkach? Czy np. na woltomierzu widziałeś dwa impulsy / obrót przy powolnym obracaniu wałka ręką?

7. Pokaż co próbowałeś (program) i co dokładnie w nim nie działało.

EDIT: I jeszcze:

8. O jakim zakresie prędkości rpm lub obr/s mówimy?

Dzięki za szybką odpowiedź.

Kartę produktu widziałem, podłączałem zgodnie z objaśnieniami w niej zawartymi. Jest dosyć zrozumiała oprócz tego zdania, które podałeś (wiem, że wyjście cyfrowe, ale mi nie działało).

Schematu połączenia praktycznie nie ma, czujnik połączony z Arduino na płytce zgodnie z kartą produktu.

Testy polegają na zbliżaniu metalowego elementu do czujnika, na razie nie mam dostępu do wałka.

Ostatni program, na którym coś sprawdzałem:

int odczytanawartosc=0;
void setup() { // put your setup code here, to run once:
      pinMode(A5,INPUT);
    Serial.begin(9600);
 }

void loop() {
 odczytanawartosc=analogRead(A5);
 if (odczytanawartosc>0){
 Serial.println(odczytanawartosc);
delayMicroseconds(15);
}  
}

Problem jest taki, że pokazuje mi cały czas wartości większe od 0, których nie powinno być. Zakres: 0-1000 obr/min

Chyba nie zrozumiałeś. Miałeś odpowiedzieć na wszystkie 8 pytań a nie tylko na wybrane. Umiesz liczyć? To spodziewam się 8 punktów odpowiedzi.

Wskazówka: Nie zadaję pytań bo interesuje mnie Twój projekt. One miały naprowadzić Cię na rozwiązanie.

Moje dotychczasowe wnioski:

- Nie rozumiesz wyrażenia "open collector" - poczytaj o tym i zmień konfigurację swojego wejścia bo to jest tu kluczowe,
- Jeśli nie podłączyłeś woltomierza i nie sprawdziłeś czy czujnik podaje cyfrowe stany 0/1 na wejście procesora to a) nie rozumiesz tego co czytasz, b) nie umiesz(?) zrobić najprostszego pomiaru (albo nie masz woltomierza..) za to wolisz zmyślać jakieś bzdury np. o sygnale analogowym (skąd Ci to przyszło do głowy, przecież podobno czytałeś kartę katalogową?),
- Program jest tak głupi, że nie chce mi się go nawet komentować.

Skoro już wiesz, że czujnik ma wyjście cyfrowe i przeczytałeś już o "open collector" np. tutaj:

http://www.creative-robotics.com/qei-levels

oraz wiesz już co zrobić by procesor prawidłowo współpracował z takim wyjściem to skieruj teraz swoje działania na wykrycie zmian stanów na wejściu cyfrowym a wcześniej na upewnienie się, że w ogóle coś z czujnika do procesora dociera. Podczas zbliżenia elementu metalowego do czujnika powinieneś dostawać na pinie procesora stan niski a bez niczego - wysoki. Bez tego nawet najlepszy program nie zadziała więc miernik do ręki i do roboty.

Jest stan niski na wyjściu podczas zbliżania metalowego przedmiotu do czujnika, zastanawiam się jak liczyć czas pomiędzy impulsami. Nie wiem jak to napisać w UART żeby na niskich obrotach nie pokazywało błędnych wyników. Należy użyć funkcji pilseIn?

Edit:

Woltomierz oczywiście podłączałem. Teraz w monitorze portu mam 0 i 1 (przy zbliżaniu metalu - 0).

Najpierw liczby:

Skoro myślisz o zakresie 0-1000rpm to przekładając na polski i pamiętając o dwóch śrubkach w wałku dostaniesz 0-34 impulsów/s. Dla procesora to pikuś. Pomiar czegoś takiego robisz dwiema alternatywnymi metodami:

a. Mierzysz odstęp czasu między impulsami:

- czekasz na impuls

- włączasz któryś timer procesora

- czekając na: kolejny impuls lub przepełnienie timera

- jeżeli nastąpiło przepełnienie timera, obroty są mniejsze niż jakaś górna granica i pokazujesz 0

- jeżeli doczekałeś się impulsu, odczytujesz timer i przeliczasz czas na rpm.

b. Mierzysz liczbę impulsów w jakiejś jednostce czasu np. 2 sekund:

- zerujesz licznik impulsów

- odpalasz timer na czas 2 sekund

- jeżeli przyszedł impuls, inkrementujesz licznik

- jeżeli timer doliczył do zera, przeliczasz licznik na rpm i pokazujesz wynik

Każda z tych metod ma wady i zalety, widzisz je? Napisz o nich, bo być może to określi którą metodę powinieneś wybrać. A którą wybierasz?

EDIT: Co to znaczy "napisać w UART"?

Myślę, że metoda a jest dokładniejsza i bardziej czuła na zmiany prędkości obrotowej, ale wydaje mi się, ze będzie bardziej obciążała Arduino, natomiast metoda b będzie prostsza w napisaniu. Oczywiście napisać w C#

Zależy mi na płynnym odczycie prędkości, bo wchodzi ona do dalszych procesów w moim projekcie, więc skłaniałbym się do metody a (o ile dobrze określiłem zalety tych metod).

To jeszcze weź pod uwagę że metoda A:

- Oddaje wyniki z różną częstotliwością. Jeżeli masz dalej jakiś proces regulacji, to zwykle potrzebujesz danych co stałe odcinki czasu.

- To oznacza, że nawet jeśli będziesz wywoływał funkcję pomiaru co stały okres czasu to będzie ona wracać z wynikiem z różnym opóźnieniem a w skrajnym przypadku po czasie przepełnienia timera. Jeśli ustawisz go na długi czas, będziesz mógł mierzyć wolne obroty, ale wtedy na wynik możesz czekać np. ponad sekundę. Jeśli ustawisz go na krótki timeout, nie będziesz mógł mierzyć wolnych obrotów. Ustal jakąś granicę powyżej której procesor uznaje, że nie ma nadziei na kolejny impuls.

Za to metoda B:

- Oddaje wyniki w przewidywalnych chwilach

- Oddaje je rzadko i okres ten wydłuża się gdy chcesz mierzyć wolne obroty z sensowną rozdzielczością. Przy kilku obr/s trzeba by mierzyć przez 10s?

Wygląda, że dość istotna jest liczba śrubek/karbów w wałku. Musisz to wszystko poprzeliczać na czasy pomiaru, zakresy prędkości, dokładności i znaleźć optimum dla swojej aplikacji. Napisz co wymyśliłeś. Ograniczeniem są też 16-bitowe długości timerów.

Jeżeli wyniki są tylko dla człowieka, to 2-3 pomiary na sekundę są akceptowalne.

Możesz spróbować obu metod na raz, przecież w procku mogą chodzić dwa algorytmy korzystające z tego samego wejścia.

Obciążenie procesora? Jeżeli napiszesz to źle, to każda z metod zajmie jego 100% czasu.A jeśli dobrze, w obu przypadkach myślę że do osiągnięcia jest 0.1%.

Masz może poradnik do zastosowania timerów? Nie mam pojęcia jak napisać żeby mierzyło czas od impulsu do impulsu, ani żeby mierzyło impulsy np. podczas dwóch sekund. Nie zajmuję się programowaniem na co dzień i nie znalazłem nigdzie informacji co do timerów.

Te timery nie są skomplikowane, przeczytaj o nich rozdział w danych katalogowych procesora albo poszukaj jakiegoś poradnika w sieci. To w sumie kilka stron tekstu plus parę obrazków. Wybierasz albo taktowanie zegarem procesora (ew. jakoś podzielonym/zwolnionym) i wtedy masz licznik czasu albo "napędzanie" timera impulsami zewnętrznymi i wtedy masz licznik zdarzeń. W tej drugiej wersji musisz jeszcze mieć osobny pomiar czasu. To raptem dwa rejestry sterujące na krzyż, nic wielkiego. Proste zapytanie "timery AVR":

https://ep.com.pl/files/4787.pdf

http://www.easy-soft.net.pl/artykuly/mikrokontrolery/timery-w-avr-ustawienia-i-opis-funkcji

http://diycenter.acid19.linuxpl.com/readarticle.php?article_id=3

a jeśli nie chcesz grzebać w rejestrach (niektórzy programiści, szczególnie piszący na większe maszyny, mają taką fobię) to poszukaj bibliotek do Arduino.

Gy już coś będziesz wiedział a utkniesz w szczegółach (albo czas zacznie naglić - bywa), pytaj 🙂

Ważne żebyś wiedział co chcesz zrobić i jak podzielić zadania: co ma robić sprzęt a co program. No i czy procesor ma coś (w czasie pomiaru) robić jeszcze, czy może w 100% poświęcić się liczeniu - wtedy kod wygląda prościej, ale puryści mogą być niezadowoleni.

  • 2 tygodnie później...

Witam ponownie, długo nie pisałem, ale miałem trochę spraw (egzaminy, remont). Udało mi się napisać program, który działa (wkręciłem do wentylatora z CPU śrubkę i mierze obroty). Program pokazuje sensowne wartości, ale pewnie jest w nim trochę błędow.

#include <Timers.h> 
#define czujnik 2 //załączanie bibliotek i definicja pinu jako czujnik
Timers <1> czas; //dodanie timera 
volatile unsigned int przerwanie;
unsigned int obr;
unsigned long cz;
byte srubki = 2; //dodanie zmiennych

void setup() {

 Serial.begin(9600);
 pinMode(czujnik, INPUT_PULLUP);    //definicja czujnika  
 attachInterrupt(0,pomiarprzerwania,FALLING); //dodanie przerwania i jego definicja 
 przerwanie = 0;
 obr = 0;
 cz = 0; //zerowanie zmiennych
 czas.attach(0,1000,pomiarpr); //zdefiniowanie wątku timera
}

void pomiarprzerwania() {
przerwanie++; //inkrementacja licznika przerwan
}
void pomiarpr(){
 if (cz+1000<millis()){
   obr = (((float)przerwanie/srubki)/((millis()-cz)/1000))*60;
   Serial.println(obr);
   przerwanie=0;
   cz = millis();} // funkcja poomiaru prędkości
 }
void loop() {
 czas.process(); //odnawianie wątku 
}

Z góry dzięki.

Ale za co? Może napisz dokładnie co - jeżeli w ogóle coś - nie działa albo co Ci się nie podoba. A jeśli uporałeś się z problemem, to gratulacje. Opisz jaką metodę przyjąłeś, jakie napotkałeś trudności i jak je rozwiązałeś. Jakie prędkości mierzy program, jak go testowałeś, jak często masz wyniki o co później z nimi chcesz zrobić.

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...