วันพุธที่ ๒๙ มิถุนายน พ.ศ. ๒๕๕๙

Internet of Things (IoT) ตอนที่ 5

ตอนที่ 5 ว่าด้วยเรื่อง Raspberry Pi กับการต่อ input ที่เป็น micro switch เข้าทาง GPIO

การต่อสัญญาณเข้าไปประมวลผลใน MCU ของ Raspberry Pi เปรียบเสมือนกับการที่เราใช้ keyboard ป้อนข้อมูลเข้าเครื่องคอมพิวเตอร์ เพียงแต่ Raspberry Pi ได้ออกแบบ GPIO สำหรับให้เราต่ออุปกรณ์อิเล็คทรอนิกส์ เช่น สวิทช์ เพื่อส่งสัญญาณไปบอก MCU ว่ามีการกด หรือส่งสัญญาณไป แล้วคำสั่งใน MCU จะไปประมวลผลเพื่อไปควบคุมเครื่องใช้ไฟฟ้า หรืออุปกรณ์อิเล็คทรอนิกส์อีกทีหนึ่ง

แต่การต่อไมโครสวิทช์ ที่เราจะต่อวงจรเองนั้น มีความซับซ้อนและมีปัญหาหลาย ๆ อย่าง ในกรณีที่จะนำไปใช้งานจริง จึงต้องทดสอบ และพิถีพิถัน ให้มากยิ่งขึ้น

วงจรการต่อสวิทช์

การต่อสวิทช์ที่เกี่ยวข้องกับงาน MCU นั้น มี 2 วิธี ได้แก่


  • การต่อให้ส่งสัญญาณไปยัง MCU เป็น  0 volt หรือ Active Low
  • การต่อให้ส่งสัญญาณไปยัง MCU เป็น 3.3 volt หรือ Active Hi

วงจรสวิทช์ที่ทำงานแบบ Active Low






กรณีที่เป็น 0 volt (active low) นั่นหมายถึง ปกติแรงดันไฟฟ้าที่รออยู่เป็นสถานะ Hi หรือมีแรงดันไฟฟ้าประมาณ 3.3 volt เพราะกระแสไฟฟ้าจะไหลจาก vcc 3.3v ผ่าน R1 ที่เป็นความต้านทานขนาด 10K และผ่าน R2 ขนาด 1K ไปยังขา GPIO IN 

แต่เมื่อเรากดสวิทช์ สถานะ Hi จะเปลี่ยน Low เพราะว่า ขากราวด์ (0 volt) จะไหลผ่านสวิทช์ ไปสู่ R2 แล้วไปสู่ขา GPIO IN  ในขณะที่ R1 มีความต้านทานสูงถึง 10 K มันจึงไม่สามารถไหลผ่านไปได้ ตามหลักการของไฟฟ้าที่กระแสไฟฟ้าจะไหลผ่านสิ่งที่มีความต้านทานน้อยกว่า

วงจรสวิทช์ที่ทำงานแบบ Active Hi



การทำงานของวงจรสวิทช์แบบนี้ จะทำงานตรงกันข้ามกับแบบแรก ให้พิจารณาที่สวิทช์และ R1 จะสลับกับภาพแรก ดังนั้น เมื่อกดสวิทช์แรงดันไฟฟ้า 3.3 volt จากขา Vcc จะไหลผ่านสวิทช์ผ่านไปยัง R2 แล้วไปยังขา GPIO IN ประมาณแรงดันที่ 3.3 volt หรือ Active Hi นั่นเอง


การเขียนโปรแกรมทั้งสองวิธีก็แตกต่างกัน แต่ในปัจจุบันอุปกรณ์ที่เป็น micro switch ที่ใช้ในงาน MCU มักจะทำมาขายสำเร็จรูปมีความต้านทานอยู่ภายในอยู่แล้ว จึงมีขาเสียบ 3 ขา คือขา Vcc, GND และขาต่อ GPIO 

ในบอร์ดของ Arduino อาจต้องต่อวงจรแบบนี้ แต่สำหรับ Raspberry Pi แล้ว เขาออกแบบมาให้สามารถต่อวงจรไม่ต้องใช้ R ทั้ง 2 ตัวเลยก็ได้ ดังนี้



จากวงจรสวิทช์ที่ต่อใน breadboard นั้น เราสามารถต่อขาจาก Vcc 3v3 จาก GPIO มาเข้าขาเข้าสวิทช์ ส่วนขาออกสวิทช์ก็สามารถต่อไปยัง GPIO input ได้เลย แต่เราต้องกำหนดใน setup เป็นดังนี้


GPIO.setup(17, GPIO.IN, pull_up_down=GPIO.PUD_DOWN)

มาดู Source code ในการเขียนคำสั่งเพื่อรับ input จาก switch กันเลย

