Soros kapcsolat#
Bevezetés#
A serial_link osztály lehetővé teszi nyers bájtok folyamának küldését robotok között. Robotok közötti kommunikációra tervezték, ahol a küldő és a fogadó robot egyaránt érti az adatfolyam tartalmát.
A send minden egyes használata adatokat ad hozzá a csatolt EXP Brain sorához, és a sor FIFO (first-in, first-out) elv szerint kerül olvasásra. Ha több üzenet is elküldésre kerül, mielőtt a másik EXP Brain fogadást használna, akkor azok egyenként, a küldésük sorrendjében kerülnek tárolásra és visszaküldésre. Mivel az üzenetek sorba állíthatók, ugyanazon állapot ismételt elküldése minden ciklusban várakozást okozhat; időkritikus logika esetén csak akkor küldjön üzenetet, ha az értékek megváltoznak.
Fontos: Mindkét robotnak egyszerre kell olyan projekteket futtatnia, amelyek serial_link használják, különben nem történik adatküldés/fogadás.
Osztálykonstruktorok#
serial_link(
int32_t index,
const char *name,
linkType type,
bool isWired = false );
Osztálydestruktor#
Megsemmisíti a serial_link objektumot és felszabadítja a hozzá tartozó erőforrásokat.
~serial_link();
Paraméterek#
Paraméter |
Típus |
Leírás |
|---|---|---|
|
|
Az üzenetkapcsolathoz tartozó intelligens port, amelyet |
|
|
A link neve. Javasoljuk, hogy ez az egyedi karakterlánc elég hosszú legyen ahhoz, hogy a vexos általi hashelése egyedi azonosítót hozzon létre. Egy rossz linknév valami általános lenne, például a „vexlink”, mivel azt egy másik csapat is használhatja. |
|
|
A kapcsolat típusa, vagy
|
|
|
Azt jelzi, hogy a serial_link objektum vezetékes-e (alapértelmezett érték:
|
Megjegyzések#
A VEXlink támogatja mind a vezeték nélküli, mind a vezetékes kommunikációt, vezetékes csatlakozás esetén pedig módosított intelligens kábel használata ajánlott az áramellátási problémák elkerülése érdekében.
A vezeték nélküli kommunikációhoz minden robotnak szüksége van egy V5 Robot Radio-ra, amely egy Smart Porthoz csatlakozik.
A VEXlink rádió használható az EXP vezérlő VEXnet rádiója mellett, amelyet a legmagasabb számú Smart Porthoz kell csatlakoztatni az ütközések elkerülése érdekében.
VEXlink létrehozásához mindkét EXP Brain-t csatlakoztatni kell egy V5 Robot Rádióhoz.
Példa#
1. robot kódja
// Create a wireless link in Port 1 serial_link link = serial_link( PORT1, // index "VEXRoboticsLink123456789", // name linkType::manager, // type true); // isWiredRobot 2 kódja
// Create a wireless link in Port 1 serial_link link = serial_link( PORT1, // index "VEXRoboticsLink123456789", // name linkType::worker, // type true); // isWired
Tagfüggvények#
A serial_link osztály a következő tagfüggvényeket tartalmazza:
isLinked— Ellenőrzi, hogy az EXP Brains párosítva vannak-e és kommunikálnak-e ezen a kapcsolaton.send— Üzenetet küld a párosított Agynak.receive— Várakozás a következő bejövő üzenetre, majd visszaküldi azt.received— Regisztrál egy függvényt, amely minden új üzenet érkezésekor meghívódik.
Bármely serial_link tagfüggvény meghívása előtt létre kell hozni egy serial_link példányt, az alábbiak szerint:
1. robot kódja
// Create a wireless link in Port 1 serial_link link = serial_link( PORT1, // index "VEXRoboticsLink123456789", // name linkType::manager, // type true); // isWiredRobot 2 kódja
// Create a wireless link in Port 1 serial_link link = serial_link( PORT1, // index "VEXRoboticsLink123456789", // name linkType::worker, // type true); // isWired
isLinked#
Visszaadja, hogy a soros kapcsolaton lévő EXP Brain-ek párosítva vannak-e egymással.
Available Functionsbool isLinked();
Ennek a függvénynek nincsenek paraméterei.
Return ValuesEgy logikai értéket ad vissza, amely jelzi, hogy az EXP Brains össze van-e kapcsolva:
true— The two EXP Brains are paired and communicating on this link.false— The two EXP Brains are not paired on this link.
Jó gyakorlat, ha a projekt elején mindig ellenőrizzük, hogy az EXP Brain-ek össze vannak-e kapcsolva, mielőtt bármilyen további kódot futtatnánk.
1. robot kódja
// 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));
Robot 2 kódja
// 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#
Üzenetet küld a párosított Agynak.
Available Functions1 — Bájtpuffer használatával küld üzenetet.
int32_t send( uint8_t *buffer, int32_t length );
Parameters2 — Karakterpuffer használatával küld üzenetet.
int32_t send( const char *buffer, int32_t length );
Paraméter |
Típus |
Leírás |
|---|---|---|
|
|
A másik összekapcsolt EXP Brain-nek küldendő puffer. |
|
|
A küldendő puffer hossza. |
Egy int32_t értéket ad vissza, amely az elküldött bájtok számát jelöli.
1. robot kódja
// 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); }
Robot 2 kódja
// 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#
Megvárja és visszaküldi a következő bejövő üzenetet.
Available FunctionsParameters1 — Karakterpufferbe fogad egy üzenetet, opcionális időtúllépéssel.
int32_t receive( char *buffer, int32_t length, int32_t timeoutMs = 500);
Paraméter |
Típus |
Leírás |
|---|---|---|
|
|
A fogadott üzenet tárolására szolgáló puffer. |
|
|
A puffer hossza. |
|
|
Mennyi ideig (ezredmásodpercben) vár a |
Egy int32_t értéket ad vissza, amely a fogadott bájtok számát jelöli.
A
receivevisszaadja a másik összekapcsolt EXP Brain következő sorban álló üzenetét.Az üzenetek FIFO sorrendben kerülnek olvasásra (a legrégebbi olvasatlannal kezdődnek).
Ha a várólista üres a
receivemeghívásakor, akkor a megadotttimeoutMsideig vár új üzenetre.Ha az adott ablakban nem érkezik üzenet,
receiveparancs0értéket ad vissza, és az utána küldött üzenetek a sorban maradnak, hogyreceiveparancs következő használatakor beolvassák őket.
1. robot kódja
// 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); }
Robot 2 kódja
// 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#
Regisztrál egy függvényt, amely minden alkalommal meghívódik, amikor az EXP Brain elküldött üzenetet kap.
Available Functions1 — Minden fogadott üzenethez regisztrál egy visszahívó függvényt.
void received( void (* callback)(const char *, const char *, double) );
2 — Minden olyan fogadott üzenetre regisztrál egy visszahívást, amely egy további int32_t mezőt tartalmaz.
void received( void (* callback)(const char *, const char *, int32_t, double) );
3 — Csak az üzenettel megegyező nevű fogadott üzenetek esetén regisztrál visszahívást.
void received( const char *message, void (* callback)(const char *, const char *, double) );
Parameters4 — Csak az üzenettel megegyező nevű fogadott üzenetek esetén regisztrál visszahívást, ahol az üzenet hasznos adata egy további int32_t mezőt is tartalmaz.
void received( const char *message, void (* callback)(const char *, const char *, int32_t, double) );
Paraméter |
Típus |
Leírás |
|---|---|---|
|
|
Az egyeztetendő üzenet neve (karakterlánc). Amikor egy fogadott üzenet neve megegyezik ezzel az értékkel, a |
|
|
Egy korábban definiált függvény, amely akkor fut le, amikor az EXP Brain egyező üzenetet kap |
Ez a függvény nem ad vissza értéket.
Notesreceivedvisszahívásokat négy argumentummal hívjuk meg:
callback(message, linkname, index, value)
Érv |
Leírás |
|---|---|
|
A fogadott üzenet neve (például |
|
A hivatkozás neve, amelyről az üzenet érkezett. |
|
Az üzenettel együtt küldött egész szám (ha meg van adva). |
|
Az üzenettel együtt küldött lebegőpontos érték (ha meg van adva). |
1. robot kódja
// 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(); // 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.pressed(screen_pressed); }
Robot 2 kódja
// 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..."); }