جلسه بیست و ششم : راه اندازی NRF24L01 با آردوینو

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

بنابراین ما باید دنبال راه حلی بگردیم که بتونیم داده هامون رو به صورت بی سیم ارسال کنیم .
به روش های مختلفی میشه این کار رو انجام داد که به مرور زمان دونه دونه باهاشون آشنا میشیم .
این جلسه این ارتباط بی سیم رو با NRF24L01 انجام میدیم.
توضیح این که NRF بر چه اساسی کار می کنه و چرا این طوریه و چرا اون طوریه خودش در حد یک کتابه . اینجا من فقط یه سری مقدمات میگم که دونستنش به درد همه می خوره.

وقتی اسم ارتباط بی سیم میاد اولین سوالی که پیش میاد اینه که روی چه فرکانسی این ارسال و دریافت داره انجام میشه ؟ در جواب باید گفت که NRF ها روی فرکانس 2.4 گیگا هرتز داده ارسال می کنن. این باند فرکانس باند فرکانسی خیلی شلوغیه . توی این آموزش در مورد این موضوع یه مقدار بیشتر توضیح داده . اما یه جواب مهم برای این سوال که چرا با وجود شلوغی این باند باز هم ازش استفاده میشه اینه که که آنتن مورد نیاز برای این فرکانس نیازی نیست خیلی بزرگ باشه و همین مزیت بزرگ باعث پرکاربرد بودنش میشه.

دومین سوالی که پیش میاد اینه که تا چند متر یا حتی کیلومتر میتونه ارسال داده دقیق و بدون خطا انجام بشه. اصن یه چیزی وقتی NRF رو تا سایتا سرچ می کنیم مدل های مختلف میاره . یکیش بردش 100 متره یکیش بردش 1000 متره . یکیش آنتن داره یکیش آنتن نداره . داستان چیه ؟
جواب این سوال یه کم به توضیح بیشتری احتیاج داره . بله ماژولی که از چیپ NRF24L01 میسازن بردهای مختلفی داره . نقطه مشترک همه این ماژول ها اینه که چیپ اصلیشون NRF24L01 هست. این ماژول رو ببینید :
tc24l01plus-500x500
توی طراحی این ماژول فقط و فقط تنها از چیپ خود NRF24L01 استفاده شده . آنتش هم به صورت PCB هست . نه آمپلی فایری داره نه آنتن خارجی ای . همین دو تا موضوع باعث میشه که برد این ماژول کم باشه . برد اسمیش طبق دیتاشیت ها 100 متره (که در عمل کمتر از اینه )
حالا این ماژول رو ببینید:
npa4
این ماژول علاوه بر خود چیپ NRF24L01 از دو تا مدار دیگه به عنوان آمپلی فایر قدرت و آمپلی فایر کاهش نویز استفاده کرده . همچنین اومده از آنتن خارجی هم استفاده کرده که ترکیب اون آمپلی فایر ها و این آنتن بردی حدود 1000 متر ( برد اسمی ) رو به ماژول میده . اگه به اسم ثبت شده تو سایت مگاه کنید میبیند که کنار اسم این ماژول علاوه بر NRF24L01 دو تا اسم دیگه هم می بینید : NRF24L01+PA+LNA . منظور از این PA و LNA همون دو تا مداری هست که بالا گفتم. PA یعنی Power Amplifier و LNA یعنی Low Noise Amplifier . بنابراین بسته به این که قصد دارید دادتون رو تا چه فاصله ای ارسال کنید باید ماژول مناسب با کارتون رو خریداری کنید. و این رو هم بدونید که وقتی آمپلی فایر و آنتن خارجی به طراحی ماژول اضافه بشه قیمتش هم میره بالاتر !!!

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

توضیحات کامل و ریز به ریز در مورد NRF رو میتونید از اینجا بخونید.

