آموزش ساخت و برنامه نویسی ربات با استفاده از آردینو ، رزبری پای ، ای وی آر و آرم

ساخت ربات عنکبوتی

طراحی و کنترل ربات عنکبوتی چهارپا با ESP32

طبیعت همیشه منبع باورنکردنی الهام برای پیشرفت‌های تکنولوژی بوده و مهندسان به دنبال تکرار مکانیسم‌های پیچیده موجود در حیوانات مختلف بوده‌اند.

یکی از این خلاقیت های قابل توجه ربات عنکبوتی است. این ربات به دلیل داشتن چهار پا می تواند به عنوان یک ربات چهارپا نیز شناخته شود. هدف این پروژه رباتیک نوآورانه شبیه سازی حرکت و رفتار عنکبوت ها است.

ربات عنکبوتی یک ربات راه رونده ی چهار پا است که از عنکبوت الهام گرفته شده است که از پاهای خود برای حرکت استفاده می کند. پاها به گونه ای چیده شده اند که به آنها امکان می دهد به روش های مختلف از جمله راه رفتن، دویدن و بالا رفتن حرکت کنند. یکی از اجزای جدایی ناپذیر این پروژه، ادغام میکروکنترلر ESP32 است که کنترل بی سیم و هماهنگی حرکتی پیشرفته را امکان پذیر می کند. ESP32 به عنوان یک پلت فرم ایده آل برای ربات عنکبوتی عمل می کند و چابکی، تطبیق پذیری و ظرفیت آن را برای پیمایش موثر در زمین های پیچیده افزایش می دهد. ربات‌های عنکبوتی با چابکی، تطبیق پذیری و توانایی فوق‌العاده خود برای عبور از زمین‌های پیچیده، پتانسیل بسیار زیادی در زمینه‌های مختلف، از جمله مأموریت‌های جستجو و نجات، اکتشاف، و حتی کمک‌های خانگی دارند.

مکانیزم کارکرد ربات عنکبوتی

مکانیسم یک ربات عنکبوتی شامل چندین مؤلفه و اصول کلیدی است که حرکت و عملکرد آن را امکان پذیر می کند.

ربات‌های عنکبوتی متعلق به دسته روبات‌های پادار هستند که معمولاً پیچیده‌تر از روبات‌های چرخدار هستند. ربات های پادار در عبور از زمین های چالش برانگیز در مقایسه با ربات های چرخ دار برتر هستند. در حالی که ربات های چرخ دار معمولاً دارای موتورهای DC هستند در حالی که ربات های پادار معمولاً دارای موتورهای سروو هستند.

یکی از تمایزات اساسی بین ربات های چرخدار و پادار در درجات آزادی آنها (DOF) نهفته است. ربات های چرخ دار فقط یک درجه آزادی دارند در حالی که ربات های پادار دارای حرکت پیچیده تری هستند.

درجات آزادی (DOF) یک جسم با تعداد پارامترهایی که برای تعیین موقعیت همان جسم لازم است تعریف می شود. در مورد ربات عنکبوتی ما ۲ موتور سروو در هر یک از پاهای خود دارد تا ۲ جهت مختلف حرکت را نشان دهد. این بدان معنی است که درجه آزادی (DOF) برای یک پا ۲ است. بنابراین مجموع درجات آزادی (DOF) ربات عنکبوتی ۸ است.

این پروژه ممکن است از نظر سیم کشی و مونتاژ خیلی پیچیده نباشد، اما درک سینماتیک پشت حرکت ربات عنکبوتی چهارپا بسیار پیچیده است. برای دستیابی به حرکت کنترل شده، ربات باید تعداد متفاوتی از حالت ها را انجام دهد که در مجموع یک حرکت واحد ایجاد می کنند. این کار را می توان با اجرای راه رفتن کرال (الگوی حرکت) انجام داد که در آن یک پا در هوا و سه پای باقی مانده باید در هنگام حرکت با زمین در تماس باشند. به طور معمول، برای برداشتن یک قدم به جلو، ربات ۶ حالت متمایز را پشت سر می گذارد.

راه رفتن چهارپا برای حرکت به جلو

راه رفتن به الگوی خاصی از حرکت پا اشاره دارد که برای حرکت بدن به سمت مقصد مورد نظر لازم است. در مورد ربات های چهارپا، راه رفتن شامل بلند کردن یک پا در یک زمان است در حالی که سه پایه باقی مانده یک سه پایه حمایتی را تشکیل می دهند. این حرکت هماهنگ ثبات و حرکت کارآمد را تضمین می کند.

برای دستیابی به راه رفتن چهارپا، نکته کلیدی این است که تعیین کنید هر پا چه زمانی و در چه موقعیتی حرکت کند. این فرآیند به عنوان سینماتیک معکوس شناخته می شود. سینماتیک معکوس ما را قادر می سازد تا مقادیر لازم را برای سروو موتورهای کنترل کننده پاها محاسبه کنیم و به موقعیت دقیق پاها اجازه می دهد تا به الگوی راه رفتن مورد نظر دست یابیم.

سینماتیک معکوس نقش مهمی در اجرای صاف راه رفتن چهارپا دارد. با ارائه دستورالعمل های لازم به سروو موتورها، می توان پاهای ربات را به طور دقیق به موقعیت های مورد نظر حرکت داد. این به حفظ تعادل و دستیابی به حرکت موثر کمک می کند

نمودار بالا راه رفتن چهارپا رو به جلو را نشان می دهد و دنباله ای از حرکات پا را نشان می دهد که برای حرکت موثر روبات به جلو لازم است. خط نقطه نشان می دهد که پا بلند شده است.

برای اطمینان از پایداری ربات، بسیار مهم است که مرکز جرم (COM) در چند ضلعی پشتیبانی باقی بماند. چند ضلعی پشتیبانی به یک چند ضلعی خیالی اشاره دارد که در صورت قرار گرفتن COM در داخل آن، ربات می تواند تعادل خود را حفظ کند. با این حال، اگر COM به خارج از چند ضلعی پشتیبانی جابجا شود، ربات ناپایدار می شود و ممکن است واژگون شود. این مفهوم در شکل زیر نشان داده شده است، جایی که ربات تا زمانی که COM در داخل چند ضلعی پشتیبانی قرار دارد متعادل باقی می ماند. این به عنوان یک اصل مهم برای حفظ ثبات و جلوگیری از سقوط در عملکرد ربات عمل می کند.

اجزای مورد نیاز برای ربات عنکبوتی

میکروکنترلر ESP32

سروو موتور دنده پلاستیکی SG90 – هشت عدد

عدد مبدل DC-DC Buck LM2596

باتری ۱۲ ولت لیتیوم یونی

سوییچ

سیم های جامپر

برد بورد یا PCB (برد مدار چاپی)

پیچ، مهره، اسپیسر

فایل های برش لیزری ربات عنکبوتی

ما قطعات اکریلیک Quadruped Spider Robot را با استفاده از SolidWorks طراحی کرده ایم. فایل های .dxf را می توانید در اینجا دانلود کنید. اگر می خواهید تغییری ایجاد کنید، می توانید فایل .svg را نیز پیدا کنید. این قطعات همچنین به راحتی در بسیاری از وب سایت های تجارت الکترونیک در دسترس هستند.

مونتاژ ربات عنکبوتی

تنظیم موقعیت سروو موتورها

قبل از شروع مونتاژ، باید تنظیم زاویه سروو موتورها را تنظیم کنیم. در غیر این صورت ربات شما به درستی کار نخواهد کرد.

برای شروع، بازوی سروو را با تراز کردن و محکم کردن آن در جای خود به سروو متصل کنید. ما می توانیم به صورت دستی زاویه موتور سروو را کالیبره و تنظیم کنیم، اما مدتی کالیبراسیون دستی دقیق نیست یا ممکن است امکان پذیر نباشد. بنابراین می توانید سروو موتورهای خود را با استفاده از کد شماره ۱ کالیبره کنید. به نمودار مدار ذکر شده در زیر مراجعه کنید و سروو موتورهای خود را بر این اساس به پایه های ۲۱، ۱۹، ۳۳، ۲۵، ۲۷، ۱۴، ۱۲ و ۱۳ متصل کنید. کد شماره ۱ ارائه شده را در ESP32 خود آپلود کنید، که فرآیند کالیبراسیون را تسهیل می کند. عدم اجرای این مرحله ممکن است منجر به عملکرد ناپایدار ربات شما شود.

با اطمینان از تراز و کالیبراسیون مناسب سرووها، پایه و اساس یک ربات پایدار و با عملکرد خوب را ایجاد می کنید. پس از انجام تنظیمات سروو، می توانید به مراحل مونتاژ پاهای ربات بروید.

مونتاژ پاهای ربات

مرحله ۱: یک بازوی سروو را بردارید و آن را روی صفحه پایه پایه قرار دهید. پیچ نصب سروو را از سمت عقب صفحه محوری پا به بالا وارد بازوی تکی سروو کنید. پیچ را سفت کنید تا بازوی تک سروو به طور ایمن به صفحه محوری متصل شود.

مرحله ۲: اکنون یک بازوی سروو دیگر را به بازوی سروو ایستاده وصل کنید. برای انجام این کار، یک پیچ نصب سروو را از پشت بازوی سروو پا وارد کنید و آن را به بازوی تک سروو محکم کنید. اطمینان حاصل کنید که اتصال محکم و پایدار است.

مرحله ۳: حرکت به سمت جلو، اتصال موازی پا را با استفاده از یک پیچ M3x10mm و یک مهره فیبر M3 به قطعه ساق وصل کنید. سفتی پیچ را دوبار بررسی کنید تا مطمئن شوید که اتصال محکم به قطعه ساق متصل شده است.

مرحله ۴: سپس با استفاده از یک پیچ M3x10mm و یک مهره فیبر M3، قطعه ساق را به بازوی سروو پا متصل کنید.

مرحله ۵: سروو دیگری را در نگهدارنده سرو قرار دهید.

مرحله ۶: انتهای بالایی سرو دوم را در شیار سروو پایه قرار دهید.

مرحله ۷: نگهدارنده سروو را با استفاده از دو پیچ M3x12mm و دو مهره فیبر M3 به سوکت سروو پا ببندید.

مرحله ۸: اکنون یک صفحه موازی پایه را با استفاده از یک پیچ M3x10mm و یک مهره فیبر M3 به انتهای دیگر ساق وصل کنید.

مرحله ۹: با هر دو سروو در موقعیت مرکزی و مفصل موازی پا به صورت افقی، بازوی سروو پا را با استفاده از پیچ بازوی سروو ارائه شده به سروو اول وصل کنید.

مرحله ۱۰: در نهایت مونتاژ پا را که در مراحل قبل تکمیل شد، با استفاده از دو پیچ M3x10mm و دو مهره M3 به Pivot Plate Leg Bottom متصل کنید. مرحله مونتاژ پا ممکن است چالش برانگیز باشد، اما پس از تکمیل این مراحل، فرآیند باقی مانده قابل مدیریت تر می شود. اگر این مراحل را با موفقیت به پایان رسانده اید، به قسمت Body Assembly (مونتاژ بدنه ) می رویم.

مونتاژ بدنه ربات

در این مرحله باید مراقب اعداد باشید. شماتیک ها با توجه به شماره قطعات توضیح داده شده است، به طوری که شما باید لیست هایی را که ایجاد کردیم، قبل از اسمبلی مطالعه کنید.

قسمت های شماتیک مونتاژ ۱و ۲ :

۱- صفحه بالایی بدنه

۲- پیچ M3x10mm

۳- سرو موتور

۴ – M3 مهره

M3 -5 – مهره فیبر

M3*12MM 7 – پیچ

۸ – اسپیسر

۱۰ – نگهدارنده سرو

مرحله ۱: مونتاژ را با اتصال چهار فاصله دهنده بدنه به صفحه پایین بدنه شروع کنید. از چهار پیچ M3x10mm و چهار مهره مسطح M3 برای محکم کردن اسپیسرها در جای خود استفاده کنید.

مرحله ۲: چهار سروو را بردارید و آنها را روی صفحه بالایی شاسی قرار دهید و مطمئن شوید که به درستی تراز شده اند.

مرحله ۳: برای هر سروو، یک نگهدارنده سرو در بالا وصل کنید. نگهدارنده را به درستی تراز کنید و آن را در جای خود محکم کنید.

مرحله ۴: هر نگهدارنده سروو را با استفاده از پیچ های M3x12mm و مهره های فیبر M3 به صفحه بالایی شاسی ببندید. اطمینان حاصل کنید که آنها به طور ایمن سفت شده اند

مرحله ۵: اکنون، هر تکه پا را به صفحه پایین بدنه وصل کنید. برای هر قطعه پایه از یک پیچ M3x10mm و یک مهره فیبر M3 استفاده کنید. مراقب باشید پیچ ​​ها را بیش از حد سفت نکنید، زیرا ممکن است منجر به خرابی سروو شود.

مرحله ۶: صفحه پایینی بدنه و صفحه بالایی بدنه را کنار هم قرار دهید. برای اتصال محکم این دو جزء از چهار پیچ M3x10mm و مهره M3 استفاده کنید.

مرحله ۷: در حالی که سرووها و قطعات پا در جای خود قرار دارند، همانطور که در دستورالعمل نشان داده شده است، هر پا را با دقت به زاویه ۴۵ درجه بچرخانید. صفحه محوری بالای پایه را نصب کنید و با استفاده از دو پیچ M3x10mm و دو مهره M3 برای هر پایه، آن را روی هر سروو و پایه محکم کنید.

مرحله ۸: در نهایت با استفاده از پیچ سروو، تک بازوی سروو را به سرووی مربوطه خود محکم کنید و مطمئن شوید که محکم وصل شده است.

بعد از مونتاژ به صورت زیر در می آید:

نمودار مدار ESP32 برای ربات عنکبوتی چهارپا (۸ موتور سروو)

این نمودار مدار ادغام ۱۲ سروو موتور را نشان می دهد که حرکت را در تمام جهات برای ربات امکان پذیر می کند.

این ربات از چهار پایه تشکیل شده است که هر پایه آن به دو موتور سروو متصل است. یک سروو وظیفه چرخش محور (معروف به سروو محوری) را بر عهده دارد، در حالی که سروو دیگر حرکت بلند کردن پا را کنترل می کند (معروف به سروو بالابر). برای دستیابی به حرکت هماهنگ، سروو موتورها به ترتیب یا ترتیب خاصی به هم متصل می شوند. ترتیب دقیق و اتصالات به الگوی راه رفتن مورد نظر و الگوریتم کنترل خاصی که به کار گرفته می شود بستگی دارد. با کنترل حرکت این سروو موتورها به صورت هماهنگ، ربات می تواند به حرکت پایدار و هماهنگ دست یابد.

