Seri Bağlantı#
giriiş#
serial_link sınıfı, robotlar arasında ham bayt akışının gönderilmesine olanak tanır. Hem gönderen hem de alıcı robotun veri akışının içeriğini anladığı robotlar arası iletişim için tasarlanmıştır.
send’nin her kullanımı, bağlantılı EXP Beyninin kuyruğuna veri ekler ve kuyruk ilk giren ilk çıkar (FIFO) prensibiyle okunur. Diğer EXP Beyni alma işlemini kullanmadan önce birden fazla mesaj gönderilirse, bunlar depolanır ve gönderildikleri sırayla tek tek geri döndürülür. Mesajlar kuyruğa alınabildiğinden, her döngüde aynı durumu tekrar tekrar göndermek birikmeye neden olabilir; zaman açısından kritik mantık için, yalnızca değerler değiştiğinde gönderin.
Önemli: Her iki robot da aynı anda serial_link kullanan projeleri çalıştırıyor olmalıdır, aksi takdirde veri gönderilemez/alınamaz.
Sınıf Oluşturucuları#
serial_link(
int32_t index,
const char *name,
linkType type,
bool isWired = false );
Sınıf Yıkıcısı#
serial_link nesnesini yok eder ve ilişkili kaynakları serbest bırakır.
~serial_link();
Parametreler#
Parametre |
Tip |
Tanım |
|---|---|---|
|
|
Mesaj bağlantısının bağlı olduğu Akıllı Bağlantı Noktası, |
|
|
Bu bağlantının adı. Bu benzersiz dizenin, Vexos tarafından karma algoritmasıyla işlendiğinde benzersiz bir kimlik oluşturacak kadar uzun olması önerilir. “Vexlink” gibi genel bir bağlantı adı kötü bir seçim olur, çünkü başka bir ekip tarafından da kullanılabilir. |
|
|
Bağlantı türü, ya
|
|
|
serial_link nesnesinin kablolu olup olmadığı (varsayılan değer
|
Notlar#
VEXlink hem kablosuz hem de kablolu iletişimi destekler; kablolu bağlantılar için güç yönlendirme sorunlarını önlemek amacıyla modifiye edilmiş akıllı bir kablo önerilir.
Kablosuz iletişim için her robotun bir Akıllı Bağlantı Noktasına bağlı bir V5 Robot Radyosuna ihtiyacı vardır.
VEXlink Radyo, EXP Kontrol Cihazının VEXnet radyosuyla birlikte kullanılabilir; çakışmaları önlemek için VEXnet radyosunun en yüksek numaralı Akıllı Bağlantı Noktasına bağlanması gerekir.
VEXlink oluşturmak için her iki EXP Beyninin de bir V5 Robot Radyosuna bağlanması gerekir.
Örnek#
Robot 1 için Kod
// Create a wireless link in Port 1 serial_link link = serial_link( PORT1, // index "VEXRoboticsLink123456789", // name linkType::manager, // type true); // isWiredRobot 2 için Kod
// Create a wireless link in Port 1 serial_link link = serial_link( PORT1, // index "VEXRoboticsLink123456789", // name linkType::worker, // type true); // isWired
Üye Fonksiyonları#
serial_link sınıfı aşağıdaki üye fonksiyonlarını içerir:
isLinked— EXP Beyinlerinin bu bağlantı üzerinden eşleştirilip iletişim kurup kurmadığını kontrol eder.send— Eşleştirilmiş Beyne bir mesaj gönderir.receive— Bir sonraki gelen mesajı bekler ve geri döndürür.received— Yeni bir mesaj alındığında çağrılacak bir fonksiyonu kaydeder.
serial_link üye fonksiyonunu çağırmadan önce, aşağıda gösterildiği gibi bir serial_link örneği oluşturulmalıdır:
Robot 1 için Kod
// Create a wireless link in Port 1 serial_link link = serial_link( PORT1, // index "VEXRoboticsLink123456789", // name linkType::manager, // type true); // isWiredRobot 2 için Kod
// Create a wireless link in Port 1 serial_link link = serial_link( PORT1, // index "VEXRoboticsLink123456789", // name linkType::worker, // type true); // isWired
isLinked#
Seri bağlantıdaki EXP Beyinlerinin birbiriyle eşleştirilip eşleştirilmediğini döndürür.
Available Functionsbool isLinked();
Bu fonksiyonun herhangi bir parametresi yoktur.
Return ValuesEXP Beyinlerinin birbirine bağlı olup olmadığını gösteren bir Boolean değeri döndürür:
true— The two EXP Brains are paired and communicating on this link.false— The two EXP Brains are not paired on this link.
Herhangi bir kod çalıştırmadan önce projenin başlangıcında EXP Brains’in bağlantılı olduğundan emin olmak her zaman iyi bir uygulamadır.
Robot 1 için Kod
// 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 için Kod
// 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#
Eşleştirilmiş beyne bir mesaj gönderir.
Available Functions1 — Bir bayt arabelleği kullanarak mesaj gönderir.
int32_t send( uint8_t *buffer, int32_t length );
Parameters2 — Karakter arabelleği kullanarak mesaj gönderir.
int32_t send( const char *buffer, int32_t length );
Parametre |
Tip |
Tanım |
|---|---|---|
|
|
Diğer bağlantılı EXP Beynine gönderilecek tampon dosya. |
|
|
Gönderilecek arabelleğin uzunluğu. |
Gönderilen bayt sayısını temsil eden int32_t değerini döndürür.
Robot 1 için Kod
// 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 için Kod
// 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#
Gelen bir sonraki mesajı bekler ve geri gönderir.
Available FunctionsParameters1 — İsteğe bağlı zaman aşımı ile bir karakter arabelleğine mesaj alır.
int32_t receive( char *buffer, int32_t length, int32_t timeoutMs = 500);
Parametre |
Tip |
Tanım |
|---|---|---|
|
|
Alınan mesajı saklamak için kullanılan tampon bellek. |
|
|
Tamponun uzunluğu. |
|
|
|
Alınan bayt sayısını temsil eden int32_t değerini döndürür.
receivealırsa, bağlantılı diğer EXP Beyninden sıradaki bir sonraki mesajı döndürür.Mesajlar FIFO (en eski okunmamış olan önce) sırasına göre okunur.
receiveçağrıldığında kuyruk boşsa, yeni bir mesaj için belirtilentimeoutMssüresine kadar bekler.Eğer o zaman diliminde hiçbir mesaj gelmezse,
receive0değerini döndürür ve daha sonra gönderilen herhangi bir mesaj, bir sonrakireceivekullanımında okunmak üzere kuyrukta kalır.
Robot 1 için Kod
// 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 için Kod
// 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#
EXP Brain’in gönderilen bir mesajı aldığı her seferinde çağrılacak bir fonksiyonu kaydeder.
Available Functions1 — Alınan her mesaj için bir geri çağırma fonksiyonu kaydeder.
void received( void (* callback)(const char *, const char *, double) );
2 — Ek bir int32_t alanı içeren her alınan mesaj için çağrılan bir geri çağırma işlevi kaydeder.
void received( void (* callback)(const char *, const char *, int32_t, double) );
3 — Yalnızca adı “mesaj” ile eşleşen alınan mesajlar için çağrılan bir geri çağırma işlevi kaydeder.
void received( const char *message, void (* callback)(const char *, const char *, double) );
Parameters4 — Yalnızca adı “mesaj” ile eşleşen ve mesaj yükünde ek bir int32_t alanı içeren alınan mesajlar için çağrılan bir geri çağırma işlevi kaydeder.
void received( const char *message, void (* callback)(const char *, const char *, int32_t, double) );
Parametre |
Tip |
Tanım |
|---|---|---|
|
|
Eşleştirilecek mesaj adı (dize). Alınan mesajın adı bu değerle eşleştiğinde, |
|
|
EXP Beyni |
Bu fonksiyon bir değer döndürmez.
Notesreceivedgeri çağırma işlemi dört argümanla çağrılıyor:
callback(message, linkname, index, value)
Argüman |
Tanım |
|---|---|
|
Alınan mesajın adı (örneğin, |
|
Mesajın alındığı bağlantının adı. |
|
Mesajla birlikte gönderilen tamsayı değeri (eğer belirtilmişse). |
|
Mesajla birlikte gönderilen ondalık sayı değeri (eğer belirtilmişse). |
Robot 1 için Kod
// 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 için Kod
// 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..."); }