***************************************************************************
خب حالا میریم سراغ اصل قضیه یعنی راه اندازی. هدفی که تو این آموزش داریم این که بتونیم با استفاده از کامند دادن تو کنسول آردوینو فرستنده ، دو تا LED رو تو گیرنده خاموش روشن کنیم.
اگه بخوایم مسیر داده رو تفسیر کنیم به این صورت میشه :
یه داده رو از طریق کنسول آردوینو فرستنده ارسال می کنیم. این داده توسط آردوینو دریافت میشه و مورد پرادازش قرار می گیره . وقتی پردازشش تموم شد با NRF ای که به فرستنده وصله ارسال میشه . اون طرف NRF ای که سمت گیرنده هست ( و شاید حتی 1 کیلومتر با فرستنده فاصله داشته باشه ) این دیتا رو دریافت می کنه و پردازش می کنه. نتیجه حاصل از پردازشش میشه وصعیت روشنایی LED ها ی متصل به آردوینو گیرنده.

***************************************************************************
خب حالا باید سیم بندی اتصال NRF به آردوینو رو معین کنیم . یه نکته خیلی مهمی که در مورد همه NRF ها وجود داره اینه که سیم بندی تمام مدل هاش به همین شکله . چه آمپلی فایر دار باشه چه بدون آمپلی باشه .
برای این پروژه قطعات زیر رو باید داشته باشید:
1. دو تا آردوینو یکی به عنوان فرستنده یکی به عنوان گیرنده
2. دو تا ماژول NRF
3. دو تا LED
اسم و ترتیب پینهای NRF که اصطلاحا بهش میگن pin map به این صورته :
27733959955_2281f9e3b9_o
اتصال خود NRFها سمت فرستنده و گیرنده به آردوینو دقیقا مثل همه :
9440611443471082653
خیلی خیلی خیلی دقت کنید که ولتاژ کاری ماژول های NRF پنج ولت نیست بلکه 3.3 ولته . بنابراین پایه VCC مربوط به NRF به پایه 3.3 آردوینو وصل میشه .

سمت فرستنده با اتصال NRF به آردوینو کار تموم میشه اما سمت گیرنده علاوه بر متصل کردن NRF باید دو تا LED هم به آردوینو وصل کنیم که من به پین های7 و 6 وصل کردم و تو کد نویسی هم به این دو تا پین مقدار میدم ( وصل کردن دو تا LED درگیری خاصی نداره خدایی )

شروع جلسه گفتم قصد دارم در مورد پروتکل SPI هم صحبت کنم . یه نگاه به عکسی که گذاشتم بکنید. اسم پینهای NRF رو با هم مرور کنیم: SCK – MOSI – MISO – CSN – CE – IRQ . به نظر اسم های عجیب و غریبی میاد اما از این به بعد که راه اندازی سنسورها و سایر قطعات رو شروع می کنیم کاملا این بیگانگیتون با این اسم ها برطرف میشه . سوالی که پیش میاد اینه که کدوم یکی از این پینها مربوط به پروتکل SPI هست . اگه یادتون باشه وقتی داشتم در مورد پروتکل ارتباطی سریال حرف میزدم گفتم وقتی پین TX و RX رو روی یک ماژول دیدید یقینا پروتکل ارتباطی اون ماژول سریاله . در مورد SPI اگر پینهای SCK ، MOSI ،MISO و CS ( که روی ماژول های NRF نوشته میشه CSN ) رو روی یه ماژول دیدید پروتکل ارتباطی اون ماژول SPI خواهد بود . دقت کنید هر 4 تا باید وجود داشته باشن . اصن به همین خاطره که به SPI میگن پروتکل ارتباطی 4 سیمه . سول دیگه ای که به وجود میاد اینه که این پینهای پروتکل SPI میتونن به هر پین دلخواهی از آردوینو وصل بشن . جواب منفیه !
هر مدل آردوینو (UNO , مگا ، DUE ) پینهای خاصیشون رو برای پروتکل SPI در نظر گرفتن . مثلا آردوینو UNO پین های 13 و 12 و 11 اش رو تخصیص داده ( همونطور که تو سیم بندی بالا می بینید ) و برد آردوینو مگا پینهای 53 و 52 و 51 اش رو اختصاص داده . جدول کامل این تخصیص ها به صورت زیره :
2016-10-25_11-12-48
اگه یه کم دقیق بشید متوجه میشید که توی معرفی پینهای تخصیص داده شده SPI فقط اسم 3 تا پین 13 و 12 و 11 رو آوردم در صورتی که SPI چهار سیمه . پس پین چهارم چی؟ پین چهارم که همون CS هست یار آزاده و میتونه هر پین دیجیتال دلخواهی باشه . این که چرا اون سه تا باید فیسک باشن اما این پین آزاده نیاز به توضیحاتی در مورد ماهیت پروتکل SPI داره . در مورد ارتباط SPI میتونید این آموزش رو مطالعه کنید.

