ติดตั้ง MemryX MX3 บน Raspberry Pi 5 ให้พร้อมรัน Edge AI

ถ้า Raspberry Pi 5 ของเราทำ Linux, GPIO และงาน Embedded ได้อยู่แล้ว คำถามต่อไปของสาย Maker ก็คือ จะพามันไปทำ Computer Vision แบบจริงจังขึ้นได้ยังไง?

โปรเจกต์นี้พาไปไกลกว่าการเสียบ AI Accelerator แล้วจบ เพราะเริ่มตั้งแต่เขียน Raspberry Pi OS ลง microSD, ประกอบ MemryX MX3 M.2 AI Accelerator, ติดตั้ง Driver, Runtime และ SDK, ทดลอง MediaPipe Hands กับ YOLOE ก่อนปิดท้ายด้วยการเอา Computer Vision ไปควบคุม LED ผ่าน GPIO จริง

ผู้เขียนต้นฉบับเล่าว่าเคยเจอข้อจำกัดของ Microcontroller ทั้ง Memory และ Processing Power รวมถึงการต้องเพิ่ม Module แยกเมื่ออยากได้ Wireless, Cellular หรือ GPS ก่อนจะหันมาทำงานกับ Single-board Computer และเคยใช้ Raspberry Pi ทำระบบเช็กชื่อนักศึกษาในโปรเจกต์จบวิศวกรรมไฟฟ้า

จากตรงนั้นจึงมาถึงโจทย์ของบทความนี้: เปลี่ยน Raspberry Pi 5 ให้กลายเป็นแพลตฟอร์ม Edge AI ที่มองภาพจาก Webcam และสั่ง Hardware จริงได้

ติดตั้ง MemryX MX3 AI Accelerator บน Raspberry Pi 5
Raspberry Pi 5 กับ MemryX MX3 M.2 AI Accelerator ชุดฮาร์ดแวร์หลักของโปรเจกต์ Edge AI และ Computer Vision ในบทความนี้

Key Takeaways

  • โปรเจกต์ใช้ Raspberry Pi 5 โดยต้นฉบับแนะนำรุ่น RAM 8GB ร่วมกับ MemryX MX3 M.2 AI Accelerator และ PCIe HAT
  • เริ่มจาก Raspberry Pi OS แบบ 64-bit ก่อนติดตั้ง MemryX Driver, Runtime และ SDK
  • ขั้นตอนจากต้นฉบับทดสอบกับ MemryX SDK 2.2 และใช้ Python 3.12 ใน Virtual Environment
  • ทดสอบ Computer Vision ด้วย MediaPipe Hand Landmarks Tracking และ YOLOE Open-Vocabulary Segmentation
  • โปรเจกต์สุดท้ายใช้ Webcam ตรวจจับมือ แล้วเชื่อมผล Computer Vision เข้ากับ GPIO เพื่อเปิด-ปิด LED
  • Code Snippet ในบทความนี้มาจาก Source ต้นฉบับ และถูกซ่อนไว้ด้วย View more เพื่อไม่ให้บทความยาวจนอ่านยาก

ก่อนเริ่ม: คู่มือต้นฉบับระบุว่าขั้นตอน Software ถูกทดสอบกับ MemryX SDK 2.2 และ Software, Package, Repository หรือ Python Compatibility สามารถเปลี่ยนได้ในอนาคต หากคำสั่งติดตั้งไม่ตรงกับเวอร์ชันปัจจุบัน ให้ตรวจสอบ คู่มือติดตั้ง Software ล่าสุดจาก MemryX Developer Hub ก่อนแก้คำสั่งเอง

โปรเจกต์นี้จะทำอะไร?

Workflow ของต้นฉบับเดินจาก “บอร์ดเปล่า” ไปถึง “Computer Vision ควบคุม Hardware” เป็น 6 ช่วงต่อเนื่องกัน

1

เตรียม Raspberry Pi OS

เขียน Raspberry Pi OS 64-bit ลง microSD ด้วย Raspberry Pi Imager

2

ตั้งค่า Raspberry Pi Desktop

ต่อจอ Mouse Keyboard และ Network แล้วผ่าน Initial Setup Wizard

3

ประกอบ MemryX MX3

ใส่ Heatsink, PCIe HAT, Ribbon Cable และ MX3 M.2 Module ลงบน Raspberry Pi 5

4

ติดตั้ง Driver, Runtime และ SDK

ติดตั้ง MemryX Software และสร้าง Python 3.12 Virtual Environment

5

ลอง Computer Vision จริง

ใช้ MediaPipe Hands ตรวจ Landmark ของมือ และใช้ YOLOE ตรวจจับ/Segment Object จาก Webcam

6

เอา AI ไปคุม LED

ต่อ LED เข้ากับ Raspberry Pi GPIO แล้วใช้ตำแหน่งนิ้วจาก Computer Vision Toggle ไฟ ON/OFF

อุปกรณ์ที่ต้องใช้

อุปกรณ์ รายละเอียดจากต้นฉบับ
Raspberry Pi 5 ต้นฉบับแนะนำ 8GB RAM หรือมากกว่า และแนะนำ Complete Kit
MemryX MX3 MemryX MX3 M.2 Edge AI Accelerator จำนวน 1 ตัว
PCIe HAT M.2 to PCIe HAT สำหรับ Raspberry Pi
Display Monitor ที่มี HDMI Input
Input Mouse และ Keyboard
Webcam ใช้สำหรับ Computer Vision Example และ Gesture Control
Storage microSD Card + Card Reader
LED Project LED, Jumper Male-to-Female 2 เส้น, Resistor 100–330Ω, Breadboard

