সিরিয়াল লিঙ্ক#
ভূমিকা#
serial_link ক্লাসটি রোবটগুলোর মধ্যে কাঁচা বাইটের একটি প্রবাহ পাঠানোর সুযোগ দেয়। এটি রোবট-টু-রোবট যোগাযোগের জন্য ডিজাইন করা হয়েছে, যেখানে প্রেরক এবং প্রাপক উভয় রোবটই ডেটা প্রবাহের বিষয়বস্তু বুঝতে পারে।
send এর প্রতিটি ব্যবহার লিঙ্ক করা EXP Brain-এর কিউতে ডেটা যোগ করে, এবং কিউটি ফার্স্ট-ইন, ফার্স্ট-আউট (FIFO) পদ্ধতিতে পড়া হয়। যদি অন্য EXP Brain রিসিভ ব্যবহার করার আগে একাধিক মেসেজ পাঠানো হয়, তাহলে সেগুলি জমা হবে এবং পাঠানোর ক্রমানুসারে এক এক করে ফেরত দেওয়া হবে। যেহেতু মেসেজ কিউতে জমা হতে পারে, তাই প্রতিটি লুপে বারবার একই স্ট্যাটাস পাঠালে ব্যাকলগ তৈরি হতে পারে; সময়-সংবেদনশীল লজিকের জন্য, শুধুমাত্র মান পরিবর্তন হলেই পাঠান।
গুরুত্বপূর্ণ: উভয় রোবটকে অবশ্যই একই সময়ে এমন প্রজেক্ট চালাতে হবে যা 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 রেডিওটি একটি EXP কন্ট্রোলারের VEXnet রেডিওর পাশাপাশি ব্যবহার করা যেতে পারে, যা দ্বন্দ্ব এড়ানোর জন্য সর্বোচ্চ নম্বরযুক্ত স্মার্ট পোর্টে সংযুক্ত করা উচিত।
একটি VEXlink তৈরি করতে হলে, উভয় EXP 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— EXP ব্রেইনগুলো জোড়া বেঁধেছে এবং এই লিঙ্কে যোগাযোগ করছে কিনা তা পরীক্ষা করে।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#
একটি সিরিয়াল লিঙ্কে থাকা EXP ব্রেইনগুলো একে অপরের সাথে জোড়বদ্ধ কিনা তা ফেরত দেয়।
Available Functionsbool isLinked();
এই ফাংশনটির কোনো প্যারামিটার নেই।
Return ValuesEXP ব্রেইনগুলো সংযুক্ত কিনা তা নির্দেশ করে একটি বুলিয়ান মান প্রদান করে:
true— The two EXP Brains are paired and communicating on this link.false— The two EXP Brains are not paired on this link.
পরবর্তী যেকোনো কোড চালানোর আগে, প্রজেক্ট শুরুর সময়ে EXP Brain-গুলো লিঙ্ক করা আছে কিনা তা সবসময় যাচাই করে নেওয়া একটি ভালো অভ্যাস।
রোবট ১-এর জন্য কোড
// 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 );
প্যারামিটার |
প্রকার |
বর্ণনা |
|---|---|---|
|
|
অন্য সংযুক্ত EXP ব্রেইনে পাঠানোর জন্য বাফার। |
|
|
প্রেরণ করার জন্য বাফারের দৈর্ঘ্য। |
প্রেরিত বাইটের সংখ্যা বোঝাতে একটি 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অন্য লিঙ্ক করা EXP Brain থেকে পরবর্তী সারিতে থাকা বার্তাটি ফেরত দেয়।মেসেজগুলো 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#
যখনই EXP Brain কোনো প্রেরিত বার্তা গ্রহণ করে, তখন কল করার জন্য একটি ফাংশন নিবন্ধন করে।
Available Functions1 — প্রতিটি প্রাপ্ত বার্তার জন্য একটি কলব্যাক ফাংশন নিবন্ধন করে।
void received( void (* callback)(const char *, const char *, double) );
2 — একটি কলব্যাক রেজিস্টার করে যা অতিরিক্ত int32_t ফিল্ড অন্তর্ভুক্ত থাকা প্রতিটি প্রাপ্ত বার্তার জন্য আহ্বান করা হয়।
void received( void (* callback)(const char *, const char *, int32_t, double) );
3 — একটি কলব্যাক রেজিস্টার করে যা শুধুমাত্র সেইসব প্রাপ্ত মেসেজের জন্য চালু হয়, যাদের নাম মেসেজটির নামের সাথে মিলে যায়।
void received( const char *message, void (* callback)(const char *, const char *, double) );
Parameters4 — একটি কলব্যাক রেজিস্টার করে যা শুধুমাত্র সেইসব প্রাপ্ত মেসেজের জন্য আহ্বান করা হয়, যাদের নাম ‘message’-এর সাথে মেলে এবং যেখানে মেসেজ পেলোডে একটি অতিরিক্ত int32_t ফিল্ড অন্তর্ভুক্ত থাকে।
void received( const char *message, void (* callback)(const char *, const char *, int32_t, double) );
প্যারামিটার |
প্রকার |
বর্ণনা |
|---|---|---|
|
|
যে বার্তার নামটি (স্ট্রিং) মেলাতে হবে। যখন প্রাপ্ত কোনো বার্তার নাম এই মানের সাথে মিলে যায়, তখন |
|
|
পূর্বে সংজ্ঞায়িত একটি ফাংশন যা EXP Brain যখন |
এই ফাংশনটি কোনো মান ফেরত দেয় না।
Notesreceivedকলব্যাক চারটি আর্গুমেন্ট সহ কল করা হয়েছে:
callback(message, linkname, index, value)
যুক্তি |
বর্ণনা |
|---|---|
|
প্রাপ্ত বার্তার নাম (উদাহরণস্বরূপ, |
|
যে লিঙ্কের নাম থেকে বার্তাটি পাওয়া গেছে। |
|
বার্তার সাথে পাঠানো পূর্ণসংখ্যা মান (যদি প্রদান করা হয়)। |
|
বার্তার সাথে পাঠানো ফ্লোট মান (যদি প্রদান করা হয়)। |
রোবট ১-এর জন্য কোড
// 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); }
রোবট ২ এর কোড
// 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..."); }