Showing posts with label Project. Show all posts
Showing posts with label Project. Show all posts

Saturday, December 22

Raspberry Pi checking Router’s IP Address

     จากตอนที่แล้ว (คลิก) เราได้ทำความเข้าใจเรื่องการใช้งาน crond service ของ Linux กันไปแล้ว วันนี้ เราจะมาสร้างระบบคอยตรวจสอบ WAN IP Address ของ Router แล้วให้ส่งค่า IP Address ของ Router ที่ได้รับจาก ISP (ผู้ให้บริการอินเตอร์เนตที่เราใช้อยู่ ) หาก IP Address เกิดการเปลี่ยนแปลงเนื่องจากเหตุผลใดๆ ก็ตาม ให้ทำการส่งค่า IP Address ใหม่ ไปบอกเราทาง E-mail นะครับ

Raspberry Pi Checking Router's IP Address Project

     จริงๆ หลักการ ก็ไม่ได้ยากอะไร เราจะให้บอร์ด Raspberry Pi ทำการเรียกไฟล์สคริปต์ php จาก Web Server ตัวหนึ่งที่ผมได้นำไฟล์ ip.php ไปฝากไว้ ซึ่งภายในไฟล์นี้ มีเพียงคำสั่งแสดง Remote ip address ซึ่งก็คือ IP Address ของ Router นั่นเอง

<?php echo $_SERVER['REMOTE_ADDR']; ?>

เมื่อได้ค่า router IP Address มาแล้ว หาก IP Address ไม่ตรงกับที่เคยเก็บค่าไว้ ก็จะทำการส่ง E-mail ไปบอกเรา ว่า ตอนนี้ IP Address ได้มีการเปลี่ยนแปลงเกิดขึ้นแล้วนะ ซึ่งเราจะนำ IP Address ของ  Router ที่ได้ ไปสร้างโปรเจคอื่นต่อไป แต่ตอนนี้ เอาเพียงเท่านี้ก่อนนะครับ เดี๋ยวจะงง

การทำงานคร่าวๆ ก็คือ ในตอนแรก Raspberry Pi เรียกดูไฟล์ ip.php ตาม URL ที่กำหนด
Raspberry Pi---> Access Point + Router--->request http://monitoring.orgfree.com/ip.php

จากนั้น web server monitoring.orgfree.com ตอบกลับ Remote IP Address ซึ่งนั่นเป็น IP Address ของ Router ที่เราได้รับจาก ISP ขณะนั้น
Raspberry Pi<--- Access Point + Router<---response Remote IP Address

จากนั้น เราก็จะนำค่า IP Address ไปเปรียบเทียบกับค่าที่เก็บไว้ใน text file ว่าค่าตรงกันหรือไม่ หากไม่ตรงกัน ก็จะทำการส่ง E-mail ไปบอกเรา ซึ่งเราจะนำโค๊ดจากก่อนหน้านี้ มาทำการปรับปรุง จะได้ว่า

#-------------------------------------------------------------------------------
# Name:        router.py
# Purpose:     for checking router's ip address
#
# Author:     
http://raspberry-pi-th.blogspot.com
#
# Created:     22/12/2012
# Copyright:   (c) raspberry-pi-th.blogspot.com 2012
#-------------------------------------------------------------------------------
import smtplib
import urllib2
host = "
http://monitoring.orgfree.com"
script = "ip.php"
path = "/"
file_target = '/home/pi/ip.txt'

def sendmail(ip_remote):
    SMTP_SERVER = 'smtp.gmail.com'
    SMTP_PORT = 587
    sender = 'raspberry router ip checker'
    recipient = '------------------'   # email ผู้รับ
    subject = 'Router IP Address notice'
    body  = 'Your router\'s ip address is changed to ' + ip_remote
    headers = ["From: " + sender,
                "Subject: " + subject,
                "To: " + recipient,
                "MIME-Version: 1.0",
                "Content-Type: text/html"]
    headers = "\r\n".join(headers)
    username = ‘---------------------’             # user name gmail
    password = '----------------------'           # password gmail
    server = smtplib.SMTP(SMTP_SERVER,SMTP_PORT)
    server.ehlo()
    server.starttls()
    server.ehlo()
    server.login(username,password)
    server.sendmail(sender,recipient,headers + "\r\n\r\n" + body)
    server.quit()