กำลังเตรียมของสำหรับโปรเจกต์? ถ้าต้องการ Raspberry Pi 5, บอร์ดพัฒนา หรืออุปกรณ์ Maker สามารถสอบถามทีม Globalbyte ผ่าน LINE OA Globalbyte ก่อนเลือกอุปกรณ์ให้เข้ากับโปรเจกต์ได้

Step 1: เตรียม Raspberry Pi OS ลง microSD

เริ่มจาก Raspberry Pi 5 ให้เป็น Linux Computer ที่พร้อมใช้งานก่อน โดยต้นฉบับใช้ Raspberry Pi OS เวอร์ชัน 64-bit

สิ่งที่ต้องมีในขั้นตอนนี้

  • microSD Card
  • microSD Card Reader
  • คอมพิวเตอร์ Linux, macOS หรือ Windows

ขั้นตอน

  1. ดาวน์โหลดและติดตั้ง Raspberry Pi Imager จากเว็บไซต์ทางการของ Raspberry Pi
  2. เสียบ microSD Card เข้าคอมพิวเตอร์ผ่าน Card Reader
  3. เปิด Raspberry Pi Imager
  4. เลือก Device เป็น Raspberry Pi 5
  5. เลือก Operating System เป็น Raspberry Pi OS เวอร์ชันล่าสุดแบบ 64-bit
  6. เลือก microSD Card เป็น Storage
  7. ที่หน้า Customization ต้นฉบับเลือก Skip Customization
  8. กด Write เพื่อให้ Imager ลบข้อมูลเดิมและเขียน OS ลง microSD

ระวัง: ขั้นตอน Write จะลบข้อมูลบน microSD Card ให้ตรวจสอบว่าเลือก Storage ถูกตัว และ Backup ข้อมูลที่ต้องการไว้ก่อน

เมื่อ Raspberry Pi Imager เขียนระบบเสร็จ ให้นำ microSD ออกจากคอมพิวเตอร์อย่างปลอดภัย แล้วใส่เข้า Raspberry Pi 5

Step 2: ตั้งค่า Raspberry Pi Desktop ครั้งแรก

ต่ออุปกรณ์ก่อนเปิดเครื่อง

  • ต่อ HDMI-to-micro-HDMI จาก Monitor ไปที่ HDMI 0 ของ Raspberry Pi
  • ต่อ Mouse และ Keyboard ผ่าน USB
  • หากใช้ Ethernet ให้เสียบสาย Network ก่อน
  • ต่อ Power Adapter เข้าพอร์ต USB-C ของ Raspberry Pi

เมื่อ Boot ขึ้นมา จะเจอหน้าต่าง Welcome to the Raspberry Pi Desktop สำหรับตั้งค่าครั้งแรก

เดินตาม Setup Wizard

  1. กด Next ที่ Welcome Screen
  2. เลือก Country, Language และ Time Zone และเลือก Use US keyboard หากกำลังใช้ Layout แบบ US
  3. สร้าง Username และ Password
  4. เลือก Wi-Fi แล้วใส่ Password หรือข้ามได้หากใช้ Ethernet
  5. เลือก Web Browser ที่ต้องการ
  6. ระบบจะถามเรื่อง Software Update ซึ่งต้นฉบับแนะนำให้อัปเดตในขั้นตอนนี้ หาก Internet พร้อม
  7. หน้าสุดท้ายกด Launch

ตอนนี้ Raspberry Pi Desktop พร้อมสำหรับการติดตั้ง MX3 แล้ว

Step 3: ติดตั้ง MemryX MX3 Hardware

ขั้นตอนนี้มีชิ้นส่วนเล็กและ Connector หลายจุด จึงควรทำช้า ๆ และตรวจ Orientation ก่อนกดหรือขันทุกครั้ง

3.1 เตรียม MX3 และ Heatsink

  1. วาง Accelerator บน Bracket Heatsink สีเทา โดยหันด้านบนขึ้น
  2. เช็ก Alignment Post เล็ก ๆ ให้เข้าในรูวงกลมของ Accelerator Board
  3. วาง Heatsink ด้านบน และจัดรู Screw ให้ตรงกัน
  4. ใส่ Screw สีดำทั้ง 4 ตัว แล้วขันอย่างเบามือ

ห้ามขันฝืน: หากรู้สึกว่ามีแรงต้านผิดปกติ ให้หยุดและจัดตำแหน่ง Heatsink / Bracket ใหม่ ไม่ควรขัน Screw จนแน่นเกินไป

3.2 ติดตั้ง PCIe HAT

  1. ใส่ Screw ของ HAT ลงใน Mounting Hole และยึดด้วย Brass Standoff ทั้ง 4 จุด
  2. เตรียม PCIe Ribbon Cable ซึ่งมีด้านระบุ To RPi และ To HAT
  3. ด้าน To RPi ต้องต่อเข้ากับ Raspberry Pi
  4. ต้นฉบับระบุให้ Printed Markings หันออกจาก Raspberry Pi และตอนใส่ Cable ให้ Marking หันไปทาง microSD Card
  5. กด Brown Locking Tab เพื่อยึด Ribbon Cable
  6. วาง HAT ด้านบน Raspberry Pi พร้อมจัด GPIO Header และ Mounting Hole ให้ตรง
  7. เปิด Gray Locking Tab บน HAT แล้วใส่ปลาย Ribbon Cable อีกด้าน
  8. กด Locking Tab กลับลง เพื่อยึด Cable

3.3 ใส่ MX3 ลง M.2 Slot

  1. ใส่ MX3 Module เข้า M.2 Slot ที่มุมประมาณ 35 องศา
  2. ค่อย ๆ กดปลายอีกด้านลง จนรู Mounting ตรงกับ PCB
  3. ยึดด้วย M.2 Screw แค่พอให้ Module อยู่ราบและไม่ขยับ

