[TH] Reading the Accelerator sensor with raspberry pi via I2C Bus.

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

ภาพที่ 1

อุปกรณ์

  1. บอร์ด Raspberry Pi รุ่น 2/3 หรือ 4
  2. โมดูล MMA7660FC
ภาพที่ 2 โมดูล MMA7660FC ที่ติดตั้งกับฝาของกล่องบอร์ด Raspberry Pi
ภาพที่ 3 บอร์ด Raspberry Pi 3 ที่ใช้กับบทความนี้

ทำความรู้จักกับ GPIO

ก่อนเริ่มใช้งานโมดูล mma7660FC ต้องทำความเข้าใจเรื่องของ GPIO หรือขาเชื่อมต่อกับอุปกรณ์ภายนอกของบอร์ด Raspberry Pi กันก่อน โดยคำสั่งที่มีประโยชน์ต่อการใช้งานคือคำสั่ง gpio

การตรวจสอบรุ่นและคุณสมบัติของบอร์ดที่ใช้งานอยู่ทำโดยการพิมพ์คำสั่ง gpio -v หลังจากนั้นโปรแกรมรายงานรุ่นออกมาให้ทราบ พร้อมบอกรายละเอียดเกี่ยวกับบอร์ด จำนวนหน่วยความจำของบอร์ดดังภาพที่ 4

ภาพที่ 4 ผลลัพธ์ของคำสั่ง gpio -v

กรณีที่ต้องการทราบว่าแต่ละขาของ GPIO ทำหน้าที่ใด สามารถใช้คำสั่ง gpio ตามด้วยอาร์กิวเมนต์ readall เพื่อรายงานบทบาทหน้าที่ของขาได้ดังภาพที่ 5 ซึ่งในบทความนี้เลือกเชื่อมต่อกับบอร์ด Raspberry Pi ผ่านทางบัส I2C ช่องสัญญาณที่ 1

ภาพที่ 5 ผลลัพธ์ของคำสั่ง gpio readall

การเปิดใช้บัส I2C

การใช้งานบัส I2C ของบอร์ด Raspberry Pi จะต้องเปิดการอนุญาติให้เข้าถึงโดยการเข้าที่เมนูหลักและเลือกรายการเมนูชื่อ Preferences ดังภาพที่ 6 หลังจากนั้นเลือกรายการเมนูย่อยชื่อ Raspberry Pi Configuration ดังภาพที่ 7 จะมีหน้าต่างโปรแกรมดังภาพที่ 8

ภาพที่ 6 เมนูของ Raspbian
ภาพที่ 7 รายการย่อยในเมนู Preferences
ภาพที่ 8 หน้าต่างโปรแกรม Raspberry Pi Configuration

จากภาพที่ 8 ให้เลือกแท็บ interfaces และเลือก Enable ในหัวข้อ I2C เพื่อเปิดการอนุญาติให้เข้าใช้งานหรือเข้าถึงบัส I2C ของบอร์ด Raspberry Pi หลังจากเปิดการทำงานของบัส I2C เรียบร้อยให้คลิกปุ่ม OK และสั่ง reboot บอร์ด Raspberry Pi อีกครั้ง เพื่อความมั่นใจว่าบัสพร้อมใช้งาน

การเชื่อมต่อ

การเชื่อมต่อโมดูลเซ็นเซอร์เข้ากับบอร์ด Raspberry Pi ผ่านทางบัส I2C ช่องสัญญาณที่ 1 เป็นดังภาพที่ 9 และ 10 โดยต่อขาดังตารางต่อไปนี้

โมดูลเซ็นเซอร์gpio ของ Raspberry Pi
VCC3V3
GNDGND
SDASDA.1
SCLSCL.1
ภาพที่ 9 การเชื่อมต่อโมดูลเซ็นเซอร์เข้ากับ GPIO ของ Raspberry Pi
ภาพที่ 10 การเชื่อมต่อกับขา 3V3, SDA.1, SCL.1 และ GND

ตรวจสอบผลการเชื่อมต่อ

หลังจากเชื่อมต่อโมดูลเซ็นเซอร์กับ GPIo ของบอร์ด Raspberry Pi เป็นที่เรียบร้อยให้ทำการตรวจสอบผลการเชื่อมต่อด้วยการเรียกคำสั่ง i2cdetect ตามด้วยอาร์กิวเมนต์ -y 1 เพื่อระบุการตรวจสอบการเชื่อมต่อบนบัส I2Cช่องสัญญาณที่ 1 ดังภาพที่ 11 ซึ่งจะพบว่ามีอุปกรณ์ติดตั้งที่ตำแหน่ง 4c หรือ 0x4c อันเป็นตำแหน่งของโมดูลเซ็นเซอร์ที่เชื่อมต่อกับบอร์ด Raspberry Pi

