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.

nRF24L01+ ATMega 16A [C] - Brak komunikacji pomiędzy układami

02 Kwi 2015 12:32 1416 9
  • Poziom 11  
    Witam,
    Ostatnio próbuję do swojej pracy magisterskiej zrobić komunikację bezprzewodową za pomocą 2 modułów nRF24L01+. Korzystam z tego kursu: http://gizmosnack.blogspot.se/2013/04/tutorial-nrf24l01-and-avr.html
    Sprawdziłem działanie komunikacji uC z modułem nRF za pomocą SPI przy użyciu AVR Dragona. Działa bez problemu, wpisuje testową wartość do rejestru za pomocą funkcji WriteToNrf a następnie odczytuję wartość tego rejestru za pomocą funkcji GetReg, i odczytana wartość jest poprawna czyli komunikacja SPI działa poprawnie. W 1 module ustawiłem rolę modułu jako odbiornik a w 2 module jako nadajnik. Nadajnik ma posłać ciąg znaków "test" lub "1234" w zależności od wciśnięcia odpowiedniego klawisza. Po wciśnięciu klawisza funkcja transmit_payload() wykonuje się, niestety przerwanie w układzie odbiornika nie zostaje zgłoszone, również w rejestrze R_RX_PAYLOAD po odczycie nie ma żadnych zapisanych danych. Funkcja nrf24L01p_init w obu układach jest prawie taka sama, za wyjątkiem konfiguracji rejestru CONFIG odpowiedzialnego za rolę działania układu (w 1 układzie wartość ustawiam na 0x1F - odbiornik, w 2 układzie ustawiam na 0x1E - nadajnik). Moje kody (postanowiłem wrzucić je również na pastie ze względu na czytelność i łatwość skopiowania kodu):
    http://pastie.org/10066943 - kod na ATMega 32A nadajnik
    Kod: cpp
    Zaloguj się, aby zobaczyć kod

    http://pastie.org/10066940 - kod na ATMega 16A odbiornik
    Kod: cpp
    Zaloguj się, aby zobaczyć kod

    Headera nRF24L01p.h znajdziecie pod tym linkiem:
    https://github.com/maniacbug/RF24/blob/master/nRF24L01.h
    Na koniec dodam że wyzwalanie zewnętrznego przerwania INT0 jest skonfigurowane poprawnie, testowałem to za pomocą zwierania odpowiedniego pinu do masy i procesor zaczął wykonywać te procedurę. Błąd jest w skonfigurowaniu modułów nRF.
    Z góry dziękuję za pomoc i wszelkie uwagi.
  • Poziom 11  
    Ok wstawiłem taki kod na początek programu odbiornika, tuż po funkcji nrf_init(), aby sprawdzić wszystkie rejestry konfiguracyjne modułu nRF24 (w komentarzach wpisałem wartości jakie powinny być zwrócone):
    Kod: cpp
    Zaloguj się, aby zobaczyć kod

    Wartości zupełnie sie nie zgadzają z oczekiwanymi (tymi które do modułu posyłałem). Jaka jest przyczyna złego ustawienia niektórych rejestrów? Czy funkcja inicjalizująca SPI bądź writeToNrf jest błędna? Dziękuję za pomoc
  • Poziom 11  
    Odczytane wartości przez AVR Dragona były błędne. Po zmianie poziomu debugowania z 2 na 3, odczytane wartości okazały się poprawne i zgodne z oczekiwanymi, jednak wciąż brak komunikacji pomiędzy 2 modułami.
  • Poziom 16  
    Tutaj masz mojego gotowca wraz z kodem źródłowym :)

    Moduły były uruchomione na ATmega 32, 128, 328p.

    W kodach źródłowych masz dwa sposoby inicjalizacji tych układów. Pisałem to na podstawie dokumentacji producenta i pamiętam, że też było kilka haczyków podczas uruchamiania ;)

    Powodzenia
  • Poziom 11  
    Dzięki, jutro (bo dziś nie mam już sił :D ) postaram się uruchomić Twój kod i dam znać co do postępów.
  • Poziom 11  
    Witam, dziękuję za kod komunikacja zadziałała, ale jest jeden problem. Układ nadajnika czasem sie zawiesza, jak debuguje program to czasem jak pojawi się przerwanie INT0 to na case łapie default, i po wyjściu z procedury obsługi przerwania układ sie zawiesza. Po resecie uC odczytywany status nie jest poprawny gdyż wynosi 0x2E a nie 0x1E. Jedyne co można zrobić wtedy to zrobić reset na zasilaczu całego układu. Co może być przyczyną takiego błędnego działania? Mój kod:
    Kod: cpp
    Zaloguj się, aby zobaczyć kod
  • Pomocny post
    Poziom 16  
    A możesz napisać jaką wartość ma rejestr statusowy jak wejdzie do default?


    W ten sposób wyślesz to terminalem (jak masz podłączony):
    Kod: c
    Zaloguj się, aby zobaczyć kod
  • Poziom 11  
    Ok znalazłem problem,
    Kod: cpp
    Zaloguj się, aby zobaczyć kod

    Gdy w lini kodu zaznaczonej strzałką (oczekiwanie na zwolnienie SPI) wskoczyło mi przerwanie, które później działało na SPI (zmieniając jego flagi), to po wyjściu z przerwania uC sie zapętlał w tym momencie. Obejść ten problem można na 2 sposoby, albo użyć atomic_block wenątrz powyższej funkcji. Albo tak jak ja to zrobiłem:
    Kod: cpp
    Zaloguj się, aby zobaczyć kod

    i potem w mainie (podam tylko fragment)
    Kod: cpp
    Zaloguj się, aby zobaczyć kod


    Obsługa tego przerwania niestety nie będzie natychmiastowa, lecz nRF przechowuje stan rejestrów i odczyt potwierdzenia (bądź nie), od nadawania nie musi odbyć się natychmiast
  • Pomocny post
    Poziom 16  
    Dlaczego wykorzystałeś drugie rozwiązanie zamiast pierwszego (IMHO - znacznie lepszego)? Wykorzystując takie zmienne jako flagi prowadzisz do niepotrzebnego komplikowania kodu i utrudnienia kontroli dynamicznie rozwijającego się programu :)

    Jedna z propozycji rozwiązania problemu:
    Kod: c
    Zaloguj się, aby zobaczyć kod


    Powodzenia!
  • Poziom 11  
    Dziękuję za wszelkie uwagi i pomoce dotyczące mojego tematu. Problem został rozwiązany, po testach postanowiłem zastosować jednak ATOMIC_BLOCK. Temat uważam za zamknięty, pozdrawiam wszystkich forumowiczów