ارتباط بی سیم با ماژول‌ فرستنده و گیرنده رادیویی (RF)

0
96
ارتباط بی سیم با ماژول‌ فرستنده و گیرنده رادیویی

در این مقاله قصد داریم با استفاده از ماژول‌ فرستنده و گیرنده رادیویی (RF) ارزان قیمت، یک ارتباط بی ‌سیم بین دو برد آردوینو برقرار کنیم. ماژول‌های RF با فرکانس ۴۳۳ مگاهرتز به خاطر قیمت کم و سهولت استفاده بسیار محبوب هستند. آن‌ها معمولا به‌صورت یک جفت فرستنده (FS1000A) و گیرنده (XY-MK-5V) هستند که نوع ارتباط simplex یا یک طرفه دارند. به این معنا که ارتباط آن‌ها در یک کانال و در یک جهت انجام می‌شود. سرعت انتقال در این نوع ارتباط پایین است، اما با این حال، برای کاربردهای بسیاری مفید هستند.  

ماژول فرستنده و گیرنده رادیویی 433 مگاهرتز

فرکانس کاری ماژول‌ فرستنده و گیرنده رادیویی ، ۴۳۳ مگاهرتز است، زیرا یک باند فرکانسی رایگان و در دسترس است. برای استفاده از این ماژول‌ها، کافی است تغذیه‌ی آن‌ها تأمین و سپس پایه‌ی دیتا از ماژول فرستنده به یکی از آردوینوها و پایه‌ی دیتا از ماژول گیرنده به آردوینوی دیگر متصل شود. برای برنامه‌نویسی نیازی به افزودن هیچ کتابخانه‌ای نیست و تنها از یک ارتباط سریال (UART) بین دو MCUs استفاده می‌شود. با این وجود، چندین کتابخانه وجود دارد که امکان‌های ویژه‌ای از جمله بررسی خطا، بهترین انتقال، آدرس‌دهی، مسیریابی و… را برای شما فراهم می‌کند.

آنتن ماژول‌ فرستنده و گیرنده رادیویی ۴۳۳ مگاهرتز

آنتن تأثیر زیادی بر ماژول‌های گیرنده و فرستنده رادیویی، به ویژه بر ماژول گیرنده دارد. به همین خاطر توصیه می‌شود که برای رسیدن به فرکانس ۴۳۳ مگاهرتز، ماژول را به یک کابل مسی به طول حدود ۱۷ سانتی متر متصل کنیم. آنتن‌های مارپیچ یا Helical به طول ۳٫۴ سانتی متر با قطر ۵ میلی متر نیز بسیار رواج دارند و مناسب هستند. به علاوه، موقعیت آنتن بر دریافت دیتا تأثیر می‌گذارد.

آنتن شلاقی، آنتن مارپیچ و آنتن حلقوی

در این مقاله آنتن‌های مارپیچی مورد استفاده قرار گرفته‌اند.

آنتن مارپیچ

ارتباط سریال با ماژول‌ فرستنده و گیرنده رادیویی ۴۳۳ مگاهرتز

برای این نوع ارتباط، کافی است ماژول RF را بسته به اینکه فرستنده است یا گیرنده، به پایه‌های RX یا TX آردوینو متصل کنیم. برای مثال ما از یک آردوینو که اطلاعات را از طریق فرستنده‌ی RF ارسال می‌کند و یک ماژول گیرنده که به یک مبدل USB به سریال (می‌توانید از آردوینوی دیگری به جای مبدل استفاده نمائید) متصل شده‌ است، استفاده خواهیم کرد و دیتا را از کامپیوتر مشاهده خواهیم کرد. اتصالات به صورت زیر هستند.

اتصالات فرستنده:

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

اتصالات گیرنده:

نحوه سیم‌کشی ماژول گیرنده به مبدل سریال USB

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

توصیه می‌شود برای انتقال بهتر دیتا از نرخ ارسال ۲۴۰۰ یا ۱۲۰۰ یا کمتر استفاده شود. در ادامه یک نمونه کد برای تست ماژول‌ها را مشاهده خواهید کرد.  