ESP32 و سروو موتورها:

برای کنترل سرووها، پین های با قابلیت PWM (مدولاسیون عرض پالس) را روی ESP32 اختصاص دهید. این پین ها سیگنال های PWM لازم را برای تنظیم موقعیت هر سروو موتور تولید می کنند. سیم سیگنال (معمولاً به رنگ زرد یا سفید) از هر سروو موتور به یک پین جداگانه با قابلیت PWM در ESP32 وصل کنید.

ESP32 و منبع تغذیه:

ترمینال مثبت منبع تغذیه را به پین ​​های VCC هر سروو موتور وصل کنید.

ترمینال زمین منبع تغذیه را به پایه های زمین (GND) همه سروو موتورها وصل کنید.

پایه زمین (GND) ESP32 را به ترمینال زمین (-) منبع تغذیه خود وصل کنید.

پین Vin ESP32 را با کمک سوئیچ به ترمینال مثبت (+) منبع تغذیه خود وصل کنید.

هنگام کار با چندین سروو موتور در یک ربات عنکبوتی، توان مورد نیاز بیشتر از آن چیزی است که میکروکنترلر ESP32 نمی تواند ارائه دهد. بنابراین، یک ورودی برق خارجی ضروری است. با این حال، بسیار مهم است که اطمینان حاصل شود که ولتاژ ورودی از ۵ ولت تجاوز نمی کند تا از آسیب به میکروکنترلر ESP32 جلوگیری شود.

در صورت استفاده از باتری با ولتاژ بالاتر، از مدار کاهنده ولتاژ (مبدل DC – DC) استفاده کنید تا آن را به ۵ ولت کاهش دهید. خروجی مدار کاهنده ولتاژ را به هر دو موتور ESP32 و سروو وصل کنید. این منبع تغذیه ایمن و کارآمد را تضمین می کند.

لطفاً توجه داشته باشید که اتصالات پین خاص و کد برنامه‌نویسی ممکن است بسته به مدل دقیق برد ESP32 که استفاده می‌کنید و سروو موتورهایی که دارید متفاوت باشد. برای تخصیص دقیق پین ها و الزامات ولتاژ، مهم است که به دیتاشیت ها و نمودارهای پین اوت قطعات خود مراجعه کنید. علاوه بر این، مطمئن شوید که منبع تغذیه و اتصالات را با رعایت بهترین روش‌ها برای جلوگیری از آسیب‌دیدگی به قطعات، ایمن انجام می‌دهید.

توضیح کدهای ربات عنکبوتی چهارپا ESP32

ربات عنکبوتی که در این پروژه توضیح داده شده است از طریق کنترل از راه دور عمل نمی کند. در عوض، از عملکردهای مختلفی برای اعمال مختلف مانند حرکات رو به جلو، عقب، راست و چپ استفاده می کند. این توابع مبتنی بر راه رفتن خزیدن (همچنین به عنوان راه رفتن چهارپا) هستند. الگوی راه رفتن خزیدن به یک برنامه تبدیل شده و در میکروکنترلر ESP32 تعبیه شده است. این برنامه دستورالعمل هایی را به سروو موتورها ارائه می دهد و آنها را هدایت می کند تا پاهای ربات را در موقعیت های مورد نظر برای حرکات مورد نظر حرکت دهند. با اجرای راه رفتن خزیدن برنامه ریزی شده، ربات عنکبوتی می تواند به حرکت هماهنگ و کنترل شده دست یابد.

اجرای این کد #۱ قبل از شروع مراحل اسمبلی بسیار مهم است. این کد برای کالیبره کردن و تنظیم سروو موتورها در زوایای صحیح آنها طراحی شده است. با اجرای این کد می توانید اطمینان حاصل کنید که سروو موتورها به درستی کار می کنند و به درستی در محل قرار می گیرند. این به جلوگیری از هرگونه مشکل یا عوارض احتمالی در مراحل بعدی فرآیند مونتاژ کمک می کند.

توجه: لطفاً اطمینان حاصل کنید که همیشه قبل از آپلود کد در ESP32 سوئیچ را خاموش کرده و منبع تغذیه خارجی را قطع کنید. این مرحله بسیار مهم است زیرا سوئیچ جداسازی الکتریکی بین پین Vin ESP32 و پین Vcc سروو را فراهم می کند. این اقدام احتیاطی ایمنی و عملکرد صحیح اجزا را در طول فرآیند آپلود کد تضمین می کند. به یاد داشته باشید که هر بار که کد را برای ربات عنکبوتی در ESP32 آپلود می کنید، این روش را دنبال کنید، و جداسازی الکتریکی بین ESP32 و سرووها را حفظ کنید تا از هرگونه عارضه یا آسیب ناخواسته جلوگیری کنید.

کد #۱

#include <ESP32_Servo.h>    // include servo library
// Define 8 Servos
Servo myServo1; // Front Left Pivot Servo
Servo myServo2; // Front Left Lift Servo
Servo myServo3; // Back Left Pivot Servo
Servo myServo4; // Back Left Lift Servo
Servo myServo5; // Back Right Pivot Servo
Servo myServo6; // Back Right Lift Servo
Servo myServo7; // Front Right Pivot Servo
Servo myServo8; // Front Right Lift Servo
void setup() {
  // Attach servos to Arduino Pins
  myServo1.attach(21);
  myServo2.attach(19);
  myServo3.attach(33);
  myServo4.attach(25);
  myServo5.attach(27);
  myServo6.attach(14);
  myServo7.attach(12);
  myServo8.attach(13);
  myServo1.write(90);
  myServo2.write(90);
  myServo3.write(90);
  myServo4.write(90);
  myServo5.write(90);
  myServo6.write(90);
  myServo7.write(90);
  myServo8.write(90);
}
void loop() {
}

این کد شماره ۲ شامل تمام حرکات موتور سروو لازم برای عملکرد ربات شما می باشد. بدون این کد، نمی توانید پروژه را با موفقیت به پایان برسانید. برای عملکرد صحیح ربات بسیار مهم است. علاوه بر این، کد به خوبی توضیح داده شده است و توضیحاتی را برای هر بلوک کد ارائه می دهد. این نظرات به عنوان یک راهنما عمل می کنند و به شما امکان می دهند به راحتی تشخیص دهید کدام بلوک با حرکات یا عملکردهای خاص مطابقت دارد. در صورت نیاز به انجام هر گونه اصلاح یا تنظیم، نظرات به شما در درک هدف و عملکرد هر بلوک کد کمک می کند.

کد #۲ :

#include <ESP32_Servo.h>    // include servo library
This line includes the ESP32_Servo library, which provides functions for controlling servo motors using the ESP32 microcontroller.
// Define the delay between function calls (in milliseconds)
const unsigned long FUNCTION_DELAY = 2000; // 2 seconds

این خط یک ثابت جهانی به نام FUNCTION_DELAY را اعلام می کند که نشان دهنده تاخیر در میلی ثانیه بین هر فراخوانی تابع است.

// Define 8 Servos
Servo myServo1; // Front Left Pivot Servo
Servo myServo2; // Front Left Lift Servo
Servo myServo3; // Back Left Pivot Servo
Servo myServo4; // Back Left Lift Servo
Servo myServo5; // Back Right Pivot Servo
Servo myServo6; // Back Right Lift Servo
Servo myServo7; // Front Right Pivot Servo
Servo myServo8; // Front Right Lift Servo

این بلوک هشت شیء سروو را «myServo1» به «myServo8» اعلام می‌کند. هر جسم نشان دهنده یک موتور سروو است و با یک عملکرد خاص (به عنوان مثال، محور یا بالابر) و یک پای خاص از ربات عنکبوتی مرتبط است.

void setup() {
  // Attach servos to Arduino Pins
  myServo1.attach(21);
  myServo2.attach(19);
  myServo3.attach(33);
  myServo4.attach(25);
  myServo5.attach(27);
  myServo6.attach(14);
  myServo7.attach(12);
  myServo8.attach(13);
  center_servos();
  Serial.println("center");
  delay(2000);
}

هنگام راه اندازی میکروکنترلر، عملکرد راه اندازی یک بار اجرا می شود. هر شی Servo را با استفاده از متد attach() به پین ​​آردوینو مربوطه متصل می کند. تابع center_servos() فراخوانی می شود تا تمام سروو موتورها را در موقعیت مرکزی خود قرار دهد و برای پایداری یک تاخیر ۲ ثانیه ای اضافه می شود.

void loop() {
   // Move Forward 10 step
  for (int i = 0; i < 10; i++) {
    moveLegServos_Forward();
  }
  center_servos();
  delay(FUNCTION_DELAY);
    // Move Backward 10 step
  for (int i = 0; i < 10; i++) {
    moveLegServos_Backward();
  }
  center_servos();
  delay(FUNCTION_DELAY);
    // Move Right 10 step
  for (int i = 0; i < 10; i++) {
    moveLegServos_Right();
  }
  center_servos();
  delay(FUNCTION_DELAY);
    // Move Left 10 step
  for (int i = 0; i < 10; i++) {
    moveLegServos_Left();
  }
  center_servos();
  delay(FUNCTION_DELAY);
   //  dance 10 step
  for (int i = 0; i < 10; i++) {
    dance();
  }
  center_servos();
  delay(FUNCTION_DELAY);
   // pushup 10 step
  for (int i = 0; i < 10; i++) {
    pushup();
  }
  center_servos();
  delay(FUNCTION_DELAY);
}

این بلوک حاوی تابع “loop()” است که به طور مکرر پس از تابع “setup()” اجرا می شود. این شامل چندین حلقه “for” است که هر کدام تعداد مراحل را برای یک حرکت خاص کنترل می کند. در هر تکرار، یک تابع حرکتی مربوطه نامیده می‌شود (“moveLegServos_Forward()”، “moveLegServos_Backward()”، “moveLegServos_Right()”، “moveLegServos_Left()”، “pushup()”، “dance()”). پس از هر حرکت، تابع “center_servos()” فراخوانی می شود تا همه موتورهای سروو را به موقعیت مرکزی خود بازنشانی کند. تاخیر “FUNCTION_DELAY” میلی ثانیه بین هر حرکت معرفی می شود.

    // Move Spider Robot Forward Function
void moveLegServos_Forward() {
  // Control the servo actions for each leg
  // Left side leg - Leg 1
  moveLeg_Left_Forward(myServo8, myServo7, myServo8);
  // Left side leg - Leg 4
  moveLeg_Left_Forward(myServo2, myServo1, myServo2);
  // Left side leg - Legs 1 and 4
  for (int angle = 0; angle <= 90; angle += 2) {
    myServo7.write(angle);
    myServo1.write(angle);
    delay(10);
  }
  // Right side leg - Leg 2
  moveLeg_Right_Forward(myServo6, myServo5, myServo6);
  // Right side leg - Leg 3
  moveLeg_Right_Forward(myServo4, myServo3, myServo4);
  // Right side leg - Legs 2 and 3
  for (int angle = 180; angle >= 90; angle -= 2) {
    myServo5.write(angle);
    myServo3.write(angle);
    delay(10);
  }
}  

این بلوک تابع “moveLegServos_Forward()” را تعریف می کند، که اقدامات سروو را برای حرکت روبات عنکبوتی به جلو کنترل می کند. توابع “moveLeg_Left_Forward()” و “moveLeg_Right_Forward()” را برای کنترل حرکت هر پا فراخوانی می کند. عملکرد به تدریج زوایای سروو را تنظیم می کند تا به موقعیت های مطلوب پا برای حرکت رو به جلو دست یابد.

 // Move Spider Robot Backward Function
void moveLegServos_Backward() {
   // Control the servo actions for each leg
  // Left side leg - Leg 1
  moveLeg_Left_Backward(myServo2, myServo1, myServo2);
  // Left side leg - Leg 4
  moveLeg_Left_Backward(myServo8, myServo7, myServo8);
  // Left side leg - Legs 1 and 4
  for (int angle = 180; angle >= 90; angle -= 2) {
    myServo1.write(angle);
    myServo7.write(angle);
    delay(10);
  }
  // Right side leg - Leg 2
  moveLeg_Right_Backward(myServo4, myServo3, myServo4);
  // Right side leg - Leg 3
  moveLeg_Right_Backward(myServo6, myServo5, myServo6);
  // Right side leg - Legs 2 and 3
  for (int angle = 0; angle <= 90; angle += 2) {
    myServo3.write(angle);
    myServo5.write(angle);
    delay(10);
  }
}

این بلوک تابع “moveLegServos_Backward()” را تعریف می کند، که عملکردهای سروو را برای حرکت روبات عنکبوتی به جلو کنترل می کند. توابع “moveLeg_Left_Backward()” و “moveLeg_Right_Backward()” را برای کنترل حرکت هر پا فراخوانی می کند. عملکرد به تدریج زوایای سروو را تنظیم می کند تا به موقعیت های مطلوب پا برای حرکت به عقب دست یابد.

 // Move Spider Robot Right Function
 void moveLegServos_Right() {
  // Control the Right turn servo actions for each leg
  moveLeg_Right(myServo8, myServo7, myServo1); // Leg 4
  moveLeg_Right(myServo6, myServo5, myServo7); // Leg 3
  moveLeg_Right(myServo4, myServo3, myServo5); // Leg 2
  moveLeg_Right(myServo2, myServo1, myServo3); // Leg 1
}
       // Move Spider Robot Left Function  
void moveLegServos_Left() {
  // Control the Left turn servo actions for each leg
  moveLeg_Left(myServo8, myServo7, myServo1); // Leg 4
  moveLeg_Left(myServo6, myServo5, myServo7); // Leg 3
  moveLeg_Left(myServo4, myServo3, myServo5); // Leg 2
  moveLeg_Left(myServo2, myServo1, myServo3); // Leg 1
}

در این بلوک کد، توابع «moveLegServos_Right()» و «moveLegServos_Left()» به ترتیب عملکردهای سروو را برای حرکت روبات عنکبوتی به راست و چپ کنترل می کنند. این عملکردها حرکات سرووهای پا را برای دستیابی به حرکت مورد نظر ربات عنکبوتی، به سمت راست یا چپ، هماهنگ می کند. هر تابع تابع “moveLeg_Right()” یا “moveLeg_Left()” مناسب را برای هر پایه ربات فراخوانی می کند و اشیاء سروو مربوطه را به عنوان آرگومان ارسال می کند.

