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ı V5 Beyninin kuyruğuna veri ekler ve kuyruk ilk giren ilk çıkar (FIFO) prensibiyle okunur. Diğer V5 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, çakışmaları önlemek için en yüksek numaralı Akıllı Bağlantı Noktasına bağlanması gereken bir V5 Kontrol Cihazının VEXnet radyosuyla birlikte kullanılabilir.
VEXlink oluşturmak için her iki V5 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— V5 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 V5 Brain’lerin birbiriyle eşleştirilip eşleştirilmediğini döndürür.
Available Functionsbool isLinked();
Bu fonksiyonun herhangi bir parametresi yoktur.
Return ValuesV5 Beyinlerinin birbirine bağlı olup olmadığını gösteren bir Boolean değeri döndürür:
true— The two V5 Brains are paired and communicating on this link.false— The two V5 Brains are not paired on this link.
Herhangi bir kod çalıştırmadan önce, projenin başlangıcında V5 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ı V5 Beynine gönderilecek tampon bellek. |
|
|
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 V5 Brain’den kuyruğa alınmış 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#
V5 Brain veri aldığında çağrılacak bir fonksiyonu kaydeder.
Available FunctionsParameters1 — Alınan her bayt arabelleği için bir geri çağırma fonksiyonu kaydeder.
void received( void (* callback)(uint8_t *, int32_t) );
Parametre |
Tip |
Tanım |
|---|---|---|
|
|
V5 Beyni veri aldığında çalışan, önceden tanımlanmış bir fonksiyon. |
Bu fonksiyon bir değer döndürmez.
Notesreceivedgeri çağırma işlevi iki argümanla çağrılır: bir bayt arabelleği ve alınan bayt sayısı.Alınan veriler null karakterle sonlandırılmamış olabilir. Geri çağrı fonksiyonu verileri bir dize olarak ele alıyorsa, alınan baytları bir karakter dizisine kopyalayın ve bir null sonlandırıcı ekleyin.
callback(buffer, length)
Argüman |
Tanım |
|---|---|
|
Alınan bayt arabelleğine işaret eden bir gösterici. |
|
Alınan bayt sayısı. |
Robot 1 için Kod
// 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); } }
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..."); while (true) { wait(10, msec); } }