void setup() {
   // Inicializamos la comunicación serial a 2400 baudios
  Serial.begin(2400);

}

void loop() {
  Serial.print("Hola mundo ... ");
  Serial.print(millis()); // enviamos  los ms transcurridos
  Serial.println("ms");
  delay(10);    
}

برای مشاهده‌ی دیتای دریافتی، پورت COM را به پورت مبدل سریال تغییر می‌دهیم، سپس سریال مانیتور را باز کرده و نرخ ارسال ۲۴۰۰ را انتخاب می‌کنیم. دیتای دریافت شده به صورت تصویر زیر در سریال مانیتور قابل مشاهده است.

نتیجه نمونه کد تست ماژول بر روی سریال مانیتور

چندین روش برای اعتبارسنجی اطلاعات وجود دارد، ساده‌ترین آن‌ها این است که دیتای یکسانی چندین مرتبه، مثلا سه مرتبه ارسال شود و گیرنده باید با تأیید اینکه سه مرتبه دیتای یکسانی دریافت‌ شده ‌است،  اعتبارسنجی را انجام دهد. سایر روش‌ها عبارتند از استفاده از بیت توازن، افزودن فریم‌های اعتبارسنجی و … .   

ارتباط بی ‌سیم بین دو برد آردوینو با استفاده از کتابخانه‌ها

کتابخانه‌ی VirtualWire یکی از رایج‌ترین و کارآمدترین کتابخانه‌هاست که توسط Mike McCauley ایجاد شده است. در مثال های بعدی از این کتابخانه استفاده خواهیم‌ کرد.

ابتدا کتابخانه‌ی VirtualWire را دانلود و سپس آن را به  Arduino IDE  اضافه نمائید. در ادامه توابع اصلی این کتابخانه توضیح داده شده ‌است:

  • void vw_setup (uint16_t speed)

تنظیمات اولیه VirtualWire توسط این تابع انجام می‌شود. ورودی این تابع سرعت انتقال دیتا بر حسب بیت بر ثانیه است.

  • void vw_set_tx_pin (uint8_t pin)

پایه‌ی ورودی/خروجی دیجیتال که دیتا توسط آن ارسال خواهد شد.

  • void vw_set_rx_pin (uint8_t pin)

پایه‌ی ورودی/خروجی دیجیتال که دیتا توسط آن دریافت خواهد شد.

  • void vw_rx_start ()

با فراخوانی این تابع، گیرنده آماده دریافت دیتا از پایه rx می‌شود. فراخوانی این تابع برای دریافت دیتا ضروری است.

  • uint8_t vw_send (uint8_t* buf , uint8_t len)

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

  • void vw_wait_tx ()

تا زمانی که کل دیتا ارسال شود، این تابع منتظر می‌ماند.

  • uint8_t vw_get_message (uint8_t* buf, uint8_t* len)

چنانچه پیامی در دسترس باشد (همراه با checksum یا بدون آن)، پیام را در buf ذخیره می‌کند، چنانچه بررسی موفقیت‌آمیز باشد True برگردانده می‌شود. buf اشاره‌گری به موقعیت است تا در آن دیتای خوانده شده را ذخیره کند و len اشاره‌گری به تعداد بایت‌های در دسترس از سوی buf می‌باشد.

اتصالات ماژول RF و آردوینو

قبل از شروع نوشتن برنامه، لازم است ماژول‌ فرستنده و گیرنده به‌صورت زیر به آردوینوها متصل شوند.

اتصالات فرستنده:

نحوه اتصال ماژول فرستنده به آردوینو

اتصالات گیرنده:

نحوه اتصال ماژول گیرنده به آردوینو

مثال ۱ – روشن و خاموش نمودن یک LED به صورت بی‌سیم:

در این مثال، یک LED که به پایه‌ی شماره ۱۳ آردوینو متصل شده ‌است، روشن خواهد شد. روشن و خاموش نمودن آن از راه دور توسط آردوینو دیگری انجام خواهد شد. ارسال دستور را توسط کامپیوتر انجام خواهیم داد، اما از طریق یک کلید نیز قابل انجام است.

کد فرستنده به صورت زیر می‌باشد:

#include <VirtualWire.h>

void setup()
{
    Serial.begin(9600);	  
    Serial.println("Emisor RF");

    // Se inicializa el RF
    vw_setup(2000); // velocidad: Bits per segundo
    vw_set_tx_pin(2); //Pin 2 como salida para el RF 
}

void loop()
{

    
    while (Serial.available() > 0) 
    {
      char dato[1];
      dato[0] = Serial.read();
      //Enviamos el carácter recibido al RF
      vw_send((uint8_t*)dato,sizeof(dato));
      vw_wait_tx();         
    }
    delay(200);
}

همان‌طور که مشاهده می‌کنید، برنامه به‌صورت بی‌سیم، دیتا را از طریق پورت سریال ارسال و دریافت می‌کند. کد گیرنده به‌صورت زیر می‌باشد:

#include <VirtualWire.h>

void setup()
{
    Serial.begin(9600);	// Debugging only
    Serial.println("setup");

    // Se inicializa el RF
    vw_setup(2000);	 // velocidad: Bits per segundo
    vw_set_rx_pin(2);  //Pin 2 como entrada del RF
    vw_rx_start();       // Se inicia como receptor
    
    pinMode(13, OUTPUT);    //Configuramos el pin del Led como entrada
    digitalWrite(13, false);
}

void loop()
{
    uint8_t dato;
    uint8_t datoleng=1;
    //verificamos si hay un dato valido en el RF
    if (vw_get_message(&dato,&datoleng))
    {
        if((char)dato=='a')
        {
            digitalWrite(13, true); //Encendemos el Led
        }
        else if((char)dato=='b')
        {
            digitalWrite(13, false); //Apagamos el Led
        }            
    }
}

فرمان روشن و خاموش شدن LED از طریق سریال مانیتور ارسال می‌شود. به این معنا که با ارسال کاراکتر a، LED روشن و با ارسال کاراکتر b، LED خاموش می‌شود.

مثال ۲- ارسال پیام بین ماژول‌های‌ RF

در این مثال آردوینو فرستنده پیام ‘Hello world’ را به آردوینو گیرنده ارسال می‌کند، برای مشاهده‌ی پیام دریافت‌شده از سریال مانیتور استفاده خواهد شد. کد فرستنده به صورت زیر می‌باشد:

#include <VirtualWire.h>

void setup()
{
    Serial.begin(9600);	
    Serial.println("Emisor: Setup");

    // Se inicializa el RF
    vw_setup(2000);	// velocidad: Bits per segundo
    vw_set_tx_pin(2); //Pin 2 como salida para el RF 
}

void loop()
{
    const char *msg = "Hola mundo";

    digitalWrite(13, true); // Parpadeamos  el led al enviar 
    vw_send((uint8_t *)msg, strlen(msg));
    vw_wait_tx(); //Esperamos hasta que el mensaje se envie
    digitalWrite(13, false);
    delay(200);
}

کد گیرنده به صورت زیر می‌باشد:

#include <VirtualWire.h>

void setup()
{
    Serial.begin(9600);	// Debugging only
    Serial.println("Emisor: Setup");

    // Se inicializa el RF
    vw_setup(2000);	 // velocidad: Bits per segundo
    vw_set_rx_pin(2);    //Pin 2 como entrada del RF
    vw_rx_start();       // Se inicia como receptor
}

void loop()
{
    uint8_t buf[VW_MAX_MESSAGE_LEN];
    uint8_t buflen = VW_MAX_MESSAGE_LEN;
    //verificamos si hay un dato valido en el RF
    if (vw_get_message(buf, &buflen)) 
    {
	int i;

        digitalWrite(13, true); // Parpadeamos  el led al recibir
	//verificamos si hay un dato valido en el RF
	Serial.print("Mensaje: ");
	
	for (i = 0; i < buflen; i++)
	{
	    Serial.print((char)buf[i]);
	}
	Serial.println("");
        digitalWrite(13, false);
    }
}

