Tautan Serial#
Perkenalan#
Kelas serial_link memungkinkan pengiriman aliran byte mentah antar robot. Kelas ini dirancang untuk komunikasi antar robot di mana robot pengirim dan penerima sama-sama memahami isi aliran data tersebut.
Setiap penggunaan send menambahkan data ke antrian EXP Brain yang terhubung, dan antrian dibaca masuk pertama keluar pertama (FIFO). Jika beberapa pesan dikirim sebelum EXP Brain lain menggunakan fungsi terima, pesan-pesan tersebut akan disimpan dan dikembalikan satu per satu sesuai urutan pengirimannya. Karena pesan dapat mengantri, mengirim status yang sama berulang kali setiap putaran dapat menyebabkan penumpukan; untuk logika yang sensitif terhadap waktu, kirim hanya ketika nilai berubah.
Penting: Kedua robot harus menjalankan proyek yang menggunakan serial_link secara bersamaan, jika tidak, tidak ada data yang akan dikirim/diterima.
Konstruktor Kelas#
serial_link(
int32_t index,
const char *name,
linkType type,
bool isWired = false );
Destruktor Kelas#
Menghapus objek serial_link dan melepaskan sumber daya terkait.
~serial_link();
Parameter#
Parameter |
Jenis |
Keterangan |
|---|---|---|
|
|
Port Pintar yang terhubung dengan tautan pesan, ditulis sebagai |
|
|
Nama tautan ini. Disarankan agar string unik ini cukup panjang sehingga ketika di-hash oleh vexos akan menghasilkan ID unik. Nama tautan yang buruk adalah sesuatu yang generik seperti “vexlink” karena mungkin digunakan oleh tim lain. |
|
|
Jenis tautan, yaitu
|
|
|
Apakah objek serial_link terhubung melalui kabel (nilai default
|
Catatan#
VEXlink mendukung komunikasi nirkabel dan kabel, dengan koneksi kabel yang merekomendasikan kabel pintar yang dimodifikasi untuk mencegah masalah perutean daya.
Untuk komunikasi nirkabel, setiap robot membutuhkan Radio Robot V5 yang terhubung ke Smart Port.
Radio VEXlink dapat digunakan bersamaan dengan radio VEXnet pada EXP Controller, yang harus dihubungkan ke Smart Port dengan nomor tertinggi untuk menghindari konflik.
Untuk membuat VEXlink, kedua EXP Brain harus dihubungkan ke V5 Robot Radio.
Contoh#
Kode untuk Robot 1
// Create a wireless link in Port 1 serial_link link = serial_link( PORT1, // index "VEXRoboticsLink123456789", // name linkType::manager, // type true); // isWiredKode untuk Robot 2
// Create a wireless link in Port 1 serial_link link = serial_link( PORT1, // index "VEXRoboticsLink123456789", // name linkType::worker, // type true); // isWired
Fungsi Keanggotaan#
Kelas serial_link mencakup fungsi anggota berikut:
isLinked— Memeriksa apakah EXP Brains berpasangan dan berkomunikasi pada tautan ini.send— Mengirim pesan ke Otak yang berpasangan.receive— Menunggu dan mengembalikan pesan masuk berikutnya.received— Mendaftarkan fungsi yang akan dipanggil setiap kali pesan baru diterima.
Sebelum memanggil fungsi anggota serial_link apa pun, sebuah instance serial_link harus dibuat, seperti yang ditunjukkan di bawah ini:
Kode untuk Robot 1
// Create a wireless link in Port 1 serial_link link = serial_link( PORT1, // index "VEXRoboticsLink123456789", // name linkType::manager, // type true); // isWiredKode untuk Robot 2
// Create a wireless link in Port 1 serial_link link = serial_link( PORT1, // index "VEXRoboticsLink123456789", // name linkType::worker, // type true); // isWired
isLinked#
Mengembalikan nilai yang menunjukkan apakah EXP Brain pada tautan serial telah dipasangkan satu sama lain.
Available Functionsbool isLinked();
Fungsi ini tidak memiliki parameter apa pun.
Return ValuesMengembalikan nilai Boolean yang menunjukkan apakah EXP Brains terhubung atau tidak:
true— The two EXP Brains are paired and communicating on this link.false— The two EXP Brains are not paired on this link.
Sebaiknya selalu periksa untuk memastikan EXP Brains sudah terhubung di awal proyek sebelum menjalankan kode lebih lanjut.
Kode untuk Robot 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));
Kode untuk Robot 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#
Mengirim pesan ke Otak yang berpasangan.
Available Functions1 — Mengirim pesan menggunakan buffer byte.
int32_t send( uint8_t *buffer, int32_t length );
Parameters2 — Mengirim pesan menggunakan buffer karakter.
int32_t send( const char *buffer, int32_t length );
Parameter |
Jenis |
Keterangan |
|---|---|---|
|
|
Buffer yang akan dikirim ke EXP Brain lain yang terhubung. |
|
|
Panjang buffer yang akan dikirim. |
Mengembalikan nilai int32_t yang mewakili jumlah byte yang dikirim.
Kode untuk Robot 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); }
Kode untuk Robot 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#
Menunggu dan mengembalikan pesan masuk berikutnya.
Available FunctionsParameters1 — Menerima pesan ke dalam buffer karakter dengan batas waktu opsional.
int32_t receive( char *buffer, int32_t length, int32_t timeoutMs = 500);
Parameter |
Jenis |
Keterangan |
|---|---|---|
|
|
Buffer untuk menyimpan pesan yang diterima. |
|
|
Panjang buffer. |
|
|
Berapa lama dalam milidetik |
Mengembalikan nilai int32_t yang mewakili jumlah byte yang diterima.
receivemengembalikan pesan antrian berikutnya dari EXP Brain terkait lainnya.Pesan dibaca berdasarkan urutan FIFO (pesan terlama yang belum dibaca terlebih dahulu).
Jika antrean kosong saat perintah
receivedipanggil, maka antrean akan menunggu hinggatimeoutMsuntuk pesan baru.Jika tidak ada pesan yang tiba dalam jendela waktu tersebut,
receivemengembalikan0, dan pesan apa pun yang dikirim setelahnya tetap berada dalam antrian untuk dibaca pada saat berikutnyareceivedigunakan.
Kode untuk Robot 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); }
Kode untuk Robot 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#
Mendaftarkan fungsi yang akan dipanggil setiap kali EXP Brain menerima pesan yang dikirim.
Available Functions1 — Mendaftarkan fungsi callback untuk setiap pesan yang diterima.
void received( void (* callback)(const char *, const char *, double) );
2 — Mendaftarkan fungsi callback yang dipanggil untuk setiap pesan yang diterima yang menyertakan bidang int32_t tambahan.
void received( void (* callback)(const char *, const char *, int32_t, double) );
3 — Mendaftarkan fungsi callback yang hanya dipanggil untuk pesan yang diterima yang namanya cocok dengan pesan tersebut.
void received( const char *message, void (* callback)(const char *, const char *, double) );
Parameters4 — Mendaftarkan fungsi callback yang hanya dipanggil untuk pesan yang diterima yang namanya cocok dengan pesan, di mana muatan pesan mencakup bidang int32_t tambahan.
void received( const char *message, void (* callback)(const char *, const char *, int32_t, double) );
Parameter |
Jenis |
Keterangan |
|---|---|---|
|
|
The message name (string) to match. When a received message’s name matches this value, the |
|
|
Fungsi yang telah didefinisikan sebelumnya yang dijalankan ketika EXP Brain menerima pesan yang cocok dengan |
Fungsi ini tidak mengembalikan nilai.
Notesreceivedpanggilan balik yang dipanggil dengan empat argumen:
callback(message, linkname, index, value)
Argumen |
Keterangan |
|---|---|
|
Nama pesan yang diterima (misalnya, |
|
Nama tautan tempat pesan diterima. |
|
Nilai bilangan bulat yang dikirim bersama pesan (jika disediakan). |
|
Nilai float yang dikirim bersama pesan (jika disediakan). |
Kode untuk Robot 1
// 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); }
Kode untuk Robot 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..."); }