--------------------------------------------------------------------
import RPi.GPIO as GPIO
import time
green = 18
GPIO.setmode(GPIO.BCM)
GPIO.setwarnings(False) 
GPIO.setup(green,GPIO.OUT) 
GPIO.setup(17,GPIO.IN, pull_up_down=GPIO.PUD_DOWN)
i=0
while True:        
        if (GPIO.input(17)==1):        
                i+=1        
                print "button pressed: ", i
--------------------------------------------------------------------
จาก code นี้เพื่อแสดงให้เห็นถึงปัญหาจากการกดปุ่ม ในกรณีที่เขียนโปรแกรมแบบ poll หรือเข้าไปสอบถาม มันจะลูปซ้ำกันหลายครั้งในระยะที่เรากดครั้งหนึ่ง  นี้คือผลลัพธ์ของการกดปุ่ม 1 ครั้ง ด้านล่างนี้
จะเห็นว่ากดหนึ่งครั้งมันจะลูปประมาณ 1801 ครั้ง หากมีการกดสวิทช์ตัวถัดมา หรือตัวอื่น ๆ อาจจะมีปัญหา โดยเฉพาะมีการ delay ด้วย ดังนั้น raspberry pi จึงได้จัดให้มีคำสั่งสำหรับการเขียนแบบ ตรวจสอบการทำงานของปุ่มกดที่ขอบขาขึ้น และขอบขาลง คำสั่งดังตัวอย่างต่อไปนี้
--------------------------------------------------------------------
import RPi.GPIO as GPIO
GPIO.setmode(GPIO.BCM) GPIO.setup(17, GPIO.IN, pull_up_down = GPIO.PUD_DOWN)
i=0 while True: GPIO.wait_for_edge(17, GPIO.RISING)
i+=1 print "button pressed: ",i
-----------------------------------------------
ผลลัพธ์ที่ได้ จะแสดงข้อความว่า
     button pressed:  1
เพียงครั้งเดียวต่อการกด 1 ครั้ง เมื่อเรากดอีกครั้ง ข้อความจะเพิ่มเป็น
     button pressed:  2
แต่กรณีเราออกแบบให้มีสวิทช์หลายตัว เช่น ระบบจราจรที่กำลังจะทำให้ดูเป็นตัวอย่าง หากเขียนให้รอการกดปุ่มตามลำดับแบบนี้ ถ้าหากผู้ใช้กดปุ่มไม่เป็นไปตามลำดับก็จะมีปัญหา
มาดูวงจรของการทำสวิทช์ 4 ตัวเพื่อควบคุมจราจร 4 แยก ที่มีการกดปุ่มไฟเขียนตามลำดับ ดังนี้
----------------------------------------------------------
import RPi.GPIO as GPIO import time
ch1g = 21
ch1y = 20 
ch1r = 16
ch2g = 25
ch2r = 24
ch3g = 27
ch3r = 17
GPIO.setmode(GPIO.BCM) GPIO.setup(ch1g,GPIO.OUT) GPIO.setup(ch1y,GPIO.OUT) GPIO.setup(ch1r,GPIO.OUT) GPIO.setup(ch2g,GPIO.OUT) GPIO.setup(ch2r,GPIO.OUT) GPIO.setup(ch3g,GPIO.OUT) GPIO.setup(ch3r,GPIO.OUT)
GPIO.setup(05,GPIO.IN, pull_up_down=GPIO.PUD_DOWN)
GPIO.setup(06,GPIO.IN, pull_up_down=GPIO.PUD_DOWN)
GPIO.setup(13,GPIO.IN, pull_up_down=GPIO.PUD_DOWN)
GPIO.setup(19,GPIO.IN, pull_up_down=GPIO.PUD_DOWN)
def ch1():          
            GPIO.output(ch1g,GPIO.HIGH)          
            GPIO.output(ch2r,GPIO.HIGH)          
            GPIO.output(ch3r,GPIO.HIGH)          
            GPIO.output(ch1r,GPIO.LOW)
            GPIO.output(ch1y,GPIO.LOW)
            GPIO.output(ch2g,GPIO.LOW)
            GPIO.output(ch3g,GPIO.LOW)
def ch2():
            GPIO.output(ch2g,GPIO.HIGH)
            GPIO.output(ch3r,GPIO.HIGH)
            GPIO.output(ch1r,GPIO.HIGH)
            GPIO.output(ch1g,GPIO.LOW)
            GPIO.output(ch1y,GPIO.LOW)
            GPIO.output(ch2r,GPIO.LOW)
            GPIO.output(ch3g,GPIO.LOW)
def ch3():
            GPIO.output(ch3g,GPIO.HIGH)
            GPIO.output(ch2r,GPIO.HIGH)
            GPIO.output(ch1r,GPIO.HIGH)
            GPIO.output(ch3r,GPIO.LOW)
            GPIO.output(ch1y,GPIO.LOW)
            GPIO.output(ch2g,GPIO.LOW)
            GPIO.output(ch1g,GPIO.LOW)
while True:
               GPIO.wait_for_edge(05, GPIO.RISING)
               ch1()
               print "channel 1: "
               GPIO.wait_for_edge(06, GPIO.RISING)
               ch2()
               print "channel 2: "
              GPIO.wait_for_edge(13, GPIO.RISING)
               ch3()
               print "channel 3: "
