• Witaj na Forum Arduino Polska! Zapraszamy do rejestracji!
  • Znajdziesz tutaj wiele informacji na temat hardware / software.
Witaj! Logowanie Rejestracja


Ocena wątku:
  • 0 głosów - średnia: 0
  • 1
  • 2
  • 3
  • 4
  • 5
Problem z NRF24L01
#1
Witam,
porwałem się na drugi w moim życiu projekt na arduino. Tym razem sterowanie wózka z nadajnikiem i odbiornikiem opartym o NRF24L01.
Mam pewien problem. Otóż wygląda na to, że nie za każdym razem kiedy powinien zostać wysłany pakiet danych jest on wysyłany. Wysyłam go co 70 milisekund. Sprawdziłem to tak: na monitorze portu wyświetlam sobie  komunikat kiedy jest wykonywany fragment kodu przed i po wysyłce. Z reguły te dwa komunikaty dzieli około 35 milisekund (pewnie tyle czasu potrzebne jest na wysłanie danych, swoją drogą trochę długo). Jednak co jakiś czas, z reguły co około sekundę komunikat przed i po wyświetlany jest w tej samej milisekundzie więc wnioskuję, że wtedy nic nie zostało wysłane. A bardzo mi zależy żeby co te około 70 milisekund pakiet został wysłany bo odbiornik sprawdza co ile otrzymuje dane i jeśli ich nie otrzyma w określonych odstępach czasu to wyłącza silniki - a im dłuższy ten czas ustawię w odbiorniku tym większą mam bezwładność zatrzymania się wózka w razie problemów z łącznością.
Dlaczego nie za każdym razem są wysyłane dane i jak najprościej uporać się z tym problemem?

Przesyłam w sumie za każdym razem 6 bajtów. Tutaj fragment kodu odpowiadający za wysyłkę.
Kod:
  static unsigned long timeWyslaniaPakietu = 0;
  if (millis() > timeWyslaniaPakietu + 70 && (xJoystickNeutral - 25 > daneDoWyslania.xValue || xJoystickNeutral + 25 < daneDoWyslania.xValue || yJoystickNeutral - 25 > daneDoWyslania.yValue || yJoystickNeutral + 25 < daneDoWyslania.yValue || daneDoWyslania.liftValue != 0)) {
    Serial.println("przed");
    radio.stopListening();
    radio.write (&daneDoWyslania, sizeof(daneDoWyslania));
    radio.startListening();
    Serial.println("po");
    timeWyslaniaPakietu = millis();
  }
 
Odpowiedź
#2
static unsigned long timeWyslaniaPakietu = 0;
if (millis() > timeWyslaniaPakietu + 70 &&

to tak jest??
Arduino zostało wymyślone po to, by robić dobrze jedną prostą rzecz – migać diodą. 
 
Odpowiedź
#3
Tak, tak jest. Coś nie tak?
 
Odpowiedź
#4
ten millis tu nie działa on zawsze się wykonuje..

timeWyslaniaPakietu musi być zmienną globalną


static unsigned long timeWyslaniaPakietu = 0;
if (millis() > timeWyslaniaPakietu + 70

if (millis() > 0 + 70 tak to jest w tym kodzie


na końcu

timeWyslaniaPakietu = millis();
}

nie ma sensu skoro na początku przypisujesz 0
static unsigned long timeWyslaniaPakietu = 0;

Niestety nie pokazałeś całego kodu wiec nic nie można wnioskować co to jest
(xJoystickNeutral - 25 > daneDoWyslania.xValue || xJoystickNeutral + 25 < daneDoWyslania.xValue || yJoystickNeutral - 25 > daneDoWyslania.yValue || yJoystickNeutral + 25 < daneDoWyslania.yValue || daneDoWyslania.liftValue != 0)

A te dane powodują opóźnienia
Arduino zostało wymyślone po to, by robić dobrze jedną prostą rzecz – migać diodą. 
 
Odpowiedź
#5
Akurat to działa. Arduino definiuje zmienną statyczną tylko raz przy starcie - w tym przypadku 0. Nie nadpisuje jej zawsze zerem jak w przypadku zwykłej zmiennej lokalnej.

Ten fragment kodu działa prawidłowo. Chodzi mi tylko o to że nie zawsze pomimo tego że program wejdzie w warunek wysłania danych, one są wysłane. Dzieje się tak co około sekundę lub więcej. Jak można wyeliminować ten problem? można jakoś przy pomocy biblioteki do tego modułu sprawdzić czy dane zostały wysłane i gdyby się nie wysłały zrobić to ponownie?
 
Odpowiedź
#6
nie możesz napisać tak by było potwierdzenie odbioru?? jeżeli brak lub niepoprawne wyślij ponownie...
Arduino zostało wymyślone po to, by robić dobrze jedną prostą rzecz – migać diodą. 
 
Odpowiedź
#7
(29-06-2020, 21:47)Jarewa0606 napisał(a): nie możesz napisać tak by było  potwierdzenie odbioru?? jeżeli brak lub niepoprawne wyślij ponownie...
Nie mogę bo to strasznie wydłuży bezwładność odbiornika. Tak jak napisałem, odbiornik odmierza czas od ostatniego odbioru danych. Jeśli przekroczy ustalony próg czasu (chciałbym żeby było to 100 milisekund), automatycznie wyłącza silniki aby nigdzie po na przykład wyczerpaniu się baterii w pilocie samoczynnie nie jechał z przesłaną w ostatnim momencie prędkością. Jeśli ja wyślę dane, będę czekał aż odbiornik je odbierze, po czym znów wyśle dane do pilota, a pilot je odbierze to już na samym tym procesie tracę sporo ponad 100 milisekund.

Moje założenia się sprawdzają, tylko w związku z tym że raz na jakiś czas dane z jakiegoś powodu się nie wyślą następuje efekt, że od wysłania jednych danych do drugich mija około 140 milisekund, a więc nie mieszczę się w moim celu. I pytanie jak to zrobić żeby za każdym razem te dane zostały wysłane bo nie mam pojęcia dlaczego czasami się one nie wysyłają - i nie chodzi mi o to że nie dotarły do odbiornika, po prostu operacja   radio.write (&daneDoWyslania, sizeof(daneDoWyslania)); się jakby czasami nie wykonuje,a powinna.
 
Odpowiedź
#8
&daneDoWyslania, sizeof(daneDoWyslania)

Bo jest pusty?? wiec dlatego nic nie wysyla i Serial.println("przed"); jak i Serial.println("po"); sa w tym samym czasie...
Arduino zostało wymyślone po to, by robić dobrze jedną prostą rzecz – migać diodą. 
 
Odpowiedź
#9
Nie jest pusty. Po prostu nie załączyłem tego fragmentu kodu na forum. Kompilator przecież pokazałby błąd. A nawet gdyby wartości były zerem to też są bajty do wysłania.
 
Odpowiedź
#10
Jaka prędkość portu?
Policzyłeś ile trwa transmisja jednej ramki, czy strzelasz na oko?
Bo na moje, to 6bit dla np. 9600 bod, to będzie grubo poniżej 1 ms.
Jeśli masz problem z kodem lub sprzętem, zadaj pytanie na forum. Nie odpowiadam na PW, jeśli nie dotyczą one spraw forum lub innych tematów prywatnych.

[Obrazek: SsIndaG.jpg]
 
Odpowiedź
  


Skocz do:


Przeglądający: 1 gości