try:
    ip_remote =  urllib2.urlopen(host + path + script).read()
    print "ip remote " + ip_remote
    try:
        f = open(file_target,'r')
        read_ip = f.read()
        print "readout " + read_ip
        if (read_ip <> ip_remote):
            f.close()
            f = open(file_target,'w')
            f.write(ip_remote)
            sendmail(ip_remote)
            print "Email was sending"
        f.close()
    except Exception,e:
        print 'exception ' , e
        f = open(file_target,'w')
        f.write(ip_remote)
        f.close()
        sendmail(ip_remote)
        print "New file was created"
except urllib2.HTTPError, e:
    print host + path + script + " : " + str(e.code) + " " + str(e.msg)

#----------------- sript ending ----------------------------------

หมายเหตุ อย่าลืมใส่ username / password gmail account ของเราด้วยนะครับ

บันทึกไฟล์นี้ ชื่อ router.py ไว้ที่ /home/pi  อาจจะต้องทำการเปลี่ยนโหมด หากจำเป็น ด้วยคำสั่ง chmod 774 /home/pi/router.py จากนั้น นำสคริปต์ python ของเราไปฝากไว้ใน crontab (จากตอนที่แล้วของเรา) ให้ทำการเช็คทุกๆนาที หรือจะทุกๆ 10 นาที หรือ ทุกๆ ชั่วโมง ก็แล้วแต่ ความต้องการของเรา ในทีนี้ ผมให้มันเช็ค ทุกๆ นาทีหล่ะกัน จะได้เงื่อนไขใน crontab ดังนี้

* * * * * python /home/pi/router.py

ทำการบันทึก crond service แล้วรอดูผลที่ E-mail ของเรา ซึ่งในครั้งแรก ควรจะมีการส่งเมล์มาบอกเราทันที ที่สคริปต์ทำงาน เพราะว่า ไม่เคยมีไฟล์ ip.txt (ซึ่งได้จากรันสคริปต์ router.py) ปรากฏขึ้นเลยมาก่อน ก็เข้าเงื่อนไขการส่ง E-mail

Email alert from raspberry pi

เราลองลบไฟล์ ip.txt หรือไม่ก็ลองเข้าไปแก้ไข IP Address ภายในไฟล์ ip.txt แล้วลองสังเกตการเปลี่ยนแปลง ว่ายังมีการส่ง E-mail มาที่เราหรือเปล่า ซึ่งควรจะมีการส่งมา

จากนั้น เพื่อนๆ อาจจะทำการแก้ไขเงื่อนไขใน crontab เมื่อมั่นใจแล้วว่า สคริปต์ของเราทำงานได้อย่างที่ต้องการ โดยอาจจะเปลี่ยนเป็นเช็ค ทุกๆ ห้านาที ก็ได้ เพื่อไม่เป็นการ request ไปที่ web server มากเกินไป (อาจโดนเตะออก เหมือน spam ได้ )

ตั้งค่าใน crontab ใหม่ดังนี้
0,5,10,15,20,25,30,35,40,45,50,55 * * * * python /home/pi/router.py

crond service checking router's ip address

     ก็มีเพียงแค่นี้ สำหรับบทความตอนนี้ ต่อไปเราก็จะทำการ Forward Port ที่ Router ของเราให้ส่งตรงข้อมูลไปที่บอร์ด Raspbbery Pi ของเราอีกที ซึ่งนั่นจะทำให้เรา สามารถควบคุมระยะไกล จากที่ใดๆ ก็ได้มาที่บอร์ด Raspbbery Pi โดยผ่านหมายเลข router IP Address ของเรา ที่ซึ่งแม้ IP จะถูกเปลี่ยนแปลงไป เราก็ยังสามารถติดตามได้ว่า Router IP Address ของเราตอนนี้ ได้หมายเลขอะไร ซึ่งผมจะได้แสดงให้ดูในครั้งต่อไปครับ ^_^

อ่านเพิ่มเติม...

Saturday, November 3

Raspberry Pi and Arduino experiment

