主頁 > 後端開發 > MicroPython物聯網開發入門1歡迎上賊船ESP8266

MicroPython物聯網開發入門1歡迎上賊船ESP8266

2023-07-07 07:41:10 後端開發

1歡迎上賊船

1.1 關于本教程

這是一個針對Python初學者的教程,他們想學習對設備進行編程,以便與物理世界互動,你將學習如何使用MicroPython編程,MicroPython是專為在微控制器上運行的Python版本,你將學習如何撰寫的應用程式將從傳感器讀取資料,在小螢屏上顯示資訊,對按鈕作出反應,并從互聯網上傳或下載資料,有很多很酷的東西!

1.2 要求

有Python的基本編碼經驗,你不需要有任何關于微控制器、電子學、甚至MicroPython的知識,

你還需要一臺有USB介面的Ubunutu電腦,因為你要把微控制器連接到電腦上進行編程,

購物清單

1.3.1 微控制器

MicroPython可以在幾種不同型別的微控制器上運行,但在本教程中,我將只使用一種型號:ESP8266,請注意,有一些不同的板子,你可以買到相同的芯片,你想買的型號是非正式地稱為 "開發板 "的型號,更正式的名稱是ESP-12,這些板子上安裝有微控制器,小型Wi-Fi天線,用于供電和編程的微型USB輸入,以及30個可直接插入面包板的引腳,

ESP8266微控制器芯片是一個較大的銀色盒子,在它上面你可以看到一條人字形的金線,那是Wi-Fi天線,你可以看到每側有15個引腳,每個引腳都有標簽,應該印在電路板上,名稱是D0、D1、3V3、GND等,

有三個標有3V3或3.3V的引腳,它們提供電流,這個名字來自于電壓,即3.3伏,這些引腳可用于向其他元件提供輸入電流,還有四個GND或 "ground"引腳,這些引腳提供了接地連接,正如你在本教程后面所學到的,所有元件都有明確標記的引腳,用于輸入電流,通常稱為VCC,還有用于連接到地面,稱為GND,

標有D的引腳是資料引腳,這些引腳用于單片機和其他連接設備之間的通信,

電路板上有兩個內置的小LED(發光二極管,如果你愿意,也可以說是小燈泡),你可以在圖中看到黃色的,上面的LED與標有D4或GPIO2的引腳相連,而下面的LED則與D0相連,也就是GPIO16,

在其余的引腳中,A0是值得一提的,因為它是電路板上唯一的 "模擬 "引腳,所有其他的引腳要么是0,要么是1,但是模擬引腳可以有一定的數值范圍,由通過該引腳的電流大小決定,本教程不使用模擬針腳,

另一個有趣的引腳是RST,它可以用來向電路板發送復位信號,后續你將學習如何使用這個引腳來 "喚醒 "處于深度睡眠狀態的微控制器,

標有Vin的引腳可以用來給電路板供電,作為更方便的Micro-USB埠的替代,在本教程中,你要做的所有例子都是通過micro-USB埠供電的,所以你不會使用這個引腳,

其余的引腳在大多數板子上都是留給微控制器自己使用的,所以這里沒有很多有趣的功能可以提及,如果你想知道在你的特定板子上有什么用途,你應該查閱具體的檔案,因為這些引腳的接線方式不盡相同,

在底部中央,你有一個微型USB輸入連接器,在本教程中,你將總是通過這個連接器給電路板供電,如果你把電纜的另一端連接到你的電腦上,那么電路板就會在你的電腦上顯示為一個串行設備,這個串行連接將被用來向微控制器上傳代碼,

為了完成這個概述,請注意電路板上有兩個小按鈕,分別是RST和FLASH,在微型USB埠的兩側,FLASH按鈕為板子準備了新的韌體,但這個按鈕很少需要,因為當前版本的板子可以通過串行連接進入閃存模式,RST按鈕是簡單的復位按鈕,按下它可以重新啟動電路板,

1.3.2 溫度和濕度傳感器

有三個或四個引腳的模型,對于本教程都可以,

1.3.3 螢屏

一些例子會在128x64像素的OLED小螢屏上顯示資訊,

1.3.4 按鍵

一些例子將由按鈕來觸發,

1.3.5 面包板和跳線

為了能夠在不焊接的情況下輕松地建立和拆卸電路,你將需要面包板和跳線,

