logo elektroda
logo elektroda
X
logo elektroda
Adblock/uBlockOrigin/AdGuard mogą powodować znikanie niektórych postów z powodu nowej reguły.

[Mega16][C] TWI - czyli jak dogadać się z sonarem.

__rafal__ 13 Wrz 2008 15:46 2331 5
  • #1 5531542
    __rafal__
    Poziom 10  
    Witam :)

    Od dwóch dni próbuję dogadać się z ultradźwiękowym czujnikiem odległości "sonar MOBOT-US" firmy Wobit za pomocą interfejsu TWI.
    Dokumentacja: http://www.mobot.pl/download/Instrukcja%20do%20sonaru.pdf
    Zapoznanie się z interfejsem rozpocząłem od lektury kilku stron, między innymi http://www.autokacik.pl/i2c/ i przejrzenia przynajmniej 20. tematów na elektrodzie + analiza dołączanych działających plików, mam jednak nadal kilka wątpliwości.

    Według załączonej dokumentacji czujnika aby dokonać najprostszego pomiaru należy wysłać do czujnika ramkę danych 0x10 0x01 (pomiar, auto). Następnie należy odczekać 200 ms i zarządzać odpowiedzi (wyniku) wysyłając bajt 0x20 i odebrać dwa bajty danych.

    Zakładam że mój mikrokontroler atmega 16 będzie masterem i sytuacja odpowiada tej opisanej na autokącik: master - programowana przeze mnie atmega16, slave - sonar
    Cytat:

    wykonanie pomiaru:
    ˇ mikrokontroler A (master) adresuje mikrokontroler B (slave)
    ˇ mikrokontroler A (nadajnik-master) wysyła dane do mikrokontrolera B (odbiornik-slave)
    ˇ mikrokontroler A kończy transmisję.

    otrzymanie odpowiedzi:
    ˇ mikrokontroler A (master) adresuje mikrokontroler B (slave)
    ˇ mikrokontroler A (odbiornik-master) odbiera dane od mikrokontrolera B (nadajnik-slave)
    ˇ mikrokontroler A kończy transmisję.


    Postanowiłem wykorzystać znalezioną na elektrodzie bibliotekę do komunikacji po mojtwi.h (w załączniku). I tu rodzi się wątpliwość: funkcja i2c_start wymaga podania adresu - lecz właściwie co to za adres? To jest to adresowanie o którym mowa w autokąciku? Czy mam podać adres jaki wynika z dokumentacji sonaru (w moim przypadku zworki A0 A1 i A2 są rozwarte, więc adres 0x01)? Czy w ogóle muszę używać jakiś adresów jeśli do magistrali podpięte są tylko dwa urządzenia?

    W tej chwili kod wygląda w ten sposób:

    
    int spr=i2c_start(0x02);
    	itoa( spr, buffer, 10);
    	lcd_goto(1,2);
    	lcd_write_text(buffer);
    spr=i2c_write(0x10);
    	itoa( spr, buffer, 10);
    	lcd_goto(1,2);
    	lcd_write_text(buffer);
    spr=i2c_write(0x01);
    	itoa( spr, buffer, 10);
    	lcd_goto(1,2);
    	lcd_write_text(buffer);
    i2c_stop();
    _delay_ms(500);
    
    spr=i2c_start(0x02);
    	itoa( spr, buffer, 10);
    	lcd_goto(1,2);
    	lcd_write_text(buffer);
    spr=i2c_write(0x20);
    	itoa( spr, buffer, 10);
    	lcd_goto(1,2);
    	lcd_write_text(buffer);
    spr=i2c_rep_start(0x02);
    	itoa( spr, buffer, 10);
    	lcd_goto(1,2);
    	lcd_write_text(buffer);
    
    int wynik1 = i2c_readAck();
    
    int wynik2 = i2c_readNak();
    
    i2c_stop();
    
    	itoa( wynik1, buffer, 10);
    	lcd_goto(5,2);
    	lcd_write_text(buffer);
    	itoa( wynik2, buffer, 10);
    	lcd_goto(10,2);
    	lcd_write_text(buffer);
    


    Dlaczego int spr=i2c_start(0x02);? Nie wiem :) Po prostu zauważyłem, że wpisując jako ten adres 0x02 czujnik jakby wykonywał pomiar (zapala się dioda L2 co zgodnie z dokumentacją oznacza odebranie echa) jednak odebrane dane (wynik1 i wynik2) to liczby 2 i 2 a na wyjściu analogowym niezależnie od odległości od przeszkody wisi ciągle około 4,2V (dokumentacja przewiduje po pomiarze napięcie od 0 do 4V). Kolejną ciekawostką jest to, że dioda L2 zapala się "co drugi raz" - przytoczony fragment programu jest w pętli nieskończonej i obserwuje sobie na lcd wyniki - co drugą pętle zapala się D2. D1 w każdej pętli miga ułamek sekundy.

    Gdy jako adres wpiszę inny parzysty (sprawdziłem 0x04, 0x06, 0x0a) sonar pali światłem ciągłym diodę L1 , L2 nigdy się nie zapala, natomiast wpisując adres nieparzysty program "zawiesza się" przy próbie wysłania pierwszego bajtu danych
    
    spr=i2c_write(0x10);
    

    nie wykonuje operacji po tej linii (sprawdzam gdzie się zwiesza wstawiając po każdej linii kodu związanej z i2c polecenia wyświetlenia unikalnego teksu na wyświetlacz).

    Jakieś pomysły? Z góry dziękuję za pomoc i pozdrawiam.
  • Pomocny post
    #2 5531668
    zumek
    Poziom 39  
    __rafal__ napisał:
    ...Zapoznanie się z interfejsem rozpocząłem od lektury kilku stron, między innymi http://www.autokacik.pl/i2c/ i przejrzenia przynajmniej 20. tematów na elektrodzie + analiza dołączanych działających plików ...


    Zapoznaj się , jeszcze dokładniej ;)

    
    //...
    spr=i2c_start(0x02);
    	itoa( spr, buffer, 10);
    	lcd_goto(1,2);
    	lcd_write_text(buffer);
    spr=i2c_write(0x20);
    	itoa( spr, buffer, 10);
    	lcd_goto(1,2);
    	lcd_write_text(buffer);
    spr=i2c_rep_start(0x02); 
    

    Adres do odczytu , musi mieć ustawiony najmłodszy bit , czyli w Twoim przypadku , winno być 0x03 dla i2c_rep_start().

    Piotrek
  • #3 5537284
    __rafal__
    Poziom 10  
    Dziękuję...
    rozumiem, że adresowanie to 7 bitów adresu z zakresu 0-127 i ostatni bit to zapis/odczyt.

    Niestety nie rozwiązuje to mojego problemu do końca, ponieważ czujnik nadal zachowuje się jakby odbierał echo co drugą pętle, wynik jest ... poza zakresem (np 58, 236 czyli 58+236*255 = 60238 podczas gdy nie odebranie echa /poza zasięgiem/ sygnalizowane miało być wartością 30000) no i odbiera echo (w sensie zapala diodę L2) nawet gdy ręką zasłaniam nadajnik i odbiornik.
  • #5 5565244
    __rafal__
    Poziom 10  
    Dziękuję zumkowi i adamusx za podpowiedzi.
    Sporo nad tym czujnikiem siedziałem, dziś wymieniłem kabel na dłuższy i ... działa. Od razu, bez problemu - dziwne. Program po korekcie zumka wygląda następująco i jest wystarczający do komunikacji z czujnikiem :)

    
    spr=i2c_start(0x02);
    spr=i2c_write(0x10);
    spr=i2c_write(0x02);
    spr=i2c_write(0x01e);
    i2c_stop();
    
    _delay_ms(500);
    
    spr=i2c_start(0x02);
    spr=i2c_write(0x20);
    
    spr=i2c_rep_start(0x03);
    int wynik1 = i2c_readAck();
    int wynik2 = i2c_readNak();
    i2c_stop();
    
  • #6 5569205
    __rafal__
    Poziom 10  
    no i niestety... dziś już czujnik nie działa :| Nic nie zmieniałem, nic nie ruszałem - i znów odsyła głupoty. Dioda L2 zapala się w czasie co drugiego żądania wykonania pomiaru, L1 mruga w każdym cyklu. Kolejna dziwna rzecz - po podłączeniu do zasilania czujnik zapytany o aktualne ustawienia odsyła wzmocnienie 30 ilość impulsów 6, chociaż według karty katalogowej ilość impulsów winna wynosić 4. Komunikacja (chyba) działa dobrze, gdy wysyłam jakieś ustawienia to mogę je potem poprawnie odczytać - myślę, że gdyby to był problem obsługi interfesju to nie dałbym rady tego zrobić.

    No i najbardziej denerwująca rzecz - dlaczego czujnik zapala diodę L2 (odebranie echa) nawet gdy zasłonie mu nadajnik i/lub odbiornik?! Wczoraj, gdy wszystko działało, zasłonięcie jednego z nich powodowało otrzymanie prawidłowej odpowiedzi: 30000 (brak odbioru echa).

    Odnośnie linków przesłanych przez adamusx - to dokumentacja do wersji 2.0 czujnika, która jednak trochę się różni od 1. W 1 nie ma możliwości analogowego wymuszenia pomiaru, nie ma trybu testu itd...

    Jakieś pomysły?
REKLAMA