Cooling สำคัญ: เอกสาร MemryX ระบุว่า Chip สามารถเริ่ม Thermal Throttling เมื่ออุณหภูมิถึง 100°C จึงควรมี Airflow ผ่าน Heatsink โดยเฉพาะเมื่อต้องรัน AI ต่อเนื่อง

หากต้องการดูรายละเอียดฮาร์ดแวร์จากผู้ผลิตโดยตรง ให้เปิด คู่มือติดตั้ง MX3 M.2 จาก MemryX ประกอบก่อนเปิดเครื่อง

Step 4: ติดตั้ง MemryX Runtime และ SDK

Hardware อยู่ครบแล้ว รอบนี้เข้าสู่ Linux Terminal เพื่อติดตั้ง Driver, Runtime Libraries และ Developer Tools

4.1 ติดตั้ง Runtime

เปิด Terminal ด้วย Icon หรือกด Ctrl + Alt + T

อัปเดต Raspberry Pi OS
sudo apt update
sudo apt full-upgrade -y
sudo reboot
ติดตั้ง Kernel Headers
sudo apt-get install linux-headers-$(uname -r)
เพิ่ม MemryX Signing Key
wget -qO- https://developer.memryx.com/deb/memryx.asc | sudo tee /etc/apt/trusted.gpg.d/memryx.asc >/dev/null
เพิ่ม MemryX Repository
echo 'deb https://developer.memryx.com/deb stable main' | sudo tee /etc/apt/sources.list.d/memryx.list >/dev/null
ติดตั้ง Drivers และ Runtime
sudo apt-get update && sudo apt-get install memx-drivers memx-accl
ตั้งค่า Raspberry Pi 5
sudo mx_arm_setup
Reboot
sudo reboot
ตรวจอุณหภูมิ MX3
cat /sys/memx0/temperature
ตรวจ Driver Version
apt policy memx-drivers
ติดตั้ง Plugins และ GUI Utilities
sudo apt-get install memx-accl-plugins memx-utils-gui

เมื่อรัน sudo mx_arm_setup ให้เลือก Raspberry Pi 5 ตามขั้นตอนต้นฉบับ แล้ว Reboot

หลัง Boot กลับมา ใช้ apt policy memx-drivers เช็ก Driver โดยตัวอย่างในต้นฉบับเห็น Version ประมาณ 2.2.1-3

ส่วน Plugins และ Utility Libraries ในบทความต้นฉบับมี Download ประมาณ 1.4GB จึงอาจใช้เวลาสักพัก

4.2 ติดตั้ง MemryX Tools ด้วย Python 3.12

จุดนี้ต้องอ่านดี ๆ เพราะต้นฉบับระบุว่า Raspberry Pi OS ที่ใช้มี Python 3.13 แต่ MemryX Tools ณ เวลาที่เขียนบทความ ยังไม่รองรับ Version นี้

ผู้เขียนจึงใช้ uv ติดตั้ง Python 3.12 และสร้าง Virtual Environment ชื่อ ~/mx

ติดตั้ง uv
curl -LsSf https://astral.sh/uv/install.sh | sh
source $HOME/.local/bin/env
สร้าง Python 3.12 Virtual Environment
# install 3.12
uv python install 3.12

# Create the environment and include pip
uv venv --seed --python 3.12 ~/mx

# activate the venv
source ~/mx/bin/activate

# Upgrade the packaging tools
python -m pip install --upgrade pip wheel

# clear shell's command lookup cache
hash -r
ติดตั้ง System Dependencies
sudo apt-get update && sudo apt-get install libhdf5-dev python3-dev cmake python3-venv build-essential
ติดตั้ง MemryX Python Package
uv pip install --index-url https://developer.memryx.com/pip --extra-index-url https://pypi.org/simple memryx
ตรวจ Neural Compiler Version
mx_nc --version

ต้นฉบับระบุว่า System Dependencies มี Download ราว 111MB ส่วน MemryX Python Package ราว 2.2GB

เมื่อรัน mx_nc --version ตัวอย่างในคู่มือแสดง Version 2.2.1

Step 5: ทดลอง Computer Vision บน Raspberry Pi 5

Driver พร้อม SDK พร้อม รอบนี้ได้เวลาเช็กว่าระบบ AI ใช้งานจริงได้หรือยัง

ต้นฉบับเลือก 2 Example จาก MemryX Examples:

  • MediaPipe Hand Landmarks Tracking
  • YOLOE Open-Vocabulary Segmentation

Clone MemryX Examples ก่อน

Clone MemryX Examples
git clone --recursive https://github.com/memryx/memryx_examples.git
Activate Virtual Environment
source ~/mx/bin/activate

5.1 MediaPipe Hand Landmarks Tracking

Example นี้รับ Live Video จาก Webcam ส่ง Frame ไปยัง MemryX Accelerator ตรวจจับมือ แล้ววาด Landmark ลงบนภาพ

ระบบยังสามารถแยกมือซ้ายกับมือขวาได้ และนี่คือฐานที่นำไปต่อยอด Gesture Control ใน Step สุดท้าย

เข้า Folder Example
cd
cd memryx_examples/video_inference/mediapipe_hands/
ติดตั้ง OpenCV
uv pip install opencv-python==4.11.0.86
ดาวน์โหลด Pre-trained Model
mkdir models
wget https://developer.memryx.com/example_files/2p2/mediapipe_hands.zip
unzip mediapipe_hands.zip -d models
หากต้องการ Compile Model เอง
mx_nc -v -m path/to/model
Run MediaPipe Hands
cd src/python
python3 run.py