最上面的兩排和最下面的2排孔通常被稱為 "電源條",它們的作業方式實際上與家用電源條類似,

中間的孔是以五為一組的,中間兩部分的十排孔用字母a到j標示,但與電源條不同,這些行沒有連接,這些針腳的連接是垂直的,并且只覆寫了每一部分的五個垂直孔組,各列的標簽從1到30,但在許多面包板上,你只能看到每五列一個標簽,利用這些標簽,你可以看到a1、b1、c1、d1和e1孔都是相互連接的,所以任何插入這些孔的引腳都會全部連接,同樣,針腳f1、g1、h1、i1和j1之間也是相連的,但它們與上面的五個孔沒有共同的連接,

1.3.6 USB到MicroUSB電纜

你將需要一條USB線來連接你的微控制器和你的電腦,這將提供電源,也是串行連接,你將通過它把代碼上傳到微控制器的存盤器中,這和大多數安卓手機的充電線是一樣的,所以你可能已經有一條可以使用了,

1.4 Hello

到https://micropython.org/download/?port=esp8266下載韌體,一般用2M的版本:esp8266-20230426-v1.20.0.bin

將普通USB端插入計算機上的一個空閑USB埠,將微型USB端插入ESP8266板,當板子通電時,你可能會看到其中一個LED燈閃爍,但當然不會有其他事情發生,因為沒有安裝軟體,

$ sudo pip install esptool rshell
$ esptool.py write_flash 0 Downloads/esp8266-20230426-v1.20.0.bin --flash_size=detect
esptool.py v4.6.2
Found 1 serial ports
Serial port /dev/ttyACM0
Connecting....
Detecting chip type... Unsupported detection protocol, switching and trying again...
Connecting....
Detecting chip type... ESP8266
Chip is ESP8266EX
Features: WiFi
Crystal is 26MHz
MAC: d8:bf:c0:f8:16:d5
Uploading stub...
Running stub...
Stub running...
Configuring flash size...
Auto-detected Flash size: 4MB
Flash will be erased from 0x00000000 to 0x0009afff...
Flash params set to 0x0040
Compressed 634016 bytes to 420365...
Wrote 634016 bytes (420365 compressed) at 0x00000000 in 37.0 seconds (effective 136.9 kbit/s)...
Hash of data verified.

Leaving...
Hard resetting via RTS pin...

我將向你展示的是如何連接到你的電路板上運行的Python提示符,這被稱為 REPL,它是 "Read-Eval-Print-Loop "的縮寫,這是標準的Python提示符,你可能習慣于在使用常規的Python解釋器時看到它,但這次它將在你的電路板上運行,為了與它互動,你將使用串行連接到你的計算機,

在你之前發布的esptool.py命令的輸出中,尋找以Serial port開頭的一行,這一行的內容是連接到你的微控制器板的串口設備的名稱,在Linux或Mac電腦上,這將是格式為/dev/的名字,而在Windows上,它將是COM,你可以看到,對于我目前使用的電路板,設備名稱是/dev/ttyACM0,

$ rshell --port /dev/ttyACM0
Using buffer-size of 32
Connecting to /dev/ttyACM0 (buffer-size 32)...
Trying to connect to REPL  connected
Retrieving sysname ... esp8266
Testing if ubinascii.unhexlify exists ... Y
Retrieving root directories ... /boot.py/
Setting time ... Jul 06, 2023 12:57:01
Evaluating board_name ... pyboard
Retrieving time epoch ... Jan 01, 2000
Welcome to rshell. Use Control-D (or the exit command) to exit rshell.
/home/andrew> repl
Entering REPL. Use Control-X to exit.
>
MicroPython v1.20.0 on 2023-04-26; ESP module with ESP8266
Type "help()" for more information.
>>> 
>>> print('Hello, MicroPython!')
Hello, MicroPython!
>>> 

參考資料

  • 軟體測驗精品書籍檔案下載持續更新 https://github.com/china-testing/python-testing-examples 請點贊,謝謝!
  • 本文涉及的python測驗開發庫 謝謝點贊! https://github.com/china-testing/python_cn_resouce
  • python精品書籍下載 https://github.com/china-testing/python_cn_resouce/blob/main/python_good_books.md
  • https://docs.micropython.org/en/latest/esp8266/tutorial/intro.html
  • https://zhuanlan.zhihu.com/p/82366556
  • https://blog.csdn.net/makeryzx/article/details/79872567
  • https://www.espressif.com.cn/sites/default/files/documentation/2a-esp8266-sdk_getting_started_guide_cn.pdf
  • https://blog.csdn.net/qq_38405680/article/details/84571843

