کنترل سروو موتور توسط پتانسیومتر و ماژول فرستنده گیرنده رادیویی NRF24L01

الکترونیک و رباتیک -> برد های توسعه 3450 3 کاربر آکادمی پارتینه

در حالی محبوبت که اینترنت اشیاء (IoT) در صنعت، تعامل ماشین‌ها با انسان و ... در حال افزایش روزافزون است، به دنبال آن نیاز به استفاده از تکنولوژی‌های بی‌سیم نیز پر رنگ‌تر می‌شود. طراحان از بسیاری از سیستم‌های ارتباطی بی‌سیم مانند بلوتوث، ماژول‌های وای‌فای دارای چیپESP43 ، زیگبی، ماژول‌هایRF  ، لورا و غیره استفاده می‌کنند. انتخاب نوع شبکه ارتباطی بستگی به قابلیت‌ها و کاربردهایی دارد که کاربر از آن انتظار دارد. در میان تمامی این سیستم‌های ارتباطی یک شبکه ارتباطی بی‌سیم محبوب، شبکه محلی nRF24L01 است. این ماژول‌ها در پهنای باند 2.4 گیگاهرتز ( باند ISM ) با سرعت انتقال داده از 250Kbps تا 2Mbps که مقداری استاندارد در بسیاری از کشورها بوده و قابل استفاده درکاربردهای صنعتی و پزشکی است، عمل می‌کنند. همچنین ادعا می‌شود که در صورت استفاده از آنتن مناسب، این ماژول ها قابلیت ارتباط تا فاصله‌ی حداکثر 100 متر را دارند. در این قسمت اول این آموزش ابتدا با ماژول های nRF24l01 و نحوه ارتباط آن با یک پلتفرم مانند آردوینو آشنا شده و در قسمت دوم توسط این ماژول و با استفاده از پتانسیومتر موقعیت یک سروو موتور را کنترل می‌کنیم.

ماژول فرستنده گیرنده رادیویی NRF24L01 را بیشتر بشناسیم.

ماژول‌های NRF24L01 ماژول‌های فرستنده گیرنده (Transceiver) هستند که می توانند داده‌ها را بطور همزمان ارسال یا دریافت کنند. پروتکل ارتباطی این ماژول با میکروکنترلر SPI است. پین‌های خروجی یک ماژول استاندارد NRF24L01 در تصویر زیر نشان داده شده است.

ولتاژ کاری این ماژول از 1.9 ولت تا 3.6 ولت است (به طور معمول 3.3 ولت). سایر پایه‌­های ارتباطی ماژول قابلیت تحمل 5 ولت را داشته و مستقیما به میکروکنترلرهای 5 ولتی متصل می‌شوند. جریان مصرفی این ماژول در حالت آماده کار نزدیک به صفر بوده و در حالت دریافت سیگنال با بیشترین سرعت انتقال داده (2Mbps) حدود 13میلی‌آمپر جریان می‌کشد. این میزان جریان مصرفی بسیار کم،  امکان استفاده از این ماژول در پروژه‌های قابل حمل که باید انرژی از طریق باتری تامین می‌شود را فراهم می‌کند. مزیت دیگر استفاده از این ماژول‌ها این است که هر ماژول NRF می‌تواند به 6 ماژول دیگر متصل شده و یک شبکه با توپولوژی ستاره یا مش تشکیل دهد.

در این آموزش نحوه‌ی ارتباط NRF24L01 با آردوینو و کنترل یک سروو موتور مورد بررسی قرار خواهد گرفت. برای سادگی از یک ماژول به عنوان فرستنده و از ماژول دیگر به عنوان گیرنده استفاده شده و ارتباط با ماژول دو طرفه نیست. به این معنا که هر ماژول قابلیت ارسال و دریافت را همزمان ندارد. در شکل زیر دیاگرام مداری ماژول با آردوینو نشان داده شده است. برای تنوع از آردوینو UNO درسمت گیرنده و آردوینو NANO در سمت فرستنده استفاده شده است.

مواد اولیه :
# عنوان تعداد لینک
0 پتانسیومتر ۱۰ کیلو اهم 1 لینک خرید
1 خرید برد آردوینو 1 لینک خرید
2 ماژول‌ NRF24L01 1 لینک خرید

مرحله 1 : اتصال ماژول NRF24L01 به آردوینو UNO (سمت گیرنده)

همانطور که در پیش‌تر اشاره شد NRF24L01 با کمک پروتکل SPI ارتباط برقرار می‌کند. در آردوینو NANO و UNO از پین های 11 ، 12 و 13 برای ارتباطات SPI استفاده می شود. از این رو به ترتیب پین های MOSI ، MISO و SCK را از NRF به پین های 11 ، 12 و 13 متصل می‌شوند. پین‌های CE و CS قابل تنظیم توسط کاربر هستند که در اینجا از پین 7 و 8 برای اتصال آن‌ها استفاده شده است. سروو موتور به پین 7 آردوینو متصل شده است و از طریق 5 ولت آردوینو نیز تغذیه می‌شود.

 