จากครั้งที่แล้ว เราได้เปิดการใช้งาน Serial Port ของ Raspberry Pi ไปแล้ว วันนี้เราจะมาลองเพิ่มประสิทธิภาพของ Raspberry Pi ด้วยการเพิ่ม Arduino ให้สื่อสารกับ Raspberry Pi ผ่านทาง Serial Communication โดยจะมีการรับส่ง คำสั่งและส่งค่ากลับผ่านทาง Serial Port ของ Raspberry Pi และ Serial Port ของ Arduino เพื่อเป็นแนวทางในการนำ Arduino มาใช้เป็น I/O ของ Raspberry Pi ซึ่งเราจะได้ I/O ที่เป็นดิจิตอล และ ได้ Analog input เพิ่มจาก Arduino นั่นก็แปลว่า Raspberry Pi เราจะมีความสามารถมากขึ้นไปอีก

ปล. สำหรับมือใหม่ Arduino คือไมโครคอนโทรลเลอร์ ที่มีการอ้างไปหาตำแหน่งหน่วย Input/output ของไมโครคอนโทรลเลอร์ ด้วยรูปแบบที่เหมือนๆ กัน มาใส่ไว้ที่ Bootloader ไม่ว่าจะเอาไมโครคอนโทรลเลอร์ตระกูลใด(ที่สามารถทำได้) ให้มาอยู่ใน Platform ของ Arduino แล้วหล่ะก็ ชื่อของ Input / Output ก็จะเหมือนๆ กัน ทำให้เง่ายต่อการศึกษา และป็นที่นิยมมาก

หลักการ ก็คือ Arduino และ Raspberry Pi เองจะต้องมีการเขียนโปรแกรมเพื่อรอรับค่า และส่งค่า ผ่านทาง Serial Comm เมื่อได้รับคำสั่ง (ที่เราเองเป็นคนกำหนดแล้ว) ก็จะให้แต่ละบอร์ด ไปทำตามคำสั่งนั้น แล้วส่งผลลัพธ์กลับไป ผ่านทาง Serial Comm เหมือนเดิม นั่นก็แปลว่า ทั้งทางฝั่ง Arduino และทางฝั่ง Raspberry Pi จะต้องมีโปรแกรมรองรับเป็นของตัวเอง แต่คุยกันด้วยรูปแบบการสื่อสาร UART  นั่นเป็นหลักการ เปรียบได้กับ ไม่ว่าบอร์ดนั้นจะมาจากไหน ตระกูลใด Platform ใดก็ตาม แต่ถ้าต้องการคุยกันให้รู้เรื่อง ต้องคุยกันเป็นแบบมาตรฐาน เช่น คุยกันรูปแบบ UART  สิ่งที่แต่ละบอร์ดต้องทำนั้นก็คือ ทำให้สัญญาณที่ต้องการจะสื่อสารกันนั้น อยู่ในรูปแบบภาษากลาง เป็นมาตรฐาน (ในที่นี่คือ UART) นั่นเอง เหมือนกันกับ แต่ละชาติ แต่ละภาษา หากต้องการสื่อสารกัน เราจะใช้ภาษาอังกฤษ เป็นตัวกลางในการสื่อสารนั่นเอง

ที่นี่ เรามาลองทำโจทย์กันง่ายๆ ก่อน เพื่อให้เกิดความเข้าใจ ระหว่างการเขียนโปรแกรมให้ Raspberry Pi และ Arduino ให้สื่อสารกันได้ โดยเราจะให้  Raspberry Pi ทำการอ่านค่าการกดสวิทช์ที่ต่ออยู่กับช่องดิจิตอลของ  Raspberry Pi ช่องที่ 24 และ 26 เมื่อมีการกดสวิทช์เกิดขึ้น  Raspberry Pi จะส่งค่าคำขอไปที่ Arduino เพื่อให้ทำการอ่านค่าสัญญาณอะนาล๊อก (ซึ่งอาจจะเป็นค่าจากเซนเซอร์แบบใดๆก็ได้) ในที่นี้ เราจะให้ R ปรับค่าได้เป็นตัวสร้างสัญญาณอะนาล๊อก ที่ช่องสัญญาณ AN0 และ AN1 ของบอร์ด Arduino แล้วให้ Arduino ทำการส่งค่ากลับไปบอก Raspberry Pi ส่วน Raspberry Pi เมื่อได้ค่ามาแล้วให้แสดงผลผ่านทาง Console ต่อไป