ถ้า Compile Model เอง ต้นฉบับกำหนดให้ตั้งชื่อ models.dfp และวางไว้ใน Folder models

5.2 YOLOE Open-Vocabulary Segmentation

Example ที่สองคือ YOLOE ซึ่งเปิดให้ใส่ชื่อ Object Category ที่ต้องการตรวจจับ แล้วระบบจะ Detect และ Segment Object ที่ตรงกับ Class นั้นใน Live Video

Interface ยังมี Option เปิดหรือปิด Segmentation และ Remove Background เพื่อให้เหลือเฉพาะ Object ที่ตรวจพบ

เข้า YOLOE Folder
cd
cd memryx_examples/open_vocabulary/yoloe
ติดตั้ง Dependencies
uv pip install -r requirements.txt
ดาวน์โหลด Precompiled YOLOE Model
wget https://developer.memryx.com/example_files/2p2/YoloE-v8s-seg_640_640_3_onnx.zip
mkdir -p models
unzip YoloE-v8s-seg_640_640_3_onnx.zip -d models
Compile Model เอง
mx_nc -v -m model
Run YOLOE
cd src/python
python3 demo.py  # default video path /dev/video0

Step 6: ใช้ Computer Vision ควบคุม LED จริง

ถึงตรงนี้เรามีทั้ง AI Accelerator, Webcam และ Hand Tracking แล้ว ขั้นสุดท้ายคือเอาผลจาก Computer Vision ออกจากหน้าจอ แล้วเชื่อมกับ Hardware จริงผ่าน GPIO

6.1 ต่อวงจร LED

อุปกรณ์:

  • Raspberry Pi 5
  • LED สีใดก็ได้
  • Male-to-Female Jumper 2 เส้น
  • Resistor 100Ω โดยต้นฉบับระบุว่าใช้ 100–330Ω ได้
  • Breadboard

การต่อ

  1. เสียบ LED ลง Breadboard
  2. ต่อ Resistor แบบ Series เข้ากับขา Negative ของ LED
  3. ขายาวของ LED โดยทั่วไปคือ Positive หรือ Anode ส่วนขาสั้นคือ Negative หรือ Cathode
  4. ต่อ Physical Pin 32 ซึ่งตรงกับ BCM GPIO 12 ไปยังขา Positive ของ LED
  5. ต่อ Physical Pin 34 หรือ Ground Pin ที่ว่าง ไปยังปลาย Resistor อีกด้าน

เช็ก Pin Numbering ให้ชัด: ต้นฉบับใช้ BCM GPIO 12 = Physical Pin 32 อย่าสลับระหว่างเลข GPIO กับ Physical Pin ก่อนต่อวงจรจริง

6.2 ทดสอบ Blink LED ก่อน

ก่อนเอา AI เข้ามาเกี่ยว ให้เช็กพื้นฐานก่อนว่าวงจร LED และ GPIO ทำงานถูกต้อง

ติดตั้ง GPIO Library
pip3 uninstall RPi.GPIO
pip3 install rpi-lgpio
สร้าง led_on_off.py
nano led_on_off.py
led_on_off.py
import RPi.GPIO as GPIO
import time

LED_PIN = 12

GPIO.setmode(GPIO.BCM)
GPIO.setup(LED_PIN, GPIO.OUT)

try:
    while True:
        GPIO.output(LED_PIN, GPIO.HIGH)
        print("LED ON")
        time.sleep(1)

        GPIO.output(LED_PIN, GPIO.LOW)
        print("LED OFF")
        time.sleep(1)

except KeyboardInterrupt:
    print("Stopped")

finally:
    GPIO.cleanup()
Run LED Test
python3 led_on_off.py

ถ้า LED กระพริบ ON/OFF ทุกประมาณ 1 วินาที แปลว่าส่วน Circuit และ GPIO พร้อมแล้ว

6.3 เอา MediaPipe Hands มาคุม LED

ขั้นตอนสุดท้ายคือรวม MediaPipe Hands จาก Step 5 เข้ากับ GPIO Code

โปรแกรมจะสร้าง Toggle Box ที่มุมซ้ายบนของภาพ Webcam และใช้ Index Fingertip Landmark หมายเลข 8 ตรวจว่าปลายนิ้วเข้าไปอยู่ใน Box หรือไม่

เมื่อปลายนิ้ว “เข้า Box ครั้งแรก” ระบบจะ Toggle LED หนึ่งครั้ง และใช้ตัวแปร touching_box ป้องกันไม่ให้ LED Toggle ซ้ำต่อเนื่อง ขณะที่นิ้วยังค้างอยู่ใน Box

เข้า MediaPipe Hands Source Folder
cd memryx_examples/video_inference/mediapipe_hands/src/python
สร้าง led_hand_toggle.py
nano led_hand_toggle.py
led_hand_toggle.py
import threading
import cv2
import sys
import os
import numpy as np
from pathlib import Path
from MxHandPose import MxHandPose
import time

import RPi.GPIO as GPIO


LED_PIN = 12  # BCM GPIO12, physical pin 32