مرحله 2 : اتصال ماژول NRF24L01 به آردوینو NANO (سمت فرستنده)

شماتیک مدار فرستنده نیز مانند گیرنده است. به علاوه یک پتانسیومتر نیز به منظور کنترل سروو موتور در سمت گیرنده به پین A7 آردوینو NANO متصل شده است. هر دو برد از طریق درگاه USB تغذیه می‌شوند.

مرحله 3 : کدنویسی و تنظیمات نرم‌افزاری

راه‌اندازی این ماژول توسط آردوینو با وجود کتابخانه‌ی RF24 بسیار آسان است. فایل زیپ این کتابخانه را از طریق لینک‌ قرار داد‌ه‌شده در انتهای آموزش دانلود کرده و از طریق مسیر زیر به کتابخانه‌ی آردوینو IDE اضافه کنید.

 Sketch -> Include Library -> Add .ZIP

پس از اضافه کردن کتابخانه، باید دو برنامه یکی برای طرف فرستنده و دیگری برای سمت گیرنده تنظیم شوند. اما همانطور که قبلاً اشاره شد هر ماژول می تواند هم به عنوان فرستنده و هم گیرنده کار عمل کند. برنامه را با ضافه کردن کتابخانه‌های ضروری شروع می‌کنیم. از آنجا که NRF از پروتکل SPI استفاده می‌کند، کتابخانه‌ی SPI و همچنین کتابخانه‌ی NRF را فراخوانی می‌کنیم. از کتابخانه سروو موتور نیز برای کنترل آن استفاده می‌شود.

#include <SPI.h> 

#include "RF24.h"

#include <Servo.h>

در این قسمت پین‌های اتصال پایه‌های ()CE و ()CS را مشخص می‌کنیم. مطابق با اتصالات ما به پایه‌های 7 و 8 متصل هستند.

RF24 myRadio (7, 8);

در این برنامه ازمتغیر msg برای ارسال و دریافت داده ها از ماژول RF استفاده می شود. هر ماژول RF یک آدرس منحصر به فرد دارد که با استفاده از آن می تواند داده ها را به دستگاه مربوطه ارسال کند. به دلیل اینکه در این برنامه از تنها از دو ماژول استفاده شده است آدرس را هم در سمت گیرنده و هم در سمت فرستنده صفر می‌کنیم. اگربخواهید ازچندین ماژول استفاده کنید می ‌توانید 6 رقم منحصر به فرد را به عنوان شناسه در نظر بگیرید.

byte addresses[][6] = {"0"};

در مرحله بعدی در داخل تابع setup void ، ماژول RF راه اندازی اولیه کرده و به پهنای باند عاری از نویز 115 و حداقل سرعت 250Kbps را برای آن تنظیم می‌کنیم.

void setup()
{
  Serial.begin(9600);
  myRadio.begin();
  myRadio.setChannel(115);  //115 band above WIFI signals
  myRadio.setPALevel(RF24_PA_MIN); //MIN power low rage
  myRadio.setDataRate( RF24_250KBPS ) ;  //Minimum speed
  myservo.attach(6);
  Serial.print("Setup Initialized");
  delay(500);
}

 تابع WritData داده های ارسال شده به ماژول را می نویسد. همانطور که قبلاً گفته شد NRF می‌تواند در آن واحد با چندین ماژول دیگر ارتباط داشته باشد. بنابراین برای مشخص شدن هر ارتباط از یک آدرس استفاده می‌شود. در اینجا از 0xF0F0F0F066 به عنوان آدرس برای نوشتن داده‌ها استفاده شده است. در سمت گیرنده نیز از همان آدرس تابع  ReadData استفاده کنیم تا داده هایی که نوشته شده است را دریافت کنیم.

void WriteData()
{
  myRadio.stopListening(); //Stop Receiving and start transminitng
  myRadio.openWritingPipe(0xF0F0F0F066);//Sends data on this 40-bit address
  myRadio.write(&data, sizeof(data));
  delay(300);
}

در تابع  ReadData  داده‌ها خوانده شده و در داخل یک متغیر قرار می‌گیرند. از عدد  0xF0F0F0F0AA به عنوان آدرسی برای خواندن داده‌ها نیز استفاده شده است. این بدان معنی است که اطلاعات فرستاده شده از ماژول دیگر در این آدرس نوشته شده و قرار است که این اطلاعات خوانده شوند.

