สื่อสารไร้สายด้วยคลื่น RF กับ Arduino UNO
ถ้ากล่าวถึงการสื่อสารระยะใกล้ๆ โดยที่ไม่ต้องการความแม่นยำของข้อมูลสูง และมีราคาที่ต่ำมากๆ หลายคนคงนึกถึง การสื่อสารด้วยคลื่นวิทยุ (Radio Frequency) ซึ่งในบทความนี้จะมาทดลองสื่อสาร
ผ่านทางคลื่น RF นี้โดยใช้คลื่นความถี่ 433.92 MHz กัน โดยเตรียมอุปกรณ์ตามนี้เลยครับ
ผ่านทางคลื่น 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
}
#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;
}
#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
olekhanchai@gmail.com หรือสนใจอุปกรณ์สามารถเข้าสั่งซื้อได้ในเว็บ http://www.hobbyembshop.biz หรือสินค้าโปรโมชั่นที่ https://www.facebook.com/hobbyembedded
ขอให้สนุกกับการประยุกต์ใช้งานนะครับ เจอกันคราวหน้าครับ...
อ้างอิง http://www.glacialwanderer.com/hobbyrobotics/?p=291