ในด้านฮาร์ดแวร์นั้น เนื่องจาก Arduino เองสามารถส่งสัญญาณแรงดันออกมาได้ถึง 5 V เพราะฉะนั้น ที่ด้านส่งข้อมูลออกของ Arduino จะต้องทำการปรับแรงดันให้เหลือ ในระดับที่ปลอดภัยสำหรับ Raspberry Pi เสียก่อน ส่วนทางด้านรับข้อมูลเข้าของ Arduino ไม่จำเป็นต้องปรับแรงดัน เพราะแรงดันจากขาออก 3.3V จาก Raspberry Pi นั้น เป็นระดับที่ Arduino เข้าใจได้

Arduino                                                  Raspberry Pi
   Rx<--------------------------------------------->Tx
   Tx (ปรับลงเหลือ 3.3 V ก่อน)<---------------> Rx
   GND<----------------------------------------->GND

ในการแปลงแรงดันจาก 5V ให้ลดลงเหลือ 3.3V เราใช้วิธี Voltage Divider โดยเราจะใช้ตัวต้านทานค่า 10k ทำการแบ่งแรงดัน  (ผมลองวัดค่าดูแล้ว ค่าไม่เกิน 3.3V และอยู่ในช่วงที่ Raspberry Pi เข้าใจระดับสัญญาณได้)

Raspberry Pi and Arduino Experiment

คำเตือน : ระวังเรื่องของระดับสัญญาณด้วยนะครับ อย่าให้เกิน 3.3V สำหรับตำแหน่งใดๆ ก็ตามที่จะต่อเข้า GPIO ของ Raspberry Pi

การพัฒนาโปรแกรมทางฝั่ง Arduino
สามารถเริ่มต้นศึกษาได้จากตัวอย่างที่ผมได้ทำไว้แล้ว จากที่นี่ http://mechacity.blogspot.com/2011/03/arduino.html  ทำการเขียนโค๊ดบน ARDUINO IDE แล้วทำการโปรแกรมลงบนบอร์ด Arduino
ด้วยโค๊ด

const int analogInPin0 = A0;    // Analog input pin that the potentiometer is attached to
const int analogInPin1 = A1;    // Analog input pin that the potentiometer is attached to

void setup() {
  // initialize serial communications at 115200 bps:
  Serial.begin(115200);
}

void loop() {
  unsigned int cmd;
  unsigned int sensorValue = 0;        // value read from the pot
  if(Serial.available() > 0){
    cmd = int(Serial.read()) - 48;
    switch(cmd){
      case 1:
        sensorValue = analogRead(analogInPin0);
        Serial.print("A0=" );
        Serial.print(sensorValue,DEC);
        Serial.print("|" );
        Serial.flush();
        break;     
      case 2:
        sensorValue = analogRead(analogInPin1);
        Serial.print("A1=" );
        Serial.print(sensorValue,DEC);
        Serial.print("|" );
        Serial.flush();
        break;   
    }
  }   
}

Arduino Firmware

หมายเหตุ : ในระหว่างการทำการโปรแกรมลงบอร์ด Arduino เราต้องไม่ให้ pin RX ของ Arduino ต่ออยู่กับอะไรในวงจร เพราะวงจรในบอร์ด Arduino ต้องใช้ pin RX ในการโปรแกรม (Burn) ลงชิพ

การพัฒนาโปรแกรมทางฝั่ง Raspberry Pi
เรายังคงใช้ภาษา Python แล้วโมดูล Python-serial ในการพัฒนาโปรแกรม โดยนำโค๊ดจากตัวอย่างที่แล้ว มาทำการดัดแปลงให้เข้ากับโจทย์ที่เราจะทดลอง บันทึกชื่อไฟล์ arduinoProj1.py
โค๊ด

#! /usr/bin/python
import serial
import time
import RPi.GPIO as GPIO

GPIO.setmode(GPIO.BOARD)
GPIO.setup(24,GPIO.IN,pull_up_down=GPIO.PUD_UP)
GPIO.setup(26,GPIO.IN,pull_up_down=GPIO.PUD_UP)

