วันพุธที่ 16 เมษายน พ.ศ. 2557

มาทำ Home Automation กันเถอะ

        หลังจากห่างหายไปเป็นเวลาสามเดือน ก็ขอสวัสดีปีใหม่ไทยท่านผู้อ่านทุกๆ ท่านในช่วงสงกรานต์และขอกลับมาเขียนบล็อกให้ทุกท่านได้อ่านกันอีกครั้งนะครับ จากในหัวข้อที่กล่าวไว้ข้างต้นว่า
Home Automation คือการควบคุมอุปกรณ์ภายในบ้าน วันนี้ขอหยิบยกการทำอุปกรณ์ควบคุมภายในบ้านโดยใช้ Raspberry Pi และ Arduino มาให้ลองทำที่บ้านเล่นๆ กันนะครับ แต่ขอเตือนว่าโปรเจคนี้ค่อนข้างจะอันตราย หากไม่มีความรู้ด้านไฟฟ้าควรหาที่ปรึกษาด้านไฟฟ้าไว้นะครับ เพราะว่าโปรเจคนี้เล่นกับไฟฟ้าในบ้านที่มีแรงดัน 220 V หากไม่ระมัดระวังอาจเกิดอันตรายถึงชีวิตได้ โดยหากเกิดอะไรขึ้น ทางผู้เขียนจะไม่รับผิดชอบใดๆ เพราะถือว่าได้เตือนแล้ว  อาจจะฟังดูน่ากลัวไปหน่อย แต่คิดว่าคนที่สามารถทำวงจรนี้ได้คงมีความรู้ด้านไฟฟ้าอิเล็กทรอนิกส์พอตัวเหมือนกัน    เรามาเริ่มเตรียมอุปกรณ์กันเลยนะครับ รายการอุปกรณ์ที่จำเป็นจะต้องใช้ตามรายการด้านล่างเลยครับ

1.  Raspberry Pi Model B 512 MB      1          ตัว
2.  SD Card  4 GB ขึ้นไป      1          ตัว
3.  Arduino Pro Mini 16 MHz 5v      2          ตัว
4.  เต้าเสียบไฟฟ้าตัวเมีย      1          ตัว
5.  หม้อแปลง 5V 2A      1          ตัว
6.  Wireless RF Transmitter & Receiver 433 MHz      1       ชุด
7.  Optoisolator TLP560J      1       ตัว
8.  เสาอากาศ      2       อัน
9.  LED สีแดง      1       ตัว
10.  LED สีเขียว      1       ตัว
11.  PCB อเนกประสงค์      1       แผ่น
12.  Resistor 1.6 K Ohm      1       ตัว
13.  Resistor 3.3 K Ohm      1       ตัว

        เมื่อได้อุปกรณ์ครบทั้งหมดตามรายการเรียบร้อยแล้ว ขั้นตอนต่อไป เราจะแยกรายการอุปกรณ์
ดังกล่าวออกเป็นสองส่วนซึ่งรายละเอียดจะแยกอธิบายเป็นส่วนๆ ดังนี้ครับ

Wireless Plug

 

        ส่วนของ Wireless Plug จะเป็นส่วนของเต้าเสียบไฟฟ้าที่ใช้ Arduino Pro Mini ในการเปิดปิดเต้าเสียบเพื่อจ่ายไฟหรือหยุดการจ่ายไฟให้กับอุปกรณ์ที่เสียบกับเต้าเสียบนัันๆ โดยจะมี Opto เป็นตัวเปิดปิดแรงดันไฟฟ้าจากปลั๊กไฟไปยังเต้าเสียบไฟฟ้า ซึ่งจะควบคุมโดย Arduino Pro Mini ผ่านทาง