برای مشاهده‌ی دیتا، سریال مانیتور گیرنده را باز کنید:

پیام دریافتی گیرنده بر روی سریال مانیتور

مثال ۳ – ارسال دیتا و متغیرها با ماژول‌ RF

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

کد فرستنده به‌صورت زیر می‌باشد:

#include <VirtualWire.h>

void setup()
{
    Serial.begin(9600);	  // Debugging only
    Serial.println("setup");

    // Se inicializa el RF
    vw_setup(2000); // velocidad: Bits per segundo
    vw_set_tx_pin(2); //Pin 2 como salida para el RF 
}

void loop()
{
    char buf[VW_MAX_MESSAGE_LEN]; // Cadena para enviar
    int dato1=millis()/1000; //variable con el tiempo en segundos
    float dato2=3.14;   //segundo dato para enviar
    String str="";  
    
    str="i"+String(dato1); //convertimos el entero a String y agramos un inicio de trama
    str.toCharArray(buf,sizeof(buf)); //convertimos el String en un array
    vw_send((uint8_t *)buf, strlen(buf)); //Enviamos el array
    vw_wait_tx(); //Esperamos hasta que el mensaje se envie
    
    str="f"+String(dato2); //convertimos el float a String y agramos un inicio de trama
    str.toCharArray(buf,sizeof(buf)); //convertimos el String en un array
    vw_send((uint8_t *)buf, strlen(buf)); ////Enviamos el array
    vw_wait_tx(); //Esperamos hasta que el mensaje se envie
    
    delay(200);
}

کد گیرنده به‌صورت زیر می‌باشد:

#include <VirtualWire.h>

void setup()
{
    Serial.begin(9600);	// Debugging only
    Serial.println("Receptor: setup");

    // Se inicializa el RF
    vw_setup(2000);	 // velocidad: Bits per segundo
    vw_set_rx_pin(2);    //Pin 2 como entrada del RF
    vw_rx_start();       // Se inicia como receptor
}

void loop()
{
    uint8_t buf[VW_MAX_MESSAGE_LEN];
    uint8_t buflen = VW_MAX_MESSAGE_LEN;
    int dato1=0;
    float dato2=0.0;
    //verificamos si hay un dato valido en el RF
    if (vw_get_message((uint8_t *)buf,&buflen))
    {
	int i;
	String  DatoCadena="";
        if((char)buf[0]=='i') //verificamos el inicio de trama
        {
            for (i = 1; i < buflen; i++)
            {
        	DatoCadena.concat((char)buf[i]);
            }
            dato1=DatoCadena.toInt();
            Serial.print("Dato1 recivido: ");
            Serial.println(dato1);
        }
        else if((char)buf[0]=='f') //verificamos el inicio de trama
        {
            for (i = 1; i < buflen; i++)
            {
        	DatoCadena.concat((char)buf[i]);
            }
            dato2=DatoCadena.toFloat();
            Serial.print("Dato2 recivido: ");
            Serial.println(dato2);
        }
    }
}

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

دریافت دیتا در سریال مانیتور گیرنده

امیدواریم که این مقاله بتواند راهنمای مناسبی برای کار با ماژول‌ فرستنده و گیرنده رادیویی و برقراری ارتباط بی ‌سیم بین دو برد آردوینو باشد. شما عزیزان می‌توانید سوالات خود را در بخش دیدگاه بنویسید و پاسخ خود را دریافت کنید. در ضمن می‌توانید در زمینه مورد علاقه خود در الکترونیک، مقاله بنویسید و با نام خود در ۱۱۸ELEC منتشر کنید.  

ارسال یک پاسخ

لطفا دیدگاه خود را وارد کنید!
لطفا نام خود را در اینجا وارد کنید