class MediapipeHandsDemo:

    def __init__(self, mxpose, **kwargs):
        self.mxpose = mxpose

        # GPIO LED setup
        GPIO.setmode(GPIO.BCM)
        GPIO.setup(LED_PIN, GPIO.OUT)
        GPIO.output(LED_PIN, GPIO.LOW)

        self.led_on = False

        # Used so one touch toggles only once
        self.touching_box = False

        # Threading
        self.stop_event = threading.Event()
        self.camera_read_thread = threading.Thread(target=self.camera_read, daemon=True)
        self.display_thread = threading.Thread(target=self.and_display, daemon=True)

        self.cam_width = 0
        self.cam_height = 0
        self.cap = self.video_capture()

        # Start threads
        self.camera_read_thread.start()
        self.display_thread.start()

        # Keep main thread alive
        self.camera_read_thread.join()
        self.display_thread.join()

    ##############################################################################################################
    # LED control
    ##############################################################################################################

    def toggle_led(self):
        self.led_on = not self.led_on

        if self.led_on:
            GPIO.output(LED_PIN, GPIO.HIGH)
            print("LED ON")
        else:
            GPIO.output(LED_PIN, GPIO.LOW)
            print("LED OFF")

    def cleanup(self):
        try:
            GPIO.output(LED_PIN, GPIO.LOW)
            GPIO.cleanup()
        except Exception:
            pass

    ##############################################################################################################
    # Camera capture and display
    ##############################################################################################################

    def video_capture(self):
        camera = cv2.VideoCapture(0)
        camera.set(cv2.CAP_PROP_FOURCC, cv2.VideoWriter_fourcc(*'MJPG'))
        camera.set(cv2.CAP_PROP_FPS, 30)

        self.cam_width = int(camera.get(cv2.CAP_PROP_FRAME_WIDTH))
        self.cam_height = int(camera.get(cv2.CAP_PROP_FRAME_HEIGHT))

        return camera

    def camera_read(self):
        if not self.cap.isOpened():
            print("Error: Could not open camera.")
            self.cleanup()
            return

        while not self.stop_event.is_set():
            ret, frame = self.cap.read()

            if not ret:
                print("Error: Could not read frame.")
                break

            if not self.mxpose.full():
                frame = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)
                self.mxpose.put(frame)

        self.mxpose.stop()
        self.cap.release()
        self.cleanup()
        os._exit(0)

    def and_display(self):
        cv2.namedWindow('MediapipeHands', cv2.WINDOW_NORMAL)
        cv2.resizeWindow('MediapipeHands', self.cam_width + 20, self.cam_height + 20)

        while not self.stop_event.is_set():

            if cv2.getWindowProperty('MediapipeHands', cv2.WND_PROP_VISIBLE) < 1:
                self.stop_event.set()
                break

            if not self.mxpose.empty():
                annotated_frame = self.mxpose.get()

                frame = self.draw(annotated_frame)

                frame = cv2.cvtColor(frame, cv2.COLOR_RGB2BGR)

                cv2.imshow('MediapipeHands', frame)

                key = cv2.waitKey(1) & 0xFF
                if key == ord('q') or key == 27:
                    self.stop_event.set()
                    break

        cv2.destroyAllWindows()
        self.cleanup()
        os._exit(0)

    ##############################################################################################################
    # Drawing and interaction
    ##############################################################################################################

    def draw(self, annotated_frame):
        handkeypoints_lst, handtype_lst = self.get_handkeypoints_handtype(annotated_frame)
        img = annotated_frame.image

        currently_touching = False

        # Draw hand/finger landmarks again
        for i, hand_points in enumerate(handkeypoints_lst):
            is_left = False

            if i < len(handtype_lst):
                is_left = str(handtype_lst[i]).lower() == "left"

            img = self.drawLandmarks(img, [hand_points], is_left)

            # Index fingertip is landmark 8
            fingertip = hand_points[8]

            if self.check_box_touch(fingertip):
                currently_touching = True

        # Toggle only when finger first enters the box
        if currently_touching and not self.touching_box:
            self.toggle_led()

        self.touching_box = currently_touching

        # Draw the toggle box
        img = self.draw_toggle_box(img)


        '''
        # Show LED state text
        state_text = "LED: ON" if self.led_on else "LED: OFF"
        state_color = (0, 255, 0) if self.led_on else (255, 0, 0)

        cv2.putText(
            img,
            state_text,
            (20, 110),
            cv2.FONT_HERSHEY_SIMPLEX,
            0.9,
            state_color,
            2,
            cv2.LINE_AA
        )
        '''

        return img

    def get_handkeypoints_handtype(self, annotated_frame):
        handkeypoints_lst = []
        handtype_lst = []

        for handpose in annotated_frame.handposes:
            hp_reshaped = handpose.landmarks.reshape(21, 3).astype(np.int32)
            singlehand_keypoints = [(int(x), int(y)) for x, y, z in hp_reshaped]

            handkeypoints_lst.append(singlehand_keypoints)
            handtype_lst.append(handpose.handedness)

        return handkeypoints_lst, handtype_lst

    ##############################################################################################################
    # One toggle box
    ##############################################################################################################

    def get_toggle_box_region(self):
        return {
            "name": "TOGGLE",
            "x1": 20,
            "y1": 20,
            "x2": 170,
            "y2": 80,
        }

    def check_box_touch(self, fingertip):
        x, y = fingertip
        box = self.get_toggle_box_region()

        return box["x1"] <= x <= box["x2"] and box["y1"] <= y <= box["y2"]

    def draw_toggle_box(self, frame):
        box = self.get_toggle_box_region()

        x1 = box["x1"]
        y1 = box["y1"]
        x2 = box["x2"]
        y2 = box["y2"]

        if self.led_on:
            fill_color = (0, 255, 0)      # green in RGB
            text_color = (0, 0, 0)
            label = "ON"
        else:
            fill_color = (255, 0, 0)      # red in RGB
            text_color = (255, 255, 255)
            label = "OFF"

        # Filled box
        cv2.rectangle(frame, (x1, y1), (x2, y2), fill_color, -1)

        # Border
        cv2.rectangle(frame, (x1, y1), (x2, y2), (255, 255, 255), 3)

        # Text
        cv2.putText(
            frame,
            f"TOGGLE {label}",
            (x1 + 10, y1 + 38),
            cv2.FONT_HERSHEY_SIMPLEX,
            0.7,
            text_color,
            2,
            cv2.LINE_AA
        )

        return frame

    ##############################################################################################################
    # Hand landmark drawing
    ##############################################################################################################

    def drawLandmarks(self, frame, data, is_left):
        allhands = data

        if is_left:
            color = (255, 0, 255)
        else:
            color = (0, 255, 255)

        for myHand in allhands:
            cv2.line(frame, (myHand[0][0], myHand[0][1]), (myHand[1][0], myHand[1][1]), color, 2)
            cv2.line(frame, (myHand[1][0], myHand[1][1]), (myHand[2][0], myHand[2][1]), color, 2)
            cv2.line(frame, (myHand[2][0], myHand[2][1]), (myHand[3][0], myHand[3][1]), color, 2)
            cv2.line(frame, (myHand[3][0], myHand[3][1]), (myHand[4][0], myHand[4][1]), color, 2)

            cv2.line(frame, (myHand[0][0], myHand[0][1]), (myHand[5][0], myHand[5][1]), color, 2)
            cv2.line(frame, (myHand[5][0], myHand[5][1]), (myHand[6][0], myHand[6][1]), color, 2)
            cv2.line(frame, (myHand[6][0], myHand[6][1]), (myHand[7][0], myHand[7][1]), color, 2)
            cv2.line(frame, (myHand[7][0], myHand[7][1]), (myHand[8][0], myHand[8][1]), color, 2)

            cv2.line(frame, (myHand[0][0], myHand[0][1]), (myHand[17][0], myHand[17][1]), color, 2)
            cv2.line(frame, (myHand[17][0], myHand[17][1]), (myHand[18][0], myHand[18][1]), color, 2)
            cv2.line(frame, (myHand[18][0], myHand[18][1]), (myHand[19][0], myHand[19][1]), color, 2)
            cv2.line(frame, (myHand[19][0], myHand[19][1]), (myHand[20][0], myHand[20][1]), color, 2)

            cv2.line(frame, (myHand[5][0], myHand[5][1]), (myHand[9][0], myHand[9][1]), color, 2)
            cv2.line(frame, (myHand[9][0], myHand[9][1]), (myHand[13][0], myHand[13][1]), color, 2)
            cv2.line(frame, (myHand[13][0], myHand[13][1]), (myHand[17][0], myHand[17][1]), color, 2)

            cv2.line(frame, (myHand[9][0], myHand[9][1]), (myHand[10][0], myHand[10][1]), color, 2)
            cv2.line(frame, (myHand[10][0], myHand[10][1]), (myHand[11][0], myHand[11][1]), color, 2)
            cv2.line(frame, (myHand[11][0], myHand[11][1]), (myHand[12][0], myHand[12][1]), color, 2)

            cv2.line(frame, (myHand[13][0], myHand[13][1]), (myHand[14][0], myHand[14][1]), color, 2)
            cv2.line(frame, (myHand[14][0], myHand[14][1]), (myHand[15][0], myHand[15][1]), color, 2)
            cv2.line(frame, (myHand[15][0], myHand[15][1]), (myHand[16][0], myHand[16][1]), color, 2)

            for point in myHand:
                cv2.circle(frame, (point[0], point[1]), 4, (23, 90, 10), 1)

            for point in myHand:
                cv2.circle(frame, (point[0], point[1]), 3, (255, 255, 125), -1)

            # Highlight index fingertip clearly
            fingertip = myHand[8]
            cv2.circle(frame, (fingertip[0], fingertip[1]), 8, (0, 255, 0), 2)

        return frame