ขาที่ 7 อีกที โดยมีการรับคำสั่งจาก RF Receiver และมี LED แสดงสถานะการจ่ายไฟให้กับเต้าเสียบไฟฟ้า  ซึ่งการทำงานที่อธิบายข้างต้นสามารถต่อวงจรได้ตามรูปด้านล่างครับ


        หลังจากประกอบวงจรเสร็จเรียบร้อยแล้ว จำเป็นจะต้องมีการเขียนโปรแกรมให้กับ Arduino Pro Mini เพื่อที่จะให้วงจรสามารถสื่อสารกับ Wireless Server ได้ โดยโปรแกรมดังกล่าว จะขอหยิบยกเอาบทความของเดือน ตุลาคม 2013 มาดัดแปลง โดยโค๊ดดังกล่าวจะทำงานตามหลักการข้างต้น ส่วนการ Upload Program สามารถดูได้จากบทความของเดือน พฤศจิกายน 2013 ได้นะครับ ซึ่งรายละเอียดของโค๊ดตามข้อความข้างล่างเลยครับ

#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_ON        5
#define LED_OFF      6 
#define LELAY_ON   7
void setup()
{
  pinMode(LED_ON, OUTPUT);
  pinMode(LED_OFF, OUTPUT);
  pinMode(LELAY_ON, OUTPUT);
  digitalWrite(LED_ON, LOW);
  digitalWrite(LED_OFF, HIGH);
  digitalWrite(LELAY_ON, LOW);
  Serial.begin(1200);
}

void loop()
{
  Serial.write(readUInt(true));
}

void plugOn()
{
  digitalWrite(LED_ON, HIGH);
  digitalWrite(LELAY_ON, HIGH);
  digitalWrite(LED_OFF, LOW);
}

void plugOff()
{
  digitalWrite(LED_ON, LOW);
  digitalWrite(LELAY_ON, LOW);
  digitalWrite(LED_OFF, HIGH);
}

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;
}

        เท่านี้เราก็ได้ Wireless Plug ที่พร้อมใช้งานได้แล้วครับ หากนำวงจรข้างต้นมาประกอบลงเต้าเสียบไฟฟ้า จะได้หน้าตาของ Wireless Plug ประมาณนี้ครับ

 

Wireless RPI Server

 

        ส่วนของ Wireless RPI Server นี้จะเป็นศูนย์สั่งการให้กับเต้าเสียบต่างๆ ที่เชื่อมต่อกับ Server ด้วย Wireless RF Module โดยจะทำหน้าที่ในการรับคำสั่งผ่านเว็บ Interface ซึ่งอาจจะใช้ Android, IPhone หรือ Notebook ในการเข้าหน้าเว็บดังกล่าวเพื่อควบคุมก็แล้วแต่ความสะดวกของแต่ละท่านนะครับ
ส่วนของ Server นี้จะมีความซับซ้อนในการติดตั้งนิดนึง โดยสามารถทำตามขั้นตอนต่อไปนี้ได้เลยครับ

        Raspbian Setup

        ขั้นตอนการติดตั้ง Raspbian ขอละไว้ในฐานที่เข้าใจนะครับ ซึ่งสามารถกลับไปดูบทความแรกของ
ปี 2013 ในการติดตั้งได้ หน้าตาของการติดตั้งอาจจะเปลี่ยนแปลงไปตามการอัพเดทของแต่ละเวอร์ชันของ Raspbian แต่ขั้นตอนยังเหมือนเดิมครับ

        LAMP Setup 

        ขั้นตอนการติดตั้ง LAMP ก็ขอละไว้ในฐานที่เข้าใจด้วยเช่นกัน ซึ่งสามารถย้อนกลับไปดูบทความของเดือนมิถุนายนของปี 2013 ได้ครับ

        Serial Port (UART) Setup 

        Raspberry Pi จะทำการส่งข้อมูลการแสดงผลออกทาง Serial Port ตั้งแต่เริ่มทำงาน ด้วย getty