1.5控制板載的LED

正如我前面提到的,這個板子有兩個LED,更準確地說,幾乎都是這樣的,但有些老的ESP8266開發板只有一個LED,讓我們首先嘗試控制最常見的那個,即所有板子都有的那個:

>>> import machine
>>> led = machine.Pin(2, machine.Pin.OUT)

machine是板子介面的內置一,這個包最重要的特征之一是Pin()類,它被用來讀取或寫入資料引腳,

位于Wi-Fi天線旁邊的LED是連接到D4引腳的,那么為什么我用2來初始化這個引腳呢?這是因為微控制器中引腳的命名通常非常混亂,印在電路板上的引腳名稱其實并不那么有用,在尋址方面真正重要的是它的GPIO(General-purpose input/output)編號,GPIO是通用輸入/輸出的意思,是對可供應用程式使用的一組引腳的名稱,如果你回到本文頂部的引腳圖,你會注意到D4也是GPIO2,所以我使用2作為引腳編號,

Pin()類的建構式需要第二個引數,它是常數,宣告這個引腳是輸出引腳,這意味著該引腳將被配置為被寫入,當針腳被設定為0時,LED會打開,而當針腳被設定為1時,LED會關閉,當你用上面的Python陳述句將引腳2初始化為輸出時,你可能會看到電路板上的LED立即打開,因為在默認情況下,這個引腳的狀態是0,

如果你想關閉LED,你可以向該引腳寫一個1:

# 關燈
>>> led.value(1)
>>> led.on()
# 開燈
>>> led.value(0)
>>> led.off()

記住,LED是反向接線的,所以on()把它關掉,off()把它打開!

第二個LED在D0引腳上,也被稱為GPIO16,如果它存在,它也是反向布線的,

>>> led2 = machine.Pin(16, machine.Pin.OUT)
>>> led2.off()

如果你的電路板有第二個LED,上面的代碼應該把它打開,第二個LED位于RST按鈕附近,

MicroPython解釋器支持控制結構,其方式與標準Python相同,可以用while回圈、兩個LED和time.sleep()函式創造一個小小的燈光秀:

>>> import time
>>> while True:
...     led.off()
...     led2.on()
...     time.sleep(0.5)
...     led.on()
...     led2.off()
...     time.sleep(0.5)
...

欣賞完燈光秀后,你可以按Ctrl-C鍵跳出while-loop并停止它,然后你可以按Ctrl-X鍵退出REPL,回到rshell提示符,最后,你可以按Ctrl-D退出rshell,回到你的終端,

1.6 MicroPython的檔案系統

在ESP8266板上,實際上沒有檔案存盤器,所以MicroPython分配了一部分閃存并在其中創建了一個虛擬檔案系統,本教程推薦的ESP8266開發板帶有4MB的閃存,這足以容納MicroPython韌體和小型檔案系統,

兩個檔案在MicroPython中具有特殊的意義,名字分別是boot.py和main.py,作為正常啟動程式的一部分,MicroPython會在內部檔案系統中尋找帶有這些名字的檔案,如果找到它們,它就會自動執行它們,正如你即將看到的,MicroPython韌體已經提供了一個boot.py檔案,但它不包括main.py,它是留給開發者提供的,所以要創建保存在板子閃存中的應用程式,需要做的就是把它作為main.py寫到板子上,

REPL的rshell工具提供了訪問檔案系統的功能,所以,讓我們用USB線把板子連接到電腦上,然后啟動rshell,當你進入rshell提示符時,輸入help來查看它提供的所有命令:

$ rshell --port /dev/ttyACM0
Using buffer-size of 32
Connecting to /dev/ttyACM0 (buffer-size 32)...
Trying to connect to REPL  connected
Retrieving sysname ... esp8266
Testing if ubinascii.unhexlify exists ... Y
Retrieving root directories ... /boot.py/
Setting time ... Jul 06, 2023 15:05:37
Evaluating board_name ... pyboard
Retrieving time epoch ... Jan 01, 2000
Welcome to rshell. Use Control-D (or the exit command) to exit rshell.
/home/andrew> help