//  Spider Robot dance Function
void dance(){
    // Move the selected servos from 0 to 180 degrees
  for (int angle = 0; angle <= 180; angle += 2) {
    myServo1.write(angle);
    myServo3.write(angle);
    myServo5.write(angle);
    myServo7.write(angle);
    delay(10);  // Delay between each angle change (adjust as needed)
  }
  // Move the selected servos from 180 to 0 degrees
  for (int angle = 180; angle >= 0; angle -= 2) {
    myServo1.write(angle);
    myServo3.write(angle);
    myServo5.write(angle);
    myServo7.write(angle);
    delay(10);  // Delay between each angle change (adjust as needed)
  }
}
         //  Spider Robot pushup Function    
void pushup(){
    // Move the selected servos from 0 to 180 degrees
  for (int angle = 0; angle <= 180; angle += 2) {
    myServo2.write(angle);
    myServo4.write(angle);
    myServo6.write(angle);
    myServo8.write(angle);
    delay(10);  // Delay between each angle change (adjust as needed)
  }
  // Move the selected servos from 180 to 0 degrees
  for (int angle = 180; angle >= 0; angle -= 2) {
    myServo2.write(angle);
    myServo4.write(angle);
    myServo6.write(angle);
    myServo8.write(angle);
    delay(10);  // Delay between each angle change (adjust as needed)
  }
}

این بلوک تابع pushup() و dance() را تعریف می کند که عملکردهای سروو را برای ربات عنکبوتی برای انجام یک حرکت pushup و رقص کنترل می کند. زوایای سروو را بین ۰ تا ۱۸۰ درجه برای سرووهای انتخابی (myServo1، myServo3، myServo5، myServo7) برای دستیابی به افکت حرکت رقص و (myServo2، myServo4، myServo6، myServo8) برای جلوه حرکت فشاری تغییر می‌دهد.

 // Move Spider Robot Forward logic
void moveLeg_Left_Forward(Servo& liftServo, Servo& pivotServo , Servo& oppositePivotServo) {
  // Move the lift servo from 90 to 180
  for (int angle = 90; angle <= 180; angle += 2) {
    liftServo.write(angle);
    delay(10);
  }
  // Move the pivot servo from 90 to 0
  for (int angle = 90; angle >= 0; angle -= 2) {
    pivotServo.write(angle);
    delay(10);
  }
  // Move the lift servo from 180 to 90
  for (int angle = 180; angle >= 90; angle -= 2) {
    liftServo.write(angle);
    delay(10);
  }
}
void moveLeg_Right_Forward(Servo& liftServo, Servo& pivotServo , Servo& oppositePivotServo) {
  // Move the lift servo from 90 to 180
  for (int angle = 90; angle <= 180; angle += 2) {
    liftServo.write(angle);
    delay(10);
  }
  // Move the pivot servo from 90 to 180
  for (int angle = 90; angle <= 180; angle += 2) {
    pivotServo.write(angle);
    delay(10);
  }
  // Move the lift servo from 180 to 90
  for (int angle = 180; angle >= 90; angle -= 2) {
    liftServo.write(angle);
    delay(10);
  }
}
        // Move Spider  Robot Backward logic
void moveLeg_Left_Backward(Servo& liftServo, Servo& pivotServo, Servo& oppositePivotServo) {
  // Move the lift servo from 90 to 180
  for (int angle = 90; angle <= 180; angle += 2) {
    liftServo.write(angle);
    delay(10);
  }
  // Move the pivot servo from 90 to 180
  for (int angle = 90; angle <= 180; angle += 2) {
    pivotServo.write(angle);
    delay(10);
  }
  // Move the lift servo from 180 to 90
  for (int angle = 180; angle >= 90; angle -= 2) {
    liftServo.write(angle);
    delay(10);
  }
}
void moveLeg_Right_Backward(Servo& liftServo, Servo& pivotServo, Servo& oppositePivotServo) {
  // Move the lift servo from 90 to 180
  for (int angle = 90; angle <= 180; angle += 2) {
    liftServo.write(angle);
    delay(10);
  }
  // Move the pivot servo from 90 to 0
  for (int angle = 90; angle >= 0; angle -= 2) {
    pivotServo.write(angle);
    delay(10);
  }
  // Move the lift servo from 180 to 90
  for (int angle = 180; angle >= 90; angle -= 2) {
    liftServo.write(angle);
    delay(10);
  }
}

این بلوک کد شامل چهار تابع «moveLeg_Left_Forward()»، «moveLeg_Right_Forward()»، «moveLeg_Left_Backward()» و «moveLeg_Right_Backward()» است. moveLeg_Left_Forward(): این تابع وظیفه حرکت پای چپ ربات عنکبوتی را به جلو بر عهده دارد. سه شی سروو را به عنوان پارامتر می گیرد: liftServo، pivotServo، و counterPivotServo. این تابع ابتدا liftServo را از ۹۰ درجه به ۱۸۰ درجه با افزایش ۲ درجه حرکت می دهد. سپس، PivotServo را از ۹۰ درجه به ۰ درجه با همان افزایش حرکت می دهد. در نهایت، liftServo را از ۱۸۰ به ۹۰ درجه به عقب می برد. با استفاده از عبارت delay(10) هر حرکت با تاخیر ۱۰ میلی ثانیه ای همراه است. moveLeg_Right_Forward(): این تابع وظیفه حرکت پای راست ربات عنکبوتی را به جلو بر عهده دارد. ساختاری شبیه به moveLeg_Left_Forward() دارد، اما با اضافه شدن یک حرکت اضافی. پس از حرکت liftServo و pivotServo همانطور که در بالا توضیح داده شد، PivotServo مقابل را از ۰ به ۹۰ درجه منتقل می کند. هدف از این حرکت اضافی هماهنگ کردن حرکات پا برای حرکت رو به جلو است.

moveLeg_Left_Backward(): این تابع وظیفه حرکت دادن پای چپ ربات عنکبوتی را به سمت عقب بر عهده دارد. ساختاری شبیه به moveLeg_Left_Forward() دارد، اما با تغییراتی در افزایش زاویه و جهت. PivotServo از ۹۰ به ۱۸۰ درجه و liftServo از ۱۸۰ به ۹۰ درجه منتقل می شود. این تغییرات منجر به حرکت پا در جهت مخالف می شود. moveLeg_Right_Backward(): این تابع وظیفه حرکت دادن پای راست ربات عنکبوتی به عقب را بر عهده دارد. ساختاری شبیه به moveLeg_Left_Backward()، با اضافه کردن یک حرکت اضافی دارد. پس از حرکت liftServo و pivotServo همانطور که در بالا توضیح داده شد، PivotServo مقابل را از ۹۰ به ۰ درجه منتقل می کند.

 // Move Spider  Robot Right logic
void moveLeg_Right(Servo& liftServo, Servo& pivotServo , Servo& oppositePivotServo) {
  // Move the lift servo from 90 to 180
  for (int angle = 90; angle <= 180; angle += 2) {
    liftServo.write(angle);
    delay(10);
  }
  // Move the pivot servo from 90 to 0
  for (int angle = 90; angle >= 0; angle -= 2) {
    pivotServo.write(angle);
    delay(10);
  }
  // Move the opposite pivot servo from 0 to 90
  for (int angle = 0; angle <= 90; angle += 2) {
    oppositePivotServo.write(angle);
    delay(10);
  }
  // Move the lift servo from 90 to 180
  for (int angle = 180; angle >= 90; angle -= 2) {
    liftServo.write(angle);
    delay(10);
  }
}
          // Move Spider  Robot Left logic
void moveLeg_Left(Servo& liftServo, Servo& pivotServo , Servo& oppositePivotServo) {
  // Move the lift servo from 90 to 180
  for (int angle = 90; angle <= 180; angle += 2) {
    liftServo.write(angle);
    delay(10);
  }
  // Move the pivot servo from 90 to 180
  for (int angle = 90; angle <= 180; angle += 2) {
    pivotServo.write(angle);
    delay(10);
  }
  // Move the opposite pivot servo from 180 to 90
  for (int angle = 180; angle >= 90; angle -= 2) {
    oppositePivotServo.write(angle);
    delay(10);
  }
  // Move the lift servo from 180 to 90
  for (int angle = 180; angle >= 90; angle -= 2) {
    liftServo.write(angle);
    delay(10);
  }
}

این بلوک کد شامل دو تابع moveLeg_Right() و moveLeg_Left(). در اینجا توضیحی در مورد هر تابع آورده شده است: () moveLeg_Right: این تابع وظیفه حرکت دادن پای راست ربات عنکبوتی را در جهت یا چرخش درست دارد. سه شی سروو را به عنوان پارامتر می گیرد: liftServo، pivotServo، و counterPivotServo. عملکرد با حرکت liftServo از ۹۰ درجه به ۱۸۰ درجه با افزایش ۲ درجه شروع می شود. سپس، PivotServo را از ۹۰ درجه به ۰ درجه با همان افزایش حرکت می دهد. سپس، PivotServo مقابل را از ۰ به ۹۰ درجه منتقل می کند. در نهایت، liftServo را از ۱۸۰ به ۹۰ درجه به عقب می برد. با استفاده از عبارت delay(10) هر حرکت با تاخیر ۱۰ میلی ثانیه ای همراه است. () moveLeg_Left: این تابع وظیفه حرکت پای چپ ربات عنکبوتی را در جهت یا چرخش به چپ بر عهده دارد. ساختاری مشابه با moveLeg_Right () دارد، اما با تغییراتی در افزایش زاویه و جهت. PivotServo از ۹۰ به ۱۸۰ درجه و PivotServo مخالف از ۱۸۰ به ۹۰ درجه منتقل می شود. این تغییرات منجر به حرکت پا در جهت مخالف می شود.

// All Servos Centor function  
void center_servos() {
  myServo1.write(90);
  myServo2.write(90);
  myServo3.write(90);
  myServo4.write(90);
  myServo5.write(90);
  myServo6.write(90);
  myServo7.write(90);
  myServo8.write(90);
}

این بلوک تابع ()center_servos را تعریف می کند که با نوشتن زاویه ۹۰ درجه برای هر سروو، همه موتورهای سروو را در موقعیت مرکزی خود قرار می دهد.

به طور کلی، این کد یک چارچوب اساسی برای کنترل ربات عنکبوتی با استفاده از میکروکنترلر ESP32 و موتورهای سروو فراهم می کند و آن را قادر می سازد تا حرکات و اقدامات مختلفی را انجام دهد.

کد

کد #۱:

#include <ESP32_Servo.h>    // include servo library
// Define 8 Servos
Servo myServo1; // Front Left Pivot Servo
Servo myServo2; // Front Left Lift Servo
Servo myServo3; // Back Left Pivot Servo
Servo myServo4; // Back Left Lift Servo
Servo myServo5; // Back Right Pivot Servo
Servo myServo6; // Back Right Lift Servo
Servo myServo7; // Front Right Pivot Servo
Servo myServo8; // Front Right Lift Servo

void setup()
{

  // Attach servos to Arduino Pins
  myServo1.attach(21);
  myServo2.attach(19);
  myServo3.attach(33);
  myServo4.attach(25);
  myServo5.attach(27);
  myServo6.attach(14);
  myServo7.attach(12);
  myServo8.attach(13);

  myServo1.write(90);
  myServo2.write(90);
  myServo3.write(90);
  myServo4.write(90);
  myServo5.write(90);
  myServo6.write(90);
  myServo7.write(90);
  myServo8.write(90);
}
 void loop()
{
}

کد #۲ :

#include <ESP32_Servo.h>    // include servo library


// Define the delay between function calls (in milliseconds)
const unsigned long FUNCTION_DELAY = 2000; // 2 seconds

const unsigned long t = 2;
const unsigned long tt = 5;

// Define 8 Servos
Servo myServo1; // Front Left Pivot Servo
Servo myServo2; // Front Left Lift Servo
Servo myServo3; // Back Left Pivot Servo
Servo myServo4; // Back Left Lift Servo
Servo myServo5; // Back Right Pivot Servo
Servo myServo6; // Back Right Lift Servo
Servo myServo7; // Front Right Pivot Servo
Servo myServo8; // Front Right Lift Servo


void setup()
{

  // Attach servos to Arduino Pins
  myServo1.attach(21);
  myServo2.attach(19);
  myServo3.attach(33);
  myServo4.attach(25);
  myServo5.attach(27);
  myServo6.attach(14);
  myServo7.attach(12);
  myServo8.attach(13);

  center_servos();
  Serial.println("center");
  delay(2000);
}

void loop()
{
   //Move Forward 10 step 
  for (int i = 0; i < 10; i++) {
    moveLegServos_Forward();
  }
  center_servos();
  delay(FUNCTION_DELAY);
         
    // Move Backward 10 step
  for (int i = 0; i < 10; i++) {
    moveLegServos_Backward();
 }
  center_servos();
  delay(FUNCTION_DELAY);
    // Move Right 10 step
  for (int i = 0; i < 10; i++) {
    moveLegServos_Right();
  }
  center_servos();
  delay(FUNCTION_DELAY);
    // Move Left 10 step
  for (int i = 0; i < 10; i++) {
    moveLegServos_Left();
  }
  center_servos();
  delay(FUNCTION_DELAY);
   //  dance 10 step
  for (int i = 0; i < 5; i++) {
    dance();
  }
  center_servos();
  delay(FUNCTION_DELAY);
   // pushup 10 step
  for (int i = 0; i < 10; i++) {
    pushup();
  }
  center_servos();
  delay(FUNCTION_DELAY);
}


       // Move Spider Robot Forward Function
void moveLegServos_Forward()
{

  // Control the servo actions for each leg
  
  // Left side leg - Leg 1
  moveLeg_Left_Forward(myServo8, myServo7, myServo8);
  
  // Left side leg - Leg 4
  moveLeg_Left_Forward(myServo2, myServo1, myServo2);
  
  // Left side leg - Legs 1 and 4
  for (int angle = 0; angle <= 90; angle += 2) {
    myServo7.write(angle);
    myServo1.write(angle);
    delay(tt);
  }
  
  // Right side leg - Leg 2
  moveLeg_Right_Forward(myServo6, myServo5, myServo6);
  
  // Right side leg - Leg 3
  moveLeg_Right_Forward(myServo4, myServo3, myServo4);
  
  // Right side leg - Legs 2 and 3
  for (int angle = 180; angle >= 90; angle -= 2) {
    myServo5.write(angle);
    myServo3.write(angle);
    delay(tt);
  }
}  
  
      // Move Spider Robot Backward Function