void ReadData()
{
myRadio.openReadingPipe(1, 0xF0F0F0F0AA); //Which pipe to read, 40 bit Address
  myRadio.startListening(); //Stop Transminting and start Reveicing
  if ( myRadio.available())
  {
    while (myRadio.available())
    {
      myRadio.read( &data, sizeof(data) );
    }
    Serial.println(data.text);
  }
}

همچنین سیگنال دریافت شده از پتانسیومتر به بازهی 0 تا 180 نگاشت کرده و برای کنترل میزان چرخش سروو موتور به ماژول گیرنده فرستاده می‌شود.

/*
Partineh
Arduino Tutorial Series
Website: www.Partineh.com
*/
Code for Transmitter Part:
/*Transmit POT value through NRF24L01 using Arduino
 * 
 * Pin Conections
 *  CE - 7
    MISO - 12
    MOSI - 11
    SCK - 13
    CS - 8
    POT-A7
*/
#include <SPI.h>  
#include "RF24.h"
RF24 myRadio (7, 8);
struct package
{
  int msg = 0;
};
byte addresses[][6] = {"0"};
typedef struct package Package;
Package data;
void setup()
{
  Serial.begin(9600);
  myRadio.begin();  
  myRadio.setChannel(115);  //115 band above WIFI signals
  myRadio.setPALevel(RF24_PA_MIN); //MIN power low rage
  myRadio.setDataRate( RF24_250KBPS ) ;  //Minimum speed
  delay(500);
  Serial.print("Setup Initialized");
}
void loop()
{
  int Read_ADC = analogRead(A7);
  char servo_value = map (Read_ADC, 0, 1024, 0,180);
    if (servo_value>1)
    data.msg = servo_value;
    WriteData();
    delay(50);
// ReadData(); 
 //delay(200);
}
void WriteData()
{
  myRadio.stopListening();  //Stop Receiving and start transminitng 
  myRadio.openWritingPipe( 0xF0F0F0F0AA); //Sends data on this 40-bit address
  myRadio.write(&data, sizeof(data)); 
Serial.print("
Sent:");
  Serial.println(data.msg);
  delay(300);
}
void ReadData()
{ 
myRadio.openReadingPipe(1, 0xF0F0F0F066); // Which pipe to read, 40 bit Address
  myRadio.startListening(); //Stop Transminting and start Reveicing 
  if ( myRadio.available()) 
  {
    while (myRadio.available())
    {
      myRadio.read( &data, sizeof(data) );
    }
    Serial.print("
Received:");
    Serial.println(data.msg);
  }
}
 
Code for Receiver Part:
 
/*CE - 7
MISO - 12
MOSI - 11
SCK - 13
CS - 8
Recently tested with nano
*/
#include <SPI.h>  
#include "RF24.h" 
#include <Servo.h>
Servo myservo;
RF24 myRadio (7, 8); 
struct package
{
  int msg;
};
typedef struct package Package;
Package data;
byte addresses[][6] = {"0"}; 
void setup() 
{
  Serial.begin(9600);
  myRadio.begin(); 
  myRadio.setChannel(115);  //115 band above WIFI signals
  myRadio.setPALevel(RF24_PA_MIN); //MIN power low rage
  myRadio.setDataRate( RF24_250KBPS ) ;  //Minimum speed
  myservo.attach(6);
  
  Serial.print("Setup Initialized");
  delay(500);
}
int Servo_value;
int Pev_servo_value;
void loop()  
{
  ReadData();
  delay(50);
  
  Pev_servo_value = Servo_value;
  Servo_value = data.msg; 
  while (Pev_servo_value< Servo_value)
  {
  myservo.write(Pev_servo_value);
  Pev_servo_value++;
  delay(2);
  }
  while (Pev_servo_value> Servo_value)
  {
  myservo.write(Pev_servo_value);
  Pev_servo_value--;
  delay(2);
  }
   //data.msg = "nothing to send";
   //WriteData();
  // delay(50);
}
void ReadData()
{
  myRadio.openReadingPipe(1, 0xF0F0F0F0AA); //Which pipe to read, 40 bit Address
  myRadio.startListening(); //Stop Transminting and start Reveicing 
  if ( myRadio.available()) 
  {
    while (myRadio.available())
    {
      myRadio.read( &data, sizeof(data) );
    }
    Serial.print("
Received:");
    Serial.println(data.msg);
  }
}
void WriteData()
{
  myRadio.stopListening(); //Stop Receiving and start transminitng 
  myRadio.openWritingPipe(0xF0F0F0F066);//Sends data on this 40-bit address
  myRadio.write(&data, sizeof(data)); 
  Serial.print("
Sent:");
  Serial.println(data.msg);
  delay(300);
}
فایل های ضمیمه