Elektroda.pl
Elektroda.pl
X
Elektroda.pl
Proszę, dodaj wyjątek dla www.elektroda.pl do Adblock.
Dzięki temu, że oglądasz reklamy, wspierasz portal i użytkowników.

Odczyt z czujnika w samochodzie

voe 15 Kwi 2007 16:23 2076 5
  • Poziom 9  
    Witam,

    Chcialem zaznaczyc na poczatku ze moja wiedza z elektroniki jest praktycznie zerowa.

    Mam taki problem. Mam w samochodzie czujnik predkosci ktory co jakis czas wysyla impuls, tzn pojawia sie na nim na moment napiecie 5V. Jak cos takiego zczytac na komputerze za pomoca zlacza com a najlepiej usb ? Zaznacze ze jestem programista z tym ze nigdy nie oprogramowywalem komunikacji z urzadzeniami zewnetrznymi.
  • Poziom 38  
    wg mnie potrzebny jest transoptor wpiety pomiedzy czujnik a port com komputera i mozna zliczac impulsy ew zastosowac maly procesorek z wyswietlaczem wtedy nie bedzie potrzebny komputer.
  • Specjalista techniki cyfrowej
    Przez USB to raczej niebardzo, tam nie da się odczytać ot tak sobie stanów panujących na liniach, trzeba mić kompletny układ który będzie spełniał funkcję urządzenia USB.
    Z portem COM jest już łatwiej (ale z prawdziwym, taki z konwertera USB->RS-232 nie będzie działać raczej).
    Do odczytu stanu linii portu służy jakiś tam rejestr I/O, nie wiem który, ale myślę że ze znalezieniem tego nie powinny być problemu. Nie wiem tylko czy można czytać bezpośrednio z linii RxD, ale na pewno można z linii służących do kontroli transmisji (tylko sprawdź, które z nich są wejściami).
    Niedobrze, że jest to sygnał o napięciu 5V, bo dla RS-232 trzeba +/-3 do +/-12V, czy coś w okolicy, więc Twoje 0/+5V trzeba by zamienić na stosowny zakres napięć. Bardzo prostym i w miarę "eleganckim" rozwiązaniem było by zastosowanie specjalizowanego układu - MAX232, drogi nie jest.
    Od biedy można by poskładać taki konwerter poziomów z elementów dyskretnych, takie można znależć tu: http://www.google.com/search?rls=en&q=simple+rs232+ttl+converter

    Od strony programowej niestety nie będzie łatwo, wszystko teraz zależy od tego, w jaki sposób podawane są te impulsy. Jeżeli częstotliwość zmienia sięwraz z prędkością, to pół biedy, gorzej jeżeli zmienia sięwspółczynnik wypełnienia.
    W obu przypadkach pomiar będzie zużywał bardzo dużo czasu procesora, a to dlatego, że sprawdzanie stanu pinu trzeba wykonywać w pętli. Po zarejestrowaniu stanu niskiego, czy wysokiego, zależy od konwertera, a pamiętać trzeba, że w RS232 logiczna "1" to napięcie ujemne, odczytujesz sobie czas (t1) i czekasz na stan przeciwny. W wypadku, gdy zmienny jest współczynnik wypełnienia kolejny odczyt czasu wykonujesz w momencie zmiany stanu na przeciwny (t2). Potem czekasz znowu na przeciwny stan (ten sam co na początku) i dokonujesz odczytu czasu (t3). Jeżeli zmienna jest częstotliwość, to częstotliwość impulsów wyliczysz sobie z różnicy pomiędzy dwoma czasami wystąpienia tego samego stanu (1/(t3-t1). Jeżeli zmienny jest współczynnik wypełnienia, to dodatkowo musisz uwzględnić zmianę stanu na przeciwny i współczynnik wypełnienia obliczysz jako (t2-t1)/(t3-t1), a potem trzeba to będzie przemnożyć przez jakąś prędkość maksymalną, dla której współczynnik wypełnienia równy jest 1, ale wątpię żeby tak było raczej zmienna będzie częstotliwość.
    Problem kolejny z takim programem to gubienie impulsów, chyba że system operacyjny nie będzie wielozadaniowy.
    Najlepszym rozwiązaniem było by zastosowanie mikrokontrolera jako urządzenia pomiarowego i interfejsu do PC, wtedy przez RS232 mógł by wysyłać odrazu wartość prędkości w postaci tekstu. Na AVR można by nawet zrobić to na USB (programowa implementacja).
  • Poziom 9  
    czestosc sygnalow jest zalezna od predkosci obrotowej kol. czyli np kazdy sygnal odpowiada jednemu obrotowi kol. im szybciej samochod jedzie tym wieksza czestotliwosc sygnalow

    co do tego mikrokontrolera. ta opcja by najbardziej mnie interesowala, bo jednak zczytywanie danych przez usb byloby dla mnie najlepsza opcja. czy dalo by sie zrobic cos takiego, zeby zliczal te impulsy i co okreslona jednoste czasu wysylal to do komputera, kasowal licznik, znowu zliczal i znowu wysyalal i tak powiedzmy 5 razy na sekunde.

    jesli znasz jakies dobre materialy, tutoriale dla poczatkujacych w tym temacie mikrokontrolerow, interfejsow to chetnie bym poczytal ;)
  • Pomocny post
    Specjalista techniki cyfrowej
    Tutorial do avr taki znalazłem: http://avr.elektroda.eu/?q=node/8

    Jak byś czegoś w sieci szukał, to raczej unikaj tutoriala z patron.net, uczy złych nawyków i jest nieco nie na czasie.

    Pomiar częstotliwośći na AVR realizuje się w miarę łatwo, przy wykorzystaniu timerów, jeden timer pracuje jako licznik impulsów z zewnątrz, a drugi odmierza czas, mozna też inaczej, tylko na jednym timerze z wykorzystaniem input capture, czyli zapamiętywania stanu licznika w momenci pojawienia się sygnału na pinie, do pomiaru częstotliwości to drugie rozwiązanie jest chyba nawet lepsze, zwłaszcza że będzie ona raczej niewielka. Tak właściwie to drugie rozwiązanie to pomiar okresu, ale to się akurat bez problemu da przeliczyć.
    Zrobienie tego na RS232 będzie dużo prostsze niż na USB.
    Na RS232 potrzebujesz w zasadzie jedynie układu wejściowego (jakieś zabezpieczenie przed przepięciami, może izolacja galwaniczna - transoptor), mikrokontrolera, kwarcu i konwertera poziomów TTL - RS232, czyli MAX232. Program na mikrokontrolewrze można wtedy napisać tak, że będzie współpracował z dowolnym terminalem uruchomionym na PC. Jeżeli zrobisz to w ten sposób, to układ będzie również poprawnie współpracował z konwerterem USB - RS232.

    Żeby Cie naprowadzić, to na mikrokontrolerze (ATmega8, bo tani i ma sporo bajerów) konfigurujesz Timer1 do normalnej pracy, uaktywniasz układ input capture i piszesz procedurę przerwania dla zdarzenia input capture. W każdym przerwaniu odczytujesz wartość rejestru ICR1, w którym zapamiętywany jest stan licznika timera w momencie wystąpienia zdarzenia. Wartość tą odejmujesz od poprzedniej (którą też przechowujesz rzecz jasna) i masz już okres, ale w jednostkach będących czasem trwania jednego cyklu timera. Szybkość zliczania timera ustawiasz sobie w odpowiednich rejestrach, konkretniej to chodzi o preskaler, który podzieli zegar oscylatora przez określoną wartość. Trzeba to dobrać tak, żeby przy małej prędkości licznik timera się nie przepełniał, tzn. maksymalnie 65535 cykli na jeden okres pomiędzy impulsami z czyjnika przy minimalnej prędkości. Timer nie może też zliczać za wolno, żeby zapewnić odpowiednią dokładność przy większej prędkości. Potem wynik odejmowania mnożysz przez czas trwania cyklu timera i dostajesz okres w sekundach, robisz odwrotność i masz częstotliwość. Dalej to już sobie musisz sam przeliczyć, znając zależność częstotliwośic od prędkości. Można, a nawet trzeba by zrobić zabezpieczenie, żeby przy zbyt małej prędkości licznik nie wskazywał głupot. Codzi o to, żeby pomiędzy kolejnymi impulsami z czujnika nie wystąpiło więcej jak 65535 zliczeń timera. W tym celu można by użyć przerwania wywoływanego przez przepełnienie licznika timera (w momencie zmiany wartości z 65535 na 0). ale trochę "inteligencji" trzeba by tu dorobić, bo takie przepełnienie może się również zdarzyć w trakcie normalnej pracy. Jeżeli w C zadeklarujesz sobie zmienną w której przechowywana jest óżnica dwóch pomiarów jako 16 bitów bez znaku (uint16_t, z stdint.h) to wynik odejmowania dwóch wartości pomiędzy którymi wystąpiło przepełnienie będzie poprawny. "Inteligencję" można by zrobić tak, że jeżeli pomiędzy dwoma pomiarami wystąpi więcej jak jedno przepełnienie, to wynik uznaje się za nieważny i prędkość wtedy wynosi 0, można też zrobić to lepiej, ale na początek to powinno starczyć.
    Komunikacja przez RS jest już prosta, konfigurujesz port (prędkość, ilosć bitów, parzystość) i korzystasz z gotowca (bardzo prostego zresztą) do wysyłania / odbierania danych.
    Od strony komputera można zrobić albo tak, że układ bnędzie odsyłał wartość prędkości po wydaniu odpowiedniego polecenia przez terminal, albo będzie wysyłał dane ciągle w określonych odstępach czasu, mozliwości jest wiele.
    Na początek raczej nie polecałbym zabawy w USB, nie będzie to wcale takie proste od strony mikrokontrolera. RS-232 jest o wiele łatwiej uruchomić, zwłaszcza że od strony PC nie trzeba pisać oprogramowania, tylko użyć jakiegokolwiek terminala.

    Co do samego programowania mikrokontrolerów.
    Skomplikowane to to nie jest. Zasadnicza różnica w stosunku do programowania na PC jest taka, że wszystkie peryferia (timery, port szeregowy itd.) konfiguruje i obsługuje się przez zestaw oidpowiadających im rejestrów, a nie przez wywoływanie funkcji systemu operacyjnego. Niezbędna jest oczywiście do tego dokumentacja, bo ciężko to wszystko zapamiętać.

    Taki przykłąd kodu obsługującego input capture, darowałem sobie include'y, na początku masz funkcję wywoływaną przez przerwanie, a potem funkcję inicjującą peryferia (w tym wypadku timer i komparator analogowy, oraz porty I/O).

    Code:
    volatile uint16_t okres;
    

    SIGNAL(SIG_INPUT_CAPTURE1) {
    static uint16_t poprzedni=0;
       okres = ICR1 - poprzedni;
       poprzedni = ICR1;
    }

    void init(void) {

    /* configure pins */
    /* PORTD:
    ** PD7: analog comparator negative input
    ** PD6: analog comparator positive input
    ** PD5: Capacitor discharge (MOSFET gate)
    */
       DDRD = _BV(PD5);
       PORTD = 0;

    /* configure timer 1 */

    /* Timer 1: Normal mode, input capture noise canceler active, prescaler = 1024 */
       TCCR1A = 0;
       TCCR1B = _BV(ICNC1) | _BV(ICES1) | _BV(CS12) | _BV(CS10);

    /* Timer 1: enable interrupt on input capture event */
       TIMSK = _BV(TICIE1);

    /* Analog comparator connected to timer's 1 input capture unit */
       ACSR = _BV(ACIC);

       sei();               /* enable interupts */

    }


    W main() wywołujesz najpierw init(), do którego trzeba by jeszcze dopisać konfigurację portu szeregowego, a potem co jakiś czas wartość zmiennej okres zamieniasz na string i wysyłasz przez RS232. Do okresowego wysyłania można by dodać jeszcze jedno przerwanie, wcześniej już wspomniane - przepełnienie licznika timera. W tym ukłądzie akurat jest dość duża wartosć preskalera, przez co przy kwarcu 4MHz przepełnienie będzie występować co ok. 16 sekund, jak się domyślam dla Ciebie to za dużo, zresztą, ten program jest zupełnie do czego innego :P.
    Jeżeli będziesz używał RS232 to musisz pamiętać o zastosowaniu odpowiedniego kwarcu, 3.6864, 7.3728, czy 11.0592MHz jeżeli chcesz uzyskać większe prędkości transmisji. Z bardziej "okrągłymi" kwarcami (np. 4MHz) maksymalna prędkość transmisji jest niewielka, rzędu 9.6kbps, ale odmierzanie czasu łatwiejsze. chociaż jak zastosujesz liczby zmiennoprzecinkowe, z którymi ATmega8 radzi sobie całkiem przyzwoicie, to częstotliwość będzie Ci właściwie obojętna.
    Do programowania oprócz pakietu win-avr (kompilator avr-gcc) bedzie Ci jeszcze potrzebny programator, najprostszy to jeden ukłąd sacalony i kilka elementów, wtykany do portu LPT (STK-200, można na allegro znaleźć, niedrogie, jeżeli nie chce Ci się samemu składać), problem z nimi jest taki, że bywają zawodne, lepszy był by jakiś na RS232, albo USB, ale te z kolei są droższe.
  • Poziom 9  
    wow :)

    wielkie dzieki za bardzo konkretne informacje. w wolnych chwilach wieczorami biore sie za nauke. jak juz bede mial jakies efekty to dam znac. jeszcze raz serdeczne dzieki.