void moveLegServos_Backward()
{
   
   // Control the servo actions for each leg
  // Left side leg - Leg 1
  moveLeg_Left_Backward(myServo2, myServo1, myServo2);

  // Left side leg - Leg 4
  moveLeg_Left_Backward(myServo8, myServo7, myServo8);

  // Left side leg - Legs 1 and 4
  for (int angle = 180; angle >= 90; angle -= 2) {
    myServo1.write(angle);
    myServo7.write(angle);
    delay(tt);
  }

  // Right side leg - Leg 2
  moveLeg_Right_Backward(myServo4, myServo3, myServo4);

  // Right side leg - Leg 3
  moveLeg_Right_Backward(myServo6, myServo5, myServo6);

  // Right side leg - Legs 2 and 3
  for (int angle = 0; angle <= 90; angle += 2) {
    myServo3.write(angle);
    myServo5.write(angle);
    delay(tt);
  }
}
                
         // Move Spider Robot Right Function
 void moveLegServos_Right() {
  // Control the Right turn servo actions for each leg
  moveLeg_Right(myServo8, myServo7, myServo5); // Leg 4
  moveLeg_Right(myServo2, myServo1, myServo7); // Leg 3
  moveLeg_Right(myServo4, myServo3, myServo1); // Leg 2
  moveLeg_Right(myServo6, myServo5, myServo3); // Leg 1
}

       // Move Spider Robot Left Function   
void moveLegServos_Left() {
  // Control the Left turn servo actions for each leg
  moveLeg_Left(myServo8, myServo7, myServo1); // Leg 4
  moveLeg_Left(myServo6, myServo5, myServo7); // Leg 3
  moveLeg_Left(myServo4, myServo3, myServo5); // Leg 2
  moveLeg_Left(myServo2, myServo1, myServo3); // Leg 1
}
  
       //  Spider Robot dance Function
void dance(){
    // Move the selected servos from 0 to 180 degrees
  for (int angle = 0; angle <= 180; angle += 2) {
    myServo1.write(angle);
    myServo3.write(angle);
    myServo5.write(angle);
    myServo7.write(angle);
    delay(t);  // Delay between each angle change (adjust as needed)
  }

  // Move the selected servos from 180 to 0 degrees
  for (int angle = 180; angle >= 0; angle -= 2) {
    myServo1.write(angle);
    myServo3.write(angle);
    myServo5.write(angle);
    myServo7.write(angle);
    delay(t);  // Delay between each angle change (adjust as needed)
  }
center_servos();
  delay(100);
  lean_left();
  delay(300);
  lean_right();
  delay(300);
  lean_left();
  delay(300);
  lean_right();
  delay(300);
  lean_left();
  delay(300);
  lean_right();
  delay(300);
  lean_left();
  delay(300);
  lean_right();
  delay(500);
  center_servos();
  delay(300);
  bow();
  center_servos();
}

         //  Spider Robot pushup Function    
void pushup(){
    // Move the selected servos from 0 to 180 degrees
  for (int angle = 0; angle <= 180; angle += 2) {
    myServo2.write(angle);
    myServo4.write(angle);
    myServo6.write(angle);
    myServo8.write(angle);
    delay(10);  // Delay between each angle change (adjust as needed)
  }

  // Move the selected servos from 180 to 0 degrees
  for (int angle = 180; angle >= 0; angle -= 2) {
    myServo2.write(angle);
    myServo4.write(angle);
    myServo6.write(angle);
    myServo8.write(angle);
    delay(10);  // Delay between each angle change (adjust as needed)
  }
}



          // Move Spider Robot Forward logic

void moveLeg_Left_Forward(Servo& liftServo, Servo& pivotServo , Servo& oppositePivotServo)
{
  // Move the lift servo from 90 to 180
  for (int angle = 90; angle <= 180; angle += 2) {
    liftServo.write(angle);
    delay(tt);
  }

  // Move the pivot servo from 90 to 0
  for (int angle = 90; angle >= 0; angle -= 2) {
    pivotServo.write(angle);
    delay(tt);
  }

  // Move the lift servo from 180 to 90
  for (int angle = 180; angle >= 90; angle -= 2) {
    liftServo.write(angle);
    delay(tt);
  }
}
void moveLeg_Right_Forward(Servo& liftServo, Servo& pivotServo , Servo& oppositePivotServo)
{
  // Move the lift servo from 90 to 180
  for (int angle = 90; angle <= 180; angle += 2) {
    liftServo.write(angle);
    delay(tt);
  }

  // Move the pivot servo from 90 to 180
  for (int angle = 90; angle <= 180; angle += 2) {
    pivotServo.write(angle);
    delay(tt);
  }

  // Move the lift servo from 180 to 90
  for (int angle = 180; angle >= 90; angle -= 2) {
    liftServo.write(angle);
    delay(tt);
  }
}
        // Move Spider  Robot Backward logic
void moveLeg_Left_Backward(Servo& liftServo, Servo& pivotServo, Servo& oppositePivotServo)
{
  // Move the lift servo from 90 to 180
  for (int angle = 90; angle <= 180; angle += 2) {
    liftServo.write(angle);
    delay(tt);
  }

  // Move the pivot servo from 90 to 180
  for (int angle = 90; angle <= 180; angle += 2) {
    pivotServo.write(angle);
    delay(tt);
  }

  // Move the lift servo from 180 to 90
  for (int angle = 180; angle >= 90; angle -= 2) {
    liftServo.write(angle);
    delay(tt);
  }
}

void moveLeg_Right_Backward(Servo& liftServo, Servo& pivotServo, Servo& oppositePivotServo)
{
  // Move the lift servo from 90 to 180
  for (int angle = 90; angle <= 180; angle += 2) {
    liftServo.write(angle);
    delay(tt);
  }

  // Move the pivot servo from 90 to 0
  for (int angle = 90; angle >= 0; angle -= 2) {
    pivotServo.write(angle);
    delay(tt);
  }

  // Move the lift servo from 180 to 90
  for (int angle = 180; angle >= 90; angle -= 2) {
    liftServo.write(angle);
    delay(tt);
  }
}
             
             // Move Spider  Robot Right logic
void moveLeg_Right(Servo& liftServo, Servo& pivotServo , Servo& oppositePivotServo)
{
  // Move the lift servo from 90 to 180
  for (int angle = 90; angle <= 180; angle += 2) {
    liftServo.write(angle);
    delay(t);
  }

  // Move the pivot servo from 90 to 0
  for (int angle = 90; angle >= 0; angle -= 2) {
    pivotServo.write(angle);
    delay(t);
  }

  // Move the opposite pivot servo from 0 to 90
  for (int angle = 0; angle <= 90; angle += 2) {
    oppositePivotServo.write(angle);
    delay(t);
  }

  // Move the lift servo from 90 to 180
  for (int angle = 180; angle >= 90; angle -= 2) {
    liftServo.write(angle);
    delay(t);
  }
}

          // Move Spider  Robot Left logic
void moveLeg_Left(Servo& liftServo, Servo& pivotServo , Servo& oppositePivotServo)
{
  // Move the lift servo from 90 to 180
  for (int angle = 90; angle <= 180; angle += 2) {
    liftServo.write(angle);
    delay(t);
  }

  // Move the pivot servo from 90 to 180
  for (int angle = 90; angle <= 180; angle += 2) {
    pivotServo.write(angle);
    delay(t);
  }

  // Move the opposite pivot servo from 180 to 90
  for (int angle = 180; angle >= 90; angle -= 2) {
    oppositePivotServo.write(angle);
    delay(t);
  }

  // Move the lift servo from 180 to 90
  for (int angle = 180; angle >= 90; angle -= 2) {
    liftServo.write(angle);
    delay(t);
  }
}

void bow()
{
  center_servos();
  delay(200);
  myServo2.write(15);
  myServo8.write(15);
  delay(700);
  myServo2.write(90);
  myServo8.write(90);
  delay(700);
}

void lean_left()
{
  myServo2.write(15);
  myServo4.write(15);
  myServo6.write(150);
  myServo8.write(150);
}

void lean_right()
{
  myServo2.write(150);
  myServo4.write(150);
  myServo6.write(15);
  myServo8.write(15);
}

      // All Servos Centor function  
void center_servos()
{
  myServo1.write(90);
  myServo2.write(90);
  myServo3.write(90);
  myServo4.write(90);
  myServo5.write(90);
  myServo6.write(90);
  myServo7.write(90);
  myServo8.write(90);
}

آموزش ساخت فرکانس متر با آردینو

تقریبا برای ساخت اکثر پروژه های الکترونیکی نیاز است که فرکانس خروجی آن اندازه گیری شود .

برای اندازه گیری فرکانس معمولا از اسیلوسکوپ یا سایر تجهیزات اندازه گیری استفاده می شود .

اما این دستگاهها معمولا قیمت بالایی دارند و تهیه آنها برای همه مقدور نمی باشد . برای حل مشکل ما در

این بخش ، قصد داریم که با کمک Arduino Uno و Schmitt trigger gate یک فرکانس متر ارزان بسازیم .

همچنین برای تست این فرکانس متر می خواهیم یک سیگنال ژنراتور ساده با استفاده از آی سی ۵۵۵ بسازیم .

این مدار سیگنال ژنراتور یک موج مربعی تولید می کند که برای تست به پروژه فرکانس متر ما داده می شود .

قطعات مورد نیاز :

۱٫ آی سی تایمر ۵۵۵ و ۷۴LS14 Schmitt trigger gate

۲٫ دو عدد مقاومت ۱ کیلو اهم و یک عدد مقاومت ۱۰۰ اهم

۳٫ دو عدد خازن ۱۰۰ نانو فاراد ، یک عدد خازن ۱۰۰۰ میکرو فاراد

۴٫ LCD 16*2

۵٫ برد بورد و اتصالات مربوط به آن

۶٫ پتانسیومتر ۴۷ کیلو اهم

طراحی مدار :

در تصویر زیر مدار پروژه فرکانس متر ( اندازه گیر فرکانس ) را مشاهده می کنید .

LCD با استفاده از اتصالاتی به برد آردینو متصل شده است .

اندازه فرکانس در LCD نمایش داده می شود .

ورودی موج به مدار پروژه ی سیگنال ژنراتور می رود که از طریق آن ، سیگنال تولید شده به آردینو می رود .

از IC 74LS14 برای اطمینان از اینکه فقط موج مستطیلی به آردینو می رسد استفاده می شود .

از خازن ها جهت فیلتر کردن نویز ها استفاده شده است .

این فرکانس متر می تواند فرکانس های تا ۱ مگاهرتز را اندازه گیری کند .

مدار سیگنال در تصویر زیر رسم شده است .

مدار سیگنال ژنراتور با استفاده تایمر ۵۵۵ :

اول از همه در مورد آی سی ۵۵۵ موج مربعی صحبت خواهیم کرد .

ساخت این مدار ضروری است .

زیرا برای تست فرکانس متر نیاز به تولید سیگنال مشخص داریم .

با داشتن یک سیگنال ژنراتور ما می توانیم موج مربعی تولید کنیم و با ارسال آن به آردینو ، خطا و حساسیت و سایر پارامترها را تنظیم کنیم .

تصویر سیگنال ژنراتور ساخته شده با آی سی ۵۵۵ در تصویر زیر آمده است :

مدار شماتیک این سیگنال ژنراتور نیز در تصویر زیر آورده شده است :

فرکانس سیگنال خروجی به مقاومت های RA، RB و خازن C بستگی دارد. معادله به صورت داده شده است.

Frequency (F) = 1/ (Time period) = 1.44/ ((RA+RB2)C).

در اینجا RA و RB مقادیر مقاومت و C مقدار ظرفیت هستند. با قرار دادن مقادیر مقاومت و ظرفیت خازن در معادله فوق فرکانس موج مربع خروجی را بدست می آوریم.

در دو تصویر بالا می بینیم که RB با یک پتانسیومتر در عمل جایگزین شده است . این کار به این دلیل انجام گرفته تا بتوانیم با تغییر مقاومت پتانسیومتر

فرکانس موج مربعی را تغییر دهیم .

اشمیت تریگر گیت :

می دانیم همه سیگنال های آزمایشی مربعی یا مستطیلی نیستند .

امواج مثلثی ، سینوسی و … نیز داریم .

از آنجایی که آردینو فقط قادر به تشخیص امواج مربعی یا مستطیلی می باشد ، ما باید تمام امواج سینوسی ، مثلثی و … را به موج مربعی

یا مستطیلی تبدیل کنیم .

برای این کار از اشمیت تریگر استفاده می کنیم .

اشمیت تریگر گیت یک قطعه دیجیتال است که برای عملیات حسابی و منطقی طراحی شده است .

این گیت خروجی را بر اساس سطح ولتاژ ورودی تعیین می کند . این گیت دارای سطح ولتاژ تری شولد است .

وقتی سطح ولتاژ ورودی بالاتر از سطح ولتاژ تری شولد باشد ، خروجی سطح بالا می شود . ( سطح بالا رونده پالس مربعی ) .

برعکس ، اگر سطح ولتاژ ورودی کمتر از ولتاژ تری شولد شود ، خروجی گیت سطح پایین می شود .

و به این شکل سیگنال مربعی توسط اشمیت تریگر ساخته می شود .

معمولا قبل اشمیت تریگر یک گیت NOT قرار داده می شود .

ما قصد داریم از تراشه ۷۴LS14 استفاده کنیم، این تراشه دارای ۶ گیت Schmitt Trigger در آن است. این شش گیت همانطور که در شکل زیر نشان داده شده است به صورت داخلی متصل می شوند

جدول کارکرد اشمیت تریگر به همراه گیت NOT ( معکوس ) در جدول زیر آورده شده است :

اکنون خروجی اشمیت تریگر را می توانیم به آردینو متصل کنیم و موج مربعی بگیریم .

توضیح کدهای پروژه فرکانس متر آردینو

کد نویسی برای فرکانس متر بسیار ساده می باشد .

ما در اینجا تابع PulseIn را توضیح می دهیم که وظیفه اصلی اندازه گیری فرکانس را این تابع برعهده دارد .

این تابع ما را قادر می سازد که مدت زمان حالت مثبت یا مدت زمان حالت منفی یک پالس مستطیلی را اندازه بگیریم .

Htime = pulseIn(8,HIGH);
Ltime = pulseIn(8, LOW);

این تابع زمانی اندازه گیری می کند که لبه بالا رونده یا لبه پایین رونده در PIN8 آردینو وجود دارد .

بنابراین در یک سیکل موج مدت زمان سطوح مثبت یا منفی را در میکرو ثانیه خواهیم داشت .

این تابع مدت زمان را در حد میکرو ثانیه اندازه گیری می کند .

در یک سیگنال داده شده، زمان بالا = ۱۰ میلی ثانیه و زمان کم = ۳۰ میلی ثانیه (با فرکانس ۲۵ هرتز) داریم.

بنابراین ۳۰۰۰۰ در عدد صحیح Ltime و ۱۰۰۰۰ در Htime ذخیره می شود

وقتی آنها را با هم جمع می کنیم، مدت چرخه را خواهیم داشت و با معکوس کردن آن، فرکانس را خواهیم داشت.

