PHYSICAL PROGRAMMING ด้วย SCRATCH 1.4 บน RASPBERRY PI ตอน ควบคุม Servo motor ด้วย REMOTE SENSORS PROTOCOL

บทความก่อนหน้านี้ชี้ให้เห็นการใช้ Remote Sensors Protocol ของ  Scratch 1.4 บน Raspbian ว่าช่วยให้ Scratch ยืมมือความสามารถของ Raspberry Pi มาใช้ในการเรียนรู้ Physical Programming ได้ ในบทความนี้จะแสดงตัวอย่างที่ชัดเจนขึ้นโดยการใช้ Scratch 1.4 ควบคุม Servo motor  กันครับ แต่ก่อนจะกล่าวถึงนั้นจำเป็นต้องกล่าวถึงเรื่อง "message type" เสียก่อน 

Remote Sensors Protocol  ได้กำหนดชนิดของข้อความไว้สองชนิดคือ

1. broadcast เป็นลักษณะข้อความทั่วไป โดยมีโครงสร้างประกอบด้วยสองส่วนดังนี้

broadcast <string>

ส่วนหัวจะต้องเป็น broadcast และส่วนตัวคือเนื้อความ เช่น broadcast 'Hello World'

2. sensor-update เป็นข้อความที่มีการระบุชื่อตัวแปรและค่าของตัวแปร  มีโครงสร้างสามส่วนดังนี้

sensor-update <variable-name> <variable-value> ....

ส่วนหัวจะต้องเป็น sonsor-update ส่วนชื่อตัวแปร และ ส่วนค่าของตัวแปร เช่น sensor-update temperature 30 humidity 60

ข้อสังเกตุ

จะต้องมี space คั่นระหว่างองค์ประกอบของข้อความ ซึ่งเราจะนำไปใช้ประโยชน์ภายหลัง


การส่ง message type แบบ broadcast



การส่ง message type แบบ sensor-update จาก Python



การส่ง message type แบบ sensor-update จาก Scratch 1.4


พอจะมองภาพออกนะครับว่า message type มีส่วนสำคัญในการสื่อสาร เมื่อใดที่เราต้องการให้ระบบมีรับทราบถึงการเปลี่ยนแปลงค่าของตัวแปรหรือสถานะบางอย่าง การใช้ "sensor-update" จะเหมาะสมกว่า แต่ในกรณีทั่วไปหรือการส่งคำสั่งที่เราออกแบบเอง ก็ใช้ "broadcast"

กลับมาสู่เรื่องการควบคุม Servo motor ผมจะใช้ "sensor-update" ในการส่งค่ามุมที่ Servo ต้องหมุน จาก Scratch มายัง Python เพื่อให้ Python ทำการสั่งการ Servo ต่ออีกที ตามแผนภาพ


Scratch ควบคุมการหมุนของ Servo motor ผ่าน Python




ต่อ Raspberry Pi กับ Servo motor

เพื่อให้เห็นภาพชัดเจนขึ้นผมจะใช้ Servo motor สองตัว นำมาต่อทำมุมตั้งฉากกัน เพื่อให้มันทำงานเหมือนกับระบบ Pan and Tilt ของกล้อง ครับ






รายการอุปกรณ์

1. Servo 2 ตัว ในกรณีของผมใช้ Servo ใช้แรงดันขนาด 4.8 - 6.0 (ในรูปจะใช้แหล่งจ่ายไฟขนาด 9.0 V ซึ่งจะไม่ตรงกับความจริงนะครับ)
2.  ตัวต้านทานขนาด 1 K ohm 2 ตัว
3.  jump wires

คำอธิบาย

1. ต่อสายสัญญาณจาก GPIO Pin ตำแหน่งที่ 35 ไปยังสายสัญญาณของ Servo ที่ทำหน้าที่เป็น Tilt Servo และ จาก GPIO Pin ตำแหน่งที่ 37 ไปยังสายสัญญาณของ Servo ที่ทำหน้าที่เป็น Pan Servo โดยใช้ resistor ขนาด 1 K ohm คั่นระหว่างสายสัญญาณ

2.  ต่อสาย Ground ร่วมระหว่าง Servo ทั้งสองกับ  Raspberry Pi

3. ต่อสาย Servo เข้ากับแหล่งจ่ายไฟ


สร้าง Scratch Script




คำอธิบาย

1. Script นี้จะการวน Loop (สามารถเปลี่ยนแปลงจำนวน Loop ได้) เพื่อสอบถามผู้ใช้ถึงค่าของมุมที่ต้องการ

2. คำถามแรกเป็นการถามค่าของมุมสำหรับ tilt หรือมุมเงย พร้อมกับตรวจสอบค่าที่ป้อนเข้ามาว่าต้องอยู่ในช่วง 0 - 180