if __name__ == '__main__':

    project_dir = Path(__file__).resolve().parents[2]
    mx_modeldir = project_dir / 'models'

    try:
        mx_pose = MxHandPose(mx_modeldir=mx_modeldir, num_hands=2)
        paint = MediapipeHandsDemo(mxpose=mx_pose)

    except (FileNotFoundError, RuntimeError) as exc:
        print(f"Failed to start Mediapipe Hands: {exc}", file=sys.stderr)
        GPIO.cleanup()
        sys.exit(1)

    except KeyboardInterrupt:
        print("Stopped")
        GPIO.cleanup()
        sys.exit(0)
Run Gesture LED
python3 led_hand_toggle.py

ตำแหน่งไฟล์สำคัญ: ต้นฉบับเตือนให้เก็บ led_hand_toggle.py ไว้ใน Directory ที่กำหนด เพราะ Code อ้างอิง File และ Module อื่น ที่อยู่ในโครงสร้างของ MediaPipe Hands Example

เมื่อรันโปรแกรม หน้าต่าง Camera จะเปิดขึ้น พร้อมตรวจจับและ Highlight มือ และจะมี Toggle Box อยู่ด้านซ้ายบน

เมื่อนำปลายนิ้วเข้าไปใน Box LED จะเปลี่ยน ON/OFF เท่านี้ Computer Vision ก็เชื่อมกับ Physical Electronics ได้แล้ว

ภาพและวิดีโอขั้นตอนทั้งหมดจากต้นฉบับ

เนื่องจาก Source มีภาพจำนวนมาก จึงแสดงเฉพาะ Hero Image ด้านบนเป็นค่าเริ่มต้น ส่วน Media อื่นทั้งหมดซ่อนไว้ใน View more ตามรูปแบบที่กำหนดสำหรับบทความ Global Byte

ภาพรวมโปรเจกต์