کد کامل پروژه در این قسمت قرار داده شده است :

#include <LiquidCrystal.h>

LiquidCrystal lcd(2, 3, 4, 5, 6, 7);

int Htime;              //integer for storing high time

int Ltime;                //integer for storing low time

float Ttime;            // integer for storing total time of a cycle

float frequency;        //storing frequency

void setup()

{

    pinMode(8,INPUT);

    lcd.begin(16, 2);

}

void loop()

{

    lcd.clear();

    lcd.setCursor(0,0);

    lcd.print("Frequency of signal");

    Htime=pulseIn(8,HIGH);      //read high time

    Ltime=pulseIn(8,LOW);        //read low time

    

    Ttime = Htime+Ltime;

    frequency=1000000/Ttime;    //getting frequency with Ttime is in Micro seconds

    lcd.setCursor(0,1);

    lcd.print(frequency);

    lcd.print(" Hz");

    delay(500);

}

آموزش ساخت ربات مریخ نورد

در این بخش ، آموزش ساخت یک مدل بسیار ساده شده ی ساخت ربات مریخ نورد را ارائه خواهیم کرد .

سیاره مریخ برای قرن ها تخیل ما را مجذوب خود کرده است و ایده ارسال مریخ نوردها برای کاوش در سطح آن، کنجکاوی ما را بیش از پیش تقویت کرده است. در این پروژه، ما به دنیای هیجان انگیز رباتیک می پردازیم و نحوه ساخت مریخ نورد مبتنی بر آردوینو با قابلیت عبور از زمین های مختلف را نشان خواهیم داد.

بنابراین، کمربند ایمنی خود را ببندید تا سفر هیجان انگیز ساخت مریخ نورد خودمان را آغاز کنیم.

در این مقاله، تمرکز ما بر روی ایجاد مریخ نورد با بلوتوث آردوینو است. یک هدف این آموزش ارائه یک توضیح گام به گام روشن از ساخت شاسی مریخ نورد تا برنامه ریزی و آزمایش آن است. وظیفه اصلی ما شامل آموزش کدنویسی است که به زبان برنامه نویسی C یا C++ نوشته شده است. میکروکنترلر آردوینو کد را کامپایل و اجرا می کند و به مریخ نورد این امکان را می دهد تا مطابق مشخصات مورد نظر ما عمل کند.

توضیحات طراحی مریخ نورد

قبل از اینکه به جنبه‌های فنی بپردازیم، بیایید لحظه‌ای به درک طراحی مریخ‌نورد بپردازیم. یک مریخ نورد معمولی باید در مناظر چالش برانگیز سطح مریخ حرکت کند. برای دستیابی به این هدف، ما بر روی ساخت یک مریخ نورد با سیستم ۶ چرخ محرک با سیستم تعلیق مناسب تمرکز خواهیم کرد تا از تحرک و پایداری مطلوب برای مریخ نورد اطمینان حاصل کنیم.

شاسی مریخ نورد به عنوان پایه ای برای کل وسیله نقلیه عمل می کند. باید محکم، بادوام و قابلیت عبور از زمین های مختلف را داشته باشد و همچنین باید قطعات الکترونیکی مختلف مانند برد آردوینو، منبع تغذیه و ماژول های کنترل موتور را در خود جای دهد.

من قطعات شاسی اکریلیک را با استفاده از SolidWorks ایجاد کردم و برش لیزری را برای ساخت مریخ نورد خود انجام دادم. من فایل های .dxf را برای پروژه مریخ نورد پیوست می کنم که می توانید از آن برای برش لیزری استفاده کنید. این ویدئو روند مونتاژ مریخ نورد را نشان می دهد.

قطعات مورد نیاز مریخ نورد

شاسی برش اکریلیک مریخ نورد

۶ موتور و چرخ BO

آردوینو اونو

ماژول درایور موتور L298n

ماژول بلوتوث HC-05

باتری ۱۲ ولت لیتیوم یونی با کانکتور

گیره L (8 عدد )

مهره و پیچ و مهره ۱۰ میلی متری M4 (8 عدد )

مهره و پیچ و مهره ۱۰ میلی متری M3 (12 عدد )

مهره و پیچ و مهره ۳۰ میلی متری M3 (12 عدد )

سوئیچ و اتصال سیم ها

ماژول درایور موتور L298N

ماژول درایور موتور L298N یک ماژول راه انداز موتور است که معمولاً در پروژه های رباتیک و الکترونیک استفاده می شود. این ماژول مبتنی بر مدار مجتمع L298n است، دارای دو مدار پل H، یکی برای هر کانال موتور است که امکان کنترل دو جهته موتورها را فراهم می کند. با ارائه سیگنال های منطقی مناسب به پایه های کنترل ماژول، می توانید سرعت و جهت موتور را کنترل کنید. از آنجایی که ما از سیگنال PWM تولید شده توسط آردوینو برای کنترل سرعت موتورها استفاده نمی کنیم، آنها با حداکثر سرعت خود کار خواهند کرد. دلیل این امر این است که ما پین های ENA و ENB را که مربوط به کنترل PWM هستند، در حالت ثابت روی برد نگه می داریم. بنابراین، هدف اصلی ماژول درایور موتور در این تنظیمات، تغییر جهت چرخش موتورها است. این قابلیت ربات را قادر می سازد در هر چهار جهت از جمله جلو، عقب، چپ و راست حرکت کند.

Pinout درایور موتور L298N

ماژول درایور موتور L298N دارای پین اوت خاصی است که با عملکردهای مختلف آن مطابقت دارد. در اینجا توضیحات پین اوت ماژول درایور موتور L298N آمده است.

VCC : این پین برای اتصال یک منبع تغذیه خارجی (تا ۱۲ ولت) برای تغذیه موتورها استفاده می شود.

GND : این پایه اتصال زمین برای ماژول است و باید به زمین منبع تغذیه و منبع سیگنال کنترل (آردوینو) متصل شود.

۵V : این پین یک خروجی ۵ ولتی تنظیم شده را ارائه می دهد که می تواند برای تغذیه اجزای خارجی یا تامین ولتاژ منطقی به منبع سیگنال کنترل استفاده شود.

ENA : این پین برای فعال یا غیرفعال کردن موتور متصل به کانال A و کانال B استفاده می شود و وظیفه کنترل سرعت موتور را از طریق سیگنال های PWM (Pulse Width Modulation) بر عهده دارد.

IN1 , IN2 , IN3 , IN4: این پایه ورودی برای کنترل جهت چرخش موتور متصل به کانال A، به طور مشابه IN3 و IN4 برای کانال B استفاده می شود. با ارائه سطوح منطقی مناسب (HIGH یا LOW)، می توانید جهت مورد نظر را تنظیم کنید. این پایه ها برای دریافت سیگنال (HIGH یا LOW) به پین ​​های دیجیتال آردوینو متصل می شوند.

OUT1 , OUT2 : پین ذکر شده برای اتصال موتورها در نظر گرفته شده است. به طور خاص، یک موتور باید به OUT-1 و OUT-2 وصل شود در حالی که موتور دیگر باید به OUT-3 و OUT-4 متصل شود. لازم به ذکر است که موتورها را می توان در محدوده ولتاژ ۵ تا ۳۵ ولت متصل کرد. با این حال، شایان ذکر است که کاهش تقریبی ۲ ولت در ولتاژ خروجی در مقایسه با ولتاژ اعمال شده به پین ​​Vcc وجود خواهد داشت.

ماژول بلوتوث HC-05

HC-05 یک ماژول بلوتوث پرکاربرد است که روشی راحت و قابل اعتماد برای افزودن قابلیت های ارتباط بی سیم به دستگاه های الکترونیکی ارائه می دهد. از ارتباط سریال از طریق پروتکل UART (گیرنده-فرستنده ناهمزمان جهانی) پشتیبانی می کند.

ماژول HC-05 از مشخصات بلوتوث نسخه ۲٫۰ پشتیبانی می کند و بسته به برنامه مورد نظر می تواند به عنوان یک دستگاه Master یا Slave از طریق دستورات AT پیکربندی شود. در حالت Master، می تواند اتصالات را با سایر دستگاه های بلوتوث آغاز کند، در حالی که در حالت Slave، می تواند اتصالات ورودی را بپذیرد.

HC-05 Pinout

ماژول بلوتوث HC-05 دارای یک پین اوت خاص است که با عملکردهای مختلف آن مطابقت دارد. در اینجا توضیحات پین اوت ماژول بلوتوث HC-05 آمده است.

VCC : این پین برای تامین برق ماژول استفاده می شود. معمولاً در محدوده ولتاژ ۳٫۳ تا ۶ ولت کار می کند.

GND : این پایه اتصال زمین ماژول است و باید به زمین منبع تغذیه و منبع سیگنال کنترل متصل شود.

TXD : این پین ، پین انتقال داده است و برای ارسال اطلاعات از ماژول به دستگاه دیگر استفاده می شود. باید به پین ​​دریافت (RX) دستگاه گیرنده متصل شود.

RDX : این پین پین دریافت اطلاعات است و برای دریافت اطلاعات از دستگاه دیگری استفاده می شود. باید به پین ​​انتقال (TX) دستگاه فرستنده متصل شود.

STATE : این پین یک پین اختیاری است که می توان از آن برای بررسی وضعیت ماژول استفاده کرد. می توان آن را طوری پیکربندی کرد که اطلاعات مربوط به وضعیت اتصال ماژول یا سایر اطلاعات مرتبط را ارائه دهد.

EN : این پین برای فعال یا غیرفعال کردن ماژول (حالت Command & Data) استفاده می شود. هنگامی که این پین بالا (۳٫۳ ولت یا ۵ ولت) کشیده می شود، ماژول فعال می شود (حالت فرمان)، و هنگامی که آن را LOW (0 ولت یا GND) کشیده می شود، ماژول غیرفعال می شود (حالت داده).

مونتاژ شاسی مریخ نورد

ما از یک ورق اکریلیک برش با لیزر برای ایجاد شاسی برای پروژه خود استفاده کرده ایم. ورق دقیقاً برش داده شده است تا تمام اتصالات و اجزای لازم را در خود جای دهد و امکان مونتاژ آسان با استفاده از پیچ گوشتی را فراهم می کند.

با کمک پیچ و مهره های ۱۰ میلی متری M4 پایه عقب را به پایه جلو متصل کنید

جفت پای جلو و عقب را با صفحه پایه با کمک گیره L با مهره ها و پیچ های ۱۰ میلی متری M3، M4 وصل کنید.

موتورها را با هر دو پایه به محل مناسب خود با مهره و پیچ و مهره ۳۰ میلی متری M3 وصل کرد.

تمام قطعات الکترونیکی را با چسب دو طرفه در محل مناسب خود قرار دهید.

نمودار مدار مریخ نورد با بلوتوث کنترل شده آردوینو

در اینجا شماتیک یک مریخ نورد کنترل شده با بلوتوث را مشاهده می کنید. در این طرح مجموعاً شش موتور داریم که سه موتور به صورت موازی در سمت راست و سه موتور به صورت موازی در سمت چپ متصل می شوند. این پیکربندی به هر سه موتور در هر طرف اجازه می دهد تا به طور همزمان کار کنند و با سرعت یکسان و در یک جهت کار کنند. با اتصال موازی آنها، اطمینان حاصل می کنیم که سیگنال های کنترلی و منبع تغذیه یکسان را دریافت می کنند. این ترتیب حرکت کارآمد و هماهنگ را برای مریخ نورد امکان پذیر می کند و قدرت مانور و پایداری آن را افزایش می دهد.

اتصالات :

ماژول بلوتوث آردوینو و HC-05:

پایه TX ماژول بلوتوث را به پایه RX (معمولاً پایه دیجیتال ۰) آردوینو وصل کنید.

پایه RX ماژول بلوتوث را به پایه TX (معمولاً پایه دیجیتال ۱) آردوینو وصل کنید.

پایه های VCC و GND ماژول بلوتوث را به برق مناسب (+۵ ولت) و پایه های زمین در آردوینو وصل کنید.

آردوینو و ماژول درایور موتور:

پایه های خروجی دیجیتال آردوینو (پایه های دیجیتال ۱۰، ۹، ۸ و ۷) را به پایه های ورودی مناسب (IN1، IN2، IN3، و IN4) در ماژول درایور موتور متصل کنید.

پین های ENA و ENB ماژول درایور موتور را با کمک هدر ماده به پین ​​High State روی برد متصل کنید.

پایه های OUT1، OUT2، OUT3 و OUT4 ماژول درایور موتور را به پایانه های مناسب موتورها وصل کنید.

پایه های VCC (+5V) و GND ماژول درایور موتور را به اتصالات مناسب برق (Vin) و زمین (GND) در آردوینو وصل کنید.

منبع تغذیه:

ترمینال مثبت منبع تغذیه را به ورودی +۱۲ ولت ماژول درایور موتور وصل کنید.

ترمینال منفی منبع تغذیه را به پایه GND ماژول درایور موتور وصل کنید.

پایه GND آردوینو را به پایه GND ماژول درایور موتور وصل کنید.

توضیح کد های برنامه :

در اینجا کد کنترل کننده ی ساده ی مریخ نورد را قرار داده ایم .

پیکربندی پین : پین های روی برد آردوینو که به ماژول درایور موتور و سایر اجزا وصل شده اند تعریف شده اند. این مرحله تضمین می کند که از پین های صحیح برای کنترل موتور و سایر عملیات استفاده می شود.

ما پین های IN1، IN2، IN3 و IN4 را به صورت ۱۰،۹،۸ و ۷ پایه دیجیتال آردوینو تعریف کرده ایم. این پایه ها به پایه های ورودی ماژول درایور موتور متصل می شوند.

 int state=0;
const int motorpin11=10;  // L298n #NI1
const int motorpin12=9;   // L298n #NI2
const int motorpin21=8;   // L298n #NI3
const int motorpin22=7;   // L298n #NI4

Setup: تابع setup فقط یک بار در ابتدای اجرای کد اجرا می شود. وظیفه پیکربندی پروتکل های ارتباطی، تنظیم حالت های پین و مقداردهی اولیه متغیرها را بر عهده دارد

در تابع setup() با مقداردهی اولیه ارتباط سریال سخت افزاری با نرخ باود ۹۶۰۰ شروع می کنیم. این به آردوینو اجازه می دهد تا با دستگاه های خارجی مانند ماژول بلوتوث با سرعت انتقال داده مشخص شده ارتباط برقرار کند.

در مرحله بعد، ما حالت های پین را برای پین های کنترل جهت مورد استفاده برای کنترل موتور تنظیم می کنیم. این پین ها برای کنترل حرکت و جهت موتورها پیکربندی شده اند. با تنظیم اولیه آنها بر روی LOW، اطمینان حاصل می کنیم که موتورها در شروع اجرای برنامه در حالت توقف هستند. این امر از هرگونه حرکت ناخواسته موتورها قبل از دریافت هر گونه دستور یا دستورالعمل جلوگیری می کند.

