วันจันทร์ที่ 28 ตุลาคม พ.ศ. 2556

สื่อสารไร้สายด้วยคลื่น RF กับ Arduino UNO

สื่อสารไร้สายด้วยคลื่น RF กับ Arduino UNO

        ถ้ากล่าวถึงการสื่อสารระยะใกล้ๆ โดยที่ไม่ต้องการความแม่นยำของข้อมูลสูง และมีราคาที่ต่ำมากๆ หลายคนคงนึกถึง การสื่อสารด้วยคลื่นวิทยุ (Radio Frequency) ซึ่งในบทความนี้จะมาทดลองสื่อสาร
ผ่านทางคลื่น RF นี้โดยใช้คลื่นความถี่ 433.92 MHz กัน โดยเตรียมอุปกรณ์ตามนี้เลยครับ

1.  Arduino UNO      2          ตัว
2.  RF TRANSMITTER MODULE      1            ตัว
3.  RF RECEIVER MODULE      1      ตัว
4.  LED สี เขียว      3   หลอด
5.  สวิตช์กดติดปล่อยดับ      3      ตัว
6.  Resistor 10 K ohm      3      ตัว
7.  โพรโตบอร์ด      2      อัน
8.  สายไฟสำหรับเชื่อมต่ออุปกรณ์

 

     โมดูลการส่งสัญญาณ (RF Transmitter) 

       เตรียมอุปกรณ์เสร็จเรียบร้อยให้ประกอบวงจรตามรูปเลยครับ
 

 

      โมดูลการรับสัญญาณ (RF Receiver)

        ประกอบวงจรตามรูปด้านล่างได้เลยครับ



        หลังจากที่ได้เตรียมอุปกรณ์และประกอบวงจรเสร็จเรียบร้อยแล้ว ก็มาถึงขั้นตอนการเขียนโปรแกรมกันบ้าง โดยจะแยกโปรแกรมออกเป็น 2 ส่วน เหมือนกันกับวงจรและจะมีโค๊ดส่วนของการตรวจสอบข้อมูลระหว่างการรับส่ง ซึ่งจะเป็นตัวกรองข้อมูลขยะในการรับส่ง โดยมีรายละเอียดตามนี้เลยครับ

       โปรแกรมส่วนของการส่งข้อมูล (RF Transmitter)

#define NET_ADDR 5
#define NETWORK_SIG_SIZE 3

#define VAL_SIZE         2
#define BTN_A            5
#define BTN_B            6
#define BTN_C            7

#define BTN_PRESSED      LOW

const byte g_network_sig[NETWORK_SIG_SIZE] = {0x8F, 0xAA, NET_ADDR};  // Few bytes used to initiate a transfer
int i = 0;

void setup()
{
  pinMode(BTN_A, INPUT);
  pinMode(BTN_B, INPUT);
  pinMode(BTN_C, INPUT);
  Serial.begin(1200);
}

void loop()
{
  int btn_a;
  int btn_b;
  int btn_c;
 
  btn_a = digitalRead(BTN_A);
  btn_b = digitalRead(BTN_B);
  btn_c = digitalRead(BTN_C);
 
  if (btn_a == BTN_PRESSED) {
    writeUInt('A');
  }
  if (btn_b == BTN_PRESSED) {
    writeUInt('B');
  }
  if (btn_c == BTN_PRESSED) {
    writeUInt('C');
  }
  delay(50);
}

void writeUInt(unsigned int val)
{
  byte checksum = (val/256) ^ (val&0xFF);
  Serial.write(0xF0);  // This gets reciever in sync with transmitter
  Serial.write(g_network_sig, NETWORK_SIG_SIZE);
  Serial.write((byte*)&val, VAL_SIZE);
  Serial.write(checksum); //CHECKSUM_SIZE
}


       โปรแกรมส่วนของการรับข้อมูล (RF Receiver)

#define NETWORK_SIG_SIZE 3
#define VAL_SIZE         2
#define CHECKSUM_SIZE    1
#define PACKET_SIZE      (NETWORK_SIG_SIZE + VAL_SIZE + CHECKSUM_SIZE)

#define NET_ADDR 5

const byte g_network_sig[NETWORK_SIG_SIZE] = {0x8F, 0xAA, NET_ADDR};  // Few bytes used to initiate a transfer
char c;
#define LED_A    5
#define LED_B    6  
#define LED_C    7
void setup()
{
  pinMode(LED_A, OUTPUT);
  pinMode(LED_B, OUTPUT);
  pinMode(LED_C, OUTPUT);
  digitalWrite(LED_A, LOW);
  digitalWrite(LED_B, LOW);
  digitalWrite(LED_C, LOW);
  Serial.begin(1200);
}

void loop()
{
  switch(readUInt(true)) {
    case 'A' : ledOff();digitalWrite(LED_A, HIGH);break;
    case 'B' : ledOff();digitalWrite(LED_B, HIGH);break;
    case 'C' : ledOff();digitalWrite(LED_C, HIGH);break;
  }
}

void ledOff()
{
  digitalWrite(LED_A, LOW);
  digitalWrite(LED_B, LOW);
  digitalWrite(LED_C, LOW);
}

unsigned int readUInt(bool wait)
{
  int pos = 0;          // Position in the network signature
  unsigned int val;     // Value of the unsigned int
  byte c = 0;           // Current byte
 
  if((Serial.available() < PACKET_SIZE) && (wait == false))
  {
    return 0xFFFF;
  }
 
  while(pos < NETWORK_SIG_SIZE)
  {
    while(Serial.available() == 0); // Wait until something is avalible
    c = Serial.read();

    if (c == g_network_sig[pos])
    {
      if (pos == NETWORK_SIG_SIZE-1)
      {
        byte checksum;

        while(Serial.available() < VAL_SIZE + CHECKSUM_SIZE); // Wait until something is avalible
        val      =  Serial.read();
        val      += ((unsigned int)Serial.read())*256;
        checksum =  Serial.read();
       
        if (checksum != ((val/256) ^ (val&0xFF)))
        {
          // Checksum failed
          pos = -1;
        }
      }
      ++pos;
    }
    else if (c == g_network_sig[0])
    {
      pos = 1;
    }
    else
    {
      pos = 0;
      if (!wait)
      {
        return 0xFFFF;
      }
    }
  }
  return val;
}

        เมื่อทำการ upload โปรแกรมไปยัง Arduino UNO เรียบร้อยแล้ว ทำการทดสอบโปรแกรม 
จะได้ผลตาม video นี้เลยครับ
 

        การใช้ RF ในการสื่อสาร มีคลื่นรบกวนค่อนข้างเยอะ จึงเหมาะกับอุปกรณ์ที่ไม่ต้องการความแม่นยำในการส่งข้อมูลสูงมาก อาจจะนำไปประยุกต์ใช้กับวงจรรถบังคับวิทยุ เครื่องบินเล็ก หรือการควบคุมอุปกรณ์ต่างๆ ที่ต้องการสื่อสารระยะไกลภายในบ้านได้
        ใครมีโปรเจคที่น่าสนใจก็สามารถแชร์ความรู้กันทาง gtalk หรือทางเมลล์ได้นะครับ
olekhanchai@gmail.com หรือสนใจอุปกรณ์สามารถเข้าสั่งซื้อได้ในเว็บ http://www.hobbyembshop.biz หรือสินค้าโปรโมชั่นที่ https://www.facebook.com/hobbyembedded  
        ขอให้สนุกกับการประยุกต์ใช้งานนะครับ เจอกันคราวหน้าครับ...


 อ้างอิง  http://www.glacialwanderer.com/hobbyrobotics/?p=291