Documented commands (type help <topic>):
========================================
args    cat  connect  date  edit  filesize  help  mkdir  rm     shell
boards  cd   cp       echo  exit  filetype  ls    repl   rsync

Use Control-D (or the exit command) to exit rshell.

但這些命令以一種非常有趣的方式作業,使你能夠同時處理你的計算機中的檔案系統和板上的檔案系統,你可以使用路徑和檔案名來參考你電腦中的任何檔案,但特殊目錄/pyboard被映射到MicroPython的檔案系統中,

home/andrew> ls /pyboard
boot.py
/home/andrew> ls /
boot/       home/       opt/        snap/       usr/        lib64@      swapfile   
cdrom/      lost+found/ proc/       srv/        var/        lib@       
dev/        media/      root/       sys/        bin@        libx32@    
etc/        mnt/        run/        tmp/        lib32@      sbin@      
/home/andrew> cat /pyboard/boot.py
# This file is executed on every boot (including wake-boot from deepsleep)
#import esp
#esp.osdebug(None)
import uos, machine
#uos.dupterm(None, 1) # disable REPL on UART(0)
import gc
#import webrepl
#webrepl.start()
gc.collect()

雖然修改和/或添加代碼到boot.py中并沒有什么不妥,但不去管這個檔案,因為有些情況下MicroPython本身會修改這個檔案,我更喜歡在main.py上進行所有的編碼,因為它是可完全掌控的檔案,

1.7 閃爍燈應用程式

為了使你所有的教程檔案井井有條,讓我們創建一個子目錄,用來存放本章的代碼,所以確保你的當前目錄被設定為micropython-tutorial,并創建一個chapter3子目錄:

/home/andrew/code/micro_esp/ch2> cat main.py
import machine
import time

led = machine.Pin(2, machine.Pin.OUT)
led2 = machine.Pin(16, machine.Pin.OUT)
while True:
    led.on()
    led2.off()
    time.sleep(0.5)
    led.off()
    led2.on()
    time.sleep(0.5)
/home/andrew/code/micro_esp/ch2> cp main.py /b
/bin/      /boot.py/  /boot/     
/home/andrew/code/micro_esp/ch2> cp main.py /pyboard/
Copying '/home/andrew/code/micro_esp/ch2/main.py' to '/pyboard/main.py' ...

要把這個檔案上傳到微控制器板上,你可以在rshell提使用cp命令, 拷貝完成后reset一下即可生效,

釘釘或微信號: pythontesting 微信公眾號:pythontesting

轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/556687.html

標籤:其他

上一篇:CPython, Pypy, MicroPython...還在傻傻分不清楚?

下一篇:返回列表

標籤雲
其他(162130) Python(38266) JavaScript(25524) Java(18291) C(15238) 區塊鏈(8275) C#(7972) AI(7469) 爪哇(7425) MySQL(7288) html(6777) 基礎類(6313) sql(6102) 熊猫(6058) PHP(5876) 数组(5741) R(5409) Linux(5347) 反应(5209) 腳本語言(PerlPython)(5129) 非技術區(4971) Android(4613) 数据框(4311) css(4259) 节点.js(4032) C語言(3288) json(3245) 列表(3129) 扑(3119) C++語言(3117) 安卓(2998) 打字稿(2995) VBA(2789) Java相關(2746) 疑難問題(2699) 细绳(2522) 單片機工控(2479) iOS(2438) ASP.NET(2404) MongoDB(2323) 麻木的(2285) 正则表达式(2254) 字典(2211) 循环(2198) 迅速(2185) 擅长(2169) 镖(2155) HtmlCss(1989) .NET技术(1985) 功能(1967) Web開發(1951) C++(1942) python-3.x(1918) 弹簧靴(1913) xml(1889) PostgreSQL(1882) .NETCore(1863) 谷歌表格(1846) Unity3D(1843) for循环(1842)

