Nuoseklusis ryšys#
Įvadas#
serial_link klasė leidžia siųsti neapdorotų baitų srautą tarp robotų. Ji skirta robotų tarpusavio ryšiui, kai ir siunčiantis, ir priimantis robotas supranta duomenų srauto turinį.
Kiekvieną kartą panaudojus send, duomenys pridedami prie susietos V5 Brain eilės, o eilė skaitoma FIFO (pirmas įeina, pirmas išeina) principu. Jei prieš tai, kai kiti V5 Brain naudoja „receive“, išsiunčiami keli pranešimai, jie bus saugomi ir grąžinami po vieną tokia tvarka, kokia buvo išsiųsti. Kadangi pranešimai gali būti eilėje, pakartotinis tos pačios būsenos siuntimas kiekviename cikle gali sukelti vėlavimą; laiko požiūriu kritinei logikai siųskite duomenis tik tada, kai pasikeičia reikšmės.
Svarbu: Abu robotai vienu metu turi vykdyti projektus, kurie naudoja serial_link , kitaip duomenys nebus siunčiami / gaunami.
Klasės konstruktoriai#
serial_link(
int32_t index,
const char *name,
linkType type,
bool isWired = false );
Klasės destruktorius#
Sunaikina serial_link objektą ir išlaisvina susijusius išteklius.
~serial_link();
Parametrai#
Parametras |
Tipas |
Aprašymas |
|---|---|---|
|
|
Išmanusis prievadas, prie kurio prijungta pranešimų nuoroda, užrašomas kaip |
|
|
Šios nuorodos pavadinimas. Rekomenduojama, kad ši unikali eilutė būtų pakankamai ilga, kad, „vexos“ ją apdorojus, būtų sukurtas unikalus ID. Netinkamas nuorodos pavadinimas būtų bendrinis, pvz., „vexlink“, nes jį gali naudoti kita komanda. |
|
|
Ryšio tipas –
|
|
|
Ar „serial_link“ objektas yra laidinis (numatytoji reikšmė yra
|
Pastabos#
„VEXlink“ palaiko tiek belaidį, tiek laidinį ryšį, o laidiniams ryšiams rekomenduojama naudoti modifikuotą išmanųjį kabelį, kad būtų išvengta maitinimo nukreipimo problemų.
Belaidžiam ryšiui kiekvienam robotui reikia V5 roboto radijo, prijungto prie išmaniojo prievado.
„VEXlink“ radiją galima naudoti kartu su „V5“ valdiklio „VEXnet“ radijo imtuvu, kuris turėtų būti prijungtas prie didžiausio numerio „Smart Port“, kad būtų išvengta konfliktų.
Norint sukurti VEXlink, abu V5 Brains turi būti prijungti prie V5 roboto radijo.
Pavyzdys#
1 roboto kodas
// Create a wireless link in Port 1 serial_link link = serial_link( PORT1, // index "VEXRoboticsLink123456789", // name linkType::manager, // type true); // isWiredRoboto 2 kodas
// Create a wireless link in Port 1 serial_link link = serial_link( PORT1, // index "VEXRoboticsLink123456789", // name linkType::worker, // type true); // isWired
Narių funkcijos#
serial_link klasėje yra šios narių funkcijos:
isLinked– Patikrina, ar V5 smegenys yra suporuotos ir bendrauja šiuo ryšiu.send— Siunčia žinutę suporuotoms smegenims.receive— Laukia ir grąžina kitą gaunamą pranešimą.received— Registruoja funkciją, kuri bus iškviečiama gavus naują pranešimą.
Prieš iškviečiant bet kokias serial_link narių funkcijas, reikia sukurti serial_link egzempliorių, kaip parodyta žemiau:
1 roboto kodas
// Create a wireless link in Port 1 serial_link link = serial_link( PORT1, // index "VEXRoboticsLink123456789", // name linkType::manager, // type true); // isWiredRoboto 2 kodas
// Create a wireless link in Port 1 serial_link link = serial_link( PORT1, // index "VEXRoboticsLink123456789", // name linkType::worker, // type true); // isWired
isLinked#
Grąžina, ar V5 Brains nuosekliojoje jungtyje yra suporuoti vienas su kitu.
Available Functionsbool isLinked();
Ši funkcija neturi jokių parametrų.
Return ValuesGrąžina loginę reikšmę, nurodančią, ar V5 smegenys yra susietos:
true— The two V5 Brains are paired and communicating on this link.false— The two V5 Brains are not paired on this link.
Prieš paleidžiant bet kokį tolesnį kodą, gera praktika yra visada patikrinti, ar V5 smegenys yra susietos projekto pradžioje.
1 roboto kodas
// Create the link serial_link link(PORT1, "VEXRoboticsLink123456789", linkType::manager, true); // Do not run code UNTIL the Brains are linked while (!link.isLinked()) { wait(0.1, seconds); } Brain.Screen.print("Robot 1 - Manager"); Brain.Screen.newLine(); Brain.Screen.print("Sending message..."); // Message to send const char* message = "Hello Robot 2"; // Send the message link.send((uint8_t*)message, strlen(message));
Roboto 2 kodas
// Create the link serial_link link(PORT1, "VEXRoboticsLink123456789", linkType::worker, true); // Do not run code UNTIL the Brains are linked while (!link.isLinked()) { wait(0.1, seconds); } Brain.Screen.print("Robot 2 - Worker"); Brain.Screen.newLine(); Brain.Screen.print("Waiting..."); // Buffer to store incoming bytes uint8_t buffer[32] = {0}; int32_t n = link.receive(buffer, sizeof(buffer) - 1); // Null-terminate if (n > 0) { buffer[n] = 0; // Display the message that was sent Brain.Screen.clearScreen(); Brain.Screen.setCursor(1, 1); Brain.Screen.print("Robot 2 - Worker"); Brain.Screen.newLine(); Brain.Screen.print((char*)buffer); } else { Brain.Screen.newLine(); Brain.Screen.print("No message received"); }
send#
Siunčia žinutę suporuotoms smegenims.
Available Functions1 — Siunčia pranešimą naudodamas baitų buferį.
int32_t send( uint8_t *buffer, int32_t length );
Parameters2 — Siunčia pranešimą naudodamas simbolių buferį.
int32_t send( const char *buffer, int32_t length );
Parametras |
Tipas |
Aprašymas |
|---|---|---|
|
|
Buferis, skirtas siųsti į kitą susietą V5 smegenų atmintį. |
|
|
Siunčiamo buferio ilgis. |
Grąžina int32_t nurodantį išsiųstų baitų skaičių.
1 roboto kodas
// Create the link serial_link link(PORT1, "VEXRoboticsLink123456789", linkType::manager, true); // Do not run code UNTIL the Brains are linked while (!link.isLinked()) { wait(0.1, seconds); } Brain.Screen.clearScreen(); Brain.Screen.setCursor(1, 1); Brain.Screen.print("Robot 1 - Manager"); // Track last sent state uint8_t lastState = 255; // impossible initial value // Tell Robot 2 when the screen is being pressed while (true) { uint8_t state = Brain.Screen.pressing() ? 1 : 0; // Only send if state changed if (state != lastState) { link.send(&state, 1); lastState = state; } wait(0.02, seconds); }
Roboto 2 kodas
// Create the link serial_link link(PORT1, "VEXRoboticsLink123456789", linkType::worker, true); // Do not run code UNTIL the Brains are linked while (!link.isLinked()) { wait(0.1, seconds); } Brain.Screen.clearScreen(); Brain.Screen.setCursor(1, 1); Brain.Screen.print("Robot 2 - Worker"); Brain.Screen.newLine(); Brain.Screen.print("Waiting..."); // Track the last state uint8_t lastShown = 255; while (true) { // Variable stores 1 - pressed, 0 - not pressed uint8_t state = 0; int32_t n = link.receive(&state, 1, 200); // Only update screen if state changes if (n == 1 && state != lastShown) { Brain.Screen.clearScreen(); Brain.Screen.setCursor(1, 1); Brain.Screen.print("Robot 2 - Worker"); Brain.Screen.newLine(); // Display text if Robot 1's screen is being pressed if (state == 1) { Brain.Screen.print("Manager IS being pressed!"); } else { Brain.Screen.print("Manager is NOT being pressed"); } lastShown = state; } wait(0.02, seconds); }
receive#
Laukia ir grąžina kitą gaunamą pranešimą.
Available FunctionsParameters1 — Gauna pranešimą į simbolių buferį su pasirenkamu skirtuoju laiku.
int32_t receive( char *buffer, int32_t length, int32_t timeoutMs = 500);
Parametras |
Tipas |
Aprašymas |
|---|---|---|
|
|
Buferis gautam pranešimui saugoti. |
|
|
Buferio ilgis. |
|
|
Kiek milisekundėmis |
Grąžina int32_t , nurodantį gautų baitų skaičių.
receivegrąžina kitą eilėje esantį pranešimą iš kitos susietos V5 Brain.Pranešimai skaitomi FIFO tvarka (pirmiausia nuo seniausių neskaitytų).
Jei eilė tuščia, kai iškviečiama komanda
receive, ji laukia naujo pranešimo iki nurodytostimeoutMslaikmačio.Jei per tą langą negaunamas joks pranešimas,
receivegrąžina0, o bet koks vėliau išsiųstas pranešimas lieka eilėje, kad būtų perskaitytas kitą kartą naudojantreceive.
1 roboto kodas
// Create the link serial_link link(PORT1, "VEXRoboticsLink123456789", linkType::manager, true); // Do not run code UNTIL the Brains are linked while (!link.isLinked()) { wait(0.1, seconds); } Brain.Screen.clearScreen(); Brain.Screen.setCursor(1, 1); Brain.Screen.print("Robot 1 - Manager"); // Track last sent state uint8_t lastState = 255; // impossible initial value // Tell Robot 2 when the screen is being pressed while (true) { uint8_t state = Brain.Screen.pressing() ? 1 : 0; // Only send if state changed if (state != lastState) { link.send(&state, 1); lastState = state; } wait(0.02, seconds); }
Roboto 2 kodas
// Create the link serial_link link(PORT1, "VEXRoboticsLink123456789", linkType::worker, true); // Do not run code UNTIL the Brains are linked while (!link.isLinked()) { wait(0.1, seconds); } Brain.Screen.clearScreen(); Brain.Screen.setCursor(1, 1); Brain.Screen.print("Robot 2 - Worker"); Brain.Screen.newLine(); Brain.Screen.print("Waiting..."); // Track the last state uint8_t lastShown = 255; while (true) { // Variable stores 1 - pressed, 0 - not pressed uint8_t state = 0; int32_t n = link.receive(&state, 1, 200); // Only update screen if state changes if (n == 1 && state != lastShown) { Brain.Screen.clearScreen(); Brain.Screen.setCursor(1, 1); Brain.Screen.print("Robot 2 - Worker"); Brain.Screen.newLine(); // Display text if Robot 1's screen is being pressed if (state == 1) { Brain.Screen.print("Manager IS being pressed!"); } else { Brain.Screen.print("Manager is NOT being pressed"); } lastShown = state; } wait(0.02, seconds); }
received#
Registruoja funkciją, kuri bus iškviečiama kaskart, kai „V5 Brain“ gaus duomenis.
Available FunctionsParameters1 — Kiekvienam gautam baitų buferiui registruoja atgalinio iškvietimo funkciją.
void received( void (* callback)(uint8_t *, int32_t) );
Parametras |
Tipas |
Aprašymas |
|---|---|---|
|
|
Anksčiau apibrėžta funkcija, kuri paleidžiama, kai „V5 Brain“ gauna duomenis. |
Ši funkcija negrąžina reikšmės.
Notesreceivedgrįžtamieji iškvietimai iškviečiami su dviem argumentais: baitų buferiu ir gautų baitų skaičiumi.Gauti duomenys gali būti ne nulinės. Jei grįžtamasis iškvietimas duomenis traktuoja kaip eilutę, nukopijuokite gautus baitus į simbolių masyvą ir pridėkite nulinę nutraukiklį.
callback(buffer, length)
Argumentas |
Aprašymas |
|---|---|
|
Rodyklė į gautą baitų buferį. |
|
Gautų baitų skaičius. |
1 roboto kodas
// Create the link. serial_link link(PORT1, "VEXRoboticsLink123456789", linkType::manager, true); // Send left or right when pressed. void screen_pressed() { if (Brain.Screen.xPosition() < 240) { link.send((uint8_t*)"left", 4); } else { link.send((uint8_t*)"right", 5); } } int main() { /* vexcodeInit() is only required when using VEXcode. Remove vexcodeInit() if compiling in VS Code. */ vexcodeInit(); // Do not run code UNTIL the Brains are linked. while (!link.isLinked()) { wait(0.1, seconds); } Brain.Screen.print("Robot 1 - Manager"); Brain.Screen.pressed(screen_pressed); while (true) { wait(10, msec); } }
Roboto 2 kodas
// Called when message received. void received_callback(uint8_t *buffer, int32_t length) { char msg[32]; // Copy safely and null terminate. int n = (length < 31) ? length : 31; memcpy(msg, buffer, n); msg[n] = '\0'; Brain.Screen.clearScreen(); Brain.Screen.setCursor(1,1); Brain.Screen.print("Robot 2 - Worker"); Brain.Screen.newLine(); // Display if Robot 1's screen is pressed on left or right if (strcmp(msg, "left") == 0) { Brain.Screen.print("Manager pressed LEFT"); } else if (strcmp(msg, "right") == 0) { Brain.Screen.print("Manager pressed RIGHT"); } } int main() { /* vexcodeInit() is only required when using VEXcode. Remove vexcodeInit() if compiling in VS Code. */ vexcodeInit(); // Create the link. serial_link link(PORT1, "VEXRoboticsLink123456789", linkType::worker, true); // Do not run code UNTIL the Brains are linked. while (!link.isLinked()) { wait(0.1, seconds); } link.received(received_callback); Brain.Screen.clearScreen(); Brain.Screen.setCursor(1,1); Brain.Screen.print("Robot 2 - Worker"); Brain.Screen.newLine(); Brain.Screen.print("Waiting..."); while (true) { wait(10, msec); } }