راه‌اندازی ارتباط سریال سخت‌افزاری و تنظیم حالت‌های پین مناسب، مراحلی حیاتی در آماده‌سازی آردوینو برای کنترل مناسب موتور و اطمینان از کنترل و ثابت بودن حالت اولیه موتور هستند.

void setup() {
  Serial.begin(9600); 
  pinMode(motorpin11,OUTPUT);
  pinMode(motorpin12,OUTPUT);
  pinMode(motorpin21,OUTPUT);
  pinMode(motorpin22,OUTPUT);
  digitalWrite(motorpin11,LOW);
  digitalWrite(motorpin12,LOW);
  digitalWrite(motorpin21,LOW);
  digitalWrite(motorpin22,LOW);
} 

LOOP : تابع حلقه پس از اتمام نصب به طور مداوم اجرا می شود. این تابع شامل منطق اصلی برنامه است که رفتار مریخ نورد را بر اساس دستورات دریافتی تعریف می کند.

تابع حلقه () یا LOOP به طور مداوم دستورات دریافتی از ماژول بلوتوث را بررسی می کند. بسته به فرمان دریافتی، مریخ نورد به جلو، عقب، گردش به چپ، گردش به راست یا توقف حرکت می کند.

کد به سیگنال های بلوتوث ورودی گوش می دهد و دستورات را از یک دستگاه جفت شده دریافت می کند. این می تواند شامل دستورالعمل هایی برای حرکت به جلو، عقب، چرخش به چپ یا راست، یا توقف مریخ نورد باشد.

void loop()
  { if (Serial.available()>0)
  state=Serial.read();
{

دستورات دریافتی به سیگنال های کنترل موتور مناسب ترجمه می شوند. کد سیگنال های لازم را به ماژول راننده موتور ارسال می کند و جهت ها را مطابق دستورالعمل تنظیم می کند.

 if (state=='F') {
    digitalWrite(motorpin11,HIGH);
    digitalWrite(motorpin12,LOW);     // Forward motion of rover
    digitalWrite(motorpin21,HIGH);
    digitalWrite(motorpin22,LOW);
  }     
   else if(state=='B') {
      digitalWrite(motorpin11,LOW);
      digitalWrite(motorpin12,HIGH);   // Backward motion of rover
      digitalWrite(motorpin21,LOW);
      digitalWrite(motorpin22,HIGH);
      }
      else if(state=='S') {
        digitalWrite(motorpin11,LOW);
        digitalWrite(motorpin12,LOW);     // Stop
        digitalWrite(motorpin21,LOW);
        digitalWrite(motorpin22,LOW);
        }
        else if(state=='L') {
        digitalWrite(motorpin11,HIGH);
        digitalWrite(motorpin12,LOW);     // Left motion of rover
        digitalWrite(motorpin21,LOW);
        digitalWrite(motorpin22,HIGH);
        }
        else if(state=='R')
      {
        digitalWrite(motorpin11,LOW);
        digitalWrite(motorpin12,HIGH);     // Right motion of rover
        digitalWrite(motorpin21,HIGH);
        digitalWrite(motorpin22,LOW);
        }
        else if(state=='l')
      {
        digitalWrite(motorpin11,LOW);
        digitalWrite(motorpin12,HIGH);    // Backward Left motion of rover
        digitalWrite(motorpin21,HIGH);
        digitalWrite(motorpin22,LOW);
        }
        else if(state=='r')
      {
        digitalWrite(motorpin11,HIGH);
        digitalWrite(motorpin12,LOW);     // Backward Right motion of rover
        digitalWrite(motorpin21,LOW);
        digitalWrite(motorpin22,HIGH);
        }
  }}

داده های دریافتی با استفاده از دستورات if و else if مقایسه می شوند که امکان اجرای مشروط عبارات خاص را بر اساس ارزیابی این شرایط فراهم می کند. در این عبارات شرطی، ما هفت تابع حرکتی مختلف را تعریف کرده‌ایم که با اقدامات مختلف مریخ‌نورد مطابقت دارد. این توابع در داخل دستورات if بر اساس شرایط خاص فراخوانی می شوند. هر تابع وظیفه کنترل یک حرکت خاص مانند حرکت به جلو، عقب، چرخش به چپ یا راست، توقف، عقب به چپ و عقب به راست را بر عهده دارد. با سازماندهی کد به این روش، می‌توانیم عملکرد را مدولار کنیم و درک و نگهداری آن را آسان‌تر کنیم. عبارات شرطی تضمین می کنند که تابع حرکت مناسب زمانی که شرط مربوطه بر اساس داده های دریافتی برآورده می شود، اجرا می شود. به طور خلاصه، دستور if و else if کد را قادر می سازد تا داده های دریافتی را ارزیابی کند و تابع حرکت مربوطه را بر اساس شرایط انجام شده اجرا کند و کنترل دقیق و مانورپذیری مریخ نورد را تسهیل می کند.

برنامه اندروید را برای کنترل مریخ نورد تنظیم کنید

برای اتصال ماشین کنترل‌شده با بلوتوث به تلفن خود، این مراحل را دنبال کنید: برنامه «Bluetooth RC Car» را در دستگاه Android خود باز کنید. لطفا توجه داشته باشید که در حال حاضر، این برنامه فقط برای کاربران اندروید در دسترس است. بلوتوث گوشی خود را با رفتن به تنظیمات گوشی خود روشن کنید. گوشی خود را به ماژول بلوتوث HC-05 وصل کنید. اگر یک ماژول HC-05 جدید دارید، یک مرحله اضافی قبل از اتصال وجود دارد. به تنظیمات بلوتوث گوشی خود بروید. دستگاه های بلوتوث را جستجو کنید. یک دستگاه بلوتوث به نام HC-05 پیدا خواهید کرد. با انتخاب دستگاه بلوتوث با تلفن خود آن را جفت کنید. در طول فرآیند جفت شدن، از شما خواسته می شود یک رمز عبور وارد کنید. رمز عبور پیش فرض برای HC-05 معمولاً ۱۲۳۴ یا ۰۰۰۰ است. رمز عبور را وارد کرده و فرآیند جفت شدن را ادامه دهید. پس از موفقیت آمیز شدن جفت شدن، مریخ نورد کنترل شده با بلوتوث شما اکنون به دستگاه اندرویدی شما متصل است.

با دنبال کردن این مراحل، می‌توانید بین تلفن خود و ماژول بلوتوث مریخ‌نورد ارتباط برقرار کنید و به شما این امکان را می‌دهد تا با استفاده از برنامه «Bluetooth RC Car» به‌صورت بی‌سیم آن را کنترل کنید.

جمع بندی

تبریک می گویم! شما با موفقیت مریخ نورد مبتنی بر آردوینو خود را ساختید. اکنون زمان آن رسیده است که به آن اجازه پرسه زدن و کاوش را بدهید. مریخ نورد خود را به مناطق مختلف ببرید، آزمایش‌ها را انجام دهید و داده‌های ارزشمند را جمع‌آوری کنید. با استفاده از تلفن هوشمند یا سایر دستگاه های دارای بلوتوث آن را به صورت بی سیم کنترل کنید و نحوه مانور آن را در چالش ها مشاهده کنید.

ساخت مریخ‌نورد آردوینو فرصتی هیجان‌انگیز برای بررسی روباتیک، الکترونیک و برنامه‌نویسی ارائه می‌دهد. این به ما امکان می دهد تا کاوش سیارات دوردست را شبیه سازی کنیم و کنجکاوی ما را در مورد اسرار جهان بر می انگیزد. بنابراین، ابزارهای خود را بردارید، خلاقیت خود را آزاد کنید و با مریخ نورد خودتان وارد این سفر هیجان انگیز ساختن و کاوش شوید!

کد کامل ربات مریخ نورد

int state=0;

const int motorpin11=10;  // L298n #NI1

const int motorpin12=9;   // L298n #NI2

const int motorpin21=8;   // L298n #NI3

const int motorpin22=7;   // L298n #NI4

void setup() {

  pinMode(motorpin11,OUTPUT);

  pinMode(motorpin12,OUTPUT);

  pinMode(motorpin21,OUTPUT);

  pinMode(motorpin22,OUTPUT);

  digitalWrite(motorpin11,LOW);

  digitalWrite(motorpin12,LOW);

  digitalWrite(motorpin21,LOW);

  digitalWrite(motorpin22,LOW);

  Serial.begin(9600);

  }

  void loop()  {

  if (Serial.available()>0)

  state=Serial.read();

  {

 if (state=='F')

     {

    digitalWrite(motorpin11,HIGH);

    digitalWrite(motorpin12,LOW);     // Forward motion of rover

    digitalWrite(motorpin21,HIGH);

    digitalWrite(motorpin22,LOW);

  }

   else if(state=='B')

    {

      digitalWrite(motorpin11,LOW);

      digitalWrite(motorpin12,HIGH);   // Backward motion of rover

      digitalWrite(motorpin21,LOW);

      digitalWrite(motorpin22,HIGH);

      }

      else if(state=='S')

      {

        digitalWrite(motorpin11,LOW);

        digitalWrite(motorpin12,LOW);     // Stop

        digitalWrite(motorpin21,LOW);

        digitalWrite(motorpin22,LOW);  

        }

        else if(state=='L')

      {

        digitalWrite(motorpin11,HIGH);

        digitalWrite(motorpin12,LOW);     // Left motion of rover

        digitalWrite(motorpin21,LOW);

        digitalWrite(motorpin22,HIGH);

        }

        else if(state=='R')

      {

        digitalWrite(motorpin11,LOW);

        digitalWrite(motorpin12,HIGH);     // Right motion of rover

        digitalWrite(motorpin21,HIGH);

        digitalWrite(motorpin22,LOW);

        }

        else if(state=='l')

      {

        digitalWrite(motorpin11,LOW);

        digitalWrite(motorpin12,HIGH);    // Backward Left motion of rover

        digitalWrite(motorpin21,HIGH);

        digitalWrite(motorpin22,LOW);

        }

        else if(state=='r')

      {

        digitalWrite(motorpin11,HIGH);

        digitalWrite(motorpin12,LOW);     // Backward Right motion of rover

        digitalWrite(motorpin21,LOW);

        digitalWrite(motorpin22,HIGH);

        }

  }}

بازوی رباتیک کنترل شده با حرکت دست با استفاده از آردوینو نانو

بازوهای رباتیک یکی از خلاقیت های جذاب مهندسی است و تماشای نحوه عملکرد برای انجام کارهای پیچیده درست مانند بازوی انسان همیشه قابل توجه بوده است . این بازوهای رباتیک معمولاً در صنایع در خط مونتاژ که کارهای مکانیکی شدید مانند جوشکاری، حفاری، نقاشی و غیره را انجام می دهند، یافت می شوند.

بازوهای رباتیک پیشرفته اخیر با دقت بالا نیز برای انجام عملیات های جراحی پیچیده در حال توسعه هستند.

ما از بازوی رباتیک ایجاد شده توسط پرینتر سه بعدی استفاده خواهیم کرد تا با استفاده از آردوینو نانو، ژیروسکوپ MPU6050 و حسگر فلکس، یک بازوی رباتیک کنترل شده با حرکت دست ایجاد کنیم.

سنسور فلکس برای کنترل سروو دستگیره بازوی رباتیک و MPU6050 برای حرکت رباتیک در محور X و Y استفاده می شود. اگر چاپگر ندارید، می توانید بازوی خود را با مقوای ساده همانطور که برای پروژه بازوی رباتیک آردوینو ساختیم بسازید.

قبل از پرداختن به جزئیات، ابتدا با سنسور MPU6050 و سنسور فلکس آشنا می شویم.

سنسور ژیروسکوپی و شتاب سنج MPU6050

MPU6050 مبتنی بر فناوری سیستم های میکرو مکانیکی (MEMS) است. این سنسور دارای شتاب سنج ۳ محوره، ژیروسکوپ ۳ محوره و سنسور دمای داخلی است. می توان از آن برای اندازه گیری پارامترهایی مانند شتاب، سرعت، جهت، جابجایی و غیره استفاده کرد.

ویژگی های سنسور MPU6050:

ارتباط: پروتکل I2C با آدرس I2C قابل تنظیم

منبع تغذیه ورودی: ۳-۵ ولت

ADC 16 بیتی داخلی دقت بالایی را ارائه می دهد

DMP داخلی قدرت محاسباتی بالایی را ارائه می دهد

می توان از آن برای ارتباط با سایر دستگاه های I2C مانند مغناطیس سنج استفاده کرد

سنسور دمای داخلی

جزئیات پین اوت MPU6050:

سنسور فلکس

حسگرهای فلکس چیزی جز یک مقاومت متغیر نیستند. مقاومت سنسور فلکس زمانی که سنسور خم می شود تغییر می کند. آنها معمولا در دو اندازه ۲٫۲ اینچ و ۴٫۵ اینچ موجود هستند.

چرا در پروژه خود از سنسورهای انعطاف پذیر استفاده می کنیم؟

در این بازوی رباتیک کنترل شده با اشاره، از یک حسگر انعطاف پذیر برای کنترل گیره بازوی رباتیک استفاده شده است. هنگامی که سنسور فلکس روی دستکش خم می شود، موتور سروو متصل به گیره می چرخد ​​و گیره باز می شود.

سنسورهای فلکس می توانند در بسیاری از پروژه ها مفید باشد و کاربرد فراوانی در ساخت انواع ربات ها دارد .

آماده سازی بازوی رباتیک پرینت سه بعدی:

بازوی رباتیک پرینت سه بعدی مورد استفاده در این آموزش با پیروی از طرح ارائه شده توسط EEZYbotARM ساخته شده است که در Thingiverse موجود است. روش کامل ساخت بازوی روباتیک پرینت سه بعدی و جزئیات مونتاژ با ویدئو در پیوند Thingiverse وجود دارد که در بالا به اشتراک گذاشته شده است.

قطعات مورد نیاز :

آردوینو نانو

سنسور فلکس

مقاومت ۱۰k

MPU6050

دستکش

سیم های اتصال

برد بورد

مدار پروژه :

اتصال مدار بین MPU6050 و آردوینو نانو:

اتصال مدار بین سروو موتور و آردوینو نانو:

یک سنسور فلکس شامل دو پین است. این شامل پایانه های قطبی نیست. بنابراین پین یک P1 به پین ​​آنالوگ A0 آردوینو نانو با مقاومت pull-up 10k متصل می شود و پایه دو P2 به آردوینو متصل می شود.