熱門瀏覽
  • 【C++】Microsoft C++、C 和匯編程式檔案

    ......

    uj5u.com 2020-09-10 00:57:23 more
  • 例外宣告

    相比于斷言適用于排除邏輯上不可能存在的狀態,例外通常是用于邏輯上可能發生的錯誤。 例外宣告 Item 1:當函式不可能拋出例外或不能接受拋出例外時,使用noexcept 理由 如果不打算拋出例外的話,程式就會認為無法處理這種錯誤,并且應當盡早終止,如此可以有效地阻止例外的傳播與擴散。 示例 //不可 ......

    uj5u.com 2020-09-10 00:57:27 more
  • Codeforces 1400E Clear the Multiset(貪心 + 分治)

    鏈接:https://codeforces.com/problemset/problem/1400/E 來源:Codeforces 思路:給你一個陣列,現在你可以進行兩種操作,操作1:將一段沒有 0 的區間進行減一的操作,操作2:將 i 位置上的元素歸零。最終問:將這個陣列的全部元素歸零后操作的最少 ......

    uj5u.com 2020-09-10 00:57:30 more
  • UVA11610 【Reverse Prime】

    本人看到此題沒有翻譯,就附帶了一個自己的翻譯版本 思考 這一題,它的第一個要求是找出所有 $7$ 位反向質數及其質因數的個數。 我們應該需要質數篩篩選1~$10^{7}$的所有數,這里就不慢慢介紹了。但是,重讀題,我們突然發現反向質數都是 $7$ 位,而將它反過來后的數字卻是 $6$ 位數,這就說明 ......

    uj5u.com 2020-09-10 00:57:36 more
  • 統計區間素數數量

    1 #pragma GCC optimize(2) 2 #include <bits/stdc++.h> 3 using namespace std; 4 bool isprime[1000000010]; 5 vector<int> prime; 6 inline int getlist(int ......

    uj5u.com 2020-09-10 00:57:47 more
  • C/C++編程筆記:C++中的 const 變數詳解,教你正確認識const用法

    1、C中的const 1、區域const變數存放在堆疊區中,會分配記憶體(也就是說可以通過地址間接修改變數的值)。測驗代碼如下: 運行結果: 2、全域const變數存放在只讀資料段(不能通過地址修改,會發生寫入錯誤), 默認為外部聯編,可以給其他源檔案使用(需要用extern關鍵字修飾) 運行結果: ......

    uj5u.com 2020-09-10 00:58:04 more
  • 【C++犯錯記錄】VS2019 MFC添加資源不懂如何修改資源宏ID

    1. 首先在資源視圖中,添加資源 2. 點擊新添加的資源,復制自動生成的ID 3. 在解決方案資源管理器中找到Resource.h檔案,編輯,使用整個專案搜索和替換的方式快速替換 宏宣告 4. Ctrl+Shift+F 全域搜索,點擊查找全部,然后逐個替換 5. 為什么使用搜索替換而不使用屬性視窗直 ......

    uj5u.com 2020-09-10 00:59:11 more
  • 【C++犯錯記錄】VS2019 MFC不懂的批量添加資源

    1. 打開資源頭檔案Resource.h,在其中預先定義好宏 ID(不清楚其實ID值應該設定多少,可以先新建一個相同的資源項,再在這個資源的ID值的基礎上遞增即可) 2. 在資源視圖中選中專案資源,按F7編輯資源檔案,按 ID 型別 相對路徑的形式添加 資源。(別忘了先把檔案拷貝到專案中的res檔案 ......

    uj5u.com 2020-09-10 01:00:19 more
  • C/C++編程筆記:關于C++的參考型別,專供新手入門使用

    今天要講的是C++中我最喜歡的一個用法——參考,也叫別名。 參考就是給一個變數名取一個變數名,方便我們間接地使用這個變數。我們可以給一個變數創建N個參考,這N + 1個變數共享了同一塊記憶體區域。(參考型別的變數會占用記憶體空間,占用的記憶體空間的大小和指標型別的大小是相同的。雖然參考是一個物件的別名,但 ......

    uj5u.com 2020-09-10 01:00:22 more
  • 【C/C++編程筆記】從頭開始學習C ++:初學者完整指南

    眾所周知,C ++的學習曲線陡峭,但是花時間學習這種語言將為您的職業帶來奇跡,并使您與其他開發人員區分開。您會更輕松地學習新語言,形成真正的解決問題的技能,并在編程的基礎上打下堅實的基礎。 C ++將幫助您養成良好的編程習慣(即清晰一致的編碼風格,在撰寫代碼時注釋代碼,并限制類內部的可見性),并且由 ......

    uj5u.com 2020-09-10 01:00:41 more
最新发布
  • MicroPython物聯網開發入門1歡迎上賊船ESP8266

    ## 1歡迎上賊船 ### 1.1 關于本教程 這是一個針對Python初學者的教程,他們想學習對設備進行編程,以便與物理世界互動。你將學習如何使用MicroPython編程,MicroPython是專為在微控制器上運行的Python版本。你將學習如何撰寫的應用程式將從傳感器讀取資料,在小螢屏上顯示 ......

    uj5u.com 2023-07-07 07:41:10 more
  • CPython, Pypy, MicroPython...還在傻傻分不清楚?

    哈嘍大家好,我是咸魚 當我們說 Python 時,通常指的是官方實作的 CPython 但還有很多比如 Pypy、Jython、MicroPython、Brython、RustPython 等 “python” 許多小伙伴看到這些帶 “python” 的概念可能一頭霧水,心想這跟我平時接觸到的 py ......

    uj5u.com 2023-07-07 07:40:54 more
  • 基數排序

    最近又有個奇奇怪怪的題目,資料為 $n \le 1 \times 10^7$,并且還要用到排序,普通的排序肯定會超時,然后就發現了一種 $O(n)$ ## 介紹 基數排序(Radix Sort)是桶排序的擴展,它是將整數按位數切割成不同的數字,然后按每個數位分別比較以此來排序。 說詳細點,也就是將所 ......

    uj5u.com 2023-07-07 07:40:50 more
  • 基數排序

    ## 前言 基數排序是一種非常快且好寫的排序。 以前一直以為基數排序就是桶排,現在發現自己很智慧,警鐘長鳴。 # 思想 基數排序是一個以桶排為基礎的排序。 桶排我就不多說了,簡單且 $O(n)$。 但是桶排有一個弊端,就是由于考試時空間限制是 $10^8$ 左右,可需要排序的資料是 $10^9$ 的 ......

    uj5u.com 2023-07-07 07:40:46 more
  • 2023 年 7 個適合初學者的 Vue.js 教程

    這個精心挑選的串列將幫助 Vue 初學者找到七個很棒的資源來開始學習 Vue。 我相信你來這里是為了尋找一些資源來開始學習 Vue.js 框架的奇妙旅程,無論是作為第一個工具還是你熟悉的其他框架的附加工具。不管怎樣,你很幸運,因為這就是我們將在這篇文章中介紹的內容。 隨著現代 Web 應用程式對更多 ......

    uj5u.com 2023-07-07 07:40:41 more
  • Servlet p7 ServletContext物件

    # ServletContext物件 **每一個 web 應用都有且僅有一個 ServletContext 物件**,又稱為 Application 物件,從名稱中可知,該物件是與應用程式相關的。在WEB 容器啟動時,會為每一個 WEB 應用創建一個對應的 ServletContex物件。 **該對 ......

    uj5u.com 2023-07-07 07:40:03 more
  • 基數排序

    ## 前言 基數排序是一種非常快且好寫的排序。 以前一直以為基數排序就是桶排,現在發現自己很智慧,警鐘長鳴。 # 思想 基數排序是一個以桶排為基礎的排序。 桶排我就不多說了,簡單且 $O(n)$。 但是桶排有一個弊端,就是由于考試時空間限制是 $10^8$ 左右,可需要排序的資料是 $10^9$ 的 ......

    uj5u.com 2023-07-07 07:00:09 more
  • SSO2.0 20-20230705

    ......

    uj5u.com 2023-07-06 09:39:00 more
  • SSO2.0 20-20230705

    ......

    uj5u.com 2023-07-06 09:32:13 more
  • 對敏感操作的二次認證 —— 詳解 Sa-Token 二級認證

    ### 一、需求分析 在某些敏感操作下,我們需要對已登錄的會話進行二次驗證。 比如代碼托管平臺的倉庫洗掉操作,盡管我們已經登錄了賬號,當我們點擊 **[洗掉]** 按鈕時,還是需要再次輸入一遍密碼,這么做主要為了兩點: 1. 保證操作者是當前賬號本人。 2. 增加操作步驟,防止誤洗掉重要資料。 這就 ......

    uj5u.com 2023-07-05 09:12:40 more