Sarjalinkki#
Johdanto#
serial_link -luokka mahdollistaa raakatavuvirran lähettämisen robottien välillä. Se on suunniteltu robottien väliseen kommunikointiin, jossa sekä lähettävä että vastaanottava robotti ymmärtävät datavirran sisällön.
Jokainen send-funktion käyttökerta lisää dataa linkitetyn V5 Brainin jonoon, ja jono luetaan FIFO-periaatteella (first-in, first-out). Jos useita viestejä lähetetään ennen kuin muut V5 Brainin toiminnot vastaanottavat viestejä, ne tallennetaan ja palautetaan yksi kerrallaan lähetysjärjestyksessä. Koska viestit voivat jonottaa, saman tilan toistuva lähettäminen jokaisessa silmukassa voi luoda ruuhkan; aikakriittisissä logiikoissa lähetä vain, kun arvot muuttuvat.
Tärkeää: Molempien robottien on oltava käynnissä projekteissa, jotka käyttävät serial_link tä samanaikaisesti, muuten dataa ei lähetetä/vastaanoteta.
Luokanrakentajat#
serial_link(
int32_t index,
const char *name,
linkType type,
bool isWired = false );
Luokan tuhoaja#
Tuhoaa serial_link -objektin ja vapauttaa siihen liittyvät resurssit.
~serial_link();
Parametrit#
Parametri |
Tyyppi |
Kuvaus |
|---|---|---|
|
|
Älyportti, johon viestilinkki on yhdistetty, kirjoitetaan muodossa |
|
|
Tämän linkin nimi. On suositeltavaa, että tämä yksilöllinen merkkijono on riittävän pitkä, jotta vexos-hajautettuna se luo yksilöllisen tunnuksen. Huono linkin nimi olisi jotain yleistä, kuten “vexlink”, koska toinen tiimi saattaa käyttää sitä. |
|
|
Linkin tyyppi, joko
|
|
|
Onko serial_link-objekti langallinen (oletusarvo
|
Muistiinpanoja#
VEXlink tukee sekä langatonta että langallista tiedonsiirtoa, ja langallisissa yhteyksissä suositellaan muunneltua älykaapelia virransyöttöongelmien välttämiseksi.
Langatonta tiedonsiirtoa varten jokainen robotti tarvitsee V5-robottiradion, joka on kytketty Smart Port -porttiin.
VEXlink-radiota voidaan käyttää V5-ohjaimen VEXnet-radion rinnalla, joka tulisi kytkeä korkeimman numeron Smart Port -porttiin konfliktien välttämiseksi.
VEXlinkin luomiseksi molemmat V5 Brain -yksiköt on kytkettävä V5-robottiradioon.
Esimerkki#
Robotin 1 koodi
// Create a wireless link in Port 1 serial_link link = serial_link( PORT1, // index "VEXRoboticsLink123456789", // name linkType::manager, // type true); // isWiredRobotin 2 koodi
// Create a wireless link in Port 1 serial_link link = serial_link( PORT1, // index "VEXRoboticsLink123456789", // name linkType::worker, // type true); // isWired
Jäsenten toiminnot#
serial_link -luokka sisältää seuraavat jäsenfunktiot:
isLinked— Tarkistaa, ovatko V5-aivot paritettuja ja kommunikoivatko ne tämän linkin kautta.send— Lähettää viestin parilliselle aivolle.receive— Odottaa seuraavaa saapuvaa viestiä ja palauttaa sen.received— Rekisteröi funktion kutsuttavaksi aina, kun uusi viesti vastaanotetaan.
Ennen minkään serial_link -jäsenfunktion kutsumista on luotava serial_link -instanssi alla olevan mukaisesti:
Robotin 1 koodi
// Create a wireless link in Port 1 serial_link link = serial_link( PORT1, // index "VEXRoboticsLink123456789", // name linkType::manager, // type true); // isWiredRobotin 2 koodi
// Create a wireless link in Port 1 serial_link link = serial_link( PORT1, // index "VEXRoboticsLink123456789", // name linkType::worker, // type true); // isWired
isLinked#
Palauttaa, onko sarjalinkin V5 Brainit paritettu toisiinsa.
Available Functionsbool isLinked();
Tällä funktiolla ei ole parametreja.
Return ValuesPalauttaa totuusarvon, joka ilmaisee, ovatko V5 Brains linkitettyjä:
true— The two V5 Brains are paired and communicating on this link.false— The two V5 Brains are not paired on this link.
On hyvä käytäntö tarkistaa aina projektin alussa, että V5-aivot on linkitetty, ennen kuin jatkat koodin suorittamista.
Robotin 1 koodi
// 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));
Robotin 2 koodi
// 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#
Lähettää viestin parilliselle aivoille.
Available Functions1 — Lähettää viestin käyttäen tavupuskuria.
int32_t send( uint8_t *buffer, int32_t length );
Parameters2 — Lähettää viestin käyttäen merkkipuskuria.
int32_t send( const char *buffer, int32_t length );
Parametri |
Tyyppi |
Kuvaus |
|---|---|---|
|
|
Puskuri, joka lähetetään toiseen linkitettyyn V5 Brainiin. |
|
|
Lähetettävän puskurin pituus. |
Palauttaa arvon int32_t joka edustaa lähetettyjen tavujen määrää.
Robotin 1 koodi
// 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); }
Robotin 2 koodi
// 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#
Odottaa ja palauttaa seuraavan saapuvan viestin.
Available FunctionsParameters1 — Vastaanottaa viestin merkkipuskuriin, jossa on valinnainen aikakatkaisu.
int32_t receive( char *buffer, int32_t length, int32_t timeoutMs = 500);
Parametri |
Tyyppi |
Kuvaus |
|---|---|---|
|
|
Puskuri, johon vastaanotettu viesti tallennetaan. |
|
|
Puskurin pituus. |
|
|
Kuinka kauan millisekunteina |
Palauttaa arvon int32_t joka edustaa vastaanotettujen tavujen määrää.
receivepalauttaa seuraavan jonossa olevan viestin toiselta linkitetyltä V5 Brainilta.Viestit luetaan FIFO-järjestyksessä (vanhin lukematon ensin).
Jos jono on tyhjä, kun
receivekutsutaan, se odottaa uutta viestiä määritettyyntimeoutMsasti.Jos kyseiseen ikkunaan ei saavu viestiä,
receivepalauttaa arvon0, ja kaikki sen jälkeen lähetetyt viestit jäävät jonoon luettavaksi seuraavan kerran, kunreceivekäytetään.
Robotin 1 koodi
// 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); }
Robotin 2 koodi
// 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#
Rekisteröi funktion, jota kutsutaan aina, kun V5 Brain vastaanottaa dataa.
Available FunctionsParameters1 — Rekisteröi takaisinkutsufunktion jokaiselle vastaanotetulle tavupuskurille.
void received( void (* callback)(uint8_t *, int32_t) );
Parametri |
Tyyppi |
Kuvaus |
|---|---|---|
|
|
Aiemmin määritelty funktio, joka suoritetaan, kun V5 Brain vastaanottaa dataa. |
Tämä funktio ei palauta arvoa.
Notesreceivedtakaisinkutsuja kutsutaan kahdella argumentilla: tavupuskurilla ja vastaanotettujen tavujen lukumäärällä.Vastaanotettu data ei välttämättä ole null-päätteinen. Jos takaisinkutsu käsittelee dataa merkkijonona, kopioi vastaanotetut tavut merkistötaulukkoon ja lisää null-päätteinen merkkijono.
callback(buffer, length)
Argumentti |
Kuvaus |
|---|---|
|
Osoitin vastaanotettuun tavupuskuriin. |
|
Vastaanotettujen tavujen määrä. |
Robotin 1 koodi
// 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); } }
Robotin 2 koodi
// 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); } }