دو تا پین باقی مونده دیگه که CE و IRQ هستن . تعریف های این دو پین رو میتونید از این لینک پیدا کنید. پین CE هم مثل CSN میتونه به هر پین دیجیتال دلخواهی وصل بشه . پین IRQ بر مبنای اینتراپت کار می کنه و تو خیلی از آموزش ها دیده میشه که اصلا وصلش نمی کنن . شما هم میتونید وصلش نکنید ( هیچ مشکلی پیش نمیاد )

***************************************************************************
خب حالا باید بریم سراغ کد نویسی .
اول کد سمت فرستنده رو بررسی می کنیم بعد میریم سراغ گیرنده .
کد فرستنده ( از اونجایی که کد زیاده قسمت به قسمت تصاویرش رو میزارم ):
2016-10-24_14-18-07
قسمت 1 : این بخش کتابخونه RH_NRF24 صدا زده میشه و یک شیء به نام nrf24 از آبجکت RH_NRF24 ساخته میشه ( این شیء و کلاس یه سری قصه های برنامه نویسی دارن ) دقت کنید شیء ای که ساخته شده دو تا آرگومان داره . آرگومان اول شماره پین CE و آرگومان دوم شماره پین CSN هست. این دو تا پین طبق صحبت های قبلی میتونن هر پین دیجیتال دلخواهی باشن .

قسمت 2 و 3 و4: این قسمت ها کانفیگ های مورد نیاز هستن . کانفیگ هایی مثل ارتباط سریال بین آردوینو و کامپیوتر که بادریت روی 9600 تنظیم شده یا کانفیگ پین هایی که برای ارتباط SPI استفاده شده، کانفیگ شماره کانالی که داده داره توش ارسال میشه ، کانفیگ سرعت انتقال داده و کانفیگ قدرت ارسال فرستنده . یه نکته خیلی مهم اینه که اگر سیم بندیتون مشکل داشته باشه یا خود ماژول NRF به هر دلیلی نتونه کانال و سرعت و قدرتش با کدنویسی انجام شده تو کتابخونه تنظیم بشه یکی از ارورهای init failed ، setChannel failed و setRF failed روی کنسول نمایش داده میشه .

اگر کدتون از این قسمت ها رد بشه یعنی هم سیم بندیتون درسته هم ماژول NRF تون سالمه .
و اما تابع Loop :
2016-10-24_14-39-39
قسمت 1 :با دستور() Serial.available داریم از آردوینو می پرسیم آیا تو بافر ارتباط سریالت چیزی واسه خوندن هست یا نه . به زبون ساده داریم ازش سوال می کنیم آیا تو کنسول سریال آردوینو چیزی تایپ شده یا نه . اگر چیزی تایپ شده باشه که وارد پروسه پردازش اون داده میشه در غیر این صورت انقدر منتظر می مونه تا یه داده از طرف کنسول براش ارسال بشه .