ภาพที่ 11 ผลลัพธ์ของคำสั่ง i2cdetect -y 1

ตัวอย่างโปรแกรม

ตัวอย่างโปรแกรม code16-1 มีการสร้างคลาส MMA7660FC ซึ่งดัดแปลงมาจากตัวอย่างก่อนหน้านี้ โดยเปลี่ยนคำสั่งใช้งานให้เป็นคำสั่งของบอร์ด Raspberry Pi ซึ่งจะพบว่าการเปิดใช้งานบัส I2C ต้องเรียกใช้ไลบรารีชื่อ smbus หลังจากนั้นต้องสร้างวัตถุสำหรับอ้างอิงถึงบัส I2C ดังรูปแบบต่อไปนี้

วัตถุ = smbus.SMBus( หมายเลขช่องสัญญาณของบัสI2Cที่ใช้งาน )

การเขียนข้อมูลไปยังบัส I2C มีรูปแบบการใช้งานดังนี้

วัตถุ.write_byte_data(
ตำแหน่งอุปกรณ์,
คำสั่ง,
ข้อมูล
)

การอ่านข้อมูลแบบหลายไบต์จากบัส I2C มีรูปแบบการใช้งานดังนี้

ผลลัพธ์ = วัตถุ.read_i2c_block_data(
ตำแหน่งของอุปกรณ์,
คำสั่ง,
จำนวนข้อมูลที่อ่าน
)

เมื่อโปรแกรมทำงาน และมีการต่อวงจรที่ถูกต้องจะแสดงผลลัพธดังภาพที่ 12

# code16-1 : MMA7660FC with Raspberry Pi
import time
import smbus
import sys
if sys.platform != 'linux':
    sys.exit(1)
i2c = smbus.SMBus(1)
class MMA7660FC:
    def __init__(self, i2c, addr=0x4c):
        self.i2c = i2c
        self.mma7660fcAddr = addr
        self.i2c.write_byte_data( self.mma7660fcAddr, 0x07, 0x01 )
        self.i2c.write_byte_data( self.mma7660fcAddr, 0x08, 0x07 )
        time.sleep(0.01)
    def read(self):
        data = self.i2c.read_i2c_block_data(self.mma7660fcAddr, 0x00, 3)
        # Convert the data to 6-bits
        xAccl = data[0] & 0x3F
        if xAccl > 31 :
            xAccl -= 64
        yAccl = data[1] & 0x3F
        if yAccl > 31 :
            yAccl -= 64
        zAccl = data[2] & 0x3F
        if zAccl > 31 :
            zAccl -= 64
        return (xAccl,  yAccl,  zAccl)

if __name__=='__main__':
    sensor = MMA7660FC(i2c)
    while True:
        sData = sensor.read()
        print("Acceleration ({},{},{})".format(sData[0],sData[1],sData[2] ))
        time.sleep(1)
ภาพที่ 12 ตัวอย่างผลลัพธ์ของ code16-1

สรุป

จากบทความนี้จะพบว่าการนำโมดูลเซ็นเซอร์มาใช้งานกับบอร์ด Raspberry Pi นั้นมีความแตกต่างกับการใช้กับ ESP8266 ในเรื่องของการต่อขา การเปิดสิทธิ์การให้ใช้งานบัส I2C และไลบรารีที่ไม่เหมือนกัน เนื่องจาก ESP8266 ใช้ MicroPython ที่ตัดส่วนมาจาก Python 3 และเพิ่มเรื่องของไดรเวอร์และไบรารีที่ปรับแต่งให้เหมาะสมกับอุปกรณ์ที่มีปริมาณหน่วยความจำและพื้นที่จัดเก็บที่น้อยกว่า และมีความเร็วในการทำงานที่ช้ากว่า แต่อย่างไรก็ดี เมื่อสังเกตการเขียนโค้ดจะพบว่า หลักการเขียนหรืออัลกอริธึมของโปรแกรมนั้นยังคงเหมือนเดิม ทำให้สามารถปรับปรุงโค้ดจากแพล็ตฟอร์มหนึ่งมาเป็นแพล็ตฟอร์มอื่นได้ง่าย ซึ่งเป็นข้อดีของการพัฒนางานด้วยภาษาไพธอน

สุดท้ายนี้ทางทีมผู้เขียนหวังว่าบทความนี้คงมีประโยชน์ไม่มากก็น้อยสำหรับผู้สนใจ และขอให้สนุกกับเขียนโปรแกรมครับ

(C) 2020, โดย อ.ดนัย เจษฎาฐิติกุล/อ.จารุต บุศราทิจ
ปรับปรุงเมื่อวันที่ 2020-10-29