Σειριακός σύνδεσμος#
Εισαγωγή#
The serial_link class allows for a stream of raw bytes to be sent between robots. It’s designed for robot-to-robot communication where the transmitting and receiving robot both understand the contents of the data stream.
Every usage of send adds data to the linked V5 Brain’s queue, and the queue is read first-in, first-out (FIFO). If multiple messages are sent before the other V5 Brain uses receive, they will be stored and returned one at a time in the order they were sent. Because messages can queue, repeatedly sending the same status every loop may create backlog; for time-critical logic, send only when values change.
Important: Both robots must be running projects that use serial_link at the same time, or no data will be sent/received.
Κατασκευαστές κλάσεων#
serial_link(
int32_t index,
const char *name,
linkType type,
bool isWired = false );
Καταστροφέας κλάσης#
Destroys the serial_link object and releases associated resources.
~serial_link();
Παράμετροι#
Παράμετρος |
Τύπος |
Περιγραφή |
|---|---|---|
|
|
The Smart Port that the message link is connected to, written as |
|
|
Το όνομα αυτού του συνδέσμου. Συνιστάται αυτή η μοναδική συμβολοσειρά να έχει αρκετά μεγάλο μήκος ώστε όταν κατακερματιστεί από το vexos να δημιουργήσει ένα μοναδικό αναγνωριστικό. Ένα λανθασμένο όνομα συνδέσμου θα ήταν κάτι γενικό, όπως “vexlink”, καθώς μπορεί να χρησιμοποιηθεί από άλλη ομάδα. |
|
|
The type of link, either
|
|
|
Whether the serial_link object is wired (defaults to
|
Σημειώσεις#
Το VEXlink υποστηρίζει τόσο ασύρματη όσο και ενσύρματη επικοινωνία, με τις ενσύρματες συνδέσεις να συνιστούν ένα τροποποιημένο έξυπνο καλώδιο για την αποφυγή προβλημάτων δρομολόγησης ρεύματος.
Για ασύρματη επικοινωνία, κάθε ρομπότ χρειάζεται ένα V5 Robot Radio συνδεδεμένο σε μια Έξυπνη Θύρα.
Το VEXlink Radio μπορεί να χρησιμοποιηθεί παράλληλα με το VEXnet radio ενός V5 Controller, το οποίο θα πρέπει να είναι συνδεδεμένο στην Smart Port με τον μεγαλύτερο αριθμό για την αποφυγή διενέξεων.
Για να δημιουργήσετε ένα VEXlink, και οι δύο εγκέφαλοι V5 πρέπει να είναι συνδεδεμένοι σε ένα ρομποτικό ραδιόφωνο V5.
Παράδειγμα#
Κωδικός για το Ρομπότ 1
// Create a wireless link in Port 1 serial_link link = serial_link( PORT1, // index "VEXRoboticsLink123456789", // name linkType::manager, // type true); // isWiredΚωδικός για το Ρομπότ 2
// Create a wireless link in Port 1 serial_link link = serial_link( PORT1, // index "VEXRoboticsLink123456789", // name linkType::worker, // type true); // isWired
Συναρτήσεις Μελών#
The serial_link class includes the following member functions:
isLinked— Checks if the V5 Brains are paired and communicating on this link.send— Sends a message to the paired Brain.receive— Waits for and returns the next incoming message.received— Registers a function to be called whenever a new message is received.
Before calling any serial_link member functions, a serial_link instance must be created, as shown below:
Κωδικός για το Ρομπότ 1
// Create a wireless link in Port 1 serial_link link = serial_link( PORT1, // index "VEXRoboticsLink123456789", // name linkType::manager, // type true); // isWiredΚωδικός για το Ρομπότ 2
// Create a wireless link in Port 1 serial_link link = serial_link( PORT1, // index "VEXRoboticsLink123456789", // name linkType::worker, // type true); // isWired
isLinked#
Επιστρέφει εάν οι εγκέφαλοι V5 σε μια σειριακή σύνδεση είναι ζευγαρωμένοι μεταξύ τους.
Available Functionsbool isLinked();
Αυτή η συνάρτηση δεν έχει παραμέτρους.
Return ValuesΕπιστρέφει μια λογική τιμή που υποδεικνύει εάν οι εγκέφαλοι V5 είναι συνδεδεμένοι:
true— The two V5 Brains are paired and communicating on this link.false— The two V5 Brains are not paired on this link.
Είναι καλή πρακτική να ελέγχετε πάντα για να βεβαιωθείτε ότι οι εγκέφαλοι V5 είναι συνδεδεμένοι στην αρχή ενός έργου πριν από την εκτέλεση οποιουδήποτε περαιτέρω κώδικα.
Κωδικός για το Ρομπότ 1
// 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));
Κωδικός για το Ρομπότ 2
// 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#
Στέλνει ένα μήνυμα στον ζευγαρωμένο εγκέφαλο.
Available Functions1 — Στέλνει ένα μήνυμα χρησιμοποιώντας ένα buffer byte.
int32_t send( uint8_t *buffer, int32_t length );
Parameters2 — Στέλνει ένα μήνυμα χρησιμοποιώντας μια προσωρινή μνήμη χαρακτήρων.
int32_t send( const char *buffer, int32_t length );
Παράμετρος |
Τύπος |
Περιγραφή |
|---|---|---|
|
|
Το buffer που θα σταλεί στον άλλο συνδεδεμένο εγκέφαλο V5. |
|
|
Το μήκος του buffer που θα αποσταλεί. |
Returns an int32_t representing the number of bytes sent.
Κωδικός για το Ρομπότ 1
// 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); }
Κωδικός για το Ρομπότ 2
// 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#
Περιμένει και επιστρέφει το επόμενο εισερχόμενο μήνυμα.
Available FunctionsParameters1 — Λαμβάνει ένα μήνυμα σε μια προσωρινή μνήμη χαρακτήρων με προαιρετικό χρονικό όριο.
int32_t receive( char *buffer, int32_t length, int32_t timeoutMs = 500);
Παράμετρος |
Τύπος |
Περιγραφή |
|---|---|---|
|
|
Η προσωρινή μνήμη για την αποθήκευση του ληφθέντος μηνύματος. |
|
|
Το μήκος του buffer. |
|
|
How long in milliseconds |
Returns an int32_t representing the number of bytes received.
receivereturns the next queued message from the other linked V5 Brain.Τα μηνύματα διαβάζονται με σειρά FIFO (πρώτα τα παλαιότερα μη αναγνωσμένα).
If the queue is empty when
receiveis called, it waits up to the specifiedtimeoutMsfor a new message.If no message arrives in that window,
receivereturns0, and any message sent afterward remains in the queue to be read the next timereceiveis used.
Κωδικός για το Ρομπότ 1
// 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); }
Κωδικός για το Ρομπότ 2
// 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#
Καταγράφει μια συνάρτηση που θα καλείται κάθε φορά που ο εγκέφαλος V5 λαμβάνει δεδομένα.
Available FunctionsParameters1 — Καταχωρεί μια συνάρτηση επανάκλησης για κάθε buffer byte που λαμβάνεται.
void received( void (* callback)(uint8_t *, int32_t) );
Παράμετρος |
Τύπος |
Περιγραφή |
|---|---|---|
|
|
Μια προηγουμένως καθορισμένη συνάρτηση που εκτελείται όταν ο εγκέφαλος V5 λαμβάνει δεδομένα. |
Αυτή η συνάρτηση δεν επιστρέφει τιμή.
Notesreceivedcallbacks are called with two arguments: a byte buffer and the number of bytes received.Τα ληφθέντα δεδομένα ενδέχεται να μην έχουν τερματισμό null. Εάν η επανάκληση αντιμετωπίζει τα δεδομένα ως συμβολοσειρά, αντιγράψτε τα ληφθέντα byte σε έναν πίνακα χαρακτήρων και προσθέστε έναν τερματιστή null.
callback(buffer, length)
Επιχείρημα |
Περιγραφή |
|---|---|
|
Ένας δείκτης προς το buffer byte που λήφθηκε. |
|
Ο αριθμός των byte που ελήφθησαν. |
Κωδικός για το Ρομπότ 1
// 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); } }
Κωδικός για το Ρομπότ 2
// 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); } }