----------------------------------------------------------------------------
ผลลัพธ์การทำงานของโปรแกรมดังแสดงในคลิป ด้านล่างนี้
video


วันพฤหัสบดีที่ ๒๓ มิถุนายน พ.ศ. ๒๕๕๙

Internet of Things (IoT) ตอนที่ 4

จากตอนที่ 1 ว่าด้วยหลักการ ความเป็นมา และอนาคตของ Internet of Things ซึ่งได้โน้มน้าวให้ผู้อ่านได้เห็นถึงความสำคัญ ให้อยากที่จะศึกษา อยากทดลองทำดู เผื่อว่าจะได้นำไปประยุกต์ใช้ในชีวิตประจำวัน หรือสร้างเป็น start up ดังที่เขาฮิตกัน

งาน Internet of Things นี้ขอบอกเลยว่า งานที่ยากที่สุด คือ ไอเดีย หรือความคิดสร้างสรรค์ หรือจินตนาการที่จะผลิตหรือสร้างอะไร ดังนั้น ทุกคนสามารถสร้างงานออกมาได้ โดยเฉพาะในด้านเทคนิควิธีการ เราสามารถหาอ่านเอาได้จากอินเทอร์เน็ต หรือดูจาก youtube

ตอนที่ 2 ได้เขียนถึงภาพรวม การทำงานของ Internet of Things มีองค์ประกอบอะไรบ้าง มันทำงานสัมพันธ์กันอย่างไร ถ้าให้ครบวงจรการทำงานของมันจะต้องใช้อะไรบ้าง

ตอนที่ 3 ได้เขียนถึง คำสั่งเพื่อทดสอบการทำงานของบอร์ด และได้ทดสอบโปรแกรม รวมทั้งการต่อวงจร LED เพื่อดูผลลัพธ์

มาตอนที่ 4 จะเป็นการเขียนโปรแกรมเพิ่มความซับซ้อนขึ้นมานิดหนึ่ง โดยจะจำลองเป็นการสั่งงานให้เปิดปิดไฟจราจร 3 สี แต่ทดลองทำเพียงด้านเดียวก่อน ถ้าต้องการทำหลายด้าน ก็สามารถทำได้โดยการเขียนคำสั่งให้พอร์ตอื่น ๆ ทำงานตามต้องการ

มาดู code กัน


#---------------------------------------------------------------------
#source code: traffic.py
import RPi.GPIO as GPIO
import time
red = 18
green = 23
yellow = 24
GPIO.setmode(GPIO.BCM)
GPIO.setwarnings(False)
GPIO.setup(red,GPIO.OUT)
GPIO.setup(green,GPIO.OUT)
GPIO.setup(yellow,GPIO.OUT)

#function
def blink(pin, stime, count):
      for i in range(count):
              GPIO.output(pin,GPIO.HIGH)
              time.sleep(stime)
              GPIO.output(pin,GPIO.LOW)
              time.sleep(stime)

#main program
while True:
       #stop state
       GPIO.output(red,GPIO.HIGH)
       time.sleep(10)
       blink(red,0.25,5)
       GPIO.output(red,GPIO.LOW)

       #go state
       GPIO.output(green,GPIO.HIGH)
       time.sleep(10)
       blink(green,0.15,10)
      GPIO.output(green,GPIO.LOW)

      #stop ready
      GPIO.output(yellow,GPIO.HIGH)
      time.sleep(3)
      GPIO.output(yellow,GPIO.LOW)
      time.sleep(0.5)
#-------------------------------------------------------------
Save file กำหนดชื่อ traffic.py
เมื่อสั่ง Run โปรแกรมที่ terminal ด้วยคำสั่ง
$ sudo python traffic.py 

จะได้ผลลัพธ์ดังนี้



หากผู้อ่านได้ทดลองเอาคำสั่งของโปรแกรมนี้ไปใช้ ท่านต้อง 
ต่อขา 18 เป็น LED สีแดง
ต่อขา 23 เป็น LED สีเขียว
ต่อขา 24 เป็น LED สีเหลือง

ได้ทำเสนอแนะเกี่ยวกับการกระพริบของไฟเขียวและไฟแดง ไว้ในตอนท้าย เพื่อให้ผู้ขับรถเตรียมตัว หรือระมัดระวัง เอาไว้ด้วย

ในตอนต่อไปจะได้เขียนโปรแกรมเพิ่มฟังก์ชันให้ตำรวจจราจร กดปุ่มเพื่อปล่อยรถในแต่ละแยกได้ตามต้องการ

แล้วตอนถัดไป จะเขียนโปรแกรมให้มีการเก็บข้อมูลการกดปุ่มของจราจร เพื่อนำไปใช้ในการวิเคราะห์ (analysis) เพื่อใช้ในงาน internet of things ได้ครบวงจรต่อไป

โปรดคอยติดตาม......