Sari la conținut
ELFORUM - Forumul electronistilor

Transmisie bidirectionala wireless


nimeni_altci

Postări Recomandate

Salut.

Am o problema legata de transmisia wireless a unui robot. Controlez robotul cu un arduino care primeste comenzi seriale din laptop. Atat robotul cat si "telecomanda" transmit prin NRF24l01+. Am realizat programele care controleaza robotul si totul merge ok, dar am intampinat unele dificultati cand am vrut ca si robotul sa transmita informatii catre Arduino(telecomanda), iar in acelasi timp sa si primeasca comenzile de miscare. Pentru ca am setat module sa si trimita si sa si asculte raspuns, in genul:

void loop

{

"trimite comanda"

 "asculta comanda de la celalalt NRF"

}

 

Iar acum comenzile se trimit cu o frecventa mai mica. Adica daca apas pe butonul de mers in fata robotul va merge sacadat, pentru ca momentul cand unul primeste si celalalt asculta se sincronizeaza mia greu. Cum as putea sa remedies problema? Poate principiul meu de programare nu e bun. Va rog, ma puteti ajuta cu o idee? Am atasat si cele doua programe.

ROBOT.txt

TELECOMANDA.txt

Link spre comentariu
  • Răspunsuri 7
  • Creat
  • Ultimul Răspuns

Top autori în acest subiect

  • nimeni_altci

    4

  • one

    1

  • red93

    1

Vizitator cobru

Din cate am citit despre el, NRF-ul ala stie sa trimita sau sa primeasca dar nu ambele simultan (nici n-ar avea cum).. dar exista posibilitatea ca atunci cand trimite ACK-ul automat la pachetul primit sa trimita si un payload (doar la nrf24l01+), de 0 pina la 32 bytes.

Aici deja se complica un pic povestea, trebuie sa studiezi mult mai atent datasheet-ul https://www.sparkfun.com/datasheets/Components/SMD/nRF24L01Pluss_Preliminary_Product_Specification_v1_0.pdf sa intelegi cam cum ar functiona (sau sa citesti in detaliu codul din libraria nrf, am vazut ca implementeaza ack with payload).

Am gasit ceva despre subiectul asta aici https://forum.sparkfun.com/viewtopic.php?f=13&t=10563  dar foloseste direct comenzi pe spi, nu libraria de arduino.

 

Cum as implementa eu, bazat pe ce-am citit in datasheet si pe codul din rf24.cpp (nrf-urile mele inca stau in sertar, deci nu te baza ca va merge chiar cum zic):

 

Pe robot, in loop:

byte pipeNo;while (radio.available(&pipeNo)) {        radio.read(&cmd, 1);        radio.writeAckPayload(pipeNo, &bar, sizeof(bar)); // urmatoarea comanda va trimite ca ack valoarea lui BAR.}

Iar in setup, dupa radio.begin() si inainte de radio.openReadingPipe():

 

  radio.setAutoAck(1);  radio.enableAckPayload();  radio.setRetries(0,15); // 15 retries e ok pentru testare, finalul probabil va trebui mai putin sa nu fie asa mare timeoutul  radio.setPayloadSize(1);

 

M-am bazat pe exemplul de la creatorul librariei nrf: https://github.com/TMRh20/RF24/blob/master/examples/pingpair_ack/pingpair_ack.ino

 

Sper ca te ajuta cu ceva.

Link spre comentariu

Salut,

Iti multumesc pentru raspuns. M.am documentat in legatura cu Solutia ta, dar chiar si asa momentul in care Rx trimite ack, nu se sincronizeaza cu momentul in care Tx il primeste. Am testat acel exemplu si nu a mers. Nici in exemplul de la https://github.com/TMRh20/RF24/blob/master/examples/pingpair_ack/pingpair_ack.ino nu inteleg cum acele momente se sincronizeaza. Daca nu va merge asa m.am gandit la o alta solutie. Robotul sa trimita informatiile de la senzori doar cand sunt cerute. Cu o comanda seriala din laptop pot sa trimit o alta comanda din telecomanda in robot si odata cu primirea acelesteia, robotul sa trimita un payload cu un vector care cuprinde acele informatii. De altfel trebuie sa fac o functie in telecomanda care sa poata asculta noi comenzi din laptop doar dupa primirea acelui payload de la robot.

Link spre comentariu
Vizitator cobru

Poate nu e prea clar nici in codul meu nici in exemplul de pe github, chestia cu ack payload functioneaza daca setezi payloadul inaintea primirii pachetului.

Adica, ordinea evenimentelor e ceva de genul:

 

arduino RX apeleaza set_payload catre nrf cu 1 byte (sa zicem "0xDE") si incepe sa asculte dupa pachete

arduino TX scrie cmd catre nrf TX

nrf TX trimite pachet cu CMD si asteapta un byte raspuns

nrf RX primeste pachet cu cmd, trimite ACK cu payload 1 byte 0xDE

arduino RX primeste "cmd" de la nrf, aici apeleaza iar set_payload cu payload 1 byte 0xDF (sa zicem ca il incrementam) pentru comanda urmatoare

nrf TX primeste ACK la pachetul trimis, vede payload 1 byte 0xDE (primul payload, nu al doilea)

arduino TX vede acel 1 byte 0xDE (din nou: primul payload).

 

Am gresit in exemplu un pic, asa cum am scris codul TX-ul va vedea payload doar daca mai trimite o data comanda (adica la a doua comanda trimisa va primi raspuns cu payload). Vad ca si pe forumul de la arduino au mai patit si altii la fel: http://forum.arduino.cc/index.php/topic,178511.0.html ("pong"-ul era cu un byte in urma "ping"-ului de pe tx).

 

Incearca sa pui si in setup (la sfarsitul metodei setup) linia:

 

radio.writeAckPayload(1, &bar, sizeof(bar));

Editat de cobru
Link spre comentariu

@cobru nu am reusit cu aceasta metoda, iar ce mi.a iesit avea lag prea mare. Asa ca am ales alta solutie. In aplicatia PC am prevazut un buton " Update" care trimite o comanda telecomenzii arduino sa ceara informatiile de la robot. Cum se vede in program, cand apas "Update", programul din Windows trimite litera "N" serial catre telecomanda. Aceasta verifica daca litera primita este "N" si in caz afirmativ o trimite mai departe, si incepe ascultarea pana primeste raspuns de la robot. Robotul verifica daca litera trimisa este "N", si in caz afirmativ trimite vectorul cu informatii; acesta este trimis mai departe de telecomanda si afisat in aplicatie. Programul merge perfect, cu o mica exceptie. Cand apas de minim 3 ori consecutive pe butonul update, dar foarte repede, programul din telecomanda se agata undeva si nu mai raspunde la nici o comanda. Cand scot telecomanda de la usb si o bag iar(sau mai exact cand resetez programul telecomenzii) isi revine. Am atasat codul. Poate imi poate spune cineva de ce se agata la primirea consecutive rapida a literei "N".

telecomanda (2).txt

Editat de nimeni_altci
Link spre comentariu

Un sfat ar fi să folosești intreruperile. Nu am lucrat cu Arduino dar la AVR știu că se poate face ușor ceva de genul ăsta.

Intreruperea o configurezi pe intrarea radioreceptorului dar și pe ieșirea lui - gen Rx interrupt și Tx interrupt de la serială. Bucla principală execută comanda sau ce îi spui tu să facă. Pe întrerupere recepționezi comanda și reactualizezi valoarea ei. Dacă ai ceva de transmis pui interfața serială să trimită primul octet și configurezi intreruperea de terminare a transmisiei caracterului. Când se declanșează pui următorul caracter în buffer și ieși la execuția buclei principale.

Cel mai probabil ai probleme la "așteptatul" dispozitivului poate intră într-o buclă, sau are loc un "data colision".

Link spre comentariu

Cred ca o idee ar fi sa faci niste "ferestre" de comunicatie, altfel spus un "time division".

 

O solutie simpla pentru aceasta ar fi sa transmiti pachete catre robot si sa lasi intre acestea spatiu suficient pentru un raspuns.

 

Sa zicem trimit un pachet la fiecare 100ms, 30ms transmiti si 60ms receptionezi. Robotul va emite dupa receptionarea pachetului, daca este nevoie.

 

Cand ai nevoie de informatii, trimiti un pachet "de interogare". Sau lasi timp de raspuns numai dupa acest pachet, celelalte le poti transmite fara pauza.

Link spre comentariu

Creează un cont sau autentifică-te pentru a adăuga comentariu

Trebuie să fi un membru pentru a putea lăsa un comentariu.

Creează un cont

Înregistrează-te pentru un nou cont în comunitatea nostră. Este simplu!

Înregistrează un nou cont

Autentificare

Ai deja un cont? Autentifică-te aici.

Autentifică-te acum



×
×
  • Creează nouă...

Informații Importante

Am plasat cookie-uri pe dispozitivul tău pentru a îmbunătății navigarea pe acest site. Poți modifica setările cookie, altfel considerăm că ești de acord să continui.Termeni de Utilizare si Ghidări