ตัวอย่างการทำงานของโปรเจกต์ที่เชื่อม Computer Vision เข้ากับ Hardware จริง
รายการอุปกรณ์สำหรับติดตั้ง MemryX MX3 บน Raspberry Pi 5
ภาพรายการอุปกรณ์หลักที่ใช้กับ Raspberry Pi 5, MemryX MX3 และโปรเจกต์ Computer Vision

Step 1–2: Raspberry Pi OS และ Desktop Setup

เขียน Raspberry Pi OS ลง microSD Card
ขั้นตอนเตรียม Raspberry Pi OS ก่อนนำ microSD ไปใช้กับ Raspberry Pi 5
Raspberry Pi Imager สำหรับติดตั้ง Raspberry Pi OS 64-bit
Raspberry Pi Imager ที่ใช้เลือก Raspberry Pi 5, OS และ microSD Storage
หน้าจอประกอบขั้นตอน Raspberry Pi OS Setup
ภาพหน้าจอจากขั้นตอนเตรียมและตั้งค่า Raspberry Pi OS ในคู่มือต้นฉบับ
หน้าจอ Raspberry Pi Setup จากคู่มือต้นฉบับ
หนึ่งในหน้าจอ Setup ตามลำดับของ Raspberry Pi Imager / Raspberry Pi OS
หน้าจอตั้งค่า Raspberry Pi OS
ภาพประกอบการตั้งค่า Raspberry Pi OS จาก Source
ขั้นตอน Raspberry Pi Desktop Setup
หน้าจอในช่วง Initial Setup ของ Raspberry Pi
หน้าจอ Initial Setup Raspberry Pi
ภาพประกอบ Raspberry Pi Desktop Wizard
Raspberry Pi Desktop Wizard
อีกหนึ่งขั้นตอนของ Raspberry Pi Desktop Wizard จากต้นฉบับ
Raspberry Pi Desktop หลังตั้งค่า
ภาพจากช่วงหลังการเตรียม Raspberry Pi Desktop
Raspberry Pi 5 ในขั้นตอนการเตรียม Hardware
Raspberry Pi 5 ก่อนเข้าสู่ขั้นตอนติดตั้ง Accelerator
Welcome to the Raspberry Pi Desktop
หน้าจอ Welcome to the Raspberry Pi Desktop สำหรับ Initial Setup

Step 3: ติดตั้ง MemryX MX3 และ PCIe HAT

ขั้นตอนติดตั้ง MemryX MX3 Hardware
ภาพประกอบการเตรียมฮาร์ดแวร์ MemryX MX3 จากคู่มือต้นฉบับ
ขั้นตอนประกอบ MemryX MX3
ลำดับการประกอบ MemryX MX3, Heatsink หรือ HAT ตาม Source
อุปกรณ์ติดตั้ง MemryX MX3
รายละเอียดอุปกรณ์ในช่วงติดตั้ง Accelerator
ประกอบ MemryX MX3 AI Accelerator
ภาพขั้นตอนประกอบ Hardware ก่อนติดตั้งบน Raspberry Pi 5
ติดตั้ง MemryX MX3 และ Heatsink
ขั้นตอนติดตั้ง MX3 และชุดระบายความร้อน
จัดตำแหน่ง MemryX MX3 Heatsink
ภาพประกอบการจัดตำแหน่งชิ้นส่วนก่อนขัน Screw
ติดตั้ง Heatsink MemryX MX3
ลำดับการยึด Heatsink กับ Accelerator
ประกอบ MemryX MX3 M.2
ภาพประกอบการเตรียม MX3 M.2 Module
ติดตั้ง Raspberry Pi PCIe HAT
ขั้นตอนจัดเตรียม PCIe HAT สำหรับ Raspberry Pi 5
ติดตั้ง Brass Standoff บน PCIe HAT
ภาพประกอบการยึด HAT และ Standoff
PCIe Ribbon Cable Raspberry Pi 5
ภาพขั้นตอนเชื่อมต่อ PCIe Ribbon Cable
ต่อ Ribbon Cable เข้ากับ Raspberry Pi 5
การจัด Orientation ของ Ribbon Cable ระหว่าง Raspberry Pi และ HAT
ล็อก PCIe Ribbon Cable
ขั้นตอนยึด Ribbon Cable ด้วย Locking Tab
วาง M.2 HAT บน Raspberry Pi 5
จัดตำแหน่ง HAT บน Raspberry Pi 5
เชื่อม PCIe HAT Raspberry Pi 5
ภาพประกอบการเชื่อมต่อ HAT ในขั้นตอนถัดไป
ล็อก Ribbon Cable บน HAT
การล็อกปลาย Ribbon Cable ฝั่ง HAT
ใส่ MemryX MX3 ลง M.2 Slot
ขั้นตอนนำ MX3 Module เข้า M.2 Slot
MemryX MX3 M.2 angle installation
การใส่ Module เข้าช่อง M.2 ในมุมก่อนกดลง
ยึด MemryX MX3 M.2 Module
จัด Mounting Hole ของ MX3 ให้ตรงกับ PCB
ขัน M.2 screw MemryX MX3
ยึด MX3 ด้วย M.2 Screw โดยไม่ขันแน่นเกินไป
MemryX MX3 ติดตั้งบน Raspberry Pi 5 สำเร็จ
ชุด Raspberry Pi 5 + HAT + MemryX MX3 หลังประกอบ

Step 5: MediaPipe Hands และ YOLOE

ตัวอย่าง Computer Vision จาก MemryX Example ตาม Source
MediaPipe Hands ตรวจจับมือและ Landmark จาก Live Video
ตัวอย่างการทำงานของ YOLOE / Computer Vision Pipeline จากคู่มือต้นฉบับ
YOLOE Open Vocabulary Segmentation interface
หน้าจอ YOLOE Example สำหรับกำหนด Object Class ที่ต้องการ Detect
YOLOE segmentation output
ตัวอย่าง Output ของ YOLOE รวมถึงการทำ Segmentation / แสดง Object ที่ตรวจพบ