ser = serial.Serial('/dev/ttyAMA0',115200,timeout=1)
ser.open()
time.sleep(2)

def readLine(ser):
    str = ""
    while 1:
        ch = ser.read(1)
        if(ch == '|'):
            break
        str += ch
    return str

while True:
    line = ''
    if(GPIO.input(24) == False):
        ser.write('1')
        print 'button1 pressed'
        line = readLine(ser)
    elif(GPIO.input(26) == False):
        ser.write('2')
        print 'button2 pressed'
        line = readLine(ser)
    try:
        if line <> '':
            data = line.split('=')
            print 'Analog channel ' + data[0] + ' value = ' + data[1]
    except KeyboardInterrupt:
        pass
        GPIO.cleanup()
        ser.close()
        print 'Good bye!!!'

Raspberry Pi Firmware

ทดสอบการทำงาน ด้วยการรันโปรแกรมผ่าน Console ด้วยคำสั่ง (ภายใน directory ที่เก็บไฟล์ arduinoProj1.py) ด้วยคำสั่ง sudo ./arduinoProj1.py  จากนั้นทำการกดปุ่มที่ต่ออยู่กับ GPIO 24 และ 26 ของ Raspberry Pi สังเกตผลลัพธ์บนหน้าจอ Console แล้วทดลองปรับค่าความต้านทาน สังเกตการเปลี่ยนแปลง

Arduino and Raspberry Pi

จริงๆ แล้วเราควรที่จะเลือกใช้ Arduino Firmware ที่ยืดหยุ่นกว่านี้ ผมหมายถึง เราไม่ควรทำการแก้ไขโค๊ดที่ฝั่ง Arduino มากนัก แต่ควรจะมีโค๊ดที่สามารถปรับเปลี่ยนการทำงานตั้งแต่ฝั่ง Raspberry Pi เพื่อกำหนดการทำงานของ Arduino แทน ซึ่งในอินเตอร์เนตมี Library ประเภทนี้ อยู่ ตอนต่อไป ผมอาจจะนำมาสาธิตให้ดูนะครับ

สวัสดีครับ

อ่านเพิ่มเติม...

Wednesday, October 24

Simple Home Security System By Raspberry Pi

วันนี้ เรามาลองสร้างระบบเตือนภัยจากผู้บุกรุก โดยเราจะให้เจ้าบอร์ด Raspberry Pi ของเราทำการส่งเมล์ไปหาเรา ถ้ามีใครสักคนพยายามงัดแงะหน้าต่าง หรือประตูของเรา หรือจะเช็คจุดไหนก็ได้ ที่สามารถต่อสวิทช์ หรืออุปกรณ์ตรวจสอบใดๆ ก็ได้ที่ทำให้เกิดการเปลี่ยนแปลง logic จาก Low ไป High เพื่อที่เราจะได้ต่อเข้ากับ GPIO ของบอร์ด Raspberry Pi เมื่อเกิดการเปลี่ยนแปลงสถานะ logic ณ จุดใดๆ ที่ต่ออยู่กับ GPIO ของ Raspberry Pi แล้ว ให้เจ้าบอร์ด Raspberry Pi ของเราส่งเมล์มาบอกเรา เพียงเท่านี้ เราก็จะได้ระบบรักษาความปลอดภัย ที่กินไฟน้อยที่สุดในโลกแล้ว (อาจจะฟังดูเวอร์ไปเล็กน้อย :P )
อันนี้ เป็นวงจรการทำงานพื้นฐานนะครับ แน่นอน ถ้าจะทำจริงๆ ก็ต้องดัดแปลง ปรับปรุงให้เกิดความเสถียรภาพมากกว่านี้ ไม่ว่าจะเป็นระบบสำรองไฟฟ้า หากเกิดกรณีไฟฟ้าดับ และระบบป้องกันไฟเกิน และอื่นๆ อีกที่ควรจะใส่เข้าไป เพื่อให้ระบบเราทำงานได้ แม้ในสภาวะที่ไม่ปกติด้วยนะครับ ก็ลองไปคิดๆ กันดูว่าต้องมีอะไรบ้าง
Raspberry Pi Home Security System
ในที่นี้ ผมจะสมมติให้ push button ทำหน้าที่เป็นสวิทช์ประตู เมื่อมีการเปลี่ยน logic จาก high เป็น low ให้ raspberry Pi ทำการเริ่มส่งเมล์ มาตามที่กำหนดไว้ในโค๊ด
Raspberry Pi simple Circuit
ด้วยความสามารถของ Python เราสามารถที่จะเรียก package smtplib เพื่อติดต่อกับ mail server (ในที่นี้ ผมต้องการติดต่อกับ mail server ของ Gmail ) แล้วทำการส่งข้อความไปที่ inbox ของ mail ปลายทางที่เราต้องการได้ (ซึ่งนั่น น่าจะเป็นเมล์ของเรานะครับ) เรามาดูโค๊ดกันเลยครับ
สร้างไฟล์นี้ด้วยคำสั่ง nano mail.py
แล้วเขียนโค๊ดตามข้างล่างนี้ (ระวังเรื่อง indent ด้วยนะครับ สำหรับภาษาไพธอนเราจะใช้การ indent เป็นตัวจัดกลุ่มของคำสั่ง )
#--------------------------- Code start here ------------------------------------------------
#! /usr/bin/python
import RPi.GPIO as GPIO
import smtplib
import time
LOOP = True
GPIO.setmode(GPIO.BOARD)
GPIO.setup(26,GPIO.IN,pull_up_down=GPIO.PUD_UP)
SMTP_SERVER = 'smtp.gmail.com'
SMTP_PORT = 587
sender = 'raspberry security system'
recipient = 'wisit.paewkratok@gmail.com'
subject = 'Raspberry Pi Alert System'
body  = 'The door is opned!!!'
headers = ["From: " + sender,
           "Subject: " + subject,
           "To: " + recipient,
           "MIME-Version: 1.0",
           "Content-Type: text/html"]
