সিরিয়াল লিঙ্ক#
ভূমিকা#
serial_link ক্লাসটি রোবটগুলোর মধ্যে কাঁচা বাইটের একটি প্রবাহ পাঠানোর সুযোগ দেয়। এটি রোবট-টু-রোবট যোগাযোগের জন্য ডিজাইন করা হয়েছে, যেখানে প্রেরক এবং প্রাপক উভয় রোবটই ডেটা প্রবাহের বিষয়বস্তু বুঝতে পারে।
send এর প্রতিটি ব্যবহার লিঙ্ক করা V5 ব্রেইনের কিউতে ডেটা যোগ করে, এবং কিউটি ফার্স্ট-ইন, ফার্স্ট-আউট (FIFO) পদ্ধতিতে পড়া হয়। যদি অন্য V5 ব্রেইন রিসিভ ব্যবহার করার আগে একাধিক মেসেজ পাঠানো হয়, তবে সেগুলি সংরক্ষণ করা হবে এবং পাঠানোর ক্রমানুসারে এক এক করে ফেরত দেওয়া হবে। যেহেতু মেসেজ কিউতে জমা হতে পারে, তাই প্রতিটি লুপে বারবার একই স্ট্যাটাস পাঠালে ব্যাকলগ তৈরি হতে পারে; সময়-সংবেদনশীল লজিকের জন্য, শুধুমাত্র মান পরিবর্তন হলেই পাঠান।
গুরুত্বপূর্ণ: উভয় রোবটকে অবশ্যই একই সময়ে এমন প্রজেক্ট চালাতে হবে যা serial_link ব্যবহার করে, অন্যথায় কোনো ডেটা পাঠানো বা গ্রহণ করা যাবে না।
ক্লাস কনস্ট্রাক্টর#
serial_link(
int32_t index,
const char *name,
linkType type,
bool isWired = false );
ক্লাস ডেস্ট্রাক্টর#
serial_link অবজেক্টটি ধ্বংস করে এবং সংশ্লিষ্ট রিসোর্সসমূহ মুক্ত করে।
~serial_link();
প্যারামিটার#
প্যারামিটার |
প্রকার |
বর্ণনা |
|---|---|---|
|
|
যে স্মার্ট পোর্টের সাথে মেসেজ লিঙ্কটি সংযুক্ত থাকে, তা |
|
|
এই লিঙ্কের নাম। এই অনন্য স্ট্রিংটি যথেষ্ট দীর্ঘ হওয়ার পরামর্শ দেওয়া হচ্ছে, যাতে ভেক্সোস (vexos) দ্বারা হ্যাশ করা হলে এটি একটি অনন্য আইডি তৈরি করতে পারে। “ভেক্সলিঙ্ক” (vexlink)-এর মতো সাধারণ কোনো নাম লিঙ্কের জন্য খারাপ হবে, কারণ এটি অন্য কোনো দল ব্যবহার করতে পারে। |
|
|
লিঙ্কের ধরণ, হয়
|
|
|
serial_link অবজেক্টটি তারযুক্ত কিনা (ডিফল্ট
|
নোট#
VEXlink তারবিহীন এবং তারযুক্ত উভয় প্রকার যোগাযোগই সমর্থন করে, তবে তারযুক্ত সংযোগের ক্ষেত্রে পাওয়ার রাউটিং সংক্রান্ত সমস্যা এড়ানোর জন্য একটি পরিবর্তিত স্মার্ট ক্যাবল ব্যবহারের পরামর্শ দেওয়া হয়।
বেতার যোগাযোগের জন্য প্রতিটি রোবটের একটি স্মার্ট পোর্টের সাথে সংযুক্ত ভি৫ রোবট রেডিও প্রয়োজন।
VEXlink রেডিওটি একটি V5 কন্ট্রোলারের VEXnet রেডিওর পাশাপাশি ব্যবহার করা যেতে পারে, যা দ্বন্দ্ব এড়ানোর জন্য সর্বোচ্চ নম্বরযুক্ত স্মার্ট পোর্টে সংযুক্ত করা উচিত।
একটি VEXlink তৈরি করতে হলে, উভয় V5 Brain-কেই একটি V5 Robot Radio-র সাথে সংযুক্ত করতে হবে।
উদাহরণ#
রোবট ১-এর জন্য কোড
// Create a wireless link in Port 1 serial_link link = serial_link( PORT1, // index "VEXRoboticsLink123456789", // name linkType::manager, // type true); // isWiredরোবট ২ এর কোড
// Create a wireless link in Port 1 serial_link link = serial_link( PORT1, // index "VEXRoboticsLink123456789", // name linkType::worker, // type true); // isWired
সদস্যদের কার্যাবলী#
serial_link ক্লাসে নিম্নলিখিত সদস্য ফাংশনগুলো অন্তর্ভুক্ত রয়েছে:
isLinked— V5 ব্রেইনগুলি জোড়া বাঁধা আছে এবং এই লিঙ্কে যোগাযোগ করছে কিনা তা পরীক্ষা করে।send— জোড়া মস্তিষ্কে একটি বার্তা পাঠায়।receive— পরবর্তী আগত বার্তার জন্য অপেক্ষা করে এবং তা ফেরত পাঠায়।received— যখনই একটি নতুন বার্তা পাওয়া যাবে তখন কল করার জন্য একটি ফাংশন নিবন্ধন করে।
যেকোনো serial_link মেম্বার ফাংশন কল করার আগে, serial_link ইনস্ট্যান্স অবশ্যই তৈরি করতে হবে, যেমনটি নিচে দেখানো হয়েছে:
রোবট ১-এর জন্য কোড
// Create a wireless link in Port 1 serial_link link = serial_link( PORT1, // index "VEXRoboticsLink123456789", // name linkType::manager, // type true); // isWiredরোবট ২ এর কোড
// 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 ValuesV5 ব্রেইনগুলো সংযুক্ত আছে কিনা তা নির্দেশ করে একটি বুলিয়ান মান প্রদান করে:
true— The two V5 Brains are paired and communicating on this link.false— The two V5 Brains are not paired on this link.
পরবর্তী যেকোনো কোড চালানোর আগে, প্রজেক্ট শুরুর সময়ে V5 ব্রেইনগুলো লিঙ্ক করা আছে কিনা তা সবসময় যাচাই করে নেওয়া একটি ভালো অভ্যাস।
রোবট ১-এর জন্য কোড
// 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));
রোবট ২ এর কোড
// 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 — বাইট বাফার ব্যবহার করে বার্তা পাঠায়।
int32_t send( uint8_t *buffer, int32_t length );
Parameters2 — একটি ক্যারেক্টার বাফার ব্যবহার করে বার্তা পাঠায়।
int32_t send( const char *buffer, int32_t length );
প্যারামিটার |
প্রকার |
বর্ণনা |
|---|---|---|
|
|
অন্য সংযুক্ত V5 ব্রেইনে পাঠানোর জন্য বাফার। |
|
|
প্রেরণ করার জন্য বাফারের দৈর্ঘ্য। |
প্রেরিত বাইটের সংখ্যা বোঝাতে একটি int32_t রিটার্ন করে।
রোবট ১-এর জন্য কোড
// 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); }
রোবট ২ এর কোড
// 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);
প্যারামিটার |
প্রকার |
বর্ণনা |
|---|---|---|
|
|
প্রাপ্ত বার্তা সংরক্ষণের জন্য বাফার। |
|
|
বাফারের দৈর্ঘ্য। |
|
|
কতক্ষণ (মিলিসেকেন্ডে): |
প্রাপ্ত বাইটের সংখ্যা বোঝাতে একটি int32_t রিটার্ন করে।
receiveঅন্য সংযুক্ত V5 ব্রেইন থেকে সারিতে থাকা পরবর্তী বার্তাটি ফেরত দেয়।মেসেজগুলো FIFO ক্রমে পড়া হয় (সবচেয়ে পুরোনো অপঠিত মেসেজটি প্রথমে)।
যখন
receiveকল করা হয় এবং কিউটি খালি থাকে, তখন এটি একটি নতুন বার্তার জন্য নির্দিষ্টtimeoutMsপর্যন্ত অপেক্ষা করে।যদি সেই নির্দিষ্ট সময়ের মধ্যে কোনো বার্তা না আসে, তাহলে
receivereturns0, এবং এর পরে পাঠানো যেকোনো বার্তা পরবর্তীবারreceiveব্যবহৃত হওয়ার জন্য সারিতে থেকে যায়।
রোবট ১-এর জন্য কোড
// 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); }
রোবট ২ এর কোড
// 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 — প্রতিটি প্রাপ্ত বাইট বাফারের জন্য একটি কলব্যাক ফাংশন নিবন্ধন করে।
void received( void (* callback)(uint8_t *, int32_t) );
প্যারামিটার |
প্রকার |
বর্ণনা |
|---|---|---|
|
|
পূর্বে সংজ্ঞায়িত একটি ফাংশন যা V5 ব্রেইন ডেটা গ্রহণ করলে চলে। |
এই ফাংশনটি কোনো মান ফেরত দেয় না।
Notesreceivedকলব্যাক দুটি আর্গুমেন্ট সহ কল করা হয়: একটি বাইট বাফার এবং প্রাপ্ত বাইটের সংখ্যা।প্রাপ্ত ডেটা নাল-টার্মিনেটেড নাও হতে পারে। যদি কলব্যাক ডেটাটিকে একটি স্ট্রিং হিসাবে বিবেচনা করে, তবে প্রাপ্ত বাইটগুলিকে একটি ক্যারেক্টার অ্যারেতে কপি করুন এবং একটি নাল টার্মিনেটর যোগ করুন।
callback(buffer, length)
যুক্তি |
বর্ণনা |
|---|---|
|
প্রাপ্ত বাইট বাফারের একটি পয়েন্টার। |
|
প্রাপ্ত বাইটের সংখ্যা। |
রোবট ১-এর জন্য কোড
// 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); } }
রোবট ২ এর কোড
// 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); } }