ดังนั้นหากเราจะใช้งาน Serial Port ดังกล่าว เราจะต้องทำการตัดการทำงานของ getty ทิ้งไป โดยทำตามขั้นตอนดังนี้

        1. ทำการแก้ไขไฟล์ /etc/inittab โดยให้ค้นหาข้อความดังนี้

                T0:23:respawn:/sbin/getty -L ttyAMA0 115200 vt100

        และใส่ comment ให้กับบรรทัดดังกล่าว เพื่อปิดการทำงานของ getty ดังนี้

                #T0:23:respawn:/sbin/getty -L ttyAMA0 115200 vt100

        2. แก้ไขไฟล์ /boot/cmdline.txt โดยหาข้อความดังนี้

                console=ttyAMA0, 115200 kgdboc=ttyAMA0, 115200 

        จากนั้นให้ลบข้อความข้างต้นทิ้งไป เพื่อไม่ให้ Raspberry Pi ส่งการแสดงผลออกทาง Serial Port

        3. ติดตั้ง Py-Serial ให้กับ Raspbian ซึ่งเป็น Library ของ Python ที่ใช้ติดต่อ Port Serial  นั่นเอง โดยใช้คำสั่งดังนี้

                sudo apt-get install python-serial

        4. เปิดให้ Browser สามารถเข้าใช้งานใช้งาน Serial Port โดยการเปิดสิทธิ์การเข้าถึงของ Serial ไว้ที่ Startup เพื่อให้มีการกำหนดสิทธิ์ทุกครั้งเมื่อมีการบูทระบบใหม่ ซึ่งจะต้องสร้างไฟล์ชื่อ freeAMA0 ไว้ที่ /etc/init.d/ โดยมีเนื้อหาดังนี้

                sudo chmod 777 /dev/ttyAMA0

        ซึ่งเมื่อสร้างไฟล์ freeAMA0 ที่มีเนื้อหาข้างบนเสร็จเรียบร้อยแล้ว ให้สั่งคำสั่ง

                sudo update-rc.d freeAMA0 defaults

        เพื่อสั่งให้ freeAMA0 ทำการกำหนดสิทธิ์การเข้าถึงอัตโนมัติเมื่อมีการบูท Raspberry ทุกครั้ง

        เมื่อเสร็จขั้นตอนข้างต้นเรียบร้อยแล้ว ก็ถือว่าในส่วนของการเตรียม Serial Port ของ Raspberry Pi เสร็จสมบูรณ์
        ก่อนที่จะทำการต่อวงจรให้ Arduino Pro Mini กับ Raspberry Pi เพื่อให้สื่อสารกันนั้น ก็มาทำการเขียนโปรแกรมให้กับ Arduino Pro Mini ฝั่ง Transmitter และ Upload Program ให้กับ Arduino Pro Mini กันก่อน โดยปรแกรมจะเขียนตามโค๊ดด้านล่างเลยครับ

#include <SoftwareSerial.h>
#define NET_ADDR                   5
#define NETWORK_SIG_SIZE 3
#define VAL_SIZE                      2

SoftwareSerial swSerial(9, 10);
const byte g_network_sig[NETWORK_SIG_SIZE] = {0x8F, 0xAA, NET_ADDR};
// Few bytes used to initiate a transfer
int i = 0;
boolean turnon = false;

void setup()
{
  swSerial.begin(9600);
  Serial.begin(1200);
}