قسمت 2 : این جا یک بایت داده توسط دستور Serial.read خونده میشه و تو متغیر c ریخته میشه . حالا باید روی این داده پردازش انجام بشه .

قسمت 3 : اگر داده دریافتی کاراکتر 1 باشه توی کنسول پیغام Sending to nrf24_server چاپ میشه و با دستور nrf24.send عدد 1 ارسال میشه . دقت کنید عدد 1 توی یه متغیر به اسم data ریخته شده بعد داده این متغیر با صدا کردن دستور nrf24.send ارسال میشه . دستور nrf24.send دو تا آرگومان ورودی داره . آرگومان اولش اون داده ای هست که باید ارسال بشه و متغیر دوم سایز داده ارسالی هست که با دستور sizeof این اندازه محاسبه میشه. برای درک بهتر سیستم پست رو در نظر بگیرید . تو سیستم پست وقتی قراره یه بسته ارسال شه دو تا پارامتر مهم وجود داره یکی اسم یکی وزن . اسم که خب تکلیفش معلومه اسم رو می نویسن . اما برای به دست آوردن وزن بسته از ترازو استفاده میکنن. حالا تو کد نویسی ما کار ترازو رو دستور sizeof انجام میده ( راحت و آسوده ! ) . بعد از اون هم با دستور nrf24.waitPacketSent منتظر می مونیم تا داده کامل و بدون مشکل ارسال بشه. این از مهم ترین قابلیت های NRF هست که میتونه بفهمه داده درست و کامل ارسال شده یا نه . به این موضوع دقت کنید که من تو کدم دارم کامند 1 رو برای NRF دوم ارسال می کنم . ممکنه شما دوست داشته باشید مثلا کامند LED1 رو برای NRF دوم ارسال کنید . هیچ مشکلی نداره . کافیه اونجایی که داره متغیر دیتا رو تعریف می کنه به جای 1 توش بنویسید LED1 یعنی این شکلی : “uint8_t data[] = “LED1

قسمت 4 : دقیقا مثل قسمت 3 هست با این تفاوت که میگه از کنسول عدد 2 اومده بود NRF هم 2 رو ارسال کنه .

قسمت 5 : میگه اگر داده دریافتی از کنسول نه 1 بود نه 2 تو کنسول چاپ کن unknown character

و اما کدسمت گیرنده :
2016-10-25_10-19-05

از قسمت 1 تا قسمت 6 کاملا مشابه با کد سمت فرستنده هست.

قسمت 7 : کانفیگ پینهای 6 و7 به عنوان خروجی. این دو تا پین در واقع همون پینهایی هستن که بهشون LED وصل کردیم .
2016-10-25_10-42-25
قسمت 1 : دستور nrf24.available در واقع چک می کنه آیا داده ای داده ای توسط NRF دریافت شده یا نه . اگر دریافت شده بود میاد روی داده پردازش می کنه ، در غیر اینصورت صبر می کنه تا موقعی ای که داده بیاد .

قسمت 2 : میاد دو تا متغیر تعریف می کنه از جنس uint8_t . یکیشون متغیر buf هست و یکی len . متغیر اول که همون بافر خودمونه متغیری هست که داده دریافتی از NRF توش ریخته میشه . و len سایز متغیر بافر هست که مثل قبل اومده برای به دست آوردنش از sizeof استفاده کرده. دقت کنید که توی تعریف بافر تعداد کاراکترهاش رو RH_NRF24_MAX_MESSAGE_LEN گذاشته . این متغیر تو فایل کتابخونه مقدار دهی شده و نیازی نیست ما درگیرش بشیم ( کد و کتابخونه باهم کنار میان ).

قسمت 3 : توی این قسمت میاد چک می کنه که آیا داده دریافتی از NRF موفقیت آمیز بوده یا نه .

قسمت 4 : از اونجایی که جنس متغیر بافر از نوع uint8_t هست یه مقدار کار کردن باهاش ناخوشاینده . به خاطر همین با دستور (*char) جنس متغیر بافر رو از uint8_t تبدیل می کنیم به استرینگ .

