# 手勢控制LED亮度專案教程 | MicroPython | 機器視覺 | RTL8722DM\_MINI

**URL:** https://forum.amebaiot.com/t/led-micropython-rtl8722dm-mini/853
**Category:** MicroPython
**Tags:** rtl872xd
**Created:** [October 15, 2021, 11:44am UTC](https://forum.amebaiot.com/t/led-micropython-rtl8722dm-mini/853 "2021-10-15T11:44:27Z")
**Posts on this page:** 1
**Page:** 1

<div class="post-metadata">

### Author: ![xidameng](https://sea2.discourse-cdn.com/flex016/user_avatar/forum.amebaiot.com/xidameng/32/18_2.png) [@xidameng](https://forum.amebaiot.com/u/xidameng)
#### Post date: [October 15, 2021, 11:44am UTC](https://forum.amebaiot.com/t/led-micropython-rtl8722dm-mini/853/1 "2021-10-15T11:44:27Z")

</div>

[![](https://us1.discourse-cdn.com/flex016/uploads/ameba/original/2X/d/dcb9911b9e758426f68f34b9e786631cc536bd54.jpeg "手勢控制LED亮度 | 機器視覺 | MicroPython | RTL8722DM\_MINI") ](https://www.youtube.com/watch?v=w_-7uoVYWGo)

# RTL8722DM\_MINI + MicroPython + 機器視覺

> 嗨！如果你還沒有看過之前的演示影片，請點擊上面的影片 👆

計算機視覺雖然已經存在了很長一段時間，但是在微控制器（MCU）上運行機器視覺的應用還是有點不太實際，因為它需要大量的計算，還會消耗大量的電力，因此最好的方法是將與 CV 相關的計算移到更強大的電腦上，例如我們的筆電或云服務器，通過IoT的技術將數據下載到MCU中，讓 MCU來 實時控制傳感器/執行器。

因此這個專案主要有 2 塊組成，

- 機器視覺算法和視頻採集 → **PC**
- 運行MicroPython, 進行無線數據傳輸和 LED 控制 → **RTL8722DM\_MINI**

接下來我們會聚焦每一個重要的組成部分。

  

### 1. 視頻捕捉和運行機器視覺算法

為了實現手勢識別，我選擇了眾所周知的 [OpenCV](https://opencv.org/) 和 [MediaPipe](https://mediapipe.dev/) 庫，因為它們都是在 Github 上的開源項目，而且它們都支援Python語言開發——這意味著我們可以使用 Python 來快速實現我們的邏輯並完成原型設計。

我這裏使用的代碼主要來自名為 [Murtaza](https://www.youtube.com/channel/UCYUjYU5FveRAscQ8V21w81A) 的 Youtuber，只要在他的網站上註冊帳戶，你就可以免費地獲得他的代碼，但是因為我還沒有獲得開源他的代碼的許可，因此這裏我建議大家可以在點擊觀看他的[手部追蹤](https://www.youtube.com/watch?v=NZde8Xt78Iw&ab_channel=Murtaza%27sWorkshop-RoboticsandAI)以及 [手勢控制](https://www.youtube.com/watch?v=9iEPzbG-xLE&t=1985s&ab_channel=Murtaza%27sWorkshop-RoboticsandAI) 的影片，從影片中查看他的代碼並了解他是如何實現這些功能的。

當然，我自己也添加並編輯了的原始 Python 腳本，好讓它只運行我需要的任務，並幫助我通過 TCP socket將數據發送到我的 RTL8722DM\_MINI上。下面的圖就是在我的 PC 上運行的所有邏輯的流程圖。

 ![Untitled Diagram](https://us1.discourse-cdn.com/flex016/uploads/ameba/original/1X/f1ef9d18fa0e07e559efc74ced05995ae51af39f.png)

  

#### 程式碼

以下就是完整的代碼。

```python
# Computer Vision related Code partially adopted from https://www.youtube.com/c/MurtazasWorkshopRoboticsandAI/featured
# Credit goes to him for create the module and example

import cv2
import time
import numpy as np
import math
import socket
import mediapipe as mp

########## Module #############
class handDetector():
    def __init__ (self, mode=False, maxHands=2, detectionCon=0.5, trackCon=0.5):
        self.mode = mode
        self.maxHands = maxHands
        self.detectionCon = detectionCon
        self.trackCon = trackCon

        self.mpHands = mp.solutions.hands
        self.hands = self.mpHands.Hands(self.mode, self.maxHands,
                                        self.detectionCon, self.trackCon)
        self.mpDraw = mp.solutions.drawing_utils

    def findHands(self, img, draw=True):
        imgRGB = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)
        self.results = self.hands.process(imgRGB)
        # print(results.multi_hand_landmarks)

        if self.results.multi_hand_landmarks:
            for handLms in self.results.multi_hand_landmarks:
                if draw:
                    self.mpDraw.draw_landmarks(img, handLms,
                                               self.mpHands.HAND_CONNECTIONS)
        return img

    def findPosition(self, img, handNo=0, draw=True):

        lmList = []
        if self.results.multi_hand_landmarks:
            myHand = self.results.multi_hand_landmarks[handNo]
            for id, lm in enumerate(myHand.landmark):
                # print(id, lm)
                h, w, c = img.shape
                cx, cy = int(lm.x * w), int(lm.y * h)
                # print(id, cx, cy)
                lmList.append( [id, cx, cy])
                if draw:
                    cv2.circle(img, (cx, cy), 15, (255, 0, 255), cv2.FILLED)

        return lmList

############## Variables ##################
wCam, hCam = 640, 480
pTime = 0
minBri = 0
maxBri = 1
briArd =0

############## Declararion ##################

cap = cv2.VideoCapture(0) # default camera is 0, if you have another cam, you can set to 1
cap.set(3, wCam)
cap.set(4, hCam)
detector = handDetector(detectionCon=0.7)

########## Step 1 ###########
# Start a TCP server and bind to port 12345
# Use ipconfig to check the IP address of your PC
s = socket.socket()
print ("Socket successfully created")
port = 12345
s.bind(('', port))
print("socket binded to %s" % (port))
s.listen(5)
print ("socket is listening")
c, addr = s.accept()
print('Got connection from', addr)

######### Step 2 ###############
# Image capture and processing using mediapipe and opencv
while True:
    success, img = cap.read()
    img = detector.findHands(img)
    lmList = detector.findPosition(img, draw=False)
    if len(lmList) != 0:
        x1, y1 = lmList[4][1], lmList[4][2]
        x2, y2 = lmList[8][1], lmList[8][2]
        cx, cy = (x1 + x2) // 2, (y1 + y2) // 2

        cv2.circle(img, (x1, y1), 15, (255, 0, 255), cv2.FILLED)
        cv2.circle(img, (x2, y2), 15, (255, 0, 255), cv2.FILLED)
        cv2.line(img, (x1, y1), (x2, y2), (255, 0, 255), 3)
        cv2.circle(img, (cx, cy), 15, (255, 0, 255), cv2.FILLED)

        length = math.hypot(x2 - x1, y2 - y1)
        #print(length)

        # Hand range 50 - 300

        brightness = np.interp(length, [50, 300], [minBri, maxBri])

        briArd = np.around(brightness,2)

        #print(briArd, brightness, length)

        if length < 50:
            cv2.circle(img, (cx, cy), 15, (0, 255, 0), cv2.FILLED)

    # Print FPS
    cTime = time.time()
    fps = 1 / (cTime - pTime)
    pTime = cTime
    cv2.putText(img, f'FPS: {int(fps)}', (40, 50), cv2.FONT_HERSHEY_COMPLEX,
                1, (255, 0, 0), 3)

    # Display image
    cv2.imshow("Img", img)
    cv2.waitKey(1)

    # Sending the distance between our thumb and index wirelessly to IoT device
    c.sendall(str(briArd).encode())
    print("send data success")
    print(briArd, str(briArd))
    #c.close()

```

  

### 2.運行MicroPython來無線傳輸數據並控制LED亮度

我選擇 MicroPython 的原因是因爲這樣我就不用使用其他編程語言了 😆 😜 所有的開發都可以用Python來完成~

> 如果有人不瞭解的話 – MicroPython是專為微控制器設計的 Python 3 解釋器，而RTL8722DM\_MINI 已經支援 MicroPython。

使用MicroPython，我們就可以控制微控制器上的所有外設，以RTL8722DM\_MINI爲例，我們只需 **13行** 的Python程式碼就可實現以下的功能，

1. 連接到 **Wi-Fi**
2. 啟動一個 **TCP客戶端**
3. 通過 **PWM** 控制LED亮度

（MicroPython 的程式碼在這裡 👇）

#### 程式碼

```python
import socket
from wireless import WLAN
from machine import PWM
wifi = WLAN(mode = WLAN.STA)
wifi.connect(ssid = "yourNetwork", pswd = "password") # change the ssid and pswd to yours
c = socket.SOCK()
# make sure to check the server IP address and update in the next line of code
c.connect("192.168.0.106", 12345) 
p = PWM(pin = "PA_23")
while True:
	data = c.recv(512)
	f_brightness= float(data[:3])
	print(f_brightness)
	p.write(f_brightness)

```

  
  

## 總結

借助 Wi-Fi 和其他無線通訊方式，RTL8722DM\_MINI 等支援物聯網的設備可以成為一個 **AIoT** 專案中不可或缺的一部分。使用 Python 語言，更是可以加速產品原型設計。這也是我在這個專案中感受最深的地方。

其實RTL8722DM\_MINI 還有很多其他的有趣的功能還沒有用上，比如 **Audio Codec** 、 **Ultra-Low Power** 和 **BLE5.0** ，這些功能都很有潛力，可以讓我們用RTL8722DM\_MINI來搭建一個強大的多媒體物聯網節點，并且可以部署在外面很長時間。如果有有興趣的朋友，也可以一起來溝通討論，如何來最大化地使用這個開發板 😉