void loop()
{
  if (swSerial.available())
  {
    char buf = swSerial.read();
    if (buf == 48) {       // check for number 0
      turnon = false;
    }
    if (buf == 49) {      // check for number 1
      turnon = true;
    }
  }
  if (turnon)
  {
    writeUInt('1');
  }
  else
  {
    writeUInt('0');
  }
}

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
}

        หลังจากนั้นเราก็จะมาเตรียมการในส่วนของวงจรฝั่ง Wireless RPI Server ที่สื่อสารกันระหว่าง Raspberry Pi กับ Arduino กันบ้าง  โดยต่อวงจรตามรูปเลยครับ

   
        ในส่วนของ Serial Port นั้นจะใช้ส่วนของ GPIO ขาที่ 8 และ ขาที่ 10  ในการสื่อสารระหว่าง Raspberry Pi และ Arduino Pro Mini  ขา 9 และ ขา 10 ซึ่งในที่นี้คือ Software Serial โดย Port Serial จริงของ Arduino นั้นจะใช้ในการสื่อสารกับ Wireless Module จึงต้องสื่อสารกับ Raspberry Pi โดยใช้ Port Serial เสมือนในการติดต่อสื่อสาร (ซึ่งก็คือ Software Serial นั่นเอง) และเนื่องจาก Raspberry Pi วงจรสื่อสารภายในเป็น 3.3 V ส่วน Arduino Pro Mini นั้นจะเป็น 5 V เพื่อป้องกันความเสียหายในการติดต่อสื่อสารระหว่างทั้งสองบอร์ดจึงต้องมี Resistor สองตัวที่ต่อวงจรเป็น Voltage Divider เพื่อที่จะทำการลดแรงดันจาก Arduino Pro Mini ให้กับ Raspberry Pi ไว้ด้วย

        จากวงจรข้างต้นเราสามารถนำมาประกอบเป็นวงจร Wireless RPI Server โดยติดตั้ง Raspberry Pi กับ RF Module Socket ได้ตามรูปด้านล่างครับ

 

        Control Web Page

 

        มาถึงขั้นตอนสุดท้ายซึ่งจะเป็นหน้าเว็บที่ใช้ติดต่อกันระหว่างผู้ใช้งานและ Server โดยจะเป็นการสั่งให้ Serial Port ทำการเปิดหรือปิด Wireless Plug ที่ปลายทาง ซึ่งหน้าเว็บดังกล่าวสามารถเขียนเป็นไฟล์แยกกันได้ดังนี้

สร้างไฟล์  index.php โดยมีเนื้อหาดังนี้

        ก่อนที่จะทำการสร้างไฟล์ index ให้ดาวน์โหลด JQuery มาลงไว้ที่ /var/www เสียก่อน โดยสามารถดาวน์โหลดได้จาก http://code.jquery.com/jquery-2.1.0.min.js จากนั้นค่อนสร้างไฟล์ index.php ไว้ที่ folder เดียวกัน ซึ่งมีเนื้อหาไฟล์ดังนี้

<html>
<head>
<title> Enable / Disable Wireless Plug Demo </title>
<script src="jquery-2.1.0.min.js"></script>
<script type="text/javascript">
function onPlug(){
        $.ajax("on.php");
}
function offPlug(){
        $.ajax("off.php");
}
</script>
</head>
<body>
        <button onclick="onPlug();"> ON </button>
        <button onclick="offPlug();"> OFF </button>
</body>
</html>

สร้างไฟล์ on.php ที่มีเนื้อตามข้อความด้านล่าง

<?
echo exec("python serialTest.py 1 2>&1");
?>

สร้างไฟล์ off.php ที่มีเนื้อตามข้อความด้านล่าง

<?
echo exec("python serialTest.py 0 2>&1");
?>

และสุดท้ายสร้างไฟล์ serialTest.py ซึ่งเป็นไฟล์ส่งข้อมูลการปิดเปิดของ Wireless Plug
โดยมีเนื้อหาดังนี้

import serial
import sys

ser = serial.Serial('/dev/ttyAMA0', 9600, timeout=1)
ser.open()

print("'" + sys.argv[1] + "'")
ser.write("'" + sys.argv[1] + "'")
จากนั้นสามารถลองทดสอบโปรแกรมได้เลย โดยใช้ Web Browser เข้าไปที่หน้า index.php ซึ่งในที่นี้จะใช้มือถือ Android ในการทดสอบ  โดยหน้าตาเว็บใน Android จะเป็นหน้าตาประมาณนี้ครับ


เราลองมาทดสอบการใช้งาน Home Automation ของเรากันครับ


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


อ้างอิง  http://blog.oscarliang.net/raspberry-pi-and-arduino-connected-serial-gpio/

ไม่มีความคิดเห็น:

แสดงความคิดเห็น