قسمت 5 و 6 : حالا میایم داده دریافتیمون رو بررسی می کنیم . اگر 1 باشه LED شماره 7 رو روشن می کنیم . اگر 2 باشه LED شماره 6 رو روشن می کنیم.

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

کد ها رو که روی آردووینوهاتون آپلود کردید سمت فرستنده کنسول رو باز کنید و عدد 1 و بعد 2 رو بفرستید. اگر سیم بندهاتون درست باشه باید به ازای هر کامند وضعیت LED ها دچار تغییر بشه .

پایان جلسه

جلسه هشتم: آموزش Burn کردن بوت لودر آردوینو

 

سلام
تو این جلسه قصد داریم یاد بگیریم چجوری بوت لودر بردهای آردوینو رو به ساده ترین روش ممکن Burn کنیم. خب این وسط مساله اصلی اینه که بوت لودر چیه؟ برای آشنایی با بوت لودر اینجا یه دوری بزنید و بیاید.

برای Burn کردن بوت لودر به یه پروگرامر avr احتیاج داریم. این پروگرامر می تونه هر چیزی باشه. مثلا usbtiny یا stk500 یا usbasp و یا هر پروگرامر مناسب دیگه ای. ما تو این جلسه از پروگرامر ارزون usbasp استفاده می کنیم.
ATMEL_AVR_Programmer_USBisp-500x500

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

خب تا این جا فقط داشتیم پروگرامر رو مهیا می کردیم. این قسمت قراره پروگرامر رو به برد آردوینو وصل کنیم. برای این کار از پین های ICSP آردوینو استفاده می کنیم. پین هایی که میگیم ( و توی شکل زیر مشخص شده) 6 تا پین هدر مربوط به ارتباط SPI میکرو هست.
ArduinoUno_r2_front450px

برای وصل کردن پروگرامر usbasp به آردوینو از شکلهای زیر استفاده کنید:
USBasp_ISP_KANDA

ArduinoUno_R3_Pinouts

دقت کنید که پین های متناظر باید به هم وصل بشن. یعنی مثلا miso به miso، زمین (GND) به زمین، Vcc به Vcc و الییییی آخر. اما این وسط یه نکته کلیدی داریم. به پین های usbasp ردیف پایین دقت کنید. 4 تا گراند (زمین) داره. شاید تو دید اول فکر کنین همه این 4 تا گراند به هم وصلن در صورتی که اصلا اینطور نیست. از بین این 4 تا فقط دو تا گراند سمت چپ به هم وصلن و اون دوتای دیگه نه به هم وصلن نه به این دو تا. بنابراین تنها نکته کلیدی برای موفقیت اینه که همه این گراندها رو به هم  وصل کنید.
خب بخش سخت افزاری تموم شد از این جای داستان به بعد به بخش نرم افزاری می رسیم. usbasp رو بزنید به پورت USB کامپیوترتون. ازتون برای نصب درایور می خواد. این درایور. اگه بلد نیستید درایور نصب کنید برید اینجا قدم به قدم باهاش پیش برید.

بعد از نصب درایور وارد محیط آردوینو بشید. از منوی Tools وارد Board بشید. این جای داستان خیلی مهیجه. اگه قصد دارید بوت لودر مربوط به UNO رو Burn کنید نوع بردتون رو UNO بزارید. اگه قصد دارید بوت لودر مربوط به MEGA رو Burn کنید نوع بردتون رو MEGA انتخاب کنید و الی آخر.
SDSD

مرحله بعد توی همون منوی Tools وارد گزینه Programmer بشید و usbasp رو انتخاب کنید:
dfdf

و اما قدم آخر:
گزینه burn bootloader رو بزنید.
121212121212

دو تا عکس آخر مراحل burn شدن رو نشون میده:
sasasasass
daddaddad

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