نصب MPU6050 و سنسور فلکس روی دستکش :

ما MPU6050 و سنسور فلکس را روی یک دستکش نصب کرده ایم. در اینجا از یک اتصال سیمی برای اتصال دستکش و بازوی رباتیک استفاده می شود، اما می توان آن را با استفاده از اتصال RF یا اتصال بلوتوث بی سیم کرد.

پس از هر اتصال، تنظیمات نهایی بازوی رباتیک کنترل شده با حرکت مانند تصویر زیر به نظر می رسد:

برنامه نویسی آردوینو نانو برای بازوی رباتیک

در اینجا چند خط مهم کد توضیح داده شده است.

۱٫ ابتدا فایل های کتابخانه ای لازم را وارد کنید. کتابخانه Wire.h برای ارتباط I2C بین Arduino Nano & MPU6050 و servo.h برای کنترل سروو موتور استفاده می شود.

#include<Wire.h>                
#include<Servo.h>  

۲٫ در مرحله بعد، اشیاء برای کلاس servo اعلام می شود. همانطور که از چهار موتور سروو استفاده می کنیم، چهار شی مانند servo_1، servo_2، servo_3، servo_4 ایجاد می شود.

Servo servo_1;      
Servo servo_2;
Servo servo_3;
Servo servo_4; 

۳٫ سپس آدرس I2C MPU6050 و متغیرهای مورد استفاده اعلام می شود.

const int MPU_addr=0x68;        //MPU6050 I2C Address
int16_t axis_X,axis_Y,axis_Z;
int minVal=265;
int maxVal=402;
double x;
double y;
double z;​

۴٫ در مرحله بعدی در تنظیم void، نرخ باود ۹۶۰۰ برای ارتباط سریال تنظیم شده است.

Serial.begin(9600);

و ارتباط I2C بین Arduino Nano و MPU6050 برقرار است:

 Wire.begin();                      //Initilize I2C Communication
  Wire.beginTransmission(MPU_addr);  //Start communication with MPU6050
  Wire.write(0x6B);                  //Writes to Register 6B
  Wire.write(0);                     //Writes 0 into 6B Register to Reset
  Wire.endTransmission(true);        //Ends I2C transmission

همچنین چهار پایه PWM برای اتصالات سروو موتور تعریف شده است.

 servo_1.attach(2);   // Forward/Reverse_Motor
  servo_2.attach(3);   // Up/Down_Motor
  servo_3.attach(4);   // Gripper_Motor
  servo_4.attach(5);   // Left/Right_Motor

۵٫ سپس در تابع حلقه خالی، دوباره اتصال I2C را بین MPU6050 و آردوینو نانو برقرار کنید و سپس شروع به خواندن داده های X، Y، Z-Axis از رجیستر MPU6050 کنید و آنها را در متغیرهای مربوطه ذخیره کنید.

Wire.beginTransmission(MPU_addr);    
  Wire.write(0x3B);                  //Start with regsiter 0x3B 
  Wire.endTransmission(false);     
  Wire.requestFrom(MPU_addr,14,true);  //Read 14 Registers 
                         axis_X=Wire.read()<<8|Wire.read();                
                         axis_Y=Wire.read()<<8|Wire.read();
                         axis_Z=Wire.read()<<8|Wire.read();

پس از آن، مقدار حداقل و حداکثر داده های محور را از سنسور MPU6050 در محدوده ۹۰- تا ۹۰ ترسیم کنید.

                        int xAng = map(axis_X,minVal,maxVal,-90,90);    
                        int yAng = map(axis_Y,minVal,maxVal,-90,90);
                        int zAng = map(axis_Z,minVal,maxVal,-90,90);

سپس از فرمول زیر برای محاسبه مقادیر x، y، z از ۰ تا ۳۶۰ استفاده کنید.

x= RAD_TO_DEG * (atan2(-yAng, -zAng)+PI);       
  y= RAD_TO_DEG * (atan2(-xAng, -zAng)+PI);
                          z= RAD_TO_DEG * (atan2(-yAng, -xAng)+PI);

سپس داده های خروجی آنالوگ سنسور فلکس را در پین A0 آردوینو نانو بخوانید و با توجه به مقدار دیجیتال سنسور فلکس، زاویه سروو گیره را تنظیم کنید. بنابراین اگر داده های سنسور فلکس بیشتر از ۷۵۰ باشد، زاویه سروو موتور گیره ۰ درجه و اگر کمتر از ۷۵۰ باشد ۱۸۰ درجه است.

 int gripper;
  int flex_sensorip = analogRead(A0);             
  if(flex_sensorip > 750)      
        {
          gripper = 0;
        }
        else
        {
          gripper = 180;
        }
   servo_3.write(gripper);  

سپس حرکت MPU6050 در محور X از ۰ تا ۶۰ بر حسب ۰ تا ۹۰ درجه برای حرکت رو به جلو/عکوس سروو موتور بازوی رباتیک ترسیم می شود.

if(x >=0 && x <= 60) 
  {
     int mov1 = map(x,0,60,0,90);
     Serial.print("Movement in F/R = ");
     Serial.print(mov1);
     Serial.println((char)176);
     servo_1.write(mov1);
  } 

و حرکت MPU6050 در محور X از ۲۵۰ به ۳۶۰ بر حسب ۰ تا ۹۰ درجه برای بازوی روباتیک حرکتی UP/DOWN سروو موتور ترسیم شده است.

else if(x >=300 && x <= 360) 
  {
     int mov2 = map(x,360,250,0,90);
     Serial.print("Movement in Up/Down = ");
     Serial.print(mov2);
     Serial.println((char)176);
     servo_2.write(mov2);
  } 

حرکت MPU6050 در محور Y از ۰ تا ۶۰ بر حسب ۹۰ تا ۱۸۰ درجه برای حرکت سمت چپ بازوی رباتیک سروو موتور ترسیم شده است.

 if(y >=0 && y <= 60) 
  {
     int mov3 = map(y,0,60,90,180);
     Serial.print("Movement in Left = ");
     Serial.print(mov3);
     Serial.println((char)176);
     servo_4.write(mov3);
  } 

حرکت MPU6050 در محور Y از ۳۰۰ به ۳۶۰ بر حسب ۰ تا ۹۰ درجه برای حرکت سمت راست بازوی رباتیک سروو موتور ترسیم شده است.

else if(y >=300 && y <= 360) 
  {
     int mov3 = map(y,360,300,90,0);
     Serial.print("Movement in Right = ");
     Serial.print(mov3);
     Serial.println((char)176);
     servo_4.write(mov3);
  }

کارکرد بازوی رباتیک کنترل شده با اشاره با استفاده از آردوینو

در نهایت، کد را در آردوینو نانو آپلود کنید و دستکش نصب شده با سنسور MPU6050 و Flex را بپوشید.

۱٫ اکنون دست را به سمت پایین حرکت دهید تا بازوی رباتیک به سمت جلو حرکت کند و به سمت بالا حرکت کنید تا بازوی رباتیک به سمت بالا حرکت کند.

۲٫ سپس دست را به چپ یا راست خم کنید تا بازوی رباتیک به چپ یا راست بچرخد.

۳٫ کابل فلکس متصل شده با انگشت دستکش را خم کنید تا گیره باز شود و سپس آن را رها کنید تا ببندید.

کد :

//Code for Gesture Controlled Robotic ARM (Arduino Nano & MPU6050)

//Circuit Digest

#include<Wire.h>                //I2C Wire Library 

#include<Servo.h>               //Servo Motor Library

Servo servo_1;      

Servo servo_2;

Servo servo_3;

Servo servo_4;

const int MPU_addr=0x68;        //MPU6050 I2C Address

int16_t axis_X,axis_Y,axis_Z;

int minVal=265;

int maxVal=402;

double x;

double y;

double z;

 

void setup()

{

  Serial.begin(9600);

  

  Wire.begin();                      //Initilize I2C Communication

  Wire.beginTransmission(MPU_addr);  //Start communication with MPU6050

  Wire.write(0x6B);                  //Writes to Register 6B

  Wire.write(0);                     //Writes 0 into 6B Register to Reset

  Wire.endTransmission(true);        //Ends I2C transmission

  

  servo_1.attach(2);   // Forward/Reverse_Motor

  servo_2.attach(3);   // Up/Down_Motor

  servo_3.attach(4);   // Gripper_Motor

  servo_4.attach(5);   // Left/Right_Motor

  

}

void loop()

{

  Wire.beginTransmission(MPU_addr);    

  Wire.write(0x3B);                  //Start with regsiter 0x3B 

  Wire.endTransmission(false);     

  Wire.requestFrom(MPU_addr,14,true);  //Read 14 Registers 

  

  axis_X=Wire.read()<<8|Wire.read();                //Reads the MPU6050 X,Y,Z AXIS Value

  axis_Y=Wire.read()<<8|Wire.read();

  axis_Z=Wire.read()<<8|Wire.read();

  

  int xAng = map(axis_X,minVal,maxVal,-90,90);     // Maps axis values in terms of -90 to +90  

  int yAng = map(axis_Y,minVal,maxVal,-90,90);

  int zAng = map(axis_Z,minVal,maxVal,-90,90);

       

  x= RAD_TO_DEG * (atan2(-yAng, -zAng)+PI);       //Formula to convert into degree

  y= RAD_TO_DEG * (atan2(-xAng, -zAng)+PI);

  z= RAD_TO_DEG * (atan2(-yAng, -xAng)+PI);

  int gripper;

  int flex_sensorip = analogRead(A0);            //Reads flex sensor output

     

  if(flex_sensorip > 750)

        {

          gripper = 0;

        }

        else

        {

          gripper = 180;

        }

  

   servo_3.write(gripper);                    //Writes gripper value to 3rd servo motor

  

  if(x >=0 && x <= 60) 

  {

     int mov1 = map(x,0,60,0,90);

     Serial.print("Movement in F/R = ");

     Serial.print(mov1);

     Serial.println((char)176);

     servo_1.write(mov1);

  } 

 

  else if(x >=300 && x <= 360) 

  {

     int mov2 = map(x,360,250,0,180);

     Serial.print("Movement in Up/Down = ");

     Serial.print(mov2);

     Serial.println((char)176);

     servo_2.write(mov2);

  } 

 if(y >=0 && y <= 60) 

  {

     int mov3 = map(y,0,60,90,180);

     Serial.print("Movement in Left = ");

     Serial.print(mov3);

     Serial.println((char)176);

     servo_4.write(mov3);

  } 

 

  else if(y >=300 && y <= 360) 

  {

     int mov3 = map(y,360,300,90,0);

     Serial.print("Movement in Right = ");

     Serial.print(mov3);

     Serial.println((char)176);

     servo_4.write(mov3);

  } 

}

ربات کنترل شده با اشاره دست با استفاده از آردوینو

بیایید یک ربات با قابلیت کنترل با حرکات دست بسازیم که دوستان و خانواده شما را شگفت زده می کند – این مثل یک جادو هست! این راهنمای گام به گام به شما کمک می کند تا با استفاده از اجزای ساده ای مانند آردوینو، شتاب سنج MPU6050، جفت فرستنده و گیرنده nRF24L01 و ماژول درایور موتور L293D، یک ربات کنترل شده با اشاره دست بسازید. ما ربات را به دو قسمت تقسیم می کنیم: فرستنده و گیرنده.

بخش فرستنده شامل یک آردوینو Uno، شتاب سنج MPU6050 و ژیروسکوپ به همراه فرستنده گیرنده nRF24L01 است. از طرف دیگر، بخش گیرنده شامل یک آردوینو Uno، nRF24L01، دو موتور DC و یک درایور موتور L293D است. فرستنده به عنوان کنترل از راه دور عمل می کند و به ربات اجازه می دهد تا به اشارات پاسخ دهد و بر اساس آن حرکت کند. به طرز چشمگیری، حرکات ربات با حرکاتی که با دستان خود انجام می دهید کنترل می شود. این پروژه ترکیبی از فناوری حسگر، ارتباطات بی سیم و کنترل موتور برای ایجاد یک تجربه جذاب و تعاملی است. مراحل این آموزش را دنبال کنید تا این ربات جادویی که با اشاره کنترل می شود را زنده کنید و تأثیری ماندگار بر روی اطرافیان خود بگذارید.

ربات کنترل با اشاره چگونه کار می کند؟

این پروژه شامل دو مدار است: مدار فرستنده و مدار گیرنده. حسگر شتاب سنج MPU6050 حرکات دست را به سیگنال های الکتریکی تبدیل می کند.

آردوینو نانو این سیگنال ها را پردازش کرده و از طریق فرستنده RF ارسال می کند

در انتهای گیرنده، گیرنده RF این سیگنال ها را دریافت کرده و آنها را برای رمزگشایی به Arduino Uno ارسال می کند. پس از دریافت سیگنال ها، آردوینو Uno موتورها را از طریق درایور موتور فعال می کند و ربات را هدایت می کند تا “به جلو”، “به عقب”، “چپ” یا “راست” حرکت کند.

اگر مقدار شتاب در امتداد محور x کمتر از ۳۴۰ باشد، ربات باید به جلو حرکت کند.

اگر مقدار شتاب در امتداد محور x بیش از ۳۶۰ باشد، ربات باید به سمت عقب حرکت کند.

اگر مقدار شتاب در امتداد محور y کمتر از ۱۴۰ باشد، ربات باید به سمت چپ بچرخد.

اگر مقدار شتاب در امتداد محور y بیش از ۱۶۰ باشد، ربات باید به راست بچرخد.

اگر هیچ یک از شرایط بالا برآورده نشد، ربات باید متوقف شود.

اجزای مورد نیاز برای ساخت ربات

  1. آردینو UNO
  2. آردینو nano
  3. NRF24L01
  4. MPU6050
  5. ۲WD Acrylic Chassis kit
  6. L298N Motor Driver Module
  7. ۷٫۴V Li-ion battery/ 9V battery
  8. سیم و اتصالات

شتاب سنج و ژیروسکوپ MPU6050

ماژول حسگر MPU6050 مانند یک کامپیوتر کوچک است که می تواند حرکت را به ۶ روش مختلف حس کند: ۳ برای شتاب و ۳ برای چرخش (ژیروسکوپ). همچنین دارای سنسور دمای داخلی است. این ماژول می‌تواند با دستگاه‌های دیگر مانند میکروکنترلرها و حسگرها (مانند مغناطیس‌سنج یا سنسور فشار)، با استفاده از یک گذرگاه I2C و یک گذرگاه I2C کمکی مرتبط شود .

کار اصلی MPU6050 اندازه گیری سرعت حرکت یک چیز، جهت گیری آن و سایر موارد مرتبط با حرکت است.