headers = "\r\n".join(headers)
username = ‘ชื่อล๊อกอินของ Gmail'
password = 'พาสเวิร์ดสำหรับ Gmail'
while True:
    if(GPIO.input(26) == False):
        print('Mail alert sending....\n')
        server = smtplib.SMTP(SMTP_SERVER,SMTP_PORT)
        server.ehlo()
        server.starttls()
        server.ehlo()
        server.login(username,password)
        server.sendmail(sender,recipient,headers + "\r\n\r\n" + body)
        server.quit()
        GPIO.cleanup()
        LOOP = False
        print('Program terminated\n\n')
        break
    time.sleep(1)
    print('program is running ' + time.ctime() )
#----------------------------------- End Code ----------------------------------------------------------
ทำการบันทึกไฟล์ แล้วทำการเปลี่ยนให้ไฟล์นี้สามารถ execute ได้ ด้วยคำสั่ง
sudo chmod 755 mail.py
แล้วทำการทดลองรันสคริปต์ไพธอน ด้วยคำสั่ง
sudo ./mail.py
Python sending mail to Gmail server 
ถ้าทุกอย่างถูกต้อง เราจะพบเมล์ในกล่องขาเข้าของจดหมาย จาก raspberry security system
จากตัวอย่างที่นำเสนอนี้ เป็นรูปแบบอย่างง่าย นะครับ หากจะนำไปใช้จริงๆ เพื่อนต้องปรับแต่งให้ระบบของเพื่อนๆ สามารถที่จะตรวจสอบได้ตลอดเวลา ว่ายังทำงานอยู่หรือเปล่า และเมื่อเวลาเกิดเหตุการณ์ขึ้นแล้ว จะให้ Email ส่งมาเตือนกี่ครั้ง และจะรีเซตระบบกลับเหมือนเดิมได้อย่างไร นั่นเป็นสิ่งที่ต้องนำกลับไปคิดกันต่อนะครับ ลองๆ เอาไปประยุกต์กันดูนะครับ หวังว่าคงเริ่มสนุกกับ Raspberry Pi แล้วนะครับ
อ่านเพิ่มเติม...
 

แจกฟรี พื้นที่ฝากไฟล์ 15 GB

ติดตามข่าวสารผ่าน Twitter

ติดตาม Blog นี้

Blog อื่นๆของฉัน

Microcontroller Electronics update

สถิติเยี่ยมชมบล๊อก