3.  ทำการ set ค่าตัวแปรชื่อ tilt_ang ให้เท่ากับค่าที่ผู้ใช้ป้อนเข้ามา ในขั้นตอนนี้ Scratch จะทำการปรับปรุงค่าตัวแปร tilt_ang แล้วทำการส่งข้อความ "sensor-update tilt_ang xxx"   (xxx คือค่าทีีผู้ใช้ป้อน) ไปยัง Python โดยอัตโนมัติ

4. ทำการรอ สองวินาที

5. ทำซ้ำข้อ 2 - 4 แต่เปลี่ยนไปทำงานกับตัวแปรชื่อ pan_ang

6. ออกจากโปรแกรมเมื่อทำงานครบตามจำนวนรอบที่กำหนด

Python script

ในการใช้งาน Python จำเป็นต้องใช้ code ในบทความเรื่องก่อนหน้านี้  และในการควบคุม Servo นั้นผมใช้ Library จากโครงการ RPI.GPIO.TH

file: demo_scratch_servo.py

from ScratchPy import *
from gadgets.motors.servos import Servo5V
import time

def do_pan(angle):
     global p_servo 
     p_servo.write(angle)

def do_tilt(angle):
    global t_servo 
    t_servo.write(angle)
 
def parse_cmd(in_str):
    global stop_flag
    if  in_str[0] == 'broadcast' :
         if in_str[1] == 'finish':
              stop_flag = True
              return    
    elif in_str[0] == 'sensor-update' : 
         if in_str[1] == 'pan_ang' :
              do_pan(int(in_str[2]))
         elif in_str[1] == 'tilt_ang' :
              do_tilt(int(in_str[2])) 
  

# servo controllers
t_servo = Servo5V(pin_number=35,freq=50)
p_servo = Servo5V(pin_number=37,freq=50)

#Scratch communication
sc = Py2Scratch14()
sc.connect()

#program loop
stop_flag = False
while not stop_flag:
     try: 
          in_str =  sc.receive()
          parse_cmd(in_str)
     except KeyboardInterrupt :
          stop_flag = True


#clean up  
t_servo.cleanup() 
p_servo.cleanup() 
 


คำอธิบาย

1.  เริ่มต้นด้วยการนำเข้า Library ที่จะต้องใช้งาน
2.  ประกาศตัวแปร t_servo เป็น instance ของ Servo5V เพื่อใช้งานเป็น Tilt Servo  โดยกำหนดให้ต่อกับ GPIO Pin ตำแหน่งที่ 35
3. ประกาศตัวแปร p_servo เป็น instance ของ Servo5V เพื่อใช้งานเป็น Pan Servo  โดยกำหนดให้ต่อกับ GPIO Pin ตำแหน่งที่ 37
4. ประกาศตัวแปร sc เป็น instance ของ Py2Scratch14 เพื่อใช้ติดต่อกับ  Scratch
5. วนลูปเพื่อรับข้อความจาก Scratch เมื่อมีข้อความมา ให้ส่งไปยัง parse_cmd()
6. ภายใน parse_cmd() จะทำการแยกข้อความออกเป็นสามส่วน
    6.1 หากส่วนแรกเป็น 'broadcast' และส่วนสองเป็น "finish" ทำการกำหนด stop_flag = True
    6.2 หากส่วนแรกเป็น 'sensor-update'
        6.2.1 หากส่วนสองเป็น "pan_ang" (ชื่อตัวแปร) ให้ส่งส่วนที่สาม (ค่าตัวแปร) ไป do_pan()
        6.2.2 หากส่วนสองเป็น "tilt_ang"  ให้ส่งส่วนที่สามไป do_tilt()
7. do_pan() และ do_tilt() เป็นการสั่งการให้ Servo หมุนไปยังองศาตามตัวเลขที่ให้มา

ขั้นตอนการใช้งาน

1. ต่อ Servo เข้ากับ Raspberry Pi ตามที่ระบุไว้ข้างต้น
2. เปิด Scratch 1.4 บน Raspberry Pi แล้วทำการ  enable remote sensors connection
3. สร้างตัวแปรใน Scratch กำหนดชื่อเป็น pan_ang และ tilt_ang แล้วสร้าง Script ตามที่กล่าวไว้ข้างต้น
4. สร้าง Python code ตามที่กล่าวไว้ข้างต้น แล้วบันทึกไว้ใน demo_scratch_servo.py
5. ใช้คำสัั่ง python3 demo_scratch_servo.py
6. ผลที่ได้แสดงในวิดีโอข้างล่างนี้




หมายเหตุ

ขั้นตอนการ RPI.GPIO.TH มาใช้งาน
1.  กรณีที่ใช้ Raspbian ซึ่งมี git ติดตั้งมาแล้ว

$ git https://github.com/somchaisomph/RPI.GPIO.TH.git
$ cd RPI.GPIO.TH

สำเนา gadgets ไปใช้งาน

2. กรณีที่ไม่มี git ให้ใช้ https://github.com/somchaisomph/RPI.GPIO.TH/archive/master.zip เพื่อดาวน์โหลด code มา แตกไฟล์ที่ได้ออกมา แล้วสำเนา gadgets ไปใช้งาน
Previous
Next Post »