Step 6: LED, GPIO และ Gesture Control

อุปกรณ์ต่อ LED กับ Raspberry Pi 5
อุปกรณ์สำหรับสร้างวงจร LED กับ Raspberry Pi 5
LED resistor breadboard Raspberry Pi
ขั้นตอนประกอบ LED และ Resistor บน Breadboard
ต่อ jumper wire LED Raspberry Pi GPIO
การต่อ Jumper Wire ระหว่าง Breadboard และ Raspberry Pi GPIO
Raspberry Pi GPIO LED wiring reference
ภาพอ้างอิงการต่อวงจรในช่วง GPIO และ LED
Raspberry Pi 5 GPIO pinout diagram
Raspberry Pi GPIO Pinout ใช้ตรวจ Physical Pin และ BCM GPIO ก่อนต่อ LED
Raspberry Pi LED GPIO software test
ภาพหน้าจอจากช่วงทดสอบ LED / GPIO ในต้นฉบับ
LED Blinking บน Raspberry Pi สำหรับยืนยันว่าการต่อวงจรและ GPIO Code ทำงาน
ผลลัพธ์หลังรวม Hand Tracking เข้ากับการ Toggle LED
Circuit diagram Raspberry Pi 5 LED GPIO 12
Circuit Diagram สำหรับ Raspberry Pi 5 และ LED ตาม Source ต้นฉบับ

จาก LED ดวงเดียว ไปต่อได้ไกลกว่าที่คิด

สิ่งที่น่าสนใจของโปรเจกต์นี้ ไม่ใช่แค่การทำให้ LED เปิดหรือปิดด้วยมือ

แต่คือ Workflow ทั้งเส้น:

Camera → Computer Vision → MemryX MX3 → Raspberry Pi Software → GPIO → Hardware จริง

ต้นฉบับสรุปไว้ว่าการ Blink LED เป็นเพียงจุดเริ่มต้น เพราะเมื่อ Computer Vision สามารถส่งผลไปยัง GPIO ได้แล้ว แนวคิดเดียวกันสามารถต่อยอดไปยัง Gesture-controlled Lighting, Smart Display, Robotics และ Automation Project อื่น ๆ ได้

สำหรับสาย Maker นี่จึงเป็นโปรเจกต์ที่เห็นภาพของ Edge AI ได้ชัดมาก: AI ไม่ได้จบอยู่ที่ Bounding Box บนหน้าจอ แต่สามารถกลายเป็น Input ให้ Hardware ตัดสินใจและตอบสนองกับโลกจริงได้

ติดตั้งจริง แนะนำให้เปิดต้นฉบับควบคู่ไปด้วย

บทความนี้มีหลายส่วนที่ขึ้นกับ Version: โดยเฉพาะ Driver, Linux Kernel, Python, SDK, Precompiled Model และ Repository Structure จึงแนะนำให้เปิด คู่มือต้นฉบับ Install MemryX MX3 on Raspberry Pi 5 ควบคู่กับ MemryX Developer Hub – Install Software ก่อนลงมือจริง

FAQ: MemryX MX3 กับ Raspberry Pi 5

ต้นฉบับใช้ Raspberry Pi รุ่นไหน?

Raspberry Pi 5 โดยระบุว่า 8GB Kit เป็นรุ่นที่แนะนำสำหรับโปรเจกต์นี้

ต้องมี PCIe HAT หรือไม่?

ใน Setup ของต้นฉบับใช้ M.2 to PCIe Raspberry Pi HAT สำหรับเชื่อม MemryX MX3 M.2 Accelerator เข้ากับ Raspberry Pi 5

ใช้ Raspberry Pi OS แบบไหน?

คู่มือต้นฉบับใช้ Raspberry Pi OS แบบ 64-bit และ MemryX Developer Hub ก็ระบุ Raspberry Pi OS 64-bit สำหรับ Raspberry Pi 5

ทำไมต้องใช้ Python 3.12?

ในเวลาที่บทความต้นฉบับจัดทำ Raspberry Pi OS มี Python 3.13 แต่ MemryX Tools ยังไม่รองรับ Version ดังกล่าว จึงใช้ uv ติดตั้ง Python 3.12 และสร้าง Virtual Environment

ต้องใช้ Webcam ไหม?

Webcam ใช้กับ MediaPipe Hands, YOLOE และโปรเจกต์ Gesture-controlled LED

MX3 ร้อนแค่ไหนถึงต้องระวัง?

Source และเอกสาร MemryX ระบุว่า Accelerator สามารถเริ่ม Thermal Throttling เมื่อ Chip ถึงประมาณ 100°C จึงต้องมี Cooling และ Airflow ที่เพียงพอ

โค้ด Gesture Control วางไว้ที่ไหนก็ได้ไหม?

ไม่ได้ตามโครงสร้างของคู่มือต้นฉบับ เพราะ Code อ้างอิง Module และ File ที่อยู่ใน MediaPipe Hands Example Directory จึงต้องบันทึกในตำแหน่งที่ Source กำหนด

References / แหล่งข้อมูลต้นฉบับ

อยากเริ่ม Edge AI Project ของตัวเอง?

ถ้ากำลังหา Raspberry Pi, บอร์ดพัฒนา, Sensor หรืออุปกรณ์สำหรับ Embedded / AI / Maker Project สามารถเข้ามาดูสินค้า พูดคุยกับ Community หรือส่งโจทย์มาสอบถามทีม Globalbyte ได้

 

แท็ก


Blog posts