با یک پردازشگر دیجیتال حرکتی همراه است، یک مینی کامپیوتر درون آن که می تواند محاسبات پیچیده را انجام دهد. این باعث می شود MPU6050 برای تجزیه و تحلیل و کنترل حرکت در برنامه های مختلف مفید باشد.

ماژول گیرنده NRF24L01

nRF24L01 یک فرستنده رادیویی فشرده است که برای باند جهانی ۲٫۴ – ۲٫۵ گیگاهرتز ISM طراحی شده است. بسته بندی شده در یک تراشه واحد، شامل یک سازنده ی فرکانس کاملاً یکپارچه، یک تقویت کننده قدرت، یک نوسان ساز کریستالی، یک دمدولاتور، مدولاتور و یک موتور پروتکل پیشرفته ShockBurst است.

شما به راحتی می توانید قدرت خروجی، کانال های فرکانس و پروتکل های آن را با استفاده از یک رابط SPI تنظیم کنید.

این ماژول فرستنده گیرنده در محدوده ولتاژ ۱٫۹ ولت تا ۳٫۶ ولت کار می کند. این دستگاه دارای حالت‌های Power Down و Standby داخلی است که استفاده از آن را کم مصرف و ساده می‌کند.

طراحی مدار ربات

مدارات این ربات به دو بخش کلی تقسیم بندی می شود :

  1. مدارات فرستنده
  2. مدارات گیرنده

مدار فرستنده

بخش فرستنده این پروژه شامل شتاب‌سنج و ژیروسکوپ MPU6050، فرستنده گیرنده nRF24L01 و آردوینو Uno است. آردوینو به دریافت اطلاعات از MPU6050 ادامه می دهد و سپس این داده ها را به فرستنده nRF ارسال می کند. سپس فرستنده RF این داده ها را به محیط اطراف پخش می کند.

مدار گیرنده ربات

بخشی از ربات کنترل‌شده با اشاره که سیگنال‌ها را دریافت می‌کند شامل Arduino Uno، فرستنده گیرنده nRF24L01، ۲ موتور DC و یک ماژول درایور موتور است. گیرنده NRF24L01 داده های ارسال شده از راه دور را ضبط می کند و آن را به آردوینو منتقل می کند. پس از آن، آردوینو بر اساس سیگنال های دریافتی، به حرکت موتورهای DC فرمان می دهد. نمودار مدار این بخش گیرنده در زیر ارائه شده است.

برنامه نویسی ربات

در این قسمت کد های برنامه نویسی ربات به همراه توضیحات آن ارائه می شود .

برنامه نویسی قسمت فرستنده ربات

کد فرستنده از شتاب سنج و ژیروسکوپ MPU6050 به همراه فرستنده گیرنده nRF24L01 برای برقراری ارتباط بی سیم با گیرنده استفاده می کند.

سنسور MPU6050 داده‌های حرکتی را می‌گیرد و سپس با استفاده از ماژول nRF24L01 نقشه‌برداری و به گیرنده منتقل می‌شود.

داده های ارسالی نشان دهنده حرکات دست در امتداد محورهای X و Y است که امکان کنترل حرکت ربات را فراهم می کند.

اطمینان حاصل کنید که کتابخانه های لازم را نصب کرده اید

SPI.h library — RF24.h library — Wire.h library — I2Cdev.h library — MPU6050.h library

#include <SPI.h>        //SPI library for communicate with the nRF24L01+
#include "RF24.h"       //The main library of the nRF24L01+
#include "Wire.h"       //For communicate
#include "I2Cdev.h"     //For communicate with MPU6050
#include "MPU6050.h"    //The main library of the MPU6050

در اینجا، کتابخانه های لازم فراخوان شده است. SPI برای ارتباط با ماژول nRF24L01، RF24 کتابخانه اصلی برای nRF24L01، Wire برای ارتباطات عمومی و I2Cdev و MPU6050 برای رابط با شتاب سنج و ژیروسکوپ MPU6050 استفاده می شود.

//Define the object to access and cotrol the Gyro and Accelerometer (We don't use the Gyro data)
MPU6050 mpu;
int16_t ax, ay, az;
int16_t gx, gy, gz;

در این قسمت از برنامه ، نمونه‌ای از کلاس MPU6050 ایجاد می‌شود و متغیرهایی برای ذخیره خوانش‌های شتاب‌سنج و ژیروسکوپ (ax، ay، az، gx، gy، gz) اعلام می‌شوند.

//Define packet for the direction (X axis and Y axis)
int data[2];
 
//Define object from RF24 library - 8 and 9 are a digital pin numbers to which signals CE and CSN are connected.
RF24 radio(8,9);

یک داده آرایه با اندازه ۲ برای ذخیره داده های محور X و Y معرفی می شود . یک تابع RF24 به نام رادیو با پین های دیجیتال ۸ و ۹ به عنوان پایه های CE و CSN ایجاد می شود.

//Create a pipe addresses for the communicate                                    
const uint64_t pipe = 0xE8E8F0F0E1LL;

یک آدرس منحصر به فرد برای ارتباط بین فرستنده و گیرنده تعریف شده است.

void setup(void)
{
  Serial.begin(9600);
  Wire.begin();
  mpu.initialize();              //Initialize the MPU object
  radio.begin();                 //Start the nRF24 communicate    
  radio.openWritingPipe(pipe);   //Sets the address of the receiver to which the program will send data.
}

تابع setup ارتباط سریال، کتابخانه سیم بندی ، MPU6050 و ارتباط nRF24 را مقداردهی اولیه می کند. و آدرس ارتباطی فرستنده را تنظیم می کند.

void loop(void){
 
  //With this function, the acceleration and gyro values of the axes are taken.
  //If you want to control the car axis differently, you can change the axis name in the map command.
  mpu.getMotion6(&ax, &ay, &az, &gx, &gy, &gz);
 
  //In two-way control, the X axis (data [0]) of the MPU6050 allows the robot to move forward and backward.
  //Y axis (data [1]) allows the robot to right and left turn.
  data[0] = map(ax, -17000, 17000, 300, 400 ); //Send X axis data
  data[1] = map(ay, -17000, 17000, 100, 200);  //Send Y axis data
  radio.write(data, sizeof(data));
  Serial.print("X axix data = ");
  Serial.println(data[0]);
  Serial.print("Y axix data = ");
  Serial.println(data[1]);
}

در حلقه اصلی، تابع getMotion6 مقادیر شتاب سنج و ژیروسکوپ را می خواند. داده های محور X و Y به یک محدوده خاص نگاشت شده و در آرایه داده ذخیره می شوند.

سپس این داده ها با استفاده از تابع radio.write ارسال می شوند. داده‌های محور X و محور Y برای اشکال‌زدایی در مانیتور سریال چاپ می‌شوند.

برنامه سمت گیرنده

در سمت گیرنده، Arduino Uno با ماژول nRF24L01 داده های ارسالی را از فرستنده دریافت می کند. بسته به سیگنال های دریافتی که نشان دهنده حرکات دست هستند، آردوینو جهت دو موتور DC را با استفاده از یک ماژول درایور موتور (L293D) کنترل می کند. کد شامل منطق حرکت ربات به جلو، عقب، چپ، راست یا توقف بر اساس حرکات دست تفسیر شده است.

#include <SPI.h>      //SPI library for communicate with the nRF24L01+
#include "RF24.h"     //The main library of the nRF24L01+

این خطوط شامل کتابخانه های لازم برای ارتباط با ماژول nRF24L01 می باشد.

//Define enable pins of the Motors
const int enbA = 3;
const int enbB = 6;
 
//Define control pins of the Motors
//If the motors rotate in the opposite direction, you can change the positions of the following pin numbers
const int IN1 = 2;    //Right Motor (-)
const int IN2 = 4;    //Right Motor (+)
const int IN3 = 5;    //Left Motor (+)
const int IN4 = 7;    //Right Motor (-)
 
//Define variable for the motors speeds
//I have defined a variable for each of the two motors
//This way you can synchronize the rotation speed difference between the two motors
int RightSpd = 200;
int LeftSpd = 250;

این خطوط، پایه‌های کنترل موتور (فعال و پایه‌های ورودی) را مشخص می‌کنند و سرعت‌های اولیه را برای موتورهای راست و چپ تعیین می‌کنند.

//Define packet for the direction (X axis and Y axis)
int data[2];
 
//Define object from RF24 library - 8 and 9 are a digital pin numbers to which signals CE and CSN are connected
RF24 radio(8,9);

داده های آرایه ای با اندازه ۲ برای ذخیره داده های محور X و Y دریافت شده از فرستنده اعلام می شود. یک تابع RF24 به نام رادیو با پین های دیجیتال ۸ و ۹ به عنوان پایه های CE و CSN ایجاد می شود.

//Create a pipe addresses for the communicate
const uint64_t pipe = 0xE8E8F0F0E1LL;

یک آدرس منحصر به فرد برای ارتباط بین فرستنده و گیرنده تعریف شده است.

void setup()
{
  //Define the motor pins as OUTPUT
  pinMode(enbA, OUTPUT);
  pinMode(enbB, OUTPUT);
  pinMode(IN1, OUTPUT);
  pinMode(IN2, OUTPUT);
  pinMode(IN3, OUTPUT);
  pinMode(IN4, OUTPUT);
 
  Serial.begin(9600);
  radio.begin();                    //Start the nRF24 communicate            
  radio.openReadingPipe(1, pipe);   //Sets the address of the transmitter to which the program will receive data.
  radio.startListening();            
  }

تابع راه‌اندازی پین‌های کنترل موتور را به‌عنوان OUTPUT راه‌اندازی می‌کند، ارتباط سریال را انجام می دهد ، ماژول nRF24 را راه‌اندازی می‌کند، آدرس ارتباطی گیرنده را تنظیم می‌کند و آن را برای پذیرش داده‌های ورودی آماده می‌کند.

void loop(){
  if (radio.available()){
    radio.read(data, sizeof(data));
 
    if(data[0] < 340){
      //forward            
      analogWrite(enbA, RightSpd);
      analogWrite(enbB, LeftSpd);
      digitalWrite(IN1, HIGH);
      digitalWrite(IN2, LOW);
      digitalWrite(IN3, HIGH);
      digitalWrite(IN4, LOW);
      Serial.println("forward");
    }
   
    if(data[0] > 360){
      //backward              
      analogWrite(enbA, RightSpd);
      analogWrite(enbB, LeftSpd);
      digitalWrite(IN1, LOW);
      digitalWrite(IN2, HIGH);
      digitalWrite(IN3, LOW);
      digitalWrite(IN4, HIGH);
      Serial.println("backward");
    }
     
    if(data[1] > 160){
       //right
      analogWrite(enbA, RightSpd);
      analogWrite(enbB, LeftSpd);
      digitalWrite(IN1, LOW);
      digitalWrite(IN2, HIGH);
      digitalWrite(IN3, HIGH);
      digitalWrite(IN4, LOW);
      Serial.println("right");
    }
 
    if(data[1] < 140){
     //left
      analogWrite(enbA, RightSpd);
      analogWrite(enbB, LeftSpd);
      digitalWrite(IN1, HIGH);
      digitalWrite(IN2, LOW);
      digitalWrite(IN3, LOW);
      digitalWrite(IN4, HIGH);
      Serial.println("left");
    }
 
    if(data[0] > 340 && data[0] < 360 && data[1] > 140 && data[1] < 160){
      //stop car
      analogWrite(enbA, 0);
      analogWrite(enbB, 0);
      digitalWrite(IN1, LOW);
      digitalWrite(IN2, LOW);
      digitalWrite(IN3, LOW);
      digitalWrite(IN4, LOW);
      Serial.println("stop");
    }
  }
}

در حلقه اصلی، برنامه بررسی می کند که آیا داده های موجود از فرستنده وجود دارد یا خیر. اگر داده در دسترس باشد، مقادیر محور X و Y را از فرستنده می خواند. بسته به مقادیر دریافتی، منطق کنترل موتور خاص برای حرکت روبات به جلو، عقب، راست، چپ یا توقف اجرا می‌شود. وضعیت حرکت برای اشکال زدایی در مانیتور سریال چاپ می شود.

توجه: در کد گیرنده، منطق کنترل موتور به طور کامل اجرا نشده است و ممکن است لازم باشد آن را بر اساس تنظیمات و تنظیمات درایور موتور خاص خود تغییر دهید. همچنین، کالیبراسیون MPU6050 ممکن است برای اطمینان از خوانش دقیق ضروری باشد. اطمینان حاصل کنید که اتصالات سیم کشی با تخصیص پین در کد مطابقت دارند.

تست ربات

هنگامی که اجزای سخت افزاری را مونتاژ کردید، فرستنده و گیرنده آردوینو را به لپ تاپ خود متصل کرده و کد ارائه شده را آپلود کنید. پس از آن، شتاب‌سنج MPU6050 را برای تأثیرگذاری بر حرکات ماشین ربات تنظیم کنید.

کد

//Arduino Code for gesture controlled robot

#include <SPI.h>        //SPI library for communicate with the nRF24L01+

#include "RF24.h"       //The main library of the nRF24L01+

#include "Wire.h"       //For communicate

#include "I2Cdev.h"     //For communicate with MPU6050

#include "MPU6050.h"    //The main library of the MPU6050


//Define the object to access and cotrol the Gyro and Accelerometer (We don't use the Gyro data)

MPU6050 mpu;

int16_t ax, ay, az;

int16_t gx, gy, gz;

//Define packet for the direction (X axis and Y axis)

int data[2];

//Define object from RF24 library - 8 and 9 are a digital pin numbers to which signals CE and CSN are connected.

RF24 radio(8,9);

//Create a pipe addresses for the communicate                                    

const uint64_t pipe = 0xE8E8F0F0E1LL;

void setup(void){

  Serial.begin(9600);

  Wire.begin();

  mpu.initialize();              //Initialize the MPU object

  radio.begin();                 //Start the nRF24 communicate     

  radio.openWritingPipe(pipe);   //Sets the address of the receiver to which the program will send data.

}

void loop(void){

  

  //With this function, the acceleration and gyro values of the axes are taken. 

  //If you want to control the car axis differently, you can change the axis name in the map command.

  mpu.getMotion6(&ax, &ay, &az, &gx, &gy, &gz);

  //In two-way control, the X axis (data [0]) of the MPU6050 allows the robot to move forward and backward. 

  //Y axis (data [1]) allows the robot to right and left turn.

  data[0] = map(ax, -17000, 17000, 300, 400 ); //Send X axis data

  data[1] = map(ay, -17000, 17000, 100, 200);  //Send Y axis data

  radio.write(data, sizeof(data));

  Serial.print("X axix data = ");

  Serial.println(data[0]);

  Serial.print("Y axix